/* Секции лендинга — нейтральный каркас ядра.
 *
 * Здесь ТОЛЬКО механика: ритм, сетки, карточки, таблицы, состояния, движение.
 * Палитра, шрифт, плотность и геометрия живут в skin.css темы и переопределяют
 * токены ниже. Различие сайтов программы держится на скине, а не на копиях
 * этого файла: одинаковый skin.css на двух доменах — дефект, одинаковый
 * каркас — норма.
 *
 * Все цвета — через токены. Захардкоженный #fff здесь ломает и тёмную тему,
 * и пере-скин; единственное место, где хекс допустим, — блок токенов.
 *
 * ── ПРАВКА ТЕЗИСА, 2026-08-03 ────────────────────────────────────────────
 * Прежняя редакция этого файла держалась на строке «страница должна читаться
 * как спецификация, а не как рекламный разворот»: радиус 2px, волосяные линии
 * вместо карточек, ноль движения. Это было верно для позиционирования
 * «учёт и процессы» — и неверно для сайта студии, который продаёт в том числе
 * умение оформить. Тезис заменён осознанно, а не подправлен по краям:
 * секции отбиваются поверхностями, перечни собраны в карточки, появление
 * анимировано. Что НЕ изменилось — ни одно нормативное решение: цвет
 * предупреждения по-прежнему не брендовый (§4), проверенные и непроверенные
 * интеграции по-прежнему различаются глазом, числа по-прежнему моноширинные,
 * нумерация шагов по-прежнему счётчиком, а не текстом.
 */

:root {
	--lb-gap: 1.5rem;
	--lb-section-gap: clamp(3rem, 5.5vw, 6rem);
	--lb-measure: 68ch;

	/* Раньше эти три смотрели в --us-border / --us-ink-muted / --us-warn,
	   которых в шасси не существовало, и var() отдавал серый фолбэк при любом
	   скине. Имена в base.css заведены; фолбэки оставлены на случай подключения
	   файла к теме без шасси. */
	--lb-line: var(--us-border, rgba(128, 128, 128, .28));
	--lb-ink: var(--us-ink, inherit);
	--lb-muted: var(--us-ink-muted, rgba(128, 128, 128, .95));
	--lb-accent: var(--us-accent, currentColor);
	--lb-accent-ink: var(--us-accent-ink, #fff);
	--lb-warn: var(--us-warn, #9a5407);

	/* Геометрия и поверхности. Радиус наследуется от скина: 2px здесь были
	   вкусовым решением одного сайта, зашитым в общий каркас всех девяти. */
	--lb-radius: var(--us-radius, 12px);
	--lb-radius-sm: var(--us-radius-sm, 8px);
	--lb-card-bg: var(--us-bg-elevated, transparent);
	--lb-card-line: var(--lb-line);
	--lb-shadow: var(--us-shadow-sm, none);
	--lb-shadow-lift: var(--us-shadow, none);

	/* Фон чередующейся секции. Скин задаёт свой; по умолчанию — мягкий фон
	   шасси, то есть отбивка есть всегда, даже у темы без собственных решений. */
	--lb-band: var(--us-bg-soft, transparent);
}

/* ══════════════════════════════════════════════════════ ритм и отбивка секций */

.lb-sections {
	counter-reset: lb;
}

.lb {
	counter-increment: lb;
	position: relative;
	padding: var(--lb-section-gap) 0;
}

/*
 * Отбивка ФОНОМ, а не пустотой и не линией.
 *
 * Чередование считается от позиции секции в наборе, а набор и порядок секций —
 * данные сущности (§2: «различие DOM обеспечивается данными, а не дисциплиной
 * автора»). Поэтому одна и та же CSS-строка даёт РАЗНЫЙ ритм на страницах
 * с разным составом блоков — полосы ложатся на разные секции. Это ровно то
 * свойство, ради которого композиция хранится в данных: не приходится держать
 * пятнадцать вариантов раскраски, чтобы пятнадцать страниц не выглядели
 * штампованными.
 */
/* Чередование задаётся ЗДЕСЬ, а не классом в шаблоне: партиалу секции незачем
   знать свой номер, а автору новой секции — помнить про раскраску. `.lb--band`
   оставлен явным хуком на случай, когда скин хочет назначить полосу
   конкретному блоку независимо от его позиции. */
.lb-sections > .lb:nth-child(even),
.lb--band {
	background: var(--lb-band);
}

/*
 * Полоса обязана идти во всю ширину окна, а секция живёт внутри контейнера
 * страницы. Разворачиваем тенью на 100vmax и подрезаем по вертикали, чтобы
 * не появился горизонтальный скролл. Псевдоэлемент во всю ширину здесь не
 * годится: у `.lb` есть position:relative, и абсолютный ребёнок считал бы
 * ширину от секции, а не от окна.
 */
/* Разворот делает РАЗБРОС тени (четвёртое число), а не смещение. Через
   смещение (`-100vmax 0 0`) тень уезжает копией на 100vmax влево, а между нею
   и самой секцией остаётся непрокрашенный зазор шириной (100vmax − ширина
   секции); на 1440 px это выглядело как полоса, обрывающаяся по краю
   контейнера. Разброс раздувает прямоугольник во все стороны, а clip-path
   срезает разбухание сверху и снизу, оставляя горизонтальное. */
.lb-sections > .lb:nth-child(even),
.lb--band {
	box-shadow: 0 0 0 100vmax var(--lb-band);
	clip-path: inset(0 -100vmax);
}

/* Здесь стоял `.lb:first-child { padding-top: 1.5rem }` — срезка верхнего
   отступа у первой секции. Снята 2026-08-06 по решению владельца.
   ⚠️ Селектор не был привязан к `.lb-sections`, поэтому попадал и в полосу
   призыва над подвалом: у неё выходило 24 px сверху против 57.6 снизу.
   Теперь у обеих отступ симметричный. */

/* Секция без полосы, зажатая между двумя полосами, читается как провал, если
   у неё тот же отступ: воздуха вокруг неё вдвое больше. Гасим разницу. */
.lb-sections > .lb:nth-child(odd):not(:first-child) {
	padding-block: calc(var(--lb-section-gap) * .85);
}

.lb__inner {
	position: relative;
	z-index: 1;
}

/* ──────────────────────────────────────────────────────── шапка секции */

.lb__head {
	margin-bottom: clamp(1.75rem, 2.5vw, 2.75rem);
	max-width: var(--lb-measure);
}

.lb__title {
	margin: 0 0 .625rem;
	font-size: clamp(1.5rem, 1.15rem + 1.4vw, 2.25rem);
	line-height: 1.15;
	letter-spacing: -.02em;
	/* Одинокое слово на последней строке заголовка — самый заметный глазу
	   дефект набора; balance разносит строки по длине, а не по остатку. */
	text-wrap: balance;
}

.lb__lead {
	margin: 0;
	max-width: var(--lb-measure);
	color: var(--lb-muted);
	font-size: 1.0625rem;
	line-height: 1.6;
	text-wrap: pretty;
}

/* Числа, коды, сроки и цены — вторым, моноширинным голосом: числа должны
   читаться как измеренные, а не как рекламные. */
.lb-num,
.lb-mono {
	font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
	font-variant-numeric: tabular-nums;
}

/* ══════════════════════════════════════════════════════════════════ герой */

.lb--hero {
	padding-top: clamp(2rem, 4vw, 3.5rem);
}

.lb-hero__eyebrow {
	margin: 0 0 1rem;
	display: inline-flex;
	align-items: center;
	gap: .5rem;
	font-size: .8125rem;
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
	color: var(--lb-accent);
}

.lb-hero__eyebrow::before {
	content: '';
	width: 24px;
	height: 2px;
	background: currentColor;
	flex: none;
}

/* Первый экран с иллюстрацией — две колонки.
   -------------------------------------------------------------------------
   Класс ставит шаблон и только когда картинка ЕСТЬ: без неё разметка и вид
   прежние, в одну колонку. Поэтому у главной, хабов и любой сущности без
   медиа ничего не меняется.

   Колонки 1.15fr / 1fr, а не поровну: текст несёт заголовок, лид, якорь цены
   и две кнопки, картинка — только себя. Поровну заголовок ломался бы
   на лишнюю строку.

   Порог 900 px, а не 768: на планшете 820 px две колонки по 380 дают
   заголовок кеглем 44 px в четыре строки. Ниже порога картинка идёт
   под текстом и первой не показывается — над сгибом должен быть заголовок,
   а не иллюстрация. */
.lb-hero--with-media {
	display: grid;
	gap: clamp(1.5rem, 3vw, 3.5rem);
	align-items: center;
}

@media (min-width: 900px) {
	.lb-hero--with-media {
		grid-template-columns: 1.15fr 1fr;
	}
}

.lb-hero__media img {
	display: block;
	width: 100%;
	height: auto;
}

/* Параллакс иллюстрации первого экрана — только по параметру блока
   (`parallax`), только на двухколоночной раскладке и только когда система
   не просит убрать движение.

   ПОЧЕМУ БЕЗ JS. Картинка героя — почти всегда LCP-элемент. Обработчик
   прокрутки на ней означает работу в главном потоке ровно в тот момент,
   когда браузер рисует первый экран, плюс лишний скрипт в загрузке ради
   декора. `animation-timeline: scroll()` считает прогресс на композиторе,
   без единого кадра в главном потоке.

   ПОЧЕМУ `scroll()`, А НЕ `view()`. У `view()` прогресс элемента, уже
   стоящего в окне при загрузке, начинается НЕ с нуля — картинка при первой
   отрисовке оказалась бы смещена относительно места, отведённого ей
   раскладкой. С `scroll()` и диапазоном от нуля страницы смещение при
   загрузке ровно нулевое: пока не прокрутили, ничего не сдвинуто.

   ЧЕГО НЕ ДЕЛАЕМ. Ни `will-change`, ни постоянного слоя: браузер поднимает
   слой сам на время анимации, а `will-change` держал бы его всегда — на LCP-
   элементе это чистый расход памяти. Раскладку сдвиг не трогает вовсе:
   `transform` не участвует в потоке, поэтому CLS от этого нуля.

   ЗАПАСНОЙ ВАРИАНТ — отсутствие эффекта. Там, где `scroll()` не поддержан
   (Firefox на 2026-08), правило не применяется и картинка просто стоит.
   Ничего чинить не нужно: декор, у которого запасной вариант «нет декора»,
   безопасен по устройству. */
@media (min-width: 900px) and (prefers-reduced-motion: no-preference) {
	@supports (animation-timeline: scroll()) {
		.lb-hero__media--parallax img {
			animation: lb-hero-parallax linear both;
			animation-timeline: scroll(root block);
			/* Диапазон — первый экран. Дальше картинки всё равно не видно,
			   а «докручивать» смещение за пределами видимости незачем. */
			animation-range: 0 100vh;
		}

		/* 28 px на экран прокрутки. Больше — и иллюстрация начинает
		   заметно наезжать на текст соседней колонки; меньше — эффекта
		   не видно вовсе, то есть правило есть, а смысла нет. */
		@keyframes lb-hero-parallax {
			from { transform: translate3d(0, 0, 0); }
			to   { transform: translate3d(0, 28px, 0); }
		}
	}
}

/* Ниже порога двух колонок картинка идёт ПОД текстом, и там её надо
   ограничить: во всю ширину планшета иллюстрация 1200×630 занимает пол-экрана
   и отталкивает вниз всё, что за первым экраном. Замерено на 820 px —
   картинка выходила 820 px в ширину. Ограничение по мере, а не по проценту:
   на 480 px и на 899 px процент дал бы разный результат при одной задаче. */
@media (max-width: 899.98px) {
	.lb-hero__media {
		max-width: 420px;
		margin-inline: auto;
	}
}

/* Ограничение по знакам у заголовка и лида считается от ширины КОЛОНКИ,
   а она вдвое уже контейнера — 20ch там уже не защита, а лишняя обрезка. */
@media (min-width: 900px) {
	.lb-hero--with-media .lb-hero__title { max-width: none; }
	.lb-hero--with-media .lb-hero__lead  { max-width: none; }
}

.lb-hero__title {
	margin: 0 0 1.25rem;
	/* Заголовок во всю ширину контейнера (1200 px) — строка на 60+ знаков
	   кеглем 60 px: глаз не находит начало следующей строки. Ограничение
	   в знаках, а не в пикселях: оно переживёт смену кегля и контейнера. */
	max-width: 20ch;
	font-size: clamp(2rem, 1.3rem + 3vw, 3.75rem);
	line-height: 1.04;
	letter-spacing: -.03em;
	text-wrap: balance;
}

/* Абзацы ВНУТРИ лида первого экрана: лид размечаемый, и в нём бывает
   второй абзац. Крайние отступы снимаем — внешние задаёт сам `.lb-hero__lead`,
   иначе между заголовком и лидом появился бы двойной зазор. У сайтов
   с однострочным лидом внутреннего абзаца нет, и правило ни на что не влияет. */
.lb-hero__lead > p        { margin: 0 0 .75rem; }
.lb-hero__lead > p:last-child { margin-bottom: 0; }

/* То же у текста шага. */
.lb-process__text > p        { margin: 0 0 .5rem; }
.lb-process__text > p:last-child { margin-bottom: 0; }

.lb-hero__lead {
	margin: 0 0 1.75rem;
	max-width: 54ch;
	font-size: clamp(1.0625rem, 1rem + .35vw, 1.25rem);
	line-height: 1.55;
	color: var(--lb-muted);
	text-wrap: pretty;
}

/* Якорь цены — не строка текста, а объект: он держит внимание наравне
   с кнопкой и должен читаться с той же дистанции. */
.lb-hero__anchor {
	margin: 0 0 1.75rem;
	display: inline-flex;
	align-items: baseline;
	gap: .5rem;
	padding: .625rem 1rem;
	border: 1px solid var(--lb-card-line);
	border-radius: var(--lb-radius-sm);
	background: var(--lb-card-bg);
}

.lb-hero__anchor-label {
	font-size: .875rem;
	color: var(--lb-muted);
}

.lb-hero__anchor-value {
	font-size: clamp(1.375rem, 1.2rem + .8vw, 1.75rem);
	font-weight: 600;
	color: var(--lb-ink);
}

.lb-hero__cta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 1rem 1.5rem;
}

.lb-cta-micro {
	color: var(--lb-muted);
	text-underline-offset: .25em;
	transition: color .2s ease;
}

.lb-cta-micro:hover {
	color: var(--lb-accent);
}

/* ══════════════════════════════════════════════════════════ сетки карточек */

.lb-pains,
.lb-solution,
.lb-guarantee,
.lb-after,
.lb-techstack,
.lb-integrations,
.lb-related {
	list-style: none;
	margin: 0;
	padding: 0;
}

/*
 * Раскладка карточек: последняя строка ДОБИРАЕТ ширину, а не оставляет сироту.
 *
 * ── Повод ────────────────────────────────────────────────────────────────
 *
 * Владелец 2026-08-14 на `/products-n-1--lending`: «одна карточка во второй
 * строке выглядит сиротливо». Так и есть: у блока `pains` там пять карточек,
 * а на широком экране в строку встаёт четыре.
 *
 * ── 🔴 Почему это НЕ чинится счётом карточек ─────────────────────────────
 *
 * Напрашивается правило «держать по 4/6/8». Замер браузером показывает,
 * что его недостаточно: колонок не фиксированное число, `auto-fit` даёт
 *
 *     ≥1440 px — 4 колонки · 1024–1280 — 3 · 768–900 — 2 · уже — 1
 *
 * и сирота появляется от ПАРЫ «сколько карточек × сколько колонок».
 * Четыре карточки, которые на широком экране лежат идеально, на ноутбучной
 * ширине дают 3+1 — ту же самую сироту. А четыре карточки — самый частый
 * случай в базе: 52 блока из 114.
 *
 * Значит правило по счёту пришлось бы соблюдать для каждой ширины сразу,
 * что невозможно, и вдобавок дописать содержимое примерно полусотне блоков —
 * то есть выдумать «боли» и «выгоды» ради ровного счёта. Это ровно тот
 * наполнитель, который запрещает CONTENT_RULES §1.
 *
 * ── Что сделано вместо ───────────────────────────────────────────────────
 *
 * Flex вместо grid: карточки последней строки РАСТЯГИВАЮТСЯ на её ширину.
 * Пять карточек при четырёх колонках дают 4 + одна во всю ширину; при трёх
 * колонках — 3 + две по половине. Сироты не остаётся ни при каком счёте
 * и ни при какой ширине, и содержимое править не нужно вовсе.
 *
 * ⚠️ `min-width: min(17rem, 100%)` обязателен. У grid `minmax(17rem, 1fr)`
 * гарантировал колонке минимум и переносил лишнее; flex по умолчанию вместо
 * переноса СЖИМАЕТ элементы ниже basis. Без этой строки на узком экране
 * две карточки ужимались бы в 130 px вместо того, чтобы встать друг под друга.
 * `min()` — чтобы на экране уже 17rem карточка не вылезала за край.
 */
.lb-pains,
.lb-solution,
.lb-guarantee,
.lb-after {
	display: flex;
	flex-wrap: wrap;
	gap: var(--lb-gap);
}

.lb-pains > *,
.lb-solution > *,
.lb-guarantee > *,
.lb-after > * {
	flex: 1 1 var(--lb-card-min, 17rem);
	min-width: min(var(--lb-card-min, 17rem), 100%);
}

/*
 * Карточка. Одна декларация на четыре перечня — потому что это одна сущность
 * («тезис с подписью»), а не четыре похожие. Разъезжаться им незачем, а
 * четыре копии разъезжаются при первой правке.
 */
.lb-pains__item,
.lb-solution__item,
.lb-guarantee__item,
.lb-after__item {
	position: relative;
	display: flex;
	flex-direction: column;
	padding: clamp(1.25rem, 2vw, 1.75rem);
	border: 1px solid var(--lb-card-line);
	border-radius: var(--lb-radius);
	background: var(--lb-card-bg);
	box-shadow: var(--lb-shadow);
	transition: transform .25s cubic-bezier(.22, .61, .36, 1),
	            box-shadow .25s ease,
	            border-color .25s ease;
}

/* Наведение поднимает карточку, а не подкрашивает её: подсветка фоном на
   сетке из шести штук читается как «выбрано», хотя выбирать нечего. */
.lb-pains__item:hover,
.lb-solution__item:hover,
.lb-guarantee__item:hover,
.lb-after__item:hover {
	transform: translateY(-3px);
	box-shadow: var(--lb-shadow-lift);
	border-color: color-mix(in srgb, var(--lb-accent) 35%, var(--lb-card-line));
}

/* «Так сейчас» — состояние проблемы, и оно не должно краситься в бренд.
   Решение сохранено дословно из прежней редакции: §4. */
.lb--pains .lb-pains__item {
	border-left: 3px solid var(--lb-warn);
}

.lb--pains .lb-pains__item:hover {
	border-color: var(--lb-card-line);
	border-left-color: var(--lb-warn);
}

.lb-pains__title,
.lb-solution__title,
.lb-guarantee__title,
.lb-after__title,
.lb-process__title {
	margin: 0 0 .625rem;
	font-size: 1.0625rem;
	font-weight: 600;
	line-height: 1.3;
	letter-spacing: -.01em;
}

.lb-pains__text,
.lb-solution__text,
.lb-guarantee__text,
.lb-after__text,
.lb-process__text {
	margin: 0;
	color: var(--lb-muted);
	line-height: 1.6;
}

/* Подпись модуля прижата к низу карточки: в сетке подписи обязаны стоять
   на одной линии, иначе они читаются как часть текста, а не как сноска. */
.lb-solution__module {
	margin: auto 0 0;
	padding-top: 1rem;
	font-size: .8125rem;
	color: var(--lb-muted);
}

.lb-solution__module-label {
	text-transform: uppercase;
	letter-spacing: .06em;
	margin-right: .5em;
	opacity: .7;
}

/* ═════════════════════════════════════════════ раскладка узких секций (≥992px)

   Таблица, цена, FAQ, возражения и форма читаются в 45–70 знаков и шире
   не становятся. На контейнере в 1200 px это давало колонку слева и пустую
   правую треть на каждой второй секции — страница выглядела недовёрстанной,
   хотя всё было на месте.

   Решение — не растянуть содержимое (шире 70 знаков строка не читается),
   а занять ширину заголовком: шапка секции уходит в левую колонку и остаётся
   на виду, пока справа листается длинная таблица или гармошка.

   Оборачивать содержимое в дополнительный <div> для этого НЕ нужно, и это
   принципиально: обёртку пришлось бы добавить в каждый партиал и помнить
   про неё в новом.

   ⚠️ Гридом это НЕ делается, и первая попытка была неверной. `grid-row: 1/-1`
   на шапке читается как «занять все строки», но `-1` указывает на последнюю
   линию ЯВНОЙ сетки, а строк здесь не объявлено ни одной. Шапка оставалась
   в первой строке и задавала ей СВОЮ высоту. Замер на секции цены: плашка
   суммы кончалась на 2790, перечень «что входит» начинался на 2852 — провал
   62 px вместо 20, ровно разница между высотой заголовка и высотой плашки.

   Поэтому шапка выведена из потока абсолютом, а место под неё держит
   padding-left контейнера. Содержимое остаётся обычным потоком со своими
   отступами — их не нужно ни гасить, ни подменять зазорами грида.
*/
@media (min-width: 62em) {
	/* `:has(> .lb__head)` — не украшение, а условие корректности. Шапку печатает
	   `_head.html` ТОЛЬКО когда у блока задан заголовок, а до наполнения его нет
	   почти нигде. Без этого условия раскладка резервировала колонку в 16rem
	   под шапку, которой в разметке не существует: на странице услуги плашка
	   цены уезжала вправо на 313 px пустоты. Замер подтвердил — `innerPadL:
	   313.6px` при `head: НЕТ`. */
	.lb--tco .lb__inner:has(> .lb__head),
	.lb--compare .lb__inner:has(> .lb__head),
	.lb--price .lb__inner:has(> .lb__head),
	.lb--faq .lb__inner:has(> .lb__head),
	.lb--objections .lb__inner:has(> .lb__head),
	.lb--integrations .lb__inner:has(> .lb__head),
	.lb--lead-form .lb__inner:has(> .lb__head),
	.lb--local .lb__inner:has(> .lb__head),
	.lb--case .lb__inner:has(> .lb__head) {
		position: relative;
		/* 16rem хватает заголовку на две строки; 20rem оставляли пустую колонку
		   высотой во всю секцию. */
		padding-left: calc(16rem + clamp(2rem, 4vw, 4.5rem));
	}

	.lb--tco .lb__inner > .lb__head,
	.lb--compare .lb__inner > .lb__head,
	.lb--price .lb__inner > .lb__head,
	.lb--faq .lb__inner > .lb__head,
	.lb--objections .lb__inner > .lb__head,
	.lb--integrations .lb__inner > .lb__head,
	.lb--lead-form .lb__inner > .lb__head,
	.lb--local .lb__inner > .lb__head,
	.lb--case .lb__inner > .lb__head {
		position: absolute;
		left: 0;
		top: 0;
		width: 16rem;
		margin-bottom: 0;
	}
}

/* ══════════════════════════════════════════════════════════════════ цена */

.lb-price__value {
	margin: 0 0 1.5rem;
	/* Ячейка грида растягивает элемент на всю колонку, а inline-flex внутри
	   грида блокифицируется — плашка цены расползалась на всю ширину полосой.
	   justify-self прижимает её к содержимому. */
	justify-self: start;
	display: inline-flex;
	align-items: baseline;
	gap: .5rem;
	padding: .875rem 1.25rem;
	border-radius: var(--lb-radius);
	background: color-mix(in srgb, var(--lb-accent) 10%, transparent);
}

.lb-price__from {
	color: var(--lb-muted);
}

.lb-price__amount {
	font-size: clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem);
	font-weight: 700;
	line-height: 1;
	color: var(--lb-ink);
}

/* Строка «что входит» — название слева, пометка справа. Это таблица, а не
   абзац, поэтому мера строки её не ограничивает: обрезанная по 68 знакам,
   она отрывала правый столбец от края и ломала выравнивание пометок. */
.lb-price__includes {
	list-style: none;
	margin: 0 0 1.25rem;
	padding: 0;
}

.lb-price__row {
	display: flex;
	justify-content: space-between;
	gap: 1rem;
	padding: .875rem 0;
	border-bottom: 1px solid var(--lb-line);
}

.lb-price__row:last-child {
	border-bottom: 0;
}

.lb-price__row-title {
	font-weight: 500;
}

.lb-price__row-text {
	color: var(--lb-muted);
	text-align: right;
}

/* Сумма позиции сметы. Прижата вправо и не переносится: столбец чисел
   читается только выровненным, а разорванная посреди разрядов сумма —
   это то, ради чего разряды делит неразрывный пробел (§5).

   Обёртка, а не `margin-left:auto` у самой суммы: приставка «от» — отдельный
   элемент (она набирается основным шрифтом, сумма — цифровым), и два
   прижатых вправо элемента разошлись бы по краям строки. */
.lb-price__row-money {
	margin-left: auto;
	display: inline-flex;
	align-items: baseline;
	gap: .35rem;
	white-space: nowrap;
}

.lb-price__row-amount {
	white-space: nowrap;
	font-weight: 600;
}

/* «Что считается отдельно» — обязательная часть §2. Набирается как сноска,
   но не мельче 14px: без неё «от» читается как «столько и будет», и прятать
   её размером — тот же обман, только оформленный. */
.lb-price__note,
.lb-tco__note,
.lb-compare__note,
.lb-integrations__note {
	/* Отступ сверху обязателен: раньше его давал зазор грида, а после перехода
	   на обычный поток сноска прилипала вплотную к карточке перечня. */
	margin: 1rem 0 0;
	max-width: var(--lb-measure);
	font-size: .875rem;
	line-height: 1.55;
	color: var(--lb-muted);
}

/* ═══════════════════════════════════════════════════════════════ процесс */

.lb-process {
	list-style: none;
	margin: 0;
	padding: 0;
	counter-reset: lbstep;
	display: grid;
	gap: var(--lb-gap);
	grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.lb-process__step {
	counter-increment: lbstep;
	position: relative;
	padding: 3.25rem 1.25rem 1.5rem;
	border-radius: var(--lb-radius);
	background: var(--lb-card-bg);
	border: 1px solid var(--lb-card-line);
}

/* Нумерация — CSS-счётчиком, а не текстом в разметке: номер в тексте попал бы
   и в длину контента, и в опись числовых заявлений §4. Решение сохранено. */
.lb-process__step::before {
	content: counter(lbstep, decimal-leading-zero);
	position: absolute;
	top: 1.25rem;
	left: 1.25rem;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 2rem;
	height: 1.75rem;
	padding: 0 .5rem;
	border-radius: 999px;
	background: color-mix(in srgb, var(--lb-accent) 12%, transparent);
	color: var(--lb-accent);
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: .8125rem;
	font-weight: 600;
}

/* Срок у шага обязателен (§2, content-guard ищет его регулярным выражением).
   Раз он обязателен — он и показан как факт, а не как приписка серым. */
.lb-process__duration {
	margin: 0 0 .5rem;
	font-size: .8125rem;
	font-weight: 600;
	color: var(--lb-accent);
}

/* ══════════════════════════════════════════════════════════════════ таблицы */

.lb-tco,
.lb-compare {
	width: 100%;
	border-collapse: collapse;
	font-size: .9375rem;
	background: var(--lb-card-bg);
	/* Рамка обязательна. Без неё у таблицы нет нижнего края (последняя строка
	   намеренно без линии), и подкрашенная колонка «у нас» обрывалась в воздухе:
	   выглядело как недорисованная заливка, а не как выделенный столбец. */
	border: 1px solid var(--lb-card-line);
	border-radius: var(--lb-radius);
	overflow: hidden;
}

.lb-tco th,
.lb-tco td,
.lb-compare th,
.lb-compare td {
	padding: .875rem 1rem;
	border-bottom: 1px solid var(--lb-line);
	text-align: left;
	vertical-align: top;
}

.lb-tco tbody tr:last-child th,
.lb-tco tbody tr:last-child td,
.lb-compare tbody tr:last-child th,
.lb-compare tbody tr:last-child td {
	border-bottom: 0;
}

.lb-tco td,
.lb-compare td {
	text-align: right;
}

.lb-compare td {
	text-align: left;
}

.lb-tco thead th,
.lb-compare thead th {
	font-size: .75rem;
	letter-spacing: .06em;
	text-transform: uppercase;
	color: var(--lb-muted);
	background: color-mix(in srgb, var(--lb-ink) 4%, transparent);
	border-bottom-color: var(--lb-line);
}

/* Своя колонка выделена подложкой, а не жирным: сравнивают глазами столбцы,
   и столбец должен быть виден как столбец. Обратная сторона расчёта (§ tco:
   «подписка дешевле на месяц») от этого не прячется — она в тексте под
   таблицей, который набран тем же кеглем, что и остальное. */
.lb-tco tbody td:first-of-type,
.lb-tco thead th:nth-child(2) {
	background: color-mix(in srgb, var(--lb-accent) 7%, transparent);
}

/* Таблица шире экрана прокручивается сама, а не растягивает страницу. */
.lb--tco .lb__inner,
.lb--compare .lb__inner {
	overflow-x: auto;
}

.lb-tco__period {
	margin: 1rem 0 .5rem;
	font-size: .875rem;
	color: var(--lb-muted);
}

/* ═══════════════════════════════════════════════════════════════ перечень */

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

   Селектор — `.lb .widget`, а НЕ `.lb--listing .widget`. Прежняя редакция была
   написана под единственный тогда блок-делегат, и появление `news`
   и `categories` немедленно дало 80 px чужого `padding` внутри секции:
   у новостей между шапкой и карточками получилось 116 px против 36 у перечня,
   у плиток рубрик — полоса пустоты над первым рядом. Внутри `.lb` виджет
   бывает только один способ — делегированием, — поэтому привязка к коду блока
   тут лишняя, а список кодов пришлось бы дополнять при каждом новом делегате. */
.lb .widget {
	padding: 0;
	margin: 0;
}

.lb .widget > .container,
.lb .widget > .container-xxl {
	padding-left: 0;
	padding-right: 0;
	max-width: none;
	width: auto;
}

/* ══════════════════════════════════════════════════════════════ FAQ, Q/A */

/* Ширину гармошки мера строки не ограничивает: в свёрнутом виде это перечень
   вопросов, а не абзац. Меру держит сам ответ (`.lb-faq__a`). */
.lb-faq {
	border: 1px solid var(--lb-card-line);
	border-radius: var(--lb-radius);
	background: var(--lb-card-bg);
	overflow: hidden;
}

.lb-faq__item {
	border-bottom: 1px solid var(--lb-line);
}

.lb-faq__item:last-child {
	border-bottom: 0;
}

.lb-faq__q {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 1rem;
	padding: 1.125rem 1.25rem;
	cursor: pointer;
	font-weight: 600;
	list-style: none;
	transition: color .2s ease, background-color .2s ease;
}

.lb-faq__q:hover {
	color: var(--lb-accent);
	background: color-mix(in srgb, var(--lb-accent) 5%, transparent);
}

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

/* Знак — не «+»/«–» текстом, а повёрнутый шеврон: плюс в некоторых шрифтах
   рисуется как математический и прыгает по базовой линии при смене
   на минус. Поворот идёт трансформом, то есть композитором. */
.lb-faq__q::after {
	content: '';
	flex: none;
	width: .5rem;
	height: .5rem;
	margin-top: .45em;
	border-right: 2px solid currentColor;
	border-bottom: 2px solid currentColor;
	transform: rotate(45deg);
	transform-origin: 60% 60%;
	transition: transform .25s ease;
	opacity: .6;
}

.lb-faq__item[open] .lb-faq__q::after {
	transform: rotate(-135deg);
}

.lb-faq__a {
	padding: 0 1.25rem 1.25rem;
	max-width: var(--lb-measure);
	color: var(--lb-muted);
	line-height: 1.65;
}

/* Раскрытие <details> браузер не анимирует. Анимируем содержимое —
   этого достаточно, чтобы движение не выглядело рывком. */
.lb-faq__item[open] .lb-faq__a {
	animation: lb-fade-down .28s ease;
}

@keyframes lb-fade-down {
	from { opacity: 0; transform: translateY(-4px); }
	to   { opacity: 1; transform: none; }
}

/*
 * Пары вопрос/ответ. Гридом с одним gap НЕЛЬЗЯ: расстояние внутри пары
 * (вопрос → его ответ) и между парами получается одинаковым, и четыре строки
 * читаются как четыре не связанные между собой реплики — пары в них не видно.
 * Внутрипарный отступ обязан быть заметно меньше межпарного.
 */
.lb-objections {
	margin: 0;
	max-width: var(--lb-measure);
}

.lb-objections__q {
	margin: 2rem 0 .625rem;
	font-weight: 600;
	font-size: 1.0625rem;
	/* Вопрос отбит слева акцентом: пары вопрос/ответ в <dl> без отбивки
	   слипаются в сплошной текст, а это ровно та «портянка», от которой
	   блоки и заводились. */
	padding-left: .875rem;
	border-left: 3px solid var(--lb-accent);
}

.lb-objections__q:first-child {
	margin-top: 0;
}

.lb-objections__a {
	margin: 0 0 0 .875rem;
	color: var(--lb-muted);
	line-height: 1.65;
}

/* ══════════════════════════════════════════════════════════════ интеграции */

.lb-integrations {
	border: 1px solid var(--lb-card-line);
	border-radius: var(--lb-radius);
	background: var(--lb-card-bg);
	overflow: hidden;
}

/*
 * Три колонки, выровненные ПО ВСЕМУ списку, а не по строке.
 *
 * На флексе ширину первой колонки задавала длина названия («Telegram»,
 * «ЮKassa», «1С»), поэтому пометка и пояснение начинались на каждой строке
 * с новой позиции: перечень читался как рваный список, хотя это таблица.
 * Грид на самой строке проблему НЕ решает — `max-content` каждый <li>
 * считает у себя, и колонки всё равно расходятся.
 *
 * Поэтому дорожки объявлены на <ul>, а строка подхватывает их через
 * `subgrid`. Строка при этом остаётся собственным боксом — на ней держится
 * разделительная линия и подложка при наведении.
 */
/* Две дорожки, а не три: колонка пометки снята вместе с самой пометкой
   (решение владельца 2026-08-12, см. `blocks/integrations.html`). */
.lb-integrations {
	display: grid;
	grid-template-columns: max-content minmax(0, 1fr);
}

.lb-integrations__item {
	display: grid;
	grid-column: 1 / -1;
	grid-template-columns: subgrid;
	align-items: center;
	gap: .5rem 1rem;
	padding: .875rem 1.25rem;
	border-bottom: 1px solid var(--lb-line);
}

/* Браузер без subgrid (Safari < 16, Chrome < 117) получает флекс-строку —
   она хуже выровнена, но не разваливается. */
@supports not (grid-template-columns: subgrid) {
	.lb-integrations { display: block; }
	.lb-integrations__item {
		display: flex;
		flex-wrap: wrap;
		align-items: baseline;
	}
}

@media (max-width: 34em) {
	.lb-integrations { grid-template-columns: minmax(0, 1fr); }
	.lb-integrations__text { grid-column: 1 / -1; }
}

.lb-integrations__item:last-child {
	border-bottom: 0;
}

.lb-integrations__name {
	font-weight: 600;
}

/* ⚠️ ЗДЕСЬ ЖИЛИ ПОМЕТКИ «работает» / «делается отдельной работой» /
   «не берём» — плашка `.lb-integrations__status` и три её состояния,
   различавшиеся ФОРМОЙ рамки (заливка → контур → пунктир), а не цветом:
   цвет видит не всякий читатель, а при чёрно-белой печати — никто.

   Сняты 2026-08-12 решением владельца: «статусы не нужны по всему сайту,
   только отпугивают». Правило про форму вместо цвета остаётся в силе
   для любой будущей пометки — оно не про интеграции, а про то, как
   вообще различать состояния (§4 норматива).

   Печатаются по-прежнему ВСЕ строки, включая «не берём»: замер показал,
   что отказ у всех пяти таких строк сказан их собственным текстом,
   а пометка его лишь дублировала. Разбор — в `blocks/integrations.html`. */

.lb-integrations__text {
	color: var(--lb-muted);
	flex: 1 1 14rem;
}

/* ═══════════════════════════════════════════════════════════════════ экраны */

.lb-screens {
	margin: 0;
	display: grid;
	gap: var(--lb-gap);
	grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
}

.lb-screens__shot {
	border-radius: var(--lb-radius);
	overflow: hidden;
	background: var(--lb-card-bg);
	border: 1px solid var(--lb-card-line);
	box-shadow: var(--lb-shadow);
	transition: transform .3s cubic-bezier(.22, .61, .36, 1), box-shadow .3s ease;
}

.lb-screens__shot:hover {
	transform: translateY(-4px);
	box-shadow: var(--lb-shadow-lift);
}

.lb-screens__shot img {
	display: block;
	width: 100%;
	height: auto;
}

.lb-screens__caption {
	padding: .75rem 1rem 1rem;
	font-size: .8125rem;
	color: var(--lb-muted);
}

/* ═══════════════════════════════════════════════════════════════════ кейс */

.lb-case__client {
	margin: 0 0 .75rem;
	font-weight: 600;
}

.lb-case__summary {
	max-width: var(--lb-measure);
	color: var(--lb-muted);
	line-height: 1.65;
}

.lb-case__figures {
	margin: 2rem 0 0;
	display: grid;
	gap: var(--lb-gap);
	grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}

.lb-case__figure {
	padding: 1.25rem;
	border-radius: var(--lb-radius);
	background: var(--lb-card-bg);
	border: 1px solid var(--lb-card-line);
	border-top: 3px solid var(--lb-accent);
}

.lb-case__label {
	font-size: .8125rem;
	color: var(--lb-muted);
}

.lb-case__value {
	margin: .375rem 0 0;
	font-size: clamp(1.5rem, 1.3rem + .8vw, 2rem);
	font-weight: 700;
	line-height: 1;
	color: var(--lb-ink);
}

/* ═══════════════════════════════════════════════════════════════════ форма */

/*
 * Форма — целевое действие страницы, и на полосе она должна выглядеть как
 * объект, к которому пришли, а не как хвост секции. Панель, а не голые поля.
 */
/* Ограничение ширины — на самой форме, а не на `.lb__inner`: на широком экране
   `.lb__inner` у этой секции работает гридом (см. раскладку узких секций),
   и max-width на нём схлопнул бы обе колонки в одну. */
.lb-form {
	max-width: 34rem;
	padding: clamp(1.5rem, 3vw, 2.25rem);
	border-radius: var(--lb-radius);
	background: var(--lb-card-bg);
	border: 1px solid var(--lb-card-line);
	box-shadow: var(--lb-shadow-lift);
}

.lb-form__row {
	margin-bottom: 1.125rem;
}

.lb-form__label {
	display: block;
	margin-bottom: .4375rem;
	font-size: .875rem;
	font-weight: 500;
	color: var(--lb-ink);
}

.lb-form .form-control {
	border-radius: var(--lb-radius-sm);
	border-color: var(--lb-line);
	padding: .625rem .875rem;
	transition: border-color .2s ease, box-shadow .2s ease;
}

.lb-form .form-control:focus {
	border-color: var(--lb-accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--lb-accent) 18%, transparent);
}

.lb-form__submit {
	margin-top: .5rem;
	width: 100%;
	padding-block: .75rem;
	font-weight: 600;
}

/* Галку согласия ставит общий партиал form-consent.html, а не разметка формы
   (§5). Стили здесь — тоже общие, по той же причине: своя копия у каждой
   формы однажды разъедется, и разъедется именно та, где галка обязательна. */
.form-consent {
	display: flex;
	align-items: flex-start;
	gap: .5rem;
	margin: 1.125rem 0;
	font-size: .8125rem;
	line-height: 1.45;
}

.form-consent__box {
	margin-top: .2em;
	flex: 0 0 auto;
}

.form-consent__label {
	color: var(--lb-muted);
}

/* ══════════════════════════════════════════════════════════ смежное, гео, стек */

/* Сетка, а не колонка в 42rem. Столбиком из двух-трёх ссылок секция занимала
   треть ширины, и под ней оставалась пустая половина экрана — на последней
   секции страницы это читается как «вёрстка оборвалась». */
.lb-related {
	display: grid;
	gap: .75rem;
	grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

.lb-related__item {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 1rem;
	padding: .875rem 1rem;
	border-radius: var(--lb-radius-sm);
	background: var(--lb-card-bg);
	border: 1px solid var(--lb-card-line);
	transition: border-color .2s ease, transform .2s ease;
}

.lb-related__item:hover {
	border-color: color-mix(in srgb, var(--lb-accent) 45%, var(--lb-card-line));
	transform: translateX(3px);
}

.lb-related__link {
	font-weight: 500;
	text-decoration: none;
}

.lb-related__price {
	color: var(--lb-muted);
	flex: none;
}

.lb-local__text {
	max-width: var(--lb-measure);
	line-height: 1.65;
}

.lb-local__facts {
	list-style: none;
	margin: 1.25rem 0 0;
	padding: 0;
	display: flex;
	flex-wrap: wrap;
	gap: .5rem;
	font-size: .875rem;
}

.lb-local__facts > li {
	padding: .375rem .75rem;
	border-radius: 999px;
	background: var(--lb-card-bg);
	border: 1px solid var(--lb-card-line);
	color: var(--lb-muted);
}

/*
 * `.lb-techstack` — бывший `.lb-stack`.
 *
 * Имя `lb-stack` носили ОДНОВРЕМЕННО обёртка всех секций в render.html и
 * список технологий в stack.html, то есть внешний контейнер страницы и
 * маленький перечень внутри одной секции. Любое правило на `.lb-stack`
 * попадало в оба, и вложенность `.lb-stack .lb-stack` была законной.
 * Разведено: обёртка — `.lb-sections`, перечень — `.lb-techstack`.
 */
.lb-techstack {
	display: grid;
	gap: .5rem;
	max-width: 46rem;
}

.lb-techstack__item {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: .5rem 1rem;
	padding: .75rem 1rem;
	border-radius: var(--lb-radius-sm);
	background: var(--lb-card-bg);
	border: 1px solid var(--lb-card-line);
}

.lb-techstack__name {
	font-weight: 600;
	color: var(--lb-accent);
}

.lb-techstack__text {
	color: var(--lb-muted);
}

/* ════════════════════════════════════════════════════════ демо и калькулятор */

.lb-demo__cta,
.lb-calculator__cta {
	margin: 0;
}

/* ══════════════════════════════════════════════════════════════════ движение */

/*
 * Каскад внутри секции. Отдельного класса в разметке НЕ требует: наблюдатель
 * ставит `is-revealed` на саму секцию, а каскад считается отсюда. Иначе класс
 * пришлось бы дописывать в каждый из двадцати трёх партиалов и помнить про
 * него в двадцать четвёртом — то есть завести ровно тот способ терять
 * правило, от которого мы уходим везде.
 *
 * Прячет по-прежнему `html.js-reveal` (см. base.css §7-бис): не выполнился
 * скрипт — ничего не спрятано.
 */
html.js-reveal .lb.is-revealed .lb-pains > *,
html.js-reveal .lb.is-revealed .lb-solution > *,
html.js-reveal .lb.is-revealed .lb-guarantee > *,
html.js-reveal .lb.is-revealed .lb-after > *,
html.js-reveal .lb.is-revealed .lb-process > *,
html.js-reveal .lb.is-revealed .lb-screens > *,
html.js-reveal .lb.is-revealed .lb-case__figures > * {
	animation: lb-rise .5s cubic-bezier(.22, .61, .36, 1) backwards;
}

html.js-reveal .lb.is-revealed :is(.lb-pains, .lb-solution, .lb-guarantee, .lb-after, .lb-process, .lb-screens, .lb-case__figures) > *:nth-child(1) { animation-delay: .05s; }
html.js-reveal .lb.is-revealed :is(.lb-pains, .lb-solution, .lb-guarantee, .lb-after, .lb-process, .lb-screens, .lb-case__figures) > *:nth-child(2) { animation-delay: .11s; }
html.js-reveal .lb.is-revealed :is(.lb-pains, .lb-solution, .lb-guarantee, .lb-after, .lb-process, .lb-screens, .lb-case__figures) > *:nth-child(3) { animation-delay: .17s; }
html.js-reveal .lb.is-revealed :is(.lb-pains, .lb-solution, .lb-guarantee, .lb-after, .lb-process, .lb-screens, .lb-case__figures) > *:nth-child(4) { animation-delay: .23s; }
html.js-reveal .lb.is-revealed :is(.lb-pains, .lb-solution, .lb-guarantee, .lb-after, .lb-process, .lb-screens, .lb-case__figures) > *:nth-child(n+5) { animation-delay: .29s; }

@keyframes lb-rise {
	from { opacity: 0; transform: translateY(16px); }
	to   { opacity: 1; transform: none; }
}

/* Импульс по маршрутам и любые анимации секций выключаются по запросу
   пользователя — это требование доступности, а не украшение. */
@media (prefers-reduced-motion: reduce) {
	.lb *,
	.lb *::before,
	.lb *::after {
		animation: none !important;
		transition: none !important;
	}

	.lb-pains__item:hover,
	.lb-solution__item:hover,
	.lb-guarantee__item:hover,
	.lb-after__item:hover,
	.lb-screens__shot:hover,
	.lb-related__item:hover {
		transform: none;
	}
}

/* ─── cost_calculator ──────────────────────────────────────────────────
   Подбор ступени. Две колонки на широком экране: слева выбор, справа
   результат, который остаётся на виду при прокрутке вопросов, — иначе
   человек отмечает галочки вслепую и не видит, как меняется ответ.

   Все три ступени напечатаны сервером и видны сразу. Скрипт добавляет
   `.calc--chosen` и подсвечивает одну; без него страница остаётся рабочей,
   поэтому «неактивная» ступень приглушается прозрачностью, а не убирается
   из потока — иначе выбор дёргал бы раскладку. */

.calc {
	display: grid;
	gap: var(--lb-gap);
	grid-template-columns: 1fr;
}

@media (min-width: 62em) {
	.calc {
		grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
		align-items: start;
	}

	.calc__result {
		position: sticky;
		top: 1.5rem;
	}
}

.calc__q {
	border: 0;
	margin: 0 0 1.75rem;
	padding: 0;
}

.calc__q-title {
	float: none;
	width: auto;
	font-size: 1.05rem;
	font-weight: 600;
	margin-bottom: .35rem;
	padding: 0;
}

.calc__q-hint {
	color: var(--lb-muted);
	font-size: .92rem;
	margin: 0 0 .75rem;
	max-width: var(--lb-measure);
}

.calc__opts {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	gap: .35rem;
}

.calc__label {
	display: flex;
	gap: .65rem;
	align-items: flex-start;
	padding: .5rem .65rem;
	border-radius: var(--lb-radius-sm);
	cursor: pointer;
	transition: background-color .15s ease;
}

.calc__label:hover {
	background: var(--lb-card-bg);
}

.calc__check {
	margin-top: .25rem;
	flex: 0 0 auto;
}

.calc__opt-text {
	display: flex;
	flex-direction: column;
	gap: .1rem;
}

/* Подтверждение механизмом — мелко и приглушённо: это опора для того, кто
   проверяет, а не аргумент для того, кто выбирает. */
.calc__opt-proof {
	color: var(--lb-muted);
	font-size: .8rem;
	font-family: var(--us-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}

.calc__result {
	display: grid;
	gap: .75rem;
}

.calc__result-hint {
	color: var(--lb-muted);
	font-size: .92rem;
	margin: 0;
}

.calc__tier {
	border: 1px solid var(--lb-line);
	border-radius: var(--lb-radius);
	padding: 1rem 1.15rem;
	background: var(--lb-card-bg);
	transition: opacity .2s ease, border-color .2s ease;
}

.calc__tier-name {
	font-weight: 600;
	margin: 0 0 .2rem;
}

.calc__tier-price {
	margin: 0 0 .5rem;
	display: flex;
	align-items: baseline;
	gap: .35rem;
}

.calc__from {
	color: var(--lb-muted);
	font-size: .95rem;
}

.calc__amount {
	font-size: clamp(1.35rem, 2.4vw, 1.75rem);
	font-weight: 700;
}

.calc__tier-note {
	color: var(--lb-muted);
	font-size: .88rem;
	margin: 0 0 .5rem;
}

.calc__tier-link {
	margin: 0;
	font-size: .92rem;
}

.calc--chosen .calc__tier--active {
	border-color: var(--lb-accent);
	box-shadow: 0 0 0 1px var(--lb-accent);
}

.calc--chosen .calc__tier--dimmed {
	opacity: .45;
}

.calc__cta {
	margin: .5rem 0 0;
}

@media (prefers-reduced-motion: reduce) {
	.calc__label,
	.calc__tier {
		transition: none;
	}
}
