/*
Theme Name: leadfab
Theme URI: https://leadfab.ru
Description: Тема сайта лидогенерации leadfab
Version: 0.1.0
Requires at least: 6.6
Requires PHP: 8.2
Text Domain: leadfab
*/

@font-face {
	font-family: 'Montserrat';
	src: url('assets/fonts/montserrat-var.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}

@font-face {
	font-family: 'Unbounded';
	src: url('assets/fonts/unbounded-var.woff2') format('woff2');
	font-weight: 200 900;
	font-style: normal;
	font-display: swap;
}

:root {
	--lf-grad-from: #FF8A00;
	--lf-grad-to: #FF2D6B;
	--lf-accent: #FFC63C;
	--lf-text: #1B1B2F;
	--lf-muted: #5C5C72;
	--lf-bg: #FFFFFF;
	--lf-bg-soft: #F6F6FA;
	--lf-border: #E4E4EE;
	--lf-gradient: linear-gradient(100deg, var(--lf-grad-from), var(--lf-grad-to));
	--lf-radius: 20px;
	--lf-radius-sm: 12px;
	--lf-container: 1200px;
	--lf-gap: 24px;
	--lf-section-y: clamp(48px, 7vw, 96px);
	--lf-font: 'Montserrat', 'Segoe UI', Arial, sans-serif;
	--lf-ink: #1B1B2F;
	--lf-ink-2: #23233D;
	--lf-paper: #F7F7FB;
	--lf-line-light: #E4E4EE;
	--lf-line-dark: rgba(255, 255, 255, 0.14);
	/* Отдельный токен для разделителей на тёмном фоне - не заменяет
	   --lf-line-dark выше (тот остаётся рамкой карточек: там линию видно по
	   отличию заливки, а не только по контрасту самой линии). В секции
	   преимуществ разделитель между пунктами - единственная графическая
	   граница, поэтому нужен контраст non-text элемента по WCAG 1.4.11
	   (не ниже 3:1). alpha 0.14 (--lf-line-dark) на фоне --lf-ink даёт
	   1.54:1 - ниже нормы. alpha 0.35 даёт 3.20:1. Расчёт - та же формула
	   относительной светимости WCAG 2.1, что у --lf-error выше. */
	--lf-divider-dark: rgba(255, 255, 255, 0.35);
	--lf-font-head: 'Unbounded', 'Segoe UI', Arial, sans-serif;
	--lf-font-body: 'Montserrat', 'Segoe UI', Arial, sans-serif;
	/* Канон - --lf-ink, --lf-dark сохранён для совместимости с шапкой и подвалом */
	--lf-dark: var(--lf-ink);
	/* Цвет ошибки формы - два значения для светлого и тёмного фона, у
	   фирменного розового (--lf-grad-to, #FF2D6B) контраст ниже нормы WCAG
	   AA (4.5:1 для обычного текста): 3.6:1 на белом фоне модалки и 4.3:1 на
	   тёмной карточке .lf-cta-form. --lf-error - более тёмный оттенок для
	   светлого фона (5.34:1 к белому), --lf-error-on-dark - более светлый
	   оттенок для тёмного фона (6.39:1 к --lf-ink-2). Расчёт контраста -
	   относительная светимость по WCAG 2.1, формула (L1+0.05)/(L2+0.05). */
	--lf-error: #D6003F;
	--lf-error-on-dark: #FF7FA3;
	/* Полная высота шапки (строка + нижняя граница) - единственное место,
	   где это число записано. Используется и в min-height внутреннего блока
	   шапки, и в отрицательном отступе overlay-шапки, и в компенсирующем
	   верхнем отступе первого экрана - при правке высоты шапки менять только
	   здесь. */
	--lf-header-h: 77px;
	--lf-ease: cubic-bezier(0.2, 0.7, 0.2, 1);
	--lf-dur-fast: 180ms;
	--lf-dur-slow: 420ms;
	--lf-shift: 16px;
	--lf-dur-travel: 600ms;
	--lf-stagger: 60ms;
}

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

body {
	margin: 0;
	font-family: var(--lf-font);
	font-size: 17px;
	line-height: 1.6;
	color: var(--lf-text);
	background: var(--lf-bg);
	-webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
	font-family: var(--lf-font-head);
	font-weight: 700;
	letter-spacing: -0.02em;
	line-height: 1.05;
	margin: 0 0 0.5em;
}

h1 { font-size: clamp(32px, 5vw, 56px); font-weight: 700; }
h2 { font-size: clamp(26px, 3.4vw, 40px); font-weight: 700; }
h3 { font-size: clamp(19px, 2vw, 24px); font-weight: 600; }

a { color: inherit; }

img, svg { max-width: 100%; height: auto; }

.lf-skip-link {
	position: absolute;
	top: -100%;
	left: 16px;
	z-index: 100;
	padding: 12px 20px;
	background: var(--lf-dark);
	color: #FFFFFF;
	border-radius: var(--lf-radius-sm);
	text-decoration: none;
	transition: top var(--lf-dur-fast) var(--lf-ease);
}

.lf-skip-link:focus {
	top: 16px;
}

.lf-container {
	width: min(100% - 32px, var(--lf-container));
	margin-inline: auto;
}

.lf-section {
	padding-block: var(--lf-section-y);
}

.lf-btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	padding: 16px 28px;
	border: 0;
	border-radius: var(--lf-radius-sm);
	font: inherit;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
}

.lf-btn--primary {
	background: var(--lf-gradient);
	color: #FFFFFF;
}

.lf-btn--ghost {
	background: transparent;
	color: var(--lf-text);
	box-shadow: inset 0 0 0 2px var(--lf-border);
}

/* Вариант для тёмных секций (герой и другие тёмные блоки) - светлый текст
   и светлая рамка вместо тёмных, рассчитанных на светлый фон. */
.lf-btn--ghost-dark {
	background: transparent;
	color: #FFFFFF;
	box-shadow: inset 0 0 0 2px var(--lf-line-dark);
}

.lf-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: rgba(255, 255, 255, 0.92);
	-webkit-backdrop-filter: blur(10px);
	backdrop-filter: blur(10px);
	border-bottom: 1px solid var(--lf-border);
}

.lf-header__inner {
	display: flex;
	align-items: center;
	gap: var(--lf-gap);
	min-height: var(--lf-header-h);
}

.lf-header__nav {
	margin-inline-start: auto;
}

.lf-menu {
	display: flex;
	gap: 28px;
	margin: 0;
	padding: 0;
	list-style: none;
	font-weight: 500;
}

.lf-menu a {
	text-decoration: none;
}

.lf-menu a:hover {
	color: var(--lf-grad-to);
}

.lf-header__actions {
	display: flex;
	align-items: center;
	gap: 16px;
}

.lf-header__phone {
	font-weight: 600;
	text-decoration: none;
	white-space: nowrap;
}

/* Дублирует .lf-header__phone внутри выпадающего мобильного меню - на
   десктопе телефон уже виден в .lf-header__actions, здесь он скрыт (в
   отличие от .lf-header__phone, у которой на мобильном ровно обратная
   логика - см. медиазапрос max-width: 960px). Мобильный трафик для
   лидогенерации основной, поэтому без .lf-header__phone (скрытой на
   мобильном) номер должен остаться доступен - первым пунктом в
   раскрытом меню. */
.lf-header__nav-phone {
	display: none;
}

.lf-header__actions .lf-btn--primary {
	white-space: nowrap;
}

.lf-header__burger {
	display: none;
	position: relative;
	width: 44px;
	height: 44px;
	border: 0;
	border-radius: var(--lf-radius-sm);
	background: var(--lf-bg-soft);
	/* У элементов формы (button) свой UA-цвет по умолчанию, они не наследуют
	   color автоматически - явно включаем наследование от текста шапки. */
	color: inherit;
	cursor: pointer;
}

/* Иконка из трёх полосок: span - средняя, ::before/::after - верхняя и
   нижняя. Цвет наследуется от текста шапки (currentColor) - тёмный на
   светлой шапке, светлый на overlay. При открытом меню (aria-expanded)
   полоски складываются в крестик. */
.lf-header__burger span,
.lf-header__burger span::before,
.lf-header__burger span::after {
	position: absolute;
	left: 50%;
	width: 20px;
	height: 2px;
	background: currentColor;
	transform: translateX(-50%);
	transition: transform var(--lf-dur-fast) var(--lf-ease), opacity var(--lf-dur-fast) var(--lf-ease), top var(--lf-dur-fast) var(--lf-ease);
}

.lf-header__burger span {
	top: 50%;
	transform: translate(-50%, -50%);
}

.lf-header__burger span::before,
.lf-header__burger span::after {
	content: "";
	left: 0;
	transform: none;
}

.lf-header__burger span::before {
	top: -6px;
}

.lf-header__burger span::after {
	top: 6px;
}

.lf-header__burger[aria-expanded="true"] span {
	background: transparent;
}

.lf-header__burger[aria-expanded="true"] span::before {
	top: 0;
	transform: rotate(45deg);
}

.lf-header__burger[aria-expanded="true"] span::after {
	top: 0;
	transform: rotate(-45deg);
}

/* Прозрачная шапка поверх тёмного первого экрана (только на главной).
   Шапка - отдельный от .lf-hero элемент (общий header.php вне <main>),
   поэтому простой transparent показал бы белый фон body, а не тёмный фон
   героя. Втягиваем герой под шапку отрицательным margin-bottom на всю
   высоту шапки (--lf-header-h) и настолько же увеличиваем верхний отступ
   героя, чтобы текст не оказался под логотипом/меню. До прокрутки > 20px
   шапка сливается с тёмным фоном героя, после - становится непрозрачной
   тёмной с границей, чтобы не потеряться на светлых секциях. */
.lf-header--overlay {
	background: transparent;
	border-bottom-color: transparent;
	backdrop-filter: none;
	-webkit-backdrop-filter: none;
	color: #FFFFFF;
	margin-bottom: calc(-1 * var(--lf-header-h));
	transition: background-color var(--lf-dur-fast) var(--lf-ease), border-color var(--lf-dur-fast) var(--lf-ease);
}

.lf-header--overlay .lf-menu a {
	color: rgba(255, 255, 255, 0.82);
}

.lf-header--overlay .lf-menu a:hover {
	color: #FFFFFF;
}

.lf-header--overlay .lf-header__phone {
	color: #FFFFFF;
}

/* На overlay-шапке у бургера убираем светлую подложку - остаётся только
   иконка, наследующая белый цвет от .lf-header--overlay. */
.lf-header--overlay .lf-header__burger {
	background: transparent;
}

.lf-header--overlay.is-scrolled {
	background: var(--lf-ink);
	border-bottom-color: var(--lf-line-dark);
}

.lf-header--overlay ~ .lf-main .lf-hero-body {
	padding-top: calc(56px + var(--lf-header-h));
}

@media (max-width: 960px) {
	.lf-header__nav {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		bottom: auto;
		display: none;
		padding: 16px;
		background: var(--lf-bg);
		border-bottom: 1px solid var(--lf-border);
	}

	.lf-header.is-open .lf-header__nav {
		display: block;
	}

	.lf-menu {
		flex-direction: column;
		gap: 12px;
	}

	.lf-header__burger {
		display: block;
	}

	.lf-header__phone {
		display: none;
	}

	/* Первый пункт раскрытого меню - крупная кликабельная ссылка звонка,
	   отделённая от пунктов навигации ниже. */
	.lf-header__nav-phone {
		display: block;
		margin: 0 0 16px;
		font-weight: 600;
		font-size: 18px;
		text-decoration: none;
		color: inherit;
	}

	/* Открытое мобильное меню всегда на светлой подложке (см. .lf-header__nav
	   выше) - даже у overlay-шапки текст пунктов и телефона должен остаться
	   тёмным. */
	.lf-header--overlay.is-open .lf-menu a,
	.lf-header--overlay.is-open .lf-header__nav-phone {
		color: var(--lf-text);
	}
}

@media (max-width: 480px) {
	.lf-header__logo img {
		width: 110px;
	}

	.lf-header__inner {
		gap: 12px;
	}

	.lf-header__actions {
		gap: 8px;
	}

	.lf-header__actions .lf-btn--primary {
		padding: 10px 14px;
		font-size: 12px;
	}
}

.lf-footer {
	margin-top: var(--lf-section-y);
	padding-block: 56px 28px;
	background: var(--lf-dark);
	color: #FFFFFF;
}

.lf-footer a {
	color: #FFFFFF;
	text-decoration: none;
}

.lf-footer a:hover {
	color: var(--lf-accent);
}

.lf-footer__inner {
	display: grid;
	gap: 32px;
	grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.lf-footer__tagline {
	margin: 12px 0 0;
	color: rgba(255, 255, 255, 0.7);
}

.lf-footer__menu {
	display: grid;
	gap: 10px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.lf-footer__contacts {
	display: grid;
	gap: 10px;
	align-content: start;
	font-weight: 600;
}

.lf-footer__messengers {
	display: flex;
	gap: 16px;
	font-weight: 500;
}

.lf-footer__bottom {
	margin-top: 40px;
	padding-top: 20px;
	border-top: 1px solid rgba(255, 255, 255, 0.15);
	color: rgba(255, 255, 255, 0.6);
	font-size: 14px;
}

.lf-footer__legal a {
	margin-inline-start: 16px;
	text-decoration: underline;
}

.lf-eyebrow {
	margin: 0 0 16px;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--lf-eyebrow-color, var(--lf-muted));
}

/* Тёмные секции переопределяют --lf-eyebrow-color на светлый оттенок -
   на var(--lf-muted) контраст надзаголовка на тёмном фоне 2.59:1, ниже
   нормы 4.5:1 для мелкого текста. rgba(255, 255, 255, 0.7) - тот же
   оттенок, что уже используется для вторичного текста на тёмном
   (.lf-hero-sub, .lf-adv__item p). Секции .lf-pricing и .lf-cta ещё не
   созданы (задачи 8/13 по плану), но добавлены заранее - когда появятся,
   контраст будет верным без отдельной правки. */
.lf-hero .lf-eyebrow,
.lf-advantages .lf-eyebrow,
.lf-pricing .lf-eyebrow,
.lf-cta .lf-eyebrow {
	--lf-eyebrow-color: rgba(255, 255, 255, 0.7);
}

.lf-section-head {
	max-width: 16em;
	margin-bottom: 48px;
}

/* Общая геометрия карточек-«коробок»: рамка, радиус, отступ, белый фон.
   Переиспользуется .lf-card (что входит) вместо дублирования одних и тех
   же четырёх свойств в каждом классе. Специфика конкретной карточки
   (акцентная чёрточка, меньший отступ, тёмный вариант) остаётся в её
   собственном классе поверх этого базового набора. Секции «знакомо?» и
   «преимущества» карточек больше не используют - там строки списка и
   типографический блок без рамок. */
.lf-box {
	padding: 28px;
	border: 1px solid var(--lf-line-light);
	border-radius: var(--lf-radius);
	background: #FFFFFF;
}

.lf-hero {
	background: var(--lf-ink);
	color: #FFFFFF;
}

.lf-hero h1 {
	font-size: clamp(38px, 5.4vw, 72px);
	max-width: 11em;
}

.lf-hero-body {
	padding: 56px 0 0;
	text-align: left;
	max-width: none;
}

.lf-hero-sub {
	margin: 24px 0 0;
	max-width: 520px;
	font-size: 18px;
	line-height: 1.6;
	color: rgba(255, 255, 255, 0.78);
	text-align: left;
}

/* ---- формула цены ---- */
.lf-formula {
	position: relative;
	margin: 56px 0 0;
	max-width: 860px;
	display: flex;
	align-items: stretch;
	justify-content: flex-start;
	gap: 20px;
}

.lf-formula::before {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 50%;
	height: 2px;
	background: var(--lf-line-dark);
	transform: translateY(-50%);
	z-index: 0;
}

.lf-formula-arrival {
	position: absolute;
	top: 50%;
	right: 0;
	width: 14px;
	height: 14px;
	border-radius: 50%;
	background: var(--lf-gradient);
	box-shadow: 0 0 0 6px rgba(255, 45, 107, 0.16), 0 0 18px rgba(255, 138, 0, 0.55);
	transform: translate(50%, -50%);
	z-index: 2;
}

.lf-formula-op {
	position: relative;
	z-index: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	font-family: var(--lf-font-head);
	font-weight: 800;
	font-size: 60px;
	color: var(--lf-accent);
	flex-shrink: 0;
}

.lf-formula-card {
	position: relative;
	z-index: 1;
	flex: 1;
	max-width: 300px;
	background: var(--lf-ink-2);
	border: 1px solid var(--lf-line-dark);
	border-radius: 20px;
	padding: 28px 22px;
	text-align: left;
}

.lf-formula-card.is-arrival {
	border-color: var(--lf-accent);
}

.lf-formula-title {
	font-family: var(--lf-font-head);
	font-weight: 700;
	font-size: 19px;
	letter-spacing: -0.02em;
	line-height: 1.15;
	margin: 0 0 8px;
}

.lf-formula-caption {
	font-size: 14px;
	line-height: 1.5;
	color: rgba(255, 255, 255, 0.62);
	margin: 0;
}

.lf-formula-note {
	margin: 20px 0 0;
	font-size: 13px;
	color: var(--lf-muted);
}

.lf-hero-actions {
	margin: 32px 0 0;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	gap: 16px;
	flex-wrap: wrap;
}

/* ---- нижняя полоса фактов ---- */
.lf-strip {
	margin-top: 56px;
	border-top: 1px solid var(--lf-line-dark);
}

.lf-strip-inner {
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	/* gap 10px 32px: горизонтальный зазор добавлен - в превью факты разделял
	   span.lf-divider, которого нет в схеме поля lf_hero_facts (только text). */
	gap: 10px 32px;
	padding: 20px 24px;
	font-size: 14px;
	font-weight: 500;
	color: rgba(255, 255, 255, 0.72);
	text-align: center;
}

@media (max-width: 720px) {
	.lf-hero-body { padding-top: 40px; }
	.lf-header--overlay ~ .lf-main .lf-hero-body { padding-top: calc(40px + var(--lf-header-h)); }
	.lf-hero-sub { font-size: 16px; }

	.lf-formula {
		flex-direction: column;
		align-items: flex-start;
		margin-top: 40px;
		max-width: none;
		gap: 4px;
	}

	.lf-formula::before,
	.lf-formula-arrival { display: none; }

	.lf-formula-card {
		max-width: 420px;
		width: 100%;
	}

	.lf-formula-op { padding: 4px 0; font-size: 32px; }

	.lf-hero-actions { flex-direction: column; }
	.lf-hero-actions .lf-btn { width: 100%; max-width: 320px; }

	.lf-strip-inner { flex-direction: column; gap: 10px; }
}

.lf-pain {
	background: var(--lf-paper);
	color: var(--lf-ink);
}

.lf-pain__grid {
	display: grid;
	gap: 48px;
	grid-template-columns: minmax(280px, 5fr) minmax(280px, 7fr);
	align-items: start;
}

/* min-width: 0 снимает автоматический минимальный размер грид-ячейки по
   контенту - тот же приём, что у .lf-receipt-name в секции цены. Без него
   длинное неразрывное слово в заголовке распирало бы колонку сетки и давало
   горизонтальную прокрутку всей странице. */
.lf-pain__lead {
	min-width: 0;
}

.lf-pain__lead h2 {
	margin: 0;
	max-width: 9em;
	overflow-wrap: anywhere;
}

.lf-pain__list {
	display: grid;
	gap: 0;
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--lf-line-light);
	min-width: 0;
}

.lf-pain__item {
	padding: 22px 0 22px 44px;
	border-bottom: 1px solid var(--lf-line-light);
	font-size: 19px;
	font-weight: 500;
	position: relative;
	overflow-wrap: anywhere;
}

.lf-pain__item::before {
	content: '';
	position: absolute;
	left: 0;
	top: 32px;
	width: 24px;
	height: 2px;
	border-radius: 2px;
	background: var(--lf-gradient);
}

@media (max-width: 860px) {
	.lf-pain__grid {
		grid-template-columns: 1fr;
		gap: 28px;
	}

	.lf-pain__item {
		font-size: 17px;
	}
}

.lf-included {
	background: var(--lf-paper);
	color: var(--lf-ink);
}

/* .lf-cards больше не используется: преимущества переехали на
   типографический .lf-adv__list, отзывы - на стену цитат .lf-quotes.
   Кейсы используют свою копию правила, .lf-cases__grid, ниже - секция
   «что входит» переехала на .lf-bento ниже. */

.lf-bento {
	display: grid;
	gap: 16px;
	grid-template-columns: repeat(3, 1fr);
	grid-auto-rows: 1fr;
}

/* grid-row: span 2 наравне с grid-column: span 2 - крупная карточка забирает
   4 ячейки (2x2) вместо 2 (2x1). При двух свободных колонках, оставшихся
   рядом с 2x1-карточкой, автораскладка не может закрыть их обычными
   карточками 1x1 без остатка - получаются пустые ячейки в сетке на 3
   колонки. При 2x2 остаток всегда кратен ширине сетки, если общее число
   карточек кратно трём (см. instructions поля featured) - тогда сетка
   заполняется без единой дыры независимо от числа отмеченных карточек. */
.lf-card--wide {
	grid-column: span 2;
	grid-row: span 2;
}

.lf-card--wide h3 {
	font-size: 26px;
}

@media (max-width: 860px) {
	.lf-bento {
		grid-template-columns: repeat(2, 1fr);
	}

	/* На двух колонках span 2 уже даёт полную ширину строки - вторая
	   строка карточке не нужна, иначе снова появится пустая ячейка. */
	.lf-card--wide {
		grid-row: span 1;
	}
}

@media (max-width: 560px) {
	.lf-bento {
		grid-template-columns: 1fr;
	}

	.lf-card--wide {
		grid-column: span 1;
		grid-row: span 1;
	}
}

.lf-card h3 {
	margin-bottom: 10px;
	font-size: 20px;
}

.lf-card p {
	margin: 0;
	color: var(--lf-muted);
}

.lf-advantages {
	background: var(--lf-ink);
	color: #FFFFFF;
}

.lf-adv__list {
	display: grid;
	gap: 0 56px;
	grid-template-columns: repeat(2, 1fr);
}

/* min-width: 0 - тот же приём, что у .lf-pain__lead: без него грid-ячейка
   не может сжаться уже минимального содержимого, и длинное неразрывное
   слово в заголовке или описании даёт горизонтальную прокрутку страницы. */
.lf-adv__item {
	min-width: 0;
	padding: 28px 0;
	border-top: 1px solid var(--lf-divider-dark);
}

.lf-adv__item h3 {
	margin: 0 0 8px;
	font-size: clamp(20px, 2vw, 26px);
	overflow-wrap: anywhere;
}

/* Контраст описания на тёмном фоне секции (var(--lf-ink) #1B1B2F): белый
   текст с alpha 0.7 даёт эффективный цвет ~ rgb(187,187,193), что против
   фона считается как 8.79:1 - выше нормы 4.5:1 для обычного текста.
   overflow-wrap подстраховывает перенос длинного неразрывного слова. */
.lf-adv__item p {
	margin: 0;
	color: rgba(255, 255, 255, 0.7);
	max-width: 34ch;
	overflow-wrap: anywhere;
}

@media (max-width: 860px) {
	.lf-adv__list {
		grid-template-columns: 1fr;
		gap: 0;
	}
}

/* Секция процесса: белый фон, а не var(--lf-paper) - соседние секции
   «знакомо?» и «что входит» уже на paper, три одинаковых светлых фона
   подряд слились бы в одну полосу без границ. */
.lf-process {
	background: #FFFFFF;
}

.lf-process-head {
	max-width: 640px;
	margin-bottom: 72px;
}

.lf-steps {
	position: relative;
	display: flex;
	gap: 24px;
}

.lf-steps-line {
	position: absolute;
	top: 6px;
	left: 0;
	right: 0;
	height: 2px;
	background: var(--lf-muted);
	z-index: 0;
}

.lf-track-dot {
	position: absolute;
	top: 0;
	left: 0;
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--lf-gradient);
	box-shadow: 0 0 0 6px rgba(255, 45, 107, 0.14), 0 0 16px rgba(255, 138, 0, 0.5);
	transform: translate(-50%, -50%);
	transition: left var(--lf-dur-travel) var(--lf-ease), top var(--lf-dur-travel) var(--lf-ease);
	z-index: 2;
	pointer-events: none;
}

.lf-step {
	position: relative;
	z-index: 1;
	flex: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
}

.lf-node {
	width: 12px;
	height: 12px;
	border-radius: 50%;
	background: var(--lf-paper);
	border: 2px solid var(--lf-muted);
	margin: 0 0 24px;
	transition: background-color var(--lf-dur-fast) var(--lf-ease), border-color var(--lf-dur-fast) var(--lf-ease), box-shadow var(--lf-dur-fast) var(--lf-ease);
}

.lf-node.is-active {
	background: var(--lf-accent);
	border-color: var(--lf-accent);
	box-shadow: 0 0 0 5px rgba(255, 198, 60, 0.3);
}

/* --lf-muted на белом фоне - контраст ~7:1, номер вторичен по отношению
   к заголовку шага. Акцентный жёлтый (--lf-accent) оставлен только кольцу
   активного узла и точке - на белом фоне текст с ним читался бы ~1.6:1
   при норме 4.5:1. */
.lf-step-num {
	font-family: var(--lf-font-head);
	font-weight: 800;
	font-size: 15px;
	letter-spacing: -0.02em;
	color: var(--lf-muted);
	margin: 0 0 10px;
}

.lf-step h3 {
	font-size: 19px;
	margin: 0 0 10px;
	min-height: 1.05em;
}

.lf-step p {
	margin: 0;
	font-size: 15px;
	line-height: 1.5;
	color: var(--lf-muted);
	max-width: 220px;
}

@media (max-width: 720px) {
	.lf-process-head {
		margin-bottom: 48px;
	}

	.lf-steps {
		flex-direction: column;
		gap: 36px;
	}

	.lf-steps-line {
		top: 0;
		bottom: 0;
		left: 6px;
		right: auto;
		width: 2px;
		height: auto;
	}

	.lf-step {
		flex-direction: row;
		align-items: flex-start;
		text-align: left;
		gap: 18px;
	}

	.lf-node {
		margin: 4px 0 0;
		flex-shrink: 0;
	}

	.lf-step-content {
		min-width: 0;
		flex: 1 1 auto;
	}

	.lf-step p {
		max-width: none;
	}
}

.lf-pricing {
	background: var(--lf-ink);
	color: #FFFFFF;
}

.lf-pricing-head {
	max-width: 640px;
	margin-bottom: 56px;
}

/* Поверх .lf-box: своя ширина и выключенное центрирование, тёмный фон и
   цвет рамки под тёмную секцию, свой отступ (карточка ужата по вертикали -
   вертикальные зазоры уже даёт padding строк .lf-receipt-row). */
.lf-receipt {
	max-width: 760px;
	/* По общей левой оси страницы, а не по центру, как в превью - так решил
	   дизайн-лид при приёмке. */
	margin-inline: 0;
	background: var(--lf-ink-2);
	border-color: var(--lf-line-dark);
	padding: 12px 36px;
}

.lf-receipt-row {
	display: grid;
	grid-template-columns: 56px minmax(0, 1fr) minmax(0, 320px);
	align-items: center;
	column-gap: 24px;
	padding: 24px 0;
}

.lf-receipt-row + .lf-receipt-row {
	border-top: 1px solid var(--lf-line-dark);
}

.lf-op {
	font-family: var(--lf-font-head);
	font-weight: 800;
	font-size: 40px;
	line-height: 1;
	color: var(--lf-accent);
	text-align: center;
}

.lf-receipt-name {
	margin: 0;
	font-family: var(--lf-font-head);
	font-weight: 700;
	font-size: 19px;
	letter-spacing: -0.02em;
	/* min-width: 0 снимает автоматический минимальный размер грид-ячейки по
	   контенту - без него длинное название распирало бы колонку сетки вместо
	   того, чтобы перенестись. Перенос разрешён на всех ширинах - обрезка
	   многоточием была бы хуже: часть названия строки чека, которая объясняет,
	   за что человек платит, молча исчезала бы со страницы, а в админке поле
	   выглядело бы полным. overflow-wrap подстраховывает перенос - длинное
	   слово ломается внутри, а не выталкивает колонку за край. */
	min-width: 0;
	overflow-wrap: anywhere;
}

.lf-receipt-name.is-highlight {
	background-image: var(--lf-gradient);
	background-repeat: no-repeat;
	background-position: 0 100%;
	background-size: 100% 3px;
	padding-bottom: 6px;
	/* Подчёркивание по ширине текста, а не во всю колонку - но не шире
	   колонки: max-width подстраховывает width, если fit-content всё же
	   посчитает по полной длине текста. */
	width: fit-content;
	max-width: 100%;
}

.lf-receipt-desc {
	margin: 0;
	font-size: 14px;
	color: rgba(255, 255, 255, 0.62);
	text-align: right;
	max-width: 320px;
}

.lf-objections {
	margin-top: 40px;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	flex-wrap: wrap;
	/* gap 8px 32px: в преью соседние тезисы разделял span.lf-divider,
	   которого нет в схеме поля lf_pricing_objections (только text) - тот же
	   приём, что и у .lf-strip-inner в первом экране. */
	gap: 8px 32px;
	font-size: 14px;
	font-weight: 500;
	color: rgba(255, 255, 255, 0.72);
}

@media (max-width: 720px) {
	.lf-pricing-head {
		margin-bottom: 40px;
	}

	.lf-receipt {
		padding: 4px 20px;
	}

	.lf-receipt-row {
		grid-template-columns: 32px 1fr;
		align-items: start;
		row-gap: 6px;
		column-gap: 12px;
	}

	.lf-op {
		font-size: 26px;
	}

	.lf-receipt-desc {
		grid-column: 1 / -1;
		text-align: left;
		max-width: none;
	}
}

.lf-cases {
	background: #FFFFFF;
	color: var(--lf-ink);
}

/* Максимум трека 380px (не 1fr) - при одном опубликованном кейсе (карточка
   не заполняет весь ряд) он не растягивается на всю ширину контейнера,
   оставляя главную цифру в пустой полосе. justify-content: start прижимает
   заполненные дорожки к началу, а не растягивает их на всю ширину сетки,
   если дорожек с контентом меньше, чем поместилось бы по минимальному
   размеру. */
.lf-cases__grid {
	display: grid;
	gap: 16px;
	grid-template-columns: repeat(auto-fit, minmax(280px, 380px));
	justify-content: start;
}

/* Запасной цвет - конечный цвет градиента (--lf-grad-to), сплошной и
   читаемый: без него браузер без поддержки background-clip: text показал бы
   градиентный прямоугольник с невидимой (color: transparent) цифрой внутри -
   главный элемент карточки пропал бы. Обрезка фона по тексту применяется
   только внутри @supports, поэтому без поддержки остаётся одноцветная
   цифра. */
.lf-case__value {
	margin: 0;
	font-family: var(--lf-font-head);
	font-size: clamp(38px, 4vw, 56px);
	font-weight: 700;
	line-height: 1;
	color: var(--lf-grad-to);
}

@supports (background-clip: text) or (-webkit-background-clip: text) {
	.lf-case__value {
		background: var(--lf-gradient);
		-webkit-background-clip: text;
		background-clip: text;
		color: transparent;
	}
}

.lf-case__label {
	margin: 6px 0 20px;
	font-size: 14px;
	color: var(--lf-muted);
}

.lf-case__title {
	margin: 0 0 8px;
	font-size: 20px;
}

.lf-case__title a {
	text-decoration: none;
}

.lf-case__niche {
	margin: 0 0 12px;
	font-size: 14px;
	color: var(--lf-muted);
}

.lf-case__text {
	margin: 0 0 16px;
}

.lf-case__rest {
	display: grid;
	gap: 6px;
	margin: 0;
	padding-top: 16px;
	border-top: 1px solid var(--lf-line-light);
	font-size: 14px;
}

.lf-case__rest div {
	display: flex;
	justify-content: space-between;
	gap: 12px;
}

/* min-width: 0 снимает автоматический минимальный размер флекс-айтема по
   контенту - тот же приём, что у .lf-receipt-name в секции цены и
   .lf-pain__item в секции «знакомо?». Без него длинная однословная подпись
   метрики распирала бы строку и вытолкнула бы значение за край карточки.
   overflow-wrap подстраховывает перенос такого слова внутри самой подписи. */
.lf-case__rest dt {
	min-width: 0;
	overflow-wrap: anywhere;
	color: var(--lf-muted);
}

.lf-case__rest dd {
	margin: 0;
	font-weight: 600;
}

.lf-cases-more {
	margin-top: 32px;
}

.lf-reviews {
	background: var(--lf-paper);
	color: var(--lf-ink);
}

.lf-quotes {
	display: grid;
	gap: 16px;
	grid-template-columns: repeat(2, 1fr);
}

.lf-review--lead {
	display: grid;
	align-content: space-between;
}

/* Лидовая цитата остаётся крупной по площади при любом числе отрисованных
   отзывов n (не только запрошенных) - иначе стена вырождается в обычную
   сетку равных карточек, ту самую форму, из-за которой затевалась вся
   перевёрстка.
   Нечётное n: растягиваем на 2 строки в первой колонке (.lf-quotes--odd).
   Общее число ячеек, которые просят карточки (2 у лидовой + 1 у каждой из
   остальных n-1), равно n+1 - на сетке из 2 колонок без остатка оно
   делится, только когда n+1 чётно, то есть n нечётно.
   Чётное n: растягивание на 2 строки оставило бы одну пустую ячейку в
   конце второй колонки - тот же класс дефекта, что чинили в .lf-bento (см.
   .lf-card--wide, кратность 3 карточкам). Вместо этого растягиваем на 2
   КОЛОНКИ (.lf-quotes--even): лидовая занимает всю первую строку целиком,
   а оставшиеся n-1 карточек auto-flow заполняют обычную сетку из 2 колонок
   ниже без единой дыры - неполной может остаться только последняя строка
   целиком (естественный хвост, как у любой сетки с нечётным числом плиток
   без крупного элемента), а не дыра посреди сетки.
   Модификатор ставит шаблон section-reviews.php по числу реально
   отрисованных (не всех запрошенных) отзывов. */
.lf-quotes--odd .lf-review--lead {
	grid-row: span 2;
}

.lf-quotes--even .lf-review--lead {
	grid-column: span 2;
}

.lf-review--lead .lf-review-text {
	font-family: var(--lf-font-head);
	font-size: clamp(20px, 2.2vw, 28px);
	line-height: 1.25;
}

@media (max-width: 860px) {
	.lf-quotes {
		grid-template-columns: 1fr;
	}

	.lf-quotes--odd .lf-review--lead {
		grid-row: auto;
	}

	.lf-quotes--even .lf-review--lead {
		grid-column: auto;
	}
}

/* min-width: 0 - без него грid-ячейка на repeat(2, 1fr) не может сжаться
   уже минимального содержимого, и длинное неразрывное слово в цитате или
   подписи автора даёт горизонтальную прокрутку страницы (тот же приём,
   что у .lf-adv__item). */
.lf-review {
	display: grid;
	align-content: space-between;
	min-width: 0;
}

/* Текст отзыва - семантически blockquote (цитата стороннего лица), но без
   собственного визуала: обнуляем отступ браузера по умолчанию (обычно
   1em 40px) вместо него используем те же 0 0 18px, что были у прежнего <p>.
   overflow-wrap подстраховывает перенос длинного неразрывного слова. */
.lf-review-text {
	margin: 0 0 18px;
	overflow-wrap: anywhere;
}

/* Автор и компания - семантически cite (источник цитаты). display: block
   уже произошёл бы автоматически (элемент-грид-айтем блокифицируется), но
   указан явно для ясности. font-style: normal снимает курсив, который
   браузер даёт <cite> по умолчанию - в цитате из отзыва он не нужен.
   overflow-wrap подстраховывает перенос длинного неразрывного слова. */
.lf-review-author {
	display: block;
	margin: 0;
	font-style: normal;
	font-weight: 600;
	overflow-wrap: anywhere;
}

.lf-review-author span {
	display: block;
	font-weight: 400;
	color: var(--lf-muted);
}

/* Список логотипов - семантически ul (Находка 5 ревью): список сбрасывает
   маркеры и отступ браузера по умолчанию, чтобы выглядеть как раньше.
   role="list" в разметке (Правка 6 приёмки) возвращает списку роль для
   скринридера - список без маркеров (list-style: none) в части версий
   браузеров эту роль теряет. */
.lf-logos {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 32px;
	margin: 40px 0 0;
	padding: 0;
	list-style: none;
	opacity: 0.75;
}

/* object-fit: contain (Находка 2 ревью): атрибуты width/height у <img>
   резервируют место 140×48 под макет, но реальный логотип клиента почти
   никогда не имеет такое соотношение сторон. contain вписывает картинку в
   эту рамку целиком, без растяжения и обрезки. */
.lf-logos img {
	width: 140px;
	height: 48px;
	object-fit: contain;
}

.lf-faq {
	background: #FFFFFF;
	color: var(--lf-ink);
}

.lf-faq-list {
	border-top: 1px solid var(--lf-line-light);
	max-width: 900px;
}

.lf-faq-item {
	border-bottom: 1px solid var(--lf-line-light);
}

.lf-faq-question {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	width: 100%;
	padding: 22px 0;
	border: 0;
	background: none;
	font: inherit;
	font-weight: 600;
	text-align: start;
	cursor: pointer;
}

.lf-faq-question::after {
	content: '+';
	font-family: var(--lf-font-head);
	font-size: 24px;
	color: var(--lf-accent);
}

.lf-faq-question[aria-expanded="true"]::after {
	content: '-';
}

/* Плавное раскрытие без анимации height (высота - свойство, вызывающее
   пересчёт раскладки, animируть его нельзя). Приём с сеткой из одной
   строки: grid-template-rows идёт от 0fr к 1fr, а overflow: hidden на
   контейнере и на вложенном .lf-faq-answer__inner отрезают содержимое,
   которое ещё не поместилось - без вложенного блока браузер не сможет
   схлопнуть строку до нулевой высоты (grid-ячейка не сжимается уже своего
   содержимого без явного overflow на самом содержимом). Padding-отступ
   перенесён с .lf-faq-answer на __inner - иначе он остался бы виден даже
   при закрытом состоянии (padding контейнера не участвует в сжатии
   строки). Раскрывается через селектор по соседству с состоянием кнопки
   (aria-expanded), а не через класс на самом ответе - JS переключает
   только атрибуты (см. lfInitFaq в assets/js/main.js). */
.lf-faq-answer {
	display: grid;
	grid-template-rows: 0fr;
	color: var(--lf-muted);
	max-width: 70ch;
	overflow: hidden;
	transition: grid-template-rows var(--lf-dur-slow) var(--lf-ease);
}

.lf-faq-question[aria-expanded="true"] + .lf-faq-answer {
	grid-template-rows: 1fr;
}

.lf-faq-answer__inner {
	overflow: hidden;
}

.lf-faq-answer__inner p {
	margin: 0;
	padding-bottom: 22px;
}

.lf-cta {
	background: var(--lf-ink);
	color: #FFFFFF;
}

.lf-cta-inner {
	display: grid;
	gap: 40px;
	grid-template-columns: minmax(280px, 1fr) minmax(320px, 480px);
	align-items: start;
}

.lf-cta-text {
	color: rgba(255, 255, 255, 0.7);
	max-width: 40ch;
}

/* Поверх .lf-box: больший отступ, тёмный фон и цвет рамки под тёмную
   секцию - радиус общий, оставлен от базового класса. */
.lf-cta-form {
	padding: 32px;
	border-color: var(--lf-line-dark);
	background: var(--lf-ink-2);
}

@media (max-width: 860px) {
	.lf-cta-inner {
		grid-template-columns: 1fr;
	}
}

/* ---- форма заявки (CF7): общая для секции финального призыва
   (.lf-cta-form) и модального окна (.lf-modal__form) ---- */
.lf-form-row {
	margin-bottom: 16px;
}

.lf-input {
	display: block;
	width: 100%;
	padding: 14px 16px;
	border: 1px solid var(--lf-border);
	border-radius: var(--lf-radius-sm);
	font: inherit;
	color: var(--lf-text);
	background: #FFFFFF;
}

.lf-input:focus-visible {
	outline: 2px solid var(--lf-accent);
	outline-offset: 2px;
}

.lf-form-row--consent {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	font-size: 14px;
}

.lf-form-row--consent input {
	margin-top: 4px;
}

.wpcf7-not-valid-tip {
	display: block;
	margin-top: 6px;
	font-size: 13px;
	color: var(--lf-error);
}

/* .lf-cta-form - тёмная карточка (см. выше): текст ошибки того же тона, но
   светлее, чтобы контраст к тёмному фону остался не ниже нормы. */
.lf-cta-form .wpcf7-not-valid-tip {
	color: var(--lf-error-on-dark);
}

.wpcf7-response-output {
	margin: 16px 0 0 !important;
	padding: 12px 16px !important;
	border-radius: var(--lf-radius-sm) !important;
	font-size: 14px;
}

/* ---- модальное окно с формой заявки ---- */
.lf-modal {
	--lf-modal-gutter: 24px;
	position: fixed;
	inset: 0;
	z-index: 200;
	display: none;
	align-items: center;
	justify-content: center;
	padding: var(--lf-modal-gutter);
}

.lf-modal.is-open {
	display: flex;
}

.lf-modal__overlay {
	position: absolute;
	inset: 0;
	background: rgba(27, 27, 47, 0.72); /* тон --lf-ink с прозрачностью - подложка окна */
}

/* Поверх .lf-box: своя ширина, прокрутка на низких экранах и позиция для
   кнопки закрытия - геометрия карточки (рамка, радиус, отступ, фон) общая. */
.lf-modal__dialog {
	position: relative;
	z-index: 1;
	width: min(100%, 480px);
	max-height: calc(100vh - 2 * var(--lf-modal-gutter));
	overflow-y: auto;
}

.lf-modal__close {
	position: absolute;
	top: 16px;
	right: 16px;
	width: 36px;
	height: 36px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	border: 0;
	border-radius: 50%;
	background: var(--lf-bg-soft);
	color: var(--lf-text);
	font-size: 22px;
	line-height: 1;
	cursor: pointer;
}

.lf-modal__close:focus-visible {
	outline: 2px solid var(--lf-accent);
	outline-offset: 2px;
}

.lf-modal__text {
	margin: 0 0 20px;
	color: var(--lf-muted);
}

.lf-modal__form .wpcf7-form {
	margin: 0;
}

/* Блокирует прокрутку фона, пока открыто модальное окно (lfInitModal в
   assets/js/main.js). */
.lf-no-scroll {
	overflow: hidden;
}

@media (max-width: 480px) {
	.lf-modal {
		--lf-modal-gutter: 16px;
	}
}

/* ---- страница благодарности (page-thanks.php) ---- */
.lf-thanks-inner {
	max-width: 640px;
	text-align: center;
}

.lf-thanks-inner p {
	color: var(--lf-muted);
	font-size: 18px;
}

.lf-thanks-inner .lf-btn {
	margin-top: 8px;
}

/* Счётчик цифр (lfInitCounters в assets/js/main.js): моноширинные цифры -
   без этого цифры разной ширины дёргают раскладку на каждом кадре счёта. */
[data-lf-count] {
	font-variant-numeric: tabular-nums;
}

/* Отклик на действие. Состояние фокуса с клавиатуры (:focus-visible /
   :focus-within) зеркалит :hover для каждого элемента и держится на любом
   устройстве - иначе отклик виден только мыши, а клавиатурная навигация
   его теряет. Рамка карточки при наведении/фокусе становится акцентной
   (var(--lf-grad-to)) поверх любого фона - светлого (.lf-box) или тёмного
   (.lf-cta-form), см. их border-color выше. .lf-box сам по себе не
   интерактивен, но может содержать ссылку (например, .lf-case) -
   :focus-within поднимает всю карточку и в этом случае, а не только саму
   ссылку внутри. */
.lf-box {
	transition:
		transform var(--lf-dur-fast) var(--lf-ease),
		border-color var(--lf-dur-fast) var(--lf-ease);
}

.lf-box:focus-within {
	transform: translate3d(0, -2px, 0);
	border-color: var(--lf-grad-to);
}

.lf-btn {
	transition:
		transform var(--lf-dur-fast) var(--lf-ease),
		filter var(--lf-dur-fast) var(--lf-ease);
}

.lf-btn:focus-visible {
	transform: translate3d(0, -1px, 0);
	filter: brightness(1.05);
}

.lf-btn:active {
	transform: translate3d(0, 0, 0);
}

.lf-faq-question {
	transition: color var(--lf-dur-fast) var(--lf-ease);
}

.lf-faq-question:focus-visible {
	color: var(--lf-grad-to);
}

/* :hover - отдельно от фокуса и только на устройствах с настоящим
   наведением. На сенсорных экранах браузер эмулирует :hover по касанию и
   не снимает его до следующего тапа в другом месте - карточка осталась бы
   поднятой и с акцентной рамкой "залипшей" после обычного тапа.
   (hover: hover) and (pointer: fine) отсекает такие устройства - остаётся
   мышь/трекпад с точным позиционированием. */
@media (hover: hover) and (pointer: fine) {
	.lf-box:hover {
		transform: translate3d(0, -2px, 0);
		border-color: var(--lf-grad-to);
	}

	.lf-btn:hover {
		transform: translate3d(0, -1px, 0);
		filter: brightness(1.05);
	}

	.lf-faq-question:hover {
		color: var(--lf-grad-to);
	}
}

/* Появление элементов. Сдвиг идёт по направлению конвейера: на широком
   экране слева, на узком снизу. Правило стоит ниже блока отклика выше
   (.lf-box) намеренно: у обоих классов одна специфичность (один класс), и
   на карточках, которые одновременно .lf-reveal и .lf-box (бенто, кейсы,
   цитаты, карточка формы финального призыва), побеждает правило, идущее
   позже в файле. transition ниже включает border-color вместе с opacity и
   transform - без него отклик карточки при наведении/фокусе пропал бы у
   всех таких элементов, унаследовав только (укороченный) список свойств
   правила отклика. Третье значение в transition-delay (0s) обязательно:
   без него отклик рамки при наведении запаздывал бы на величину ступеньки
   появления, унаследованную из transition-delay для первых двух свойств. */
.lf-reveal {
	opacity: 0;
	transform: translate3d(0, var(--lf-shift), 0);
	transition:
		opacity var(--lf-dur-slow) var(--lf-ease),
		transform var(--lf-dur-slow) var(--lf-ease),
		border-color var(--lf-dur-fast) var(--lf-ease);
	transition-delay:
		calc(var(--lf-reveal-step, 0) * var(--lf-stagger)),
		calc(var(--lf-reveal-step, 0) * var(--lf-stagger)),
		0s;
}

.lf-reveal.is-revealed {
	opacity: 1;
	transform: translate3d(0, 0, 0);
}

@media (min-width: 861px) {
	.lf-reveal {
		transform: translate3d(calc(var(--lf-shift) * -1), 0, 0);
	}
}

/* Режим уменьшенного движения - один блок на весь файл (см. также
   lfInitReveal/lfInitCounters в assets/js/main.js: при этом режиме
   наблюдатель вообще не создаётся, это первая линия защиты; правила ниже -
   вторая, на случай элементов, которые не проходят через JS-инициализацию,
   и на случай самого JS-переключения классов, которое сюда не заглядывает). */
@media (prefers-reduced-motion: reduce) {
	.lf-node,
	.lf-track-dot {
		transition: none;
	}

	.lf-reveal {
		opacity: 1;
		transform: none;
		transition: none;
	}

	.lf-box,
	.lf-btn,
	.lf-faq-question,
	.lf-faq-answer {
		transition: none;
	}

	.lf-box:hover,
	.lf-box:focus-within,
	.lf-btn:hover,
	.lf-btn:focus-visible {
		transform: none;
	}
}
