:root{--ae-container:1680px;--ae-radius:0px;--ae-logo-h:96px;--ae-primary:#2E9E5B;--ae-primary-hover:#23814A;--ae-on-primary:#FFFFFF;--ae-bg:#F4FAF6;--ae-surface:#FFFFFF;--ae-surface-2:#F4F6F8;--ae-text:#12261A;--ae-text-muted:#6B7280;--ae-border:#E3E7EB;--ae-price:#12261A;--ae-price-old:#9AA1AA;--ae-sale:#E8590C;--ae-rating:#F5A623;--ae-success:#198038;--ae-danger:#D93025;--ae-header-bg:#2E9E5B;--ae-header-text:#16191D;--ae-footer-bg:#12261A;--ae-footer-text:#C7CDD4;--ae-btn-radius:0px;--ae-btn-height:44px;--ae-btn-weight:600;--ae-input-radius:0px;--ae-input-height:42px;--ae-input-border:1px;--ae-card-radius:0px;--ae-badge-radius:6px;--ae-fs-base:15px;--ae-scale:1.22;--ae-lh:1.6;--ae-fw-head:700;--ae-sticker-sale:#E23D28;--ae-sticker-new:#12925A;--ae-sticker-hit:#F5A623;--ae-sticker-low:#6B7280;--ae-gap-1:8px;--ae-gap-2:14px;--ae-gap-3:22px;--ae-gap-4:34px;--ae-radius-sm:0px;--ae-radius-lg:0px;--ae-radius-pill:999px;--ae-font-body:"Nunito Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--ae-font-head:"Nunito Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;--ae-fs-h1:40.5px;--ae-fs-h2:33.2px;--ae-fs-h3:27.2px;--ae-fs-h4:22.3px;--ae-fs-h5:18.3px;--ae-fs-h6:15px;--ae-head-transform:uppercase;--ae-shadow-1:0 2px 6px color-mix(in srgb, rgba(15, 20, 28, .5) 10%, transparent);--ae-shadow-2:0 14px 30px -12px color-mix(in srgb, rgba(15, 20, 28, .5) 16%, transparent);--ae-shadow-3:0 28px 60px -20px color-mix(in srgb, rgba(15, 20, 28, .5) 22%, transparent);--ae-shadow-4:0 48px 96px -34px color-mix(in srgb, rgba(15, 20, 28, .5) 30%, transparent);--ae-shadow-side:-30px 0 72px -30px color-mix(in srgb, rgba(15, 20, 28, .5) 30%, transparent);--ae-shadow-accent:0 16px 38px -10px color-mix(in srgb, var(--ae-primary) 60%, transparent);--ae-motion:.18s;--ae-btn-transform:uppercase;--ae-btn-spacing:.04em;--ae-btn-shadow:0 8px 20px -12px color-mix(in srgb, var(--ae-primary) 70%, transparent);--ae-input-bg:var(--ae-surface);--ae-card-border:1px;--ae-card-shadow:none;--ae-card-lift:0;--ae-card-hover-shadow:var(--ae-card-shadow);--ae-card-hover-border:color-mix(in srgb, var(--ae-primary) 45%, var(--ae-border));--ae-divider:1px solid var(--ae-border);--ae-header-text:#FFFFFF;--ae-success-solid:#198038;--ae-sale-solid:#c54c0a;--ae-accent-on-light:#2E9E5B;--ae-accent-on-light-hover:#23814A;--ae-accent-on-light-ink:#FFFFFF;--ae-accent-on-dark:#4E90F5;--ae-accent-on-dark-hover:#6BA5FA;--ae-accent-on-dark-ink:#0B1220;}@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){--ae-primary:#4E90F5;--ae-primary-hover:#6BA5FA;--ae-on-primary:#0B1220;--ae-bg:#0F1216;--ae-surface:#171B21;--ae-surface-2:#1E242B;--ae-text:#E9EDF2;--ae-text-muted:#98A2AE;--ae-border:#2A313A;--ae-price:#E9EDF2;--ae-price-old:#6E7885;--ae-sale:#FF6B55;--ae-rating:#F5B942;--ae-success:#37C48A;--ae-danger:#FF6259;--ae-header-bg:#12161B;--ae-header-text:#E9EDF2;--ae-footer-bg:#0B0E12;--ae-footer-text:#98A2AE;--ae-header-text:#FFFFFF;--ae-success-solid:#247f5a;--ae-sale-solid:#bf5040;}}:root[data-theme="dark"]{--ae-primary:#4E90F5;--ae-primary-hover:#6BA5FA;--ae-on-primary:#0B1220;--ae-bg:#0F1216;--ae-surface:#171B21;--ae-surface-2:#1E242B;--ae-text:#E9EDF2;--ae-text-muted:#98A2AE;--ae-border:#2A313A;--ae-price:#E9EDF2;--ae-price-old:#6E7885;--ae-sale:#FF6B55;--ae-rating:#F5B942;--ae-success:#37C48A;--ae-danger:#FF6259;--ae-header-bg:#12161B;--ae-header-text:#E9EDF2;--ae-footer-bg:#0B0E12;--ae-footer-text:#98A2AE;--ae-header-text:#FFFFFF;--ae-success-solid:#247f5a;--ae-sale-solid:#bf5040;}
/* ------------------------------------------------------------------
   Сброс. Ровно столько, сколько нужно: гасим различия браузеров,
   но не переопределяем то, что дальше задаётся токенами.
   ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
	-webkit-text-size-adjust: 100%;
	scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
	}
}

body {
	margin: 0;
	font-family: var(--ae-font-body);
	font-size: var(--ae-fs-base);
	line-height: var(--ae-lh);
	color: var(--ae-text);
	background: var(--ae-bg);
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

img, svg, video, canvas { display: block; max-width: 100%; height: auto; }

button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }

a { color: var(--ae-primary); text-decoration: none; }
a:hover { color: var(--ae-primary-hover); }

ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

table { border-collapse: collapse; width: 100%; }

hr { border: 0; border-top: 1px solid var(--ae-border); margin: var(--ae-gap-3) 0; }

:focus-visible {
	outline: 2px solid var(--ae-primary);
	outline-offset: 2px;
	border-radius: 2px;
}

/* Прячем содержимое, оставляя его скринридерам. */
.ae-sr {
	position: absolute;
	width: 1px; height: 1px;
	padding: 0; margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* ==================================================================
   Заставка загрузки.

   Живёт в самом начале сборки и продублирована в критических стилях:
   заставка, которая появляется вместе с остальным оформлением, не нужна
   вовсе — к этому моменту страница уже отрисована.

   Убирается скриптом по событию load, а если скрипт не выполнился —
   правилом ниже через три секунды: висящая на весь экран белая плашка
   хуже, чем её отсутствие.
   ================================================================== */
.ae-preloader {
	position: fixed;
	inset: 0;
	z-index: 2000;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--ae-preloader-bg, #fff);
	animation: ae-preloader-give-up 0s linear 3s forwards;
}
.ae-preloader.is-done {
	opacity: 0;
	visibility: hidden;
	transition: opacity .25s, visibility .25s;
}

@keyframes ae-preloader-give-up {
	to { opacity: 0; visibility: hidden; }
}

.ae-preloader img { max-width: 60vw; height: auto; }

.ae-preloader__ring {
	width: 38px;
	height: 38px;
	border: 3px solid rgba(128, 128, 128, .25);
	border-top-color: var(--ae-primary, #2f6fed);
	border-radius: 50%;
	animation: ae-preloader-spin .7s linear infinite;
}

@keyframes ae-preloader-spin {
	to { transform: rotate(360deg); }
}

/* Полоса не перекрывает страницу: читать можно сразу, а индикатор
   показывает, что работа ещё идёт. */
.ae-preloader--bar {
	inset: 0 0 auto 0;
	height: 3px;
	background: none;
	display: block;
	pointer-events: none;
}
.ae-preloader__bar {
	display: block;
	height: 100%;
	width: 0;
	background: var(--ae-primary, #2f6fed);
	animation: ae-preloader-progress 8s cubic-bezier(.1, .8, .3, 1) forwards;
}

@keyframes ae-preloader-progress {
	to { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
	.ae-preloader__ring,
	.ae-preloader__bar { animation: none; }
}

/* ------------------------------------------------------------------
   Типографика. Размеры заголовков приходят из шкалы, посчитанной
   в Assets::derived() по базовому размеру и выбранному шагу.
   ------------------------------------------------------------------ */
/* Длинное слово переносится, а не вылезает за край.

   В русском таких слов много: «зарегистрированный», «комплектующие»,
   «сельскохозяйственный». На узком экране одно такое слово в заголовке
   раздвигает страницу, и она начинает ездить вбок целиком. Правило
   объявлено на body, поэтому действует и в чужих модулях, чью разметку
   мы не контролируем. */
body { overflow-wrap: break-word; }

h1, h2, h3, h4, h5, h6, .ae-h1, .ae-h2, .ae-h3 {
	margin: 0 0 var(--ae-gap-2);
	font-family: var(--ae-font-head);
	font-weight: var(--ae-fw-head);
	line-height: 1.2;
	letter-spacing: -.015em;
	text-wrap: balance;
	color: var(--ae-text);
}

h1, .ae-h1 { font-size: var(--ae-fs-h1); }
h2, .ae-h2 { font-size: var(--ae-fs-h2); }
h3, .ae-h3 { font-size: var(--ae-fs-h3); }
h4 { font-size: var(--ae-fs-h4); }
h5 { font-size: var(--ae-fs-h5); }
h6 { font-size: var(--ae-fs-h6); }

/*
	Шкала в настройках задаётся для десктопа: там 40 пикселей у заголовка
	уместны. На телефоне тот же размер разбивает «Сравнение товаров»
	на три строки и съедает первый экран. Уменьшаем долей, а не числом,
	чтобы выбранный владельцем шаг шкалы сохранился.
*/
@media (max-width: 767px) {
	h1, .ae-h1 { font-size: calc(var(--ae-fs-h1) * .84); }
	h2, .ae-h2 { font-size: calc(var(--ae-fs-h2) * .9); }
}

@media (max-width: 575px) {
	h1, .ae-h1 { font-size: calc(var(--ae-fs-h1) * .72); }
	h2, .ae-h2 { font-size: calc(var(--ae-fs-h2) * .82); }
	h3, .ae-h3 { font-size: calc(var(--ae-fs-h3) * .9); }
}

p { margin: 0 0 var(--ae-gap-2); }
p:last-child { margin-bottom: 0; }

small, .ae-small { font-size: .875em; }
strong, b { font-weight: 600; }

/* Заголовок секции на главной и в каталоге. */
.ae-section-title {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: var(--ae-gap-2);
	margin-bottom: var(--ae-gap-3);
}
.ae-section-title > :first-child {
	margin: 0;
	text-transform: var(--ae-head-transform);
}
.ae-section-title a { font-size: .9rem; white-space: nowrap; }

/* Пользовательский текст из редактора: описания, статьи, страницы. */

/*
	Вставленный текст часто тащит за собой инлайновый цвет — Word,
	Google Docs и особенно ответы нейросетей вставляют готовую HTML-
	разметку с готовым style="color: ...". Инлайн-стиль сильнее любой
	CSS-переменной темы, поэтому такой абзац остаётся чёрным навсегда,
	в том числе на тёмном фоне: получается нечитаемый текст, который
	никакой настройкой темы не поправить — его перебивает только другой
	инлайн-стиль.

	В это поле не вставляют разметку ради разноцветного текста, поэтому
	цвет здесь всегда берётся из темы, что бы ни было вставлено. Фон,
	отступы, списки, жирность и курсив это не трогает — их задаёт
	не инлайн-цвет, а тег и класс, и остаются как были.
*/
.ae-rte, .ae-rte * { color: var(--ae-text) !important; }
.ae-rte a, .ae-rte a * { color: var(--ae-primary) !important; }
.ae-rte a:hover, .ae-rte a:hover * { color: var(--ae-primary-hover) !important; }

.ae-rte > *:first-child { margin-top: 0; }
.ae-rte > *:last-child { margin-bottom: 0; }
.ae-rte img { border-radius: var(--ae-radius-sm); margin: var(--ae-gap-2) 0; }
.ae-rte ul, .ae-rte ol { margin: 0 0 var(--ae-gap-2); padding-left: 1.35em; }
.ae-rte ul li { list-style: disc; margin-bottom: .3em; }
.ae-rte ol li { list-style: decimal; margin-bottom: .3em; }
.ae-rte table { margin-bottom: var(--ae-gap-2); }
.ae-rte th, .ae-rte td { border: 1px solid var(--ae-border); padding: .5em .75em; text-align: left; }
.ae-rte blockquote {
	margin: var(--ae-gap-2) 0;
	padding: var(--ae-gap-2) var(--ae-gap-3);
	border-left: 3px solid var(--ae-primary);
	background: var(--ae-surface-2);
	border-radius: 0 var(--ae-radius-sm) var(--ae-radius-sm) 0;
}

/* ------------------------------------------------------------------
   Раскладка страницы.
   ------------------------------------------------------------------ */
.ae-container {
	width: 100%;
	max-width: var(--ae-container);
	margin-inline: auto;
	padding-inline: var(--ae-gap-2);
}

@media (min-width: 768px) {
	.ae-container { padding-inline: var(--ae-gap-3); }
}

.ae-page { padding-block: var(--ae-gap-3) var(--ae-gap-4); }
.ae-section { margin-bottom: var(--ae-gap-4); }
.ae-section:last-child { margin-bottom: 0; }

/* Страница с колонкой: боковая колонка сверху на мобильном, сбоку на десктопе. */
.ae-layout {
	display: grid;
	gap: var(--ae-gap-3);
	grid-template-columns: minmax(0, 1fr);
	align-items: start;
}

/* Элемент сетки по умолчанию не сжимается уже своего содержимого:
   одна широкая таблица или лента внутри — и вся страница уезжает вбок.
   Правило снимает это на корню, вместо ловли каждого случая отдельно. */
.ae-layout > *,
.ae-hslot > *,
.ae-main > *,
.ae-cart > *,
.ae-contactpage__grid > *,
.ae-contactpage__bottom > *,
.ae-products > *,
.ae-depts > * { min-width: 0; }

@media (min-width: 992px) {
	.ae-layout.has-left  { grid-template-columns: 268px minmax(0, 1fr); }
	.ae-layout.has-right { grid-template-columns: minmax(0, 1fr) 268px; }
	.ae-layout.has-both  { grid-template-columns: 268px minmax(0, 1fr) 268px; }
	.ae-layout .ae-aside { position: sticky; top: calc(var(--ae-header-h, 64px) + var(--ae-gap-2)); }
}

/* Нижние секции не рендерятся, пока не приблизятся к экрану. */
.ae-defer {
	content-visibility: auto;
	contain-intrinsic-size: auto 480px;
}

/* ==================================================================
   Оформление секций: фон, картинка, отступы, цвет текста.

   Один набор правил на все блоки витрины. Значения приходят из настроек
   модуля переменными, поэтому новый блок получает всё это бесплатно —
   достаточно вывести класс и стиль в его шаблоне.
   ================================================================== */
.ae-section.has-skin {
	position: relative;
	background-color: var(--ae-skin-bg, transparent);
	padding-block: var(--ae-skin-pad, var(--ae-gap-4));
}

/* ---------- Картинка фона ----------

   Отдельным слоем, а не свойством background у самой секции: поверх
   картинки нужно затемнение, а два фона на одном элементе не дают
   управлять их прозрачностью по отдельности. */
.ae-section.has-skin-image::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image: var(--ae-skin-image);
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
}
.ae-section.is-fit-contain::before { background-size: contain; }
.ae-section.is-fit-repeat::before { background-size: auto; background-repeat: repeat; }

/* Затемнение включается только когда задано: на светлой картинке
   с тёмным текстом оно лишнее. */
.ae-section.has-skin-image::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: #000;
	opacity: var(--ae-skin-veil, 0);
	pointer-events: none;
}

.ae-section.has-skin > * { position: relative; z-index: 1; }

/* ---------- Фон во всю ширину окна ----------

   Блок лежит в контейнере, а фон должен доходить до краёв экрана.
   Тень растягивается на любую ширину и не создаёт нового блока
   в потоке; clip-path обрезает её сверху и снизу, чтобы она не легла
   на соседние секции.

   Вариант с «margin-inline: calc(50% - 50vw)» здесь не годится: 50vw
   считается вместе с полосой прокрутки, и на десктопе страница
   уезжает вбок на её ширину. */
.ae-section.has-skin.is-full {
	box-shadow: 0 0 0 100vmax var(--ae-skin-bg, transparent);
	clip-path: inset(0 -100vmax);
}

/* У картинки тень не поможет — растягиваем сам слой. */
.ae-section.has-skin-image.is-full::before,
.ae-section.has-skin-image.is-full::after {
	left: 50%;
	right: auto;
	width: 100vw;
	transform: translateX(-50%);
	max-width: none;
}

/* ---------- Цвет текста ----------

   На тёмном фоне светлым должен стать весь блок, а не только заголовок:
   подписи, счётчики и вторичный текст берут свои цвета из переменных,
   поэтому переопределяем именно их. */
.ae-section.is-ink-light {
	--ae-text: #fff;
	--ae-text-muted: rgba(255, 255, 255, .72);
	--ae-border: rgba(255, 255, 255, .22);

	/* Акцент тоже подбираем под фон блока, а не под тему сайта:
	   тёмно-синяя ссылка дневной палитры на тёмной плашке пропадает
	   ровно так же, как и заголовок. */
	--ae-primary: var(--ae-accent-on-dark, var(--ae-primary-base));
	--ae-primary-hover: var(--ae-accent-on-dark-hover, var(--ae-primary-hover-base));
	--ae-on-primary: var(--ae-accent-on-dark-ink, var(--ae-on-primary-base));
	color: #fff;
}
.ae-section.is-ink-light .ae-section-title h2,
.ae-section.is-ink-light h2,
.ae-section.is-ink-light h3 { color: #fff; }

.ae-section.is-ink-dark {
	--ae-text: #12171f;
	--ae-text-muted: rgba(18, 23, 31, .66);
	--ae-border: rgba(18, 23, 31, .16);
	--ae-primary: var(--ae-accent-on-light, var(--ae-primary-base));
	--ae-primary-hover: var(--ae-accent-on-light-hover, var(--ae-primary-hover-base));
	--ae-on-primary: var(--ae-accent-on-light-ink, var(--ae-on-primary-base));
	color: #12171f;
}
.ae-section.is-ink-dark .ae-section-title h2,
.ae-section.is-ink-dark h2,
.ae-section.is-ink-dark h3 { color: #12171f; }

/* ---------- Карточки внутри блока ----------

   Карточка рисует собственную подложку, и цвет текста блока ей не
   годится: на белой плитке белый текст не виден вовсе. Раньше «Цвет
   текста → Светлый» на тёмном фоне делал невидимыми все преимущества,
   товары, бренды и отзывы разом — их подписи брали цвет у блока.

   Возвращаем таким карточкам палитру темы. Её копия лежит на :root
   вторым именем и переопределением блока не задета.

   Список короткий по определению: в нём только то, у чего есть свой
   фон. Всё остальное лежит прямо на фоне блока и цвет берёт от него —
   заголовок секции, вкладки витрины, текстовый блок. */

/* Копия палитры темы: живёт только на :root, поэтому переопределение
   блока до неё не достаёт, и карточке есть куда вернуться. */
:root {
	--ae-text-base: var(--ae-text);
	--ae-text-muted-base: var(--ae-text-muted);
	--ae-border-base: var(--ae-border);
	--ae-primary-base: var(--ae-primary);
	--ae-primary-hover-base: var(--ae-primary-hover);
	--ae-on-primary-base: var(--ae-on-primary);
}

.ae-section.is-ink-light :is(
	.ae-card, .ae-benefit, .ae-catwall__item, .ae-brands__item,
	.ae-shopreview, .ae-post, .ae-promo__tile, .ae-story--card,
	.ae-seotext__toc, .ae-seofaq__item, .ae-seotext__links a
),
.ae-section.is-ink-dark :is(
	.ae-card, .ae-benefit, .ae-catwall__item, .ae-brands__item,
	.ae-shopreview, .ae-post, .ae-promo__tile, .ae-story--card,
	.ae-seotext__toc, .ae-seofaq__item, .ae-seotext__links a
) {
	--ae-text: var(--ae-text-base);
	--ae-text-muted: var(--ae-text-muted-base);
	--ae-border: var(--ae-border-base);
	--ae-primary: var(--ae-primary-base);
	--ae-primary-hover: var(--ae-primary-hover-base);
	--ae-on-primary: var(--ae-on-primary-base);
	color: var(--ae-text-base);
}

/* Заголовки внутри карточки правило блока задевает напрямую, мимо
   наследования, — поэтому им цвет возвращается отдельно. */
.ae-section.is-ink-light :is(
	.ae-card, .ae-benefit, .ae-catwall__item, .ae-brands__item,
	.ae-shopreview, .ae-post, .ae-promo__tile, .ae-story--card,
	.ae-seotext__toc, .ae-seofaq__item, .ae-seotext__links a
) :is(h2, h3),
.ae-section.is-ink-dark :is(
	.ae-card, .ae-benefit, .ae-catwall__item, .ae-brands__item,
	.ae-shopreview, .ae-post, .ae-promo__tile, .ae-story--card,
	.ae-seotext__toc, .ae-seofaq__item, .ae-seotext__links a
) :is(h2, h3) { color: var(--ae-text-base); }

/* Плитка промо и обложка истории красят текст сами: он лежит поверх
   фотографии, а не на подложке карточки. */
.ae-section.is-ink-light .ae-promo__tile.is-ink-light,
.ae-section.is-ink-dark .ae-promo__tile.is-ink-light { color: #fff; }
.ae-section.is-ink-light .ae-story--card .ae-story__title,
.ae-section.is-ink-dark .ae-story--card .ae-story__title { color: #fff; }

/* ---------- Отступы ---------- */
.ae-section.is-pad-0 { --ae-skin-pad: 0; }
.ae-section.is-pad-1 { --ae-skin-pad: var(--ae-gap-3); }
.ae-section.is-pad-2 { --ae-skin-pad: calc(var(--ae-gap-4) * 1.8); }

@media (max-width: 767px) {
	/* Крупные отступы на телефоне съедают экран целиком. */
	.ae-section.is-pad-2 { --ae-skin-pad: var(--ae-gap-4); }
}

/* ---------- Шапка и подвал ----------

   Те же классы, но растягивать их не нужно: они и так во всю ширину,
   а вот слой картинки должен лежать под содержимым. */
.ae-header.has-skin-image,
.ae-footer.has-skin-image { position: relative; }

.ae-header.has-skin-image::before,
.ae-footer.has-skin-image::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background-image: var(--ae-skin-image);
	background-position: center;
	background-repeat: no-repeat;
	background-size: cover;
}
.ae-header.is-fit-contain::before,
.ae-footer.is-fit-contain::before { background-size: contain; }
.ae-header.is-fit-repeat::before,
.ae-footer.is-fit-repeat::before { background-size: auto; background-repeat: repeat; }

.ae-header.has-skin-image::after,
.ae-footer.has-skin-image::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 0;
	background: #000;
	opacity: var(--ae-skin-veil, 0);
	pointer-events: none;
}

.ae-header.has-skin-image > *,
.ae-footer.has-skin-image > * { position: relative; z-index: 1; }

/* Светлый или тёмный текст в шапке и подвале: те же переменные,
   что и у секций, плюс собственные переменные этих блоков. */
.ae-header.is-ink-light { --ae-header-text: #fff; color: #fff; }
.ae-header.is-ink-dark { --ae-header-text: #12171f; color: #12171f; }
.ae-footer.is-ink-light { --ae-footer-text: #fff; color: #fff; }
.ae-footer.is-ink-dark { --ae-footer-text: #12171f; color: #12171f; }

/* ==================================================================
   Слой совместимости с Bootstrap 3.

   Тема не подключает сам Bootstrap, но тысячи сторонних модулей для
   OpenCart 3 размечены его классами, и неперекрытые шаблоны стоковой
   темы — тоже. Здесь тот же публичный API, реализованный на flex и grid:
   вёрстка не разъезжается, а вес и скорость остаются нашими.

   Всё оформлено токенами темы, поэтому чужие модули автоматически
   получают наши цвета, скругления и тёмную тему.
   ================================================================== */

/* ---------- Сетка ---------- */
.container {
	width: 100%;
	max-width: var(--ae-container);
	margin-inline: auto;
	padding-inline: var(--ae-gap-2);
}
.container-fluid { width: 100%; padding-inline: var(--ae-gap-2); }

/* Поле страницы то же, что у .ae-container. Иначе неперекрытая
   страница кабинета отступает от края на одну величину, а корзина
   рядом — на другую, и переход между ними выглядит как переход
   между двумя разными сайтами. */
@media (min-width: 768px) {
	.container,
	.container-fluid { padding-inline: var(--ae-gap-3); }
}

.row {
	display: flex;
	flex-wrap: wrap;
	margin-inline: calc(var(--ae-gap-2) / -2);
}
/* Ширина по умолчанию объявлена через :where(), поэтому весит ноль.

   Раньше правило было записано как «.row > [class*="col-"]» и по
   специфичности перебивало сами классы колонок: .col-sm-6 (0,1,0)
   проигрывал (0,2,0), и любая сетка Bootstrap на сайте схлопывалась
   в одну колонку. Это касалось всех неперекрытых страниц — кабинета,
   входа, регистрации — и всех сторонних модулей. */
.row > :where([class*="col-"]) {
	width: 100%;
	padding-inline: calc(var(--ae-gap-2) / 2);
	min-width: 0;
}

.col-xs-1  { width: 8.333333%; }  .col-xs-2  { width: 16.666667%; }
.col-xs-3  { width: 25%; }        .col-xs-4  { width: 33.333333%; }
.col-xs-5  { width: 41.666667%; } .col-xs-6  { width: 50%; }
.col-xs-7  { width: 58.333333%; } .col-xs-8  { width: 66.666667%; }
.col-xs-9  { width: 75%; }        .col-xs-10 { width: 83.333333%; }
.col-xs-11 { width: 91.666667%; } .col-xs-12 { width: 100%; }

@media (min-width: 768px) {
	.col-sm-1  { width: 8.333333%; }  .col-sm-2  { width: 16.666667%; }
	.col-sm-3  { width: 25%; }        .col-sm-4  { width: 33.333333%; }
	.col-sm-5  { width: 41.666667%; } .col-sm-6  { width: 50%; }
	.col-sm-7  { width: 58.333333%; } .col-sm-8  { width: 66.666667%; }
	.col-sm-9  { width: 75%; }        .col-sm-10 { width: 83.333333%; }
	.col-sm-11 { width: 91.666667%; } .col-sm-12 { width: 100%; }
	.col-sm-offset-1 { margin-left: 8.333333%; }
	.col-sm-offset-2 { margin-left: 16.666667%; }
	.col-sm-offset-3 { margin-left: 25%; }
	.col-sm-offset-4 { margin-left: 33.333333%; }
}

@media (min-width: 992px) {
	.col-md-1  { width: 8.333333%; }  .col-md-2  { width: 16.666667%; }
	.col-md-3  { width: 25%; }        .col-md-4  { width: 33.333333%; }
	.col-md-5  { width: 41.666667%; } .col-md-6  { width: 50%; }
	.col-md-7  { width: 58.333333%; } .col-md-8  { width: 66.666667%; }
	.col-md-9  { width: 75%; }        .col-md-10 { width: 83.333333%; }
	.col-md-11 { width: 91.666667%; } .col-md-12 { width: 100%; }
	.col-md-offset-1 { margin-left: 8.333333%; }
	.col-md-offset-2 { margin-left: 16.666667%; }
	.col-md-offset-3 { margin-left: 25%; }
	.col-md-offset-4 { margin-left: 33.333333%; }
}

@media (min-width: 1200px) {
	.col-lg-1  { width: 8.333333%; }  .col-lg-2  { width: 16.666667%; }
	.col-lg-3  { width: 25%; }        .col-lg-4  { width: 33.333333%; }
	.col-lg-5  { width: 41.666667%; } .col-lg-6  { width: 50%; }
	.col-lg-7  { width: 58.333333%; } .col-lg-8  { width: 66.666667%; }
	.col-lg-9  { width: 75%; }        .col-lg-10 { width: 83.333333%; }
	.col-lg-11 { width: 91.666667%; } .col-lg-12 { width: 100%; }
}

/* ---------- Кнопки ---------- */
/* Размеры и начертание берутся из тех же переменных, что и .ae-btn:
   владелец магазина меняет высоту, скругление и регистр кнопок в одном
   месте, а половина кнопок в теме приходит из чужих шаблонов. Без этого
   «Оформить заказ» и «Сохранить» в кабинете выглядят разными кнопками. */
.btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: .5em;
	min-height: var(--ae-btn-height);
	padding: .5em 1.2em;
	border: 1px solid transparent;
	border-radius: var(--ae-btn-radius);
	background: var(--ae-surface-2);
	color: var(--ae-text);
	font-size: .94rem;
	font-weight: var(--ae-btn-weight);
	line-height: 1.25;
	text-align: center;
	text-transform: var(--ae-btn-transform);
	letter-spacing: var(--ae-btn-spacing);

	/* Не nowrap: «Продолжить покупки» и «Изменить адрес доставки» в
	   узкой колонке на телефоне вылезали за кнопку и тянули страницу
	   вбок. Пусть подпись переносится — кнопка станет выше, но целой. */
	white-space: normal;
	text-wrap: balance;
	transition: background-color .15s, border-color .15s, color .15s;
}
.btn:hover { color: var(--ae-text); }
.btn:disabled, .btn.disabled { opacity: .55; pointer-events: none; }

.btn-default { background: var(--ae-surface); border-color: var(--ae-border); }
.btn-default:hover { background: var(--ae-surface-2); }

.btn-primary { background: var(--ae-primary); border-color: var(--ae-primary); color: var(--ae-on-primary); box-shadow: var(--ae-btn-shadow); }
.btn-primary:hover { background: var(--ae-primary-hover); border-color: var(--ae-primary-hover); color: var(--ae-on-primary); }

.btn-danger  { background: var(--ae-danger);  border-color: var(--ae-danger);  color: #fff; }
.btn-success { background: var(--ae-success); border-color: var(--ae-success); color: #fff; }
.btn-warning { background: var(--ae-rating);  border-color: var(--ae-rating);  color: #1a1200; }
.btn-info    { background: var(--ae-surface-2); border-color: var(--ae-border); }
.btn-danger:hover, .btn-success:hover, .btn-warning:hover { filter: brightness(.93); }

.btn-link { background: none; border-color: transparent; color: var(--ae-primary); padding-inline: .25em; }
.btn-link:hover { color: var(--ae-primary-hover); text-decoration: underline; }

.btn-lg { min-height: calc(var(--ae-btn-height) + 8px); padding: .6em 1.6em; font-size: 1.02rem; }
.btn-sm { min-height: calc(var(--ae-btn-height) - 10px); padding: .35em .85em; font-size: .85rem; }
.btn-xs { min-height: calc(var(--ae-btn-height) - 16px); padding: .25em .6em; font-size: .8rem; }
.btn-block { display: flex; width: 100%; }

.btn-group { display: inline-flex; max-width: 100%; }
.btn-group > .btn { border-radius: 0; }
.btn-group > .btn:first-child { border-start-start-radius: var(--ae-btn-radius); border-end-start-radius: var(--ae-btn-radius); }
.btn-group > .btn:last-child  { border-start-end-radius: var(--ae-btn-radius);   border-end-end-radius: var(--ae-btn-radius); }
.btn-group > .btn + .btn { margin-left: -1px; }
.btn-group > .btn.active { background: var(--ae-primary); border-color: var(--ae-primary); color: var(--ae-on-primary); }

/* ---------- Формы ---------- */
.form-group { margin-bottom: var(--ae-gap-2); }
.control-label { display: block; margin-bottom: .35em; font-weight: 500; font-size: .87rem; }

/* Поле — те же переменные, что у .ae-input: высота, скругление,
   толщина рамки и заливка настраиваются один раз на всю витрину. */
.form-control {
	display: block;
	width: 100%;
	min-height: var(--ae-input-height);
	padding: .5em .9em;
	border: var(--ae-input-border) solid var(--ae-border);
	border-radius: var(--ae-input-radius);
	background: var(--ae-input-bg);
	color: var(--ae-text);
	line-height: 1.3;
	transition: border-color .15s, box-shadow .15s;
}
.form-control:focus {
	outline: 0;
	border-color: var(--ae-primary);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--ae-primary) 18%, transparent);
}
.form-control::placeholder { color: var(--ae-text-muted); opacity: 1; }
textarea.form-control { min-height: 7em; resize: vertical; }
select.form-control {
	appearance: none;
	padding-right: 2.2em;
	background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position: calc(100% - 1.05em) center, calc(100% - .75em) center;
	background-size: .32em .32em, .32em .32em;
	background-repeat: no-repeat;
}

.input-group { display: flex; width: 100%; }

/* Поле в группе — обычный флекс-элемент и по умолчанию не сжимается
   уже своего содержимого: длинный placeholder вроде «Введите код
   купона» распирал группу за край колонки. */
.input-group > .form-control { flex: 1 1 auto; min-width: 0; border-radius: 0; }

.input-group-btn { display: flex; flex: none; }
.input-group-btn > .btn { border-radius: 0; white-space: nowrap; }

/* Приставка бывает и слева, и справа: сортировка и «показывать по»
   в стоковом поиске ставят подпись перед списком, купон в корзине —
   кнопку после поля. Скругления и общая рамка выбираются по месту,
   иначе подпись отрывается от поля отдельной плашкой. */
.input-group-addon {
	display: flex;
	align-items: center;
	flex: none;
	padding: 0 .85em;
	border: var(--ae-input-border) solid var(--ae-border);
	background: var(--ae-surface-2);
	color: var(--ae-text-muted);
	white-space: nowrap;
}
.input-group > :first-child,
.input-group > :first-child > .btn {
	border-start-start-radius: var(--ae-input-radius);
	border-end-start-radius: var(--ae-input-radius);
}
.input-group > :last-child,
.input-group > :last-child > .btn {
	border-start-end-radius: var(--ae-input-radius);
	border-end-end-radius: var(--ae-input-radius);
}
.input-group > .input-group-addon:first-child { border-right: 0; }
.input-group > .input-group-addon:last-child { border-left: 0; }

.input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn { min-height: calc(var(--ae-input-height) - 8px); font-size: .87rem; }

.checkbox, .radio { display: block; margin-bottom: .5em; }
.checkbox label, .radio label { display: flex; align-items: flex-start; gap: .55em; cursor: pointer; }
.checkbox input, .radio input { margin-top: .25em; accent-color: var(--ae-primary); flex: none; }

.checkbox-inline, .radio-inline { display: inline-flex; align-items: center; gap: .45em; margin-right: var(--ae-gap-2); cursor: pointer; }
.checkbox-inline input, .radio-inline input { accent-color: var(--ae-primary); flex: none; }

.help-block { display: block; margin-top: .35em; font-size: .875em; color: var(--ae-text-muted); }
.has-error .form-control { border-color: var(--ae-danger); }
.has-error .help-block, .text-danger { color: var(--ae-danger); }
.required .control-label::after,
.required > label::after { content: " *"; color: var(--ae-danger); }

/* ---------- Горизонтальная форма ----------

   Регистрация, «моя информация», адресная книга и смена пароля —
   всё это неперекрытые шаблоны с form-horizontal: подпись в col-sm-2,
   поле в col-sm-10. Правило ширины колонок живёт только внутри .row,
   а .form-group строкой не является — в итоге подпись получала 16%
   ширины блоком, и «Подтверждение пароля» ломалось на три строки
   посреди слова, а поле обрывалось на 83%.

   Возвращаем ту же раскладку, что у .ae-field: подпись над полем,
   поле во всю ширину. Так стоковая форма и форма темы выглядят
   одинаково, а места хватает при любой длине подписи. */
.form-horizontal .form-group > [class*="col-"] { width: 100%; padding-inline: 0; min-width: 0; }
.form-horizontal .control-label { width: auto; text-align: left; }
.form-horizontal .form-group { margin-inline: 0; }

/* ---------- Группы полей ----------

   Стоковые шаблоны разбивают форму на fieldset с legend, а браузер
   рисует им рамку из девяностых: угловатую, с вырезом под подпись
   и своими отступами. Оформляем как панель темы. */
.container fieldset {
	margin: 0 0 var(--ae-gap-2);
	padding: var(--ae-gap-3);
	border: 1px solid var(--ae-border);
	border-radius: var(--ae-card-radius);
	background: var(--ae-surface);
	min-width: 0;
}
.container fieldset > legend {
	float: left;
	width: 100%;
	margin: 0 0 var(--ae-gap-2);
	padding: 0 0 .5em;
	border-bottom: 1px solid var(--ae-border);
	font-family: var(--ae-font-head);
	font-size: 1.05rem;
	font-weight: 600;
}
/* legend вынут из потока float'ом — иначе следующий за ним блок
   встаёт с ним на одну строку. Возвращаем поток вручную. */
.container fieldset > legend + * { clear: both; }
.container fieldset > .form-group:last-child,
.container fieldset > .table-responsive:last-child { margin-bottom: 0; }

/* ---------- Панели и таблицы ---------- */
.panel {
	background: var(--ae-surface);
	border: 1px solid var(--ae-border);
	border-radius: var(--ae-card-radius);
	margin-bottom: var(--ae-gap-2);
	overflow: hidden;
}
.panel-heading { padding: var(--ae-gap-2) var(--ae-gap-3); border-bottom: 1px solid var(--ae-border); font-weight: 600; }
.panel-title { margin: 0; font-size: 1.05rem; }
.panel-body { padding: var(--ae-gap-3); }
.panel-footer { padding: var(--ae-gap-2) var(--ae-gap-3); border-top: 1px solid var(--ae-border); background: var(--ae-surface-2); }

.table-responsive { overflow-x: auto; margin-bottom: var(--ae-gap-2); -webkit-overflow-scrolling: touch; }
.table { margin-bottom: var(--ae-gap-2); }
.table-responsive > .table { margin-bottom: 0; }
.table th, .table td { padding: .65em .8em; text-align: left; vertical-align: middle; border-bottom: 1px solid var(--ae-border); }
/* В стоковых шаблонах OpenCart шапка таблицы размечена <td>, а не <th>
   (история заказов, закладки, загрузки, транзакции). Правило только
   на th не срабатывало ни разу, и шапка ничем не отличалась от строк. */
.table > thead > tr > th,
.table > thead > tr > td { font-weight: 600; background: var(--ae-surface-2); }
.table-bordered, .table-bordered th, .table-bordered td { border: 1px solid var(--ae-border); }
.table-striped tbody tr:nth-child(odd) { background: var(--ae-surface-2); }
.table-hover tbody tr:hover { background: var(--ae-surface-2); }
.table img { max-width: 72px; height: auto; border-radius: var(--ae-radius-sm); }

/* Таблица заказов или закладок — это шесть колонок с русскими
   заголовками. На телефоне table{width:100%} из сброса ужимает их
   до нечитаемых столбиков в два символа. Задаём таблице минимальную
   ширину: контейнер прокручивается, страница вбок не едет. */
@media (max-width: 767px) {
	.table-responsive > .table { min-width: 560px; }
}

/* ---------- Сообщения ---------- */
.alert {
	display: flex;
	align-items: flex-start;
	gap: .6em;
	padding: .85em 1em;
	border: 1px solid var(--ae-border);
	border-radius: var(--ae-radius-sm);
	background: var(--ae-surface-2);
	margin-bottom: var(--ae-gap-2);
}
.alert-success { border-color: color-mix(in srgb, var(--ae-success) 40%, transparent); background: color-mix(in srgb, var(--ae-success) 12%, var(--ae-surface)); }
.alert-danger  { border-color: color-mix(in srgb, var(--ae-danger)  40%, transparent); background: color-mix(in srgb, var(--ae-danger)  12%, var(--ae-surface)); }
.alert-warning { border-color: color-mix(in srgb, var(--ae-rating)  45%, transparent); background: color-mix(in srgb, var(--ae-rating)  14%, var(--ae-surface)); }
.alert-info    { border-color: color-mix(in srgb, var(--ae-primary) 35%, transparent); background: color-mix(in srgb, var(--ae-primary) 10%, var(--ae-surface)); }
.alert .close { margin-left: auto; font-size: 1.3em; line-height: 1; opacity: .55; }
.alert .close:hover { opacity: 1; }

/* ---------- Вкладки ---------- */
.nav-tabs {
	display: flex;
	flex-wrap: wrap;
	gap: .25em;
	border-bottom: 1px solid var(--ae-border);
	margin-bottom: var(--ae-gap-2);
}
.nav-tabs > li > a {
	display: block;
	padding: .65em 1.1em;
	color: var(--ae-text-muted);
	border-bottom: 2px solid transparent;
	font-weight: 500;
}
.nav-tabs > li.active > a, .nav-tabs > li > a:hover { color: var(--ae-text); }
.nav-tabs > li.active > a { border-bottom-color: var(--ae-primary); }
.tab-content > .tab-pane { display: none; }
.tab-content > .tab-pane.active { display: block; }

/* ---------- Списки ---------- */
.list-group { border: 1px solid var(--ae-border); border-radius: var(--ae-card-radius); overflow: hidden; margin-bottom: var(--ae-gap-2); }
.list-group-item { display: block; padding: .7em 1em; border-bottom: 1px solid var(--ae-border); background: var(--ae-surface); color: var(--ae-text); }
.list-group-item:last-child { border-bottom: 0; }
a.list-group-item:hover { background: var(--ae-surface-2); }
.list-group-item.active { background: var(--ae-primary); color: var(--ae-on-primary); }

/* Отступ снизу обязателен: на странице входа два .well лежат в
   col-sm-6, а на телефоне колонки встают друг под друга — без него
   «Новый клиент» и «Зарегистрированный клиент» слипались в один блок. */
.well {
	padding: var(--ae-gap-3);
	margin-bottom: var(--ae-gap-2);
	background: var(--ae-surface-2);
	border-radius: var(--ae-card-radius);
}

/* ---------- Выпадающие меню ---------- */
.dropdown { position: relative; }
.dropdown-menu {
	position: absolute;
	z-index: 200;
	top: 100%;
	left: 0;
	min-width: 190px;
	padding: .35em 0;
	margin: .3em 0 0;
	background: var(--ae-surface);
	border: 1px solid var(--ae-border);
	border-radius: var(--ae-radius-sm);
	box-shadow: var(--ae-shadow-3);
	display: none;
}
.dropdown-menu-right { left: auto; right: 0; }
.open > .dropdown-menu, .dropdown.open .dropdown-menu { display: block; }
.dropdown-menu > li > a, .dropdown-menu li a { display: block; padding: .5em 1em; color: var(--ae-text); white-space: nowrap; }
.dropdown-menu > li > a:hover, .dropdown-menu li a:hover { background: var(--ae-surface-2); }
.dropdown-menu .divider { height: 1px; margin: .35em 0; background: var(--ae-border); }
.caret {
	display: inline-block;
	width: 0; height: 0;
	margin-left: .3em;
	vertical-align: middle;
	border-top: .3em solid;
	border-right: .3em solid transparent;
	border-left: .3em solid transparent;
}

/* ---------- Модальные окна ---------- */
.modal {
	position: fixed;
	inset: 0;
	z-index: 1050;
	display: none;
	overflow-y: auto;
	background: rgba(0, 0, 0, .55);
	padding: var(--ae-gap-3) var(--ae-gap-2);
}
.modal.in, .modal.show { display: block; }
.modal-dialog { max-width: 620px; margin-inline: auto; }
.modal-content {
	background: var(--ae-surface);
	border-radius: var(--ae-radius);
	box-shadow: var(--ae-shadow-4);
	overflow: hidden;
}
.modal-header { display: flex; align-items: center; gap: var(--ae-gap-2); padding: var(--ae-gap-2); border-bottom: 1px solid var(--ae-border); }
.modal-header .close { margin-left: auto; font-size: 1.5em; line-height: 1; opacity: .5; }
.modal-header .close:hover { opacity: 1; }
.modal-title { margin: 0; font-size: 1.05rem; }
.modal-body { padding: var(--ae-gap-2); }
.modal-footer { display: flex; justify-content: flex-end; gap: .5em; padding: var(--ae-gap-2); border-top: 1px solid var(--ae-border); }
.modal-backdrop { display: none; }
body.modal-open { overflow: hidden; }

/* ---------- Метки, крошки, пагинация ---------- */
.label, .badge {
	display: inline-block;
	padding: .22em .55em;
	border-radius: var(--ae-radius-pill);
	background: var(--ae-surface-2);
	color: var(--ae-text);
	font-size: .78em;
	font-weight: 600;
	line-height: 1.4;
}
.label-success { background: var(--ae-success); color: #fff; }
.label-danger  { background: var(--ae-danger);  color: #fff; }
.label-warning { background: var(--ae-rating);  color: #1a1200; }
.label-info, .label-primary { background: var(--ae-primary); color: var(--ae-on-primary); }

.breadcrumb { display: flex; flex-wrap: wrap; gap: .3em .55em; margin-bottom: var(--ae-gap-2); font-size: .875rem; }
.breadcrumb > li { display: flex; align-items: center; gap: .55em; color: var(--ae-text-muted); }
.breadcrumb > li + li::before { content: "/"; color: var(--ae-border); }
.breadcrumb a { color: var(--ae-text-muted); }
.breadcrumb a:hover { color: var(--ae-primary); }

.pagination { display: flex; flex-wrap: wrap; gap: .3em; }
.pagination > li > a, .pagination > li > span {
	display: flex;
	align-items: center;
	justify-content: center;
	min-width: 2.3em;
	height: 2.3em;
	padding: 0 .5em;
	border: 1px solid var(--ae-border);
	border-radius: var(--ae-radius-sm);
	color: var(--ae-text);
}
.pagination > li > a:hover { background: var(--ae-surface-2); }
.pagination > li.active > span { background: var(--ae-primary); border-color: var(--ae-primary); color: var(--ae-on-primary); }

/* ---------- Утилиты ---------- */
.pull-left  { float: left; }
.pull-right { float: right; }
.clearfix::after { content: ""; display: table; clear: both; }
.text-left { text-align: left; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.text-muted { color: var(--ae-text-muted); }
.img-responsive { display: block; max-width: 100%; height: auto; }
.img-thumbnail { border: 1px solid var(--ae-border); border-radius: var(--ae-radius-sm); padding: 3px; background: var(--ae-surface); }
.hide, [hidden] { display: none !important; }
.center-block { display: block; margin-inline: auto; }

@media (max-width: 767px) {
	.hidden-xs { display: none !important; }
}
@media (min-width: 768px) and (max-width: 991px) {
	.hidden-sm { display: none !important; }
}
@media (min-width: 992px) and (max-width: 1199px) {
	.hidden-md { display: none !important; }
}
@media (min-width: 1200px) {
	.hidden-lg { display: none !important; }
}
@media (min-width: 768px) {
	.visible-xs { display: none !important; }
}
.hidden { display: none !important; }

/* ==================================================================
   Ритм неперекрытых страниц.

   Признак «страница пришла из темы default» — обёртка .container:
   свои страницы темы верстаются на .ae-container, и голый .container
   встречается только в стоковых шаблонах и чужих модулях. По #content
   отличать нельзя: этим идентификатором тема помечает <main>, то есть
   он есть на каждой странице.

   Это единственное место, где стоковым страницам можно задать отступы
   и типографику темы, не переписывая 79 шаблонов по отдельности.
   ================================================================== */
.breadcrumb { margin-block: var(--ae-gap-3) var(--ae-gap-2); }

#content { min-width: 0; }

/* Боковые колонки темы приходят в стоковую .row своим блоком, без
   классов col-*: раскладку страниц темы держит грид .ae-layout, а не
   сетка Bootstrap. Во флекс-ряду такой блок сжимается по содержимому —
   на телефоне меню кабинета висело узкой полосой в две трети экрана
   и вплотную к форме сверху. Отдаём ему ширину колонки. */
.row > .ae-modules {
	width: 100%;
	min-width: 0;
	padding-inline: calc(var(--ae-gap-2) / 2);
	margin-top: var(--ae-gap-3);
}

@media (min-width: 768px) {
	.row > .ae-modules { width: 25%; margin-top: 0; }
}

/* Панель сортировки в стоковых списках сложена из двух групп в
   col-xs-6. На 375px подпись «Сортировка:» съедает половину экрана,
   и от самого списка остаётся одна буква. Даём каждой группе строку. */
@media (max-width: 575px) {
	.row > [class*="col-"]:has(> .form-group.input-group) { width: 100%; }
}

/* Заголовок страницы: стоковые шаблоны ставят то h1, то h2, и оба
   берут размер из витринной шкалы. В колонке col-sm-6 такой размер
   рвёт «Зарегистрированный клиент» посреди слова. Шаг вниз. */
.container .row > [class*="col-"] > h1 { margin-bottom: var(--ae-gap-3); font-size: var(--ae-fs-h2); text-wrap: balance; }
.container .row > [class*="col-"] > h2 { margin-bottom: var(--ae-gap-3); font-size: var(--ae-fs-h3); text-wrap: balance; }

/* Второй и следующие заголовки на странице — это новый раздел
   («Результаты поиска» после формы поиска). Без отступа сверху он
   прилипал к кнопке предыдущего блока. */
.container .row > [class*="col-"] > :is(h1, h2, h3) ~ :is(h1, h2, h3) { margin-top: var(--ae-gap-4); }
.well h2, .panel h2 { font-size: var(--ae-fs-h4); }
.well h3, .panel h3 { font-size: var(--ae-fs-h5); }

/* Ряд кнопок под формой. В стоковых шаблонах он собран на float'ах:
   без очистки следующий блок наползал на кнопки, а на телефоне
   «Назад» и «Продолжить» становились друг на друга без просвета. */
.container .buttons {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--ae-gap-2);
	margin-top: var(--ae-gap-3);
}
.container .buttons > .pull-left,
.container .buttons > .pull-right { float: none; }

/* Внутри .pull-right лежат вперемешку текст согласия, чекбокс и
   кнопка отправки — строчным потоком. Кнопка выше строки, и её
   верхняя половина заезжала на текст. Разбираем на флекс-элементы. */
.container .buttons > * {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: .5em;
	min-width: 0;
}

/* ==================================================================
   Значки FontAwesome.

   Шрифт тема не подключает, а стоковые шаблоны и языковые файлы
   OpenCart размечены им до сих пор. Пустой <i class="fa fa-home">
   схлопывается в ноль: первая крошка «Главная» исчезает, а разделитель
   перед ней остаётся; кнопки «в корзину» и «удалить» в закладках
   вообще состоят из одного значка и превращаются в пустые плашки.

   Рисуем маской по currentColor: значок наследует цвет ссылки или
   кнопки и одинаково работает в светлой и тёмной теме.
   ================================================================== */
.fa-home, .fa-shopping-cart, .fa-times, .fa-times-circle, .fa-heart, .fa-heart-o,
.fa-exchange, .fa-eye, .fa-pencil, .fa-search, .fa-calendar, .fa-star, .fa-star-o,
.fa-check-circle, .fa-exclamation-circle, .fa-info-circle, .fa-caret-down, .fa-bars,
.fa-user, .fa-phone, .fa-envelope, .fa-map-marker, .fa-reply, .fa-th, .fa-th-list {
	display: inline-block;
	width: 1em;
	height: 1em;
	vertical-align: -.125em;
	background-color: currentColor;
	-webkit-mask: var(--ae-fa) center / contain no-repeat;
	mask: var(--ae-fa) center / contain no-repeat;
}

.fa-home { --ae-fa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linejoin='round'%3E%3Cpath d='M4 10.5 12 4l8 6.5V20H4z'/%3E%3Cpath d='M9.5 20v-6h5v6'/%3E%3C/svg%3E"); }
.fa-shopping-cart { --ae-fa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linejoin='round'%3E%3Cpath d='M3 4h2l2.4 11.4h9.7L20 8H6'/%3E%3Ccircle cx='10' cy='20' r='1.4'/%3E%3Ccircle cx='17' cy='20' r='1.4'/%3E%3C/svg%3E"); }
.fa-times { --ae-fa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E"); }
.fa-times-circle { --ae-fa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='m15 9-6 6M9 9l6 6'/%3E%3C/svg%3E"); }
.fa-heart, .fa-heart-o { --ae-fa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linejoin='round'%3E%3Cpath d='M12 20s-7.5-4.7-7.5-9.6A3.9 3.9 0 0 1 12 8a3.9 3.9 0 0 1 7.5 2.4C19.5 15.3 12 20 12 20z'/%3E%3C/svg%3E"); }
.fa-exchange { --ae-fa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8h15M15 4l4 4-4 4M20 16H5M9 12l-4 4 4 4'/%3E%3C/svg%3E"); }
.fa-eye { --ae-fa: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' strok