/*
 * Свои правила темы Ventala поверх style.css боевого: то, чего в Битриксе не
 * было, и то, что там жило инлайн-стилем в footer.php. Стили боевого лежат в
 * style.css и css/components/ как есть — здесь только надстройка.
 *
 * Разделы: базовое · первый экран · верхнее меню · виджет листа · /cart/ ·
 * параметры позиции · переходы страниц · мелкие появления · reduced motion.
 */

/* Атрибут hidden сильнее display из стилей компонентов (.hero{display:flex} и т.п.). */
[hidden] { display: none !important; }

/* Заглушки (404 и страницы без своего шаблона). */
.vnt-stub-main { max-width: 960px; margin: 40px auto; padding: 0 24px; }

/* Статические страницы (политика, cookies): inline-стили Битрикса переведены сидом в классы. */
.page-text { max-width: 1140px; margin: 0 auto; }
.w-70 { max-width: 70%; }
.fs-18 { font-size: 18pt; }
.fs-13 { font-size: 13pt; }

/* Картинка в <picture> ведёт себя как голый <img>: обёртка не ломает flex/grid родителя,
   а пустые <source> не занимают ячеек сетки и строк (у Chrome они без display:none). */
picture { display: contents; }
picture > source { display: none; }
/* Правила style.css вида «.images-product img:nth-child(2)» считали картинки среди
   соседей; внутри <picture> img идёт 2-м/3-м ребёнком после <source>, и эти правила
   прятали все картинки. Считаем сами обёртки — итог на мобильном тот же, что на боевом. */
@media (max-width: 768px) {
	.images-product picture:first-child img,
	.image-block-doble picture:first-child img { display: inline; }
	.images-product picture:nth-child(2) img,
	.images-product picture:nth-child(3) img,
	.image-block-doble picture:nth-child(2) img { display: none; }
}

/* ------------------------------------------------------------------------
   Первый экран: появление текста слайда. На боевом это инлайн-<style> из
   footer.php (textFadeUp): заголовок, текст и ссылка активного слайда
   всплывают снизу с задержкой .35/.55/.75 с поверх кроссфейда картинок.
   Добавлено сверх боевого: у уходящего слайда текст гаснет за .3 с, а не
   исчезает рывком в первый же кадр смены.
   ------------------------------------------------------------------------ */
.swiper-top-index .swiper-slide-active { opacity: 1; }
.swiper-top-index .h1-index,
.swiper-top-index .text-index,
.swiper-top-index .link-text-index {
	opacity: 0;
	transform: translateY(35px);
	transition: opacity .3s ease, transform .3s ease;
}
.swiper-top-index .swiper-slide-active .h1-index { animation: textFadeUp .8s ease forwards; animation-delay: .35s; }
.swiper-top-index .swiper-slide-active .text-index { animation: textFadeUp .8s ease forwards; animation-delay: .55s; }
.swiper-top-index .swiper-slide-active .link-text-index { animation: textFadeUp .8s ease forwards; animation-delay: .75s; }
@keyframes textFadeUp {
	from { opacity: 0; transform: translateY(35px); }
	to { opacity: 1; transform: translateY(0); }
}
.link-text-index { display: flex; align-items: center; gap: 10px; }
.link-text-index a { transition: opacity .3s ease; }
.link-text-index:hover a { opacity: .75; }

/* ------------------------------------------------------------------------
   Видео на слайде первого экрана (поле «Видео» у слайда, js/site.js).
   Ролик лежит под затемнением и текстом так же, как фоновая картинка, и
   растягивается как background-size: cover. Картинка слайда остаётся фоном:
   она видна, пока ролик грузится, у клонов слайда (loop у Swiper) и когда
   ролик не запускается («меньше движения», экономия трафика). Порядок слоёв
   задан явно: до видео затемнение ::before и текст стояли без z-index, а
   текст оказывался сверху только за счёт filter у заголовков.
   ------------------------------------------------------------------------ */
.vnt-hero-video { position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; pointer-events: none; }
.swiper-top-index .swiper-wrapper .swiper-slide:before { z-index: 1; }
.swiper-top-index .swiper-slide .container { position: relative; z-index: 2; }
/* В конце круга js/site.js сразу подменяет клон слайда настоящим (loopFix), и
   класс swiper-slide-active переходит к нему — анимация текста началась бы
   заново. Отрицательная задержка = исходная минус время смены слайда (.7 с):
   текст продолжает с того места, где был у клона. */
.swiper-top-index .swiper-slide-active.is-continued .h1-index { animation-delay: -.35s; }
.swiper-top-index .swiper-slide-active.is-continued .text-index { animation-delay: -.15s; }
.swiper-top-index .swiper-slide-active.is-continued .link-text-index { animation-delay: .05s; }
/* Тонировка ролика (замечания заказчика 24.09: «лёгкое тонирование», затем
   «светлее»). У слайда с видео подкладка ::before из фирменного #0C0C2D:
   мягкое пятно за блоком текста и узкие полосы под шапку (логотип, меню,
   иконки — верхние ~11 % кадра) и под нижнюю строку (стрелки, почта);
   середина кадра, где виден ролик, почти не затемнена. Равномерная плёнка
   светлее прежней роняла контраст на светлых кадрах (сварочная дуга 14 с,
   белая труба 8–9 с), а без полос терялись меню и логотип — замер в README.
   Центр и ширина пятна не меньше 340 и 640 px: на узком десктопе текст
   занимает большую долю кадра. Смешивание multiply уводит тени в синий, а
   не «туманит» кадр серым; слой ::after со смешиванием color слегка
   сдвигает оттенки к фирменному, сам ролик чуть обесцвечен.
   Слайды с картинками — как на боевом. */
.swiper-top-index .swiper-slide.has-video .vnt-hero-video { filter: saturate(.8); }
.swiper-top-index .swiper-wrapper .swiper-slide.has-video:before {
	--vnt-spot: 46% 66% at max(24%, 340px) 56%;
	--vnt-spot-stops: rgba(12, 12, 45, .42) 0%, rgba(12, 12, 45, .32) 56%, rgba(12, 12, 45, .12) 82%, rgba(12, 12, 45, 0) 100%;
	--vnt-bands: rgba(12, 12, 45, .5) 0%, rgba(12, 12, 45, .36) 9%, rgba(12, 12, 45, 0) 22%, rgba(12, 12, 45, 0) 62%, rgba(12, 12, 45, .32) 82%, rgba(12, 12, 45, .48) 100%;
	background:
		radial-gradient(var(--vnt-spot), var(--vnt-spot-stops)),
		linear-gradient(180deg, var(--vnt-bands));
	mix-blend-mode: multiply;
}
@media (max-width: 1390px) {
	/* 46 % здесь уже меньше 640 px. max() с процентами в размере градиента
	   Chrome не принимает (правило отбрасывается целиком) — поэтому так. */
	.swiper-top-index .swiper-wrapper .swiper-slide.has-video:before { --vnt-spot: 640px 66% at max(24%, 340px) 56%; }
}
@media (max-width: 768px) {
	/* На телефоне текст занимает всю середину кадра: пятно по центру, чуть
	   легче, полосы уже — светлота как была, а текст читается лучше. */
	.swiper-top-index .swiper-wrapper .swiper-slide.has-video:before {
		--vnt-spot: 90% 46% at 50% 50%;
		--vnt-spot-stops: rgba(12, 12, 45, .38) 0%, rgba(12, 12, 45, .3) 60%, rgba(12, 12, 45, .1) 86%, rgba(12, 12, 45, 0) 100%;
		--vnt-bands: rgba(12, 12, 45, .5) 0%, rgba(12, 12, 45, .36) 9%, rgba(12, 12, 45, 0) 18%, rgba(12, 12, 45, 0) 66%, rgba(12, 12, 45, .32) 84%, rgba(12, 12, 45, .48) 100%;
	}
}
.swiper-top-index .swiper-wrapper .swiper-slide.has-video:after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background: #0C0C2D;
	opacity: .3;
	mix-blend-mode: color;
}

/* ------------------------------------------------------------------------
   Верхнее меню (десктоп). На боевом при наведении на пункт с подменю:
   шапка получала top:2px, логотип менял display (inline → block, −4px
   высоты), синяя панель росла по высоте от 0, а список появлялся мгновенно —
   всё вместе дёргалось. Здесь: шапка стоит на месте, логотипы лежат друг на
   друге и меняются прозрачностью, панель постоянной высоты и подменю
   появляются плавно, а открытием управляет js/site.js (класс is-open с
   задержкой закрытия — переход курсора между пунктами не «моргает»).
   Внешне конечное состояние то же, что на боевом.
   ------------------------------------------------------------------------ */
/* На боевом scroolly ставил шапке inline top:0 и transition:all .5s; style.css
   своим .tophead.index-page{top:2px} до экрана не доходил. Классы теперь
   переключает js/site.js, поэтому то же — здесь; фон, логотипы и цвета
   меняются одной длительностью, чтобы тёмный логотип не всплывал над фото
   раньше, чем подъедет белая подложка. */
.tophead.index-page { top: 0; }
.tophead { transition: background-color .35s ease; }

@media (min-width: 769px) {
	.tophead .top-menu a { transition: color .35s ease; }
	.tophead .user path, .tophead .list path { transition: stroke .35s ease; }

	.logo { position: relative; }
	.tophead .ventala-w { display: block; position: absolute; left: 0; top: 25px; opacity: 0; transition: opacity .35s ease; }
	.tophead .ventala-color { display: inline; opacity: 1; transition: opacity .35s ease; }
	.tophead.index-page .ventala-w { opacity: 1; }
	.tophead.index-page .ventala-color { display: inline; opacity: 0; }
	/* Главная до прокрутки: на боевом виден только белый логотип блоком — та же высота шапки, что там. */
	.tophead.index-page:not(.fixed_up) .ventala-color { display: block; }

	#horizontal_multilevel_menu li.out_item a .blue_panel {
		height: 22rem;
		opacity: 0;
		pointer-events: none;
		transition: opacity .28s ease;
	}
	#horizontal_multilevel_menu li.out_item.is-open a .blue_panel { opacity: 1; pointer-events: auto; }

	#horizontal_multilevel_menu li.out_item > ul {
		display: block;
		opacity: 0;
		visibility: hidden;
		transform: translateY(-8px);
		pointer-events: none;
		transition: opacity .22s ease, transform .22s ease, visibility 0s linear .22s;
	}
	#horizontal_multilevel_menu li.out_item.is-open > ul {
		opacity: 1;
		visibility: visible;
		transform: none;
		pointer-events: auto;
		transition: opacity .25s ease .05s, transform .25s ease .05s, visibility 0s;
	}
}

/* ------------------------------------------------------------------------
   Виджет листа заявки. В стилях beehive панель анимировала сразу top (0 → 50%)
   и transform — отсюда «странный» ход; крестик закрытия и иконка в шапке
   переключались display'ем до того, как панель доезжала. Здесь панель всегда
   стоит на top:50% и едет только по горизонтали, крестик появляется, когда
   панель уже на месте, и гаснет первым при закрытии.
   ------------------------------------------------------------------------ */
#bee_cart .bc-cart-w {
	top: 50%;
	right: 0;
	transform: translate(100%, -50%);
	transition: transform .45s cubic-bezier(.22, .61, .36, 1);
}
#bee_cart.bc-cart-w-visible .bc-cart-w { transform: translate(0, -50%); }
#bee_cart .bc-cart-w-btn-show-cart-count__close {
	display: block;
	opacity: 0;
	visibility: hidden;
	transition: opacity .2s ease, visibility 0s linear .2s;
}
#bee_cart.bc-cart-w-visible .bc-cart-w-btn-show-cart-count__close {
	opacity: 1;
	visibility: visible;
	transition: opacity .25s ease .3s, visibility 0s linear .3s;
}
#bee_cart .bc-cart-w-btn-show-cart-count__ico,
#bee_cart .bc-cart-w-btn-show-cart-count { transition: opacity .25s ease; }
#bee_cart.bc-cart-w-visible .bc-cart-w-btn-show-cart-count__ico,
#bee_cart.bc-cart-w-visible .bc-cart-w-btn-show-cart-count { display: block; opacity: 0; pointer-events: none; }
@media (max-width: 380px) {
	/* На узких экранах beehive рисует кнопку «Закрыть» вместо крестика. */
	#bee_cart.bc-cart-w-visible .bc-cart-w-btn-show-cart-count__close { display: none; }
}

/* ------------------------------------------------------------------------
   /cart/: пустой лист занимает всю ширину и стоит по центру страницы,
   а не в правой колонке рядом со скрытой формой.
   ------------------------------------------------------------------------ */
.bc-cart-page-w.is-empty { width: 100%; float: none; }
.bc-cart-page-w.is-empty .bc-cart-page-w-content { margin-left: 0; }
.bc-cart-page-w.is-empty .bc-cart-page-w-content-title-empty { padding: 40px 30px 110px; }

/* ------------------------------------------------------------------------
   Позиция листа заявки (панель и /cart/): название и под ним код заказа
   жирными прописными, без подписи «Артикул:». Параметры комплектации на
   экран не выводятся — только в письме менеджеру (поле «Состав», ventala.cart).
   ------------------------------------------------------------------------ */
/* На /cart/ картинка позиции — float; описание — отдельный блочный контекст,
   чтобы длинный код не заворачивался под картинку. */
.bc-cart-page-w-content-item-detail { display: flow-root; }
.bc-cart-w-content-attr, .bc-cart-page-w-content-attr { margin-top: 6px; }
/* Регистр не трогаем: код заказа прописной сам, а «x» в размерах (950x125) — строчная. */
.bc-cart-w-content-attr-value, .bc-cart-page-w-content-attr-value {
	font: 600 12px/1.4 'Montserrat', sans-serif;
	color: #0C0C2D;
	overflow-wrap: anywhere;
}

/* /cart/: форма «Оформить заказ» и лист — две колонки одной сетки. Первая позиция
   встаёт вровень с первым полем формы (у позиций отступ сверху для разделителей;
   первой в ряду предшествует <template>, отсюда :first-of-type). На телефоне поля
   формы — во всю ширину контейнера, как крошки и заголовки. */
@media (min-width: 768px) {
	.bc-cart-page-w-content-item:first-of-type { padding-top: 0; }
}
@media (max-width: 767px) {
	.bee-form-w--inline .bee-form fieldset { padding-right: 0; }
}
/* «Заказ сформирован» — карточка в сетке, до подвала тот же воздух, что под кнопкой
   «Оформить» (48 px). Пока разметка выталкивала её из контейнера, она шла полосой
   во всю ширину и стояла вплотную к подвалу. */
.hero[data-cart-success] { margin-bottom: 48px; }

/* Телефон: кнопка листа (круг .list из шапки) — меньше и ниже прежнего, видна только
   с позициями в листе; над плашкой «Код заказа» и cookie её поднимает js/cart.js
   (--vnt-list-lift — высота плашки, 0 — плашек нет). */
@media (max-width: 768px) {
	.list {
		padding: 15px;
		bottom: max(calc(var(--vnt-list-lift, 0px) + 16px), calc(env(safe-area-inset-bottom, 0px) + 16px));
	}
	.list .bc-cart-w-btn-show-cart-count__ico svg { transform: scale(1.25); }
	.list .bc-cart-w-btn-show-cart-count { left: 33px !important; top: 12px !important; }
	.list.is-empty { display: none; }
}

/* ------------------------------------------------------------------------
   Переход между страницами: кроссфейд документа средствами браузера
   (View Transitions). Шапка вынесена в свою группу, чтобы не мерцать
   вместе со страницей. Где API нет — обычный переход, как раньше.
   ------------------------------------------------------------------------ */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vntVtOut .14s ease-out both; }
::view-transition-new(root) { animation: vntVtIn .28s cubic-bezier(.2, .7, .2, 1) both; }
.tophead { view-transition-name: vnt-header; }
::view-transition-old(vnt-header), ::view-transition-new(vnt-header) { animation-duration: .14s; }
@keyframes vntVtOut { to { opacity: 0; } }
@keyframes vntVtIn { from { opacity: 0; transform: translateY(8px); } }

/* ------------------------------------------------------------------------
   Дата в карточке новости (главная и /media/). В style.css строка даты стоит
   position:absolute у низа карточки: длинный заголовок в три строки налезал
   на неё, а на главной её ещё и уводило за карточку (bottom:-10px). Здесь
   карточка — колонка, дата идёт в потоке под заголовком и прижимается к низу
   (margin-top:auto) — в ряду карточек даты стоят на одной линии.
   ------------------------------------------------------------------------ */
.news-item-link { display: flex; flex-direction: column; }
.news-container-bottom,
.main.index .news-container-bottom {
	position: static;
	display: flex;
	height: auto;
	margin-top: auto;
	font-size: 14px;
	line-height: 20px;
}
.news-date { gap: 8px; color: #858596; }
.news-date svg { flex: none; }
.news-date time { font-variant-numeric: tabular-nums; }
.news-time:empty { display: none; }

/* ------------------------------------------------------------------------
   Плавная смена списка раздела при фильтрации (js/catalog-motion.js).
   Список — свой контекст наложения: в нём под карточками гаснут призраки
   ушедших (z-index: -1). Если ответ задержался дольше .15 с, список слегка
   гаснет — видно, что отбор применяется.
   ------------------------------------------------------------------------ */
.product-category [data-catalog-items] { position: relative; z-index: 0; }
.product-category [data-catalog-items] > .category-list { transition: opacity .2s ease; }
.product-category[data-catalog-busy] [data-catalog-items] > .category-list { opacity: .55; transition-delay: .15s; }

/* ------------------------------------------------------------------------
   SEO-проход 24.09.2026: заголовки стали настоящими h1/h2 при прежнем виде.
   Классы .title-h1, .name-section, .h1-index задают размер, жирность и
   отступы сами; остаётся верхний отступ h1 у первого слайда. В политике и
   cookies заголовок — бывший жирный абзац: h1 наследует его вид.
   Картинкам медиатеки vnt_picture() проставляет width/height — место под
   них резервируется до загрузки (сдвиг вёрстки на «Медиа» был 0,6); высоту
   считает браузер по пропорции, свои высоты в классах главнее (:where).
   ------------------------------------------------------------------------ */
.swiper-top-index h1.h1-index { margin-top: 0; }
h1.page-h1 { font-size: inherit; font-weight: inherit; line-height: inherit; margin: 1em 0; }
:where(img[width][height]) { height: auto; }

/* ---- Мелкие появления: мобильное меню и cookie-плашка ---- */
@keyframes vntFadeIn { from { opacity: 0; } }
@keyframes vntFadeUp { from { opacity: 0; transform: translateY(12px); } }
@media (max-width: 768px) {
	.top-out-menu.active { animation: vntFadeIn .22s ease both; }
}
#vnt-cookies:not([hidden]) { animation: vntFadeUp .4s ease both; }

/* ---- Системная настройка «меньше движения» ---- */
@media (prefers-reduced-motion: reduce) {
	.swiper-top-index .h1-index,
	.swiper-top-index .text-index,
	.swiper-top-index .link-text-index { opacity: 1; transform: none; animation: none; transition: none; }
	#bee_cart .bc-cart-w,
	#horizontal_multilevel_menu li.out_item > ul,
	#horizontal_multilevel_menu li.out_item a .blue_panel { transition: none; }
	::view-transition-old(root), ::view-transition-new(root),
	::view-transition-old(vnt-header), ::view-transition-new(vnt-header) { animation: none; }
	.top-out-menu.active, #vnt-cookies:not([hidden]) { animation: none; }
	.product-category [data-catalog-items] > .category-list { transition: none; }
}

/* ---- Фон окна «Спасибо»: копия WebP рядом с fon.jpg (AVIF выигрыша не дал) ---- */
.success-modal__content { background-image: image-set(url("fon.webp") type("image/webp"), url("fon.jpg")); }
