/**
 * ATS Components
 * Переиспользуемые UI-примитивы: кнопки, поля, чекбоксы/радио,
 * базовый вид карточек, бейджи, аккордеон, хлебные крошки.
 * Специфика конкретных секций сайта — в blocks.css.
 * Зависит от tokens.css и base.css.
 */

/* =====================================================
   Кнопки .ats-btn
   ===================================================== */

.ats-btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	font-family: var(--font-body);
	font-weight: 600;
	font-size: .9375rem;
	line-height: 1;
	white-space: nowrap;
	text-decoration: none;
	padding: var(--space-3) var(--space-6);
	/* Мин. высота 44px на мобильном (тач-таргет), 48px от планшета — по спеке. */
	min-height: 44px;
	border-radius: var(--r-md);
	border: 1px solid transparent;
	cursor: pointer;
	user-select: none;
	transition:
		background-color var(--t-fast) var(--ease-standard),
		border-color var(--t-fast) var(--ease-standard),
		color var(--t-fast) var(--ease-standard),
		transform var(--t-fast) var(--ease-standard),
		box-shadow var(--t-fast) var(--ease-standard);
}

@media (min-width: 768px) {
	.ats-btn { min-height: 48px; }
}

.ats-btn:active:not(:disabled):not(.is-loading) {
	transform: scale(.98);
}

.ats-btn:focus-visible {
	outline: none;
	box-shadow: var(--focus-ring);
}

.ats-btn:disabled,
.ats-btn[aria-disabled="true"] {
	cursor: not-allowed;
	background: var(--neutral-200);
	border-color: var(--neutral-200);
	color: var(--text-muted);
	box-shadow: none;
	transform: none;
}

/* --- Primary: единственный акцентный CTA, ведущий к заявке/звонку --- */
.ats-btn--primary {
	background: var(--action-primary);
	border-color: var(--action-primary);
	color: var(--text-on-accent);
	/* Токенная тень (не новая) — главная кнопка страницы была единственным
	   "плоским" элементом среди карточек с тенями и визуально проигрывала им. */
	box-shadow: var(--shadow-sm);
}

.ats-btn--primary:hover:not(:disabled) {
	background: var(--action-primary-hover);
	border-color: var(--action-primary-hover);
}

.ats-btn--primary:active:not(:disabled) {
	background: var(--action-primary-active);
	border-color: var(--action-primary-active);
}

/* --- Secondary: контурная, брендовый синий --- */
.ats-btn--secondary {
	background: transparent;
	border-color: var(--action-secondary);
	color: var(--action-secondary);
}

.ats-btn--secondary:hover:not(:disabled) {
	background: var(--surface-brand-soft);
}

.ats-btn--secondary:active:not(:disabled) {
	background: var(--brand-100);
}

/* --- Tertiary: текстовая/ghost-кнопка --- */
.ats-btn--tertiary {
	background: transparent;
	border-color: transparent;
	color: var(--action-secondary);
	padding-inline: var(--space-3);
}

.ats-btn--tertiary:hover:not(:disabled) {
	background: var(--surface-sunken);
}

/* --- Inverse: для тёмных поверхностей (hero-подложка, footer) --- */
.ats-btn--inverse {
	background: transparent;
	border-color: rgba(255, 255, 255, .4);
	color: var(--text-inverse);
}

.ats-btn--inverse:hover:not(:disabled) {
	background: rgba(255, 255, 255, .12);
	border-color: rgba(255, 255, 255, .6);
}

.ats-btn--inverse:focus-visible {
	box-shadow: 0 0 0 3px rgba(255, 255, 255, .28);
}

.ats-btn--inverse:disabled {
	background: transparent;
	border-color: rgba(255, 255, 255, .16);
	color: var(--text-inverse-muted);
}

/* --- Loading: текст скрывается, вращается спиннер из transform --- */
.ats-btn.is-loading {
	color: transparent !important;
	pointer-events: none;
}

.ats-btn.is-loading::after {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	margin: auto;
	width: 1.1em;
	height: 1.1em;
	border-radius: 50%;
	border: 2px solid rgba(18, 23, 31, .25);
	border-top-color: var(--ink-900);
	animation: ats-btn-spin var(--t-signature) linear infinite;
}

.ats-btn--secondary.is-loading::after,
.ats-btn--tertiary.is-loading::after {
	border-color: rgba(21, 101, 180, .25);
	border-top-color: var(--action-secondary);
}

.ats-btn--inverse.is-loading::after {
	border-color: rgba(255, 255, 255, .3);
	border-top-color: var(--white);
}

@keyframes ats-btn-spin {
	to { transform: rotate(360deg); }
}

/* =====================================================
   Поля форм .ats-field
   ===================================================== */

.ats-field {
	display: flex;
	flex-direction: column;
	gap: var(--space-2);
	margin-bottom: var(--space-4);
}

/*
 * Селекторы-соседи (.ats-field > span/legend) — fallback-разметка форм
 * (class-shortcodes.php) выводит подпись поля как <span> без класса, а в
 * калькуляторе — как <legend>; класс .ats-field__label там не проставлен.
 * Без этих селекторов подписи рендерились обычным текстом 1rem без
 * иерархии. Полиш-проход 2026-08-11, см. docs/02-decisions-log.md.
 */
.ats-field__label,
.ats-field > span:first-child,
.ats-field > legend {
	font-size: .875rem;
	font-weight: 600;
	color: var(--text-secondary);
}

.ats-field__label .is-optional {
	font-weight: 400;
	color: var(--text-muted);
}

/*
 * Звёздочка обязательного поля. В полной форме заявки восемь полей, а
 * обязательны из них два — телефон и согласие; без пометки человек считает
 * обязательными все и либо заполняет лишнее, либо закрывает форму. Цвет —
 * --error-text (4.5:1), а не яркий --error: звёздочка это текст.
 *
 * Смысл передаётся не одним цветом: рядом с формой стоит пояснение, а сам
 * знак читается скринридером как «обязательное поле» через .ats-visually-hidden
 * в разметке. Ревизия дизайна 2026-08-18.
 */
.ats-field__required {
	margin-left: 2px;
	color: var(--error-text);
	font-weight: 700;
}

.ats-form__legend {
	margin-bottom: var(--space-2);
	font-size: .8125rem;
	color: var(--text-muted);
}

.ats-field input:not([type="checkbox"]):not([type="radio"]),
.ats-field select,
.ats-field textarea {
	width: 100%;
	min-height: 48px;
	padding: var(--space-3) var(--space-4);
	border: 1px solid var(--border-input);
	border-radius: var(--r-md);
	background: var(--surface-base);
	color: var(--text-primary);
	font-family: var(--font-body);
	font-size: 1rem;
	line-height: 1.4;
	transition: border-color var(--t-fast) var(--ease-standard), box-shadow var(--t-fast) var(--ease-standard);
}

.ats-field textarea {
	min-height: 96px;
	resize: vertical;
}

.ats-field input:hover:not(:disabled),
.ats-field select:hover:not(:disabled),
.ats-field textarea:hover:not(:disabled) {
	border-color: var(--border-input-hover);
}

.ats-field input:focus-visible,
.ats-field select:focus-visible,
.ats-field textarea:focus-visible,
.ats-field input:focus,
.ats-field select:focus,
.ats-field textarea:focus {
	outline: none;
	border-color: var(--border-focus);
	box-shadow: var(--focus-ring);
}

.ats-field input:disabled,
.ats-field select:disabled,
.ats-field textarea:disabled {
	background: var(--surface-sunken);
	color: var(--text-muted);
	border-color: var(--border-default);
	cursor: not-allowed;
}

.ats-field__hint {
	font-size: .8125rem;
	color: var(--text-muted);
}

/*
 * .ats-field__error-message — реальный класс, который создают
 * assets/js/forms.js и calculator.js при выводе ошибки поля (было
 * .ats-field__error-text, JS такой класс никогда не проставлял — сообщения
 * об ошибках оставались без стилей). Найдено ревизией через агентов Fable,
 * 2026-08-06, см. docs/11-audit-fable-2026-08-06.md, П1.14.
 */
.ats-field__error-message {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	margin-top: var(--space-1);
	font-size: .8125rem;
	color: var(--error-text);
}

/* --- Состояние ошибки/успеха --- */
.ats-field--error input,
.ats-field--error select,
.ats-field--error textarea {
	border-color: var(--error);
	background: var(--error-bg);
}

/*
 * Коробка с сообщением «заявку отправить не удалось».
 *
 * До этого правила её не оформляло ничего: JS вешал на неё классы
 * .ats-field .ats-field--error, но те красят только input/select/textarea, а
 * внутри лежит один абзац. Получался обычный текст без рамки и подложки —
 * единственный канал, которым сайт сообщает «твоя заявка не ушла», выглядел
 * как подпись под кнопкой.
 *
 * Цвет текста задаётся селектором в две сущности намеренно: правило
 * .ats-cta-banner .ats-form-full p (blocks.css) красит абзацы форм в приглушённый
 * серый, и односоставный селектор оно перебило бы.
 */
[data-form-message] {
	grid-column: 1 / -1;
	padding: var(--space-3) var(--space-4);
	border: 1px solid var(--error);
	border-radius: var(--r-md);
	background: var(--error-bg);
}

[data-form-message] p,
.ats-form-full [data-form-message] p,
.ats-form-quick [data-form-message] p {
	margin: 0;
	color: var(--error-text);
}

[data-form-message] p + p {
	margin-top: var(--space-2);
}

/*
 * .ats-field задаёт display:flex, а он сильнее браузерного [hidden]{display:none}.
 * Без этой строки атрибут hidden на коробке не работал вовсе: сообщение об
 * ошибке оставалось на экране и после успешной повторной отправки.
 */
[data-form-message][hidden] {
	display: none;
}

.ats-field--success input,
.ats-field--success select,
.ats-field--success textarea {
	border-color: var(--success-text);
	background: var(--success-bg);
}

/* =====================================================
   Капча SmartCaptcha
   ===================================================== */

/*
 * Виджет рисует Яндекс, наша задача — не дать ему разъехаться в узкой
 * колонке формы и отделить от кнопки отправки. Ширину не задаём: виджет
 * сам подстраивается, а фиксированная ломала бы его на телефонах.
 */
.ats-captcha {
	margin-block: var(--space-4);
	max-width: 100%;
}

/* =====================================================
   Honeypot-поле форм (.ats-hp-field, class-shortcodes.php)
   ===================================================== */

/*
 * display:none, а не увод за экран.
 *
 * Прежнее решение (position:absolute; left:-9999px) держалось за то, что
 * off-screen поле остаётся «видимым» примитивным ботам, которые смотрят
 * вычисленный стиль. Цена оказалась выше выгоды: менеджеры паролей и
 * автозаполнение браузера такое поле видят точно так же и подставляют в него
 * значение сами. Живой человек ничего не делал, а ловушка срабатывала.
 *
 * display:none автозаполнение гарантированно пропускает. Ботов продолжают
 * ловить два других признака — имя поля и таймер отправки, — а с правкой в
 * LeadController подозрительная заявка больше не исчезает молча: она
 * сохраняется со статусом «Спам» и попадает менеджеру на глаза.
 *
 * История: увод за экран пришёл из ревизии Fable 2026-08-06
 * (docs/11-audit-fable-2026-08-06.md, П0.3), возврат к display:none — из
 * ревизии 2026-08-30 (docs/19-audit-10-agentov-2026-08-30.md, Б2).
 */
.ats-hp-field {
	display: none !important;
}

/* =====================================================
   Чекбоксы и радио (согласие, шаги калькулятора)
   ===================================================== */

.ats-checkbox,
.ats-radio {
	display: inline-flex;
	align-items: flex-start;
	gap: var(--space-2);
	font-size: .9375rem;
	line-height: 1.4;
	color: var(--text-secondary);
	cursor: pointer;
}

.ats-checkbox input,
.ats-radio input {
	appearance: none;
	-webkit-appearance: none;
	flex-shrink: 0;
	width: 20px;
	height: 20px;
	margin-top: 1px;
	/* --border-input, а не --border-strong: чекбокс согласия обязателен для
	   отправки заявки, а его рамка при 1.61:1 к белому была почти не видна —
	   человек не понимал, что галочку надо поставить. */
	border: 1.75px solid var(--border-input);
	background: var(--surface-base);
	position: relative;
	cursor: pointer;
	transition: background-color var(--t-fast) var(--ease-standard), border-color var(--t-fast) var(--ease-standard);
}

.ats-checkbox input { border-radius: var(--r-sm); }
.ats-radio input { border-radius: var(--r-full); }

.ats-checkbox input:checked,
.ats-radio input:checked {
	background: var(--action-secondary);
	border-color: var(--action-secondary);
}

.ats-checkbox input:checked::after {
	content: "";
	position: absolute;
	left: 6px;
	top: 2px;
	width: 5px;
	height: 10px;
	border: solid var(--white);
	border-width: 0 2px 2px 0;
	transform: rotate(45deg);
}

.ats-radio input:checked::after {
	content: "";
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	margin: auto;
	width: 8px;
	height: 8px;
	border-radius: 50%;
	background: var(--white);
}

.ats-checkbox input:focus-visible,
.ats-radio input:focus-visible {
	outline: none;
	box-shadow: var(--focus-ring);
}

.ats-checkbox input:disabled,
.ats-radio input:disabled {
	opacity: .5;
	cursor: not-allowed;
}

.ats-field--error .ats-checkbox input {
	border-color: var(--error);
}

/*
 * .ats-checkbox--consent — модификатор для чекбокса согласия на обработку ПД
 * в формах (includes/shortcodes/class-shortcodes.php::fallback_lead_form()).
 * Раньше разметка оборачивала чекбокс в <label class="ats-field ats-field--consent">
 * — .ats-field это flex-column, чекбокс оказывался НАД текстом, а не слева от
 * него, и сам input был нативным крошечным, т.к. .ats-checkbox/.ats-radio
 * (готовый дизайн-системный компонент выше) нигде не использовались. Errors:
 * JS (forms.js/calculator.js) вешает класс "ats-field--error" прямо на wrap
 * независимо от того, .ats-field это или .ats-checkbox — правило ниже ловит
 * этот случай для чекбокса/радио. Найдено ревизией через агентов Fable,
 * 2026-08-06, см. docs/11-audit-fable-2026-08-06.md, П1.15.
 */
.ats-checkbox--consent {
	margin-bottom: var(--space-4);
}

.ats-checkbox.ats-field--error input,
.ats-radio.ats-field--error input {
	border-color: var(--error);
}

/* =====================================================
   Карточки — общая база
   Специфичная вёрстка каждого типа карточки (сетки, изображения,
   бейджи) — в blocks.css. Здесь только общий "физический" вид.
   ===================================================== */

.ats-card-direction,
.ats-card-service,
.ats-card-vehicle,
.ats-card-review,
.ats-card-case,
.ats-card-post {
	display: flex;
	flex-direction: column;
	height: 100%;
	background: var(--surface-base);
	border: 1px solid var(--border-default);
	border-radius: var(--r-lg);
	overflow: hidden;
	box-shadow: var(--shadow-sm);
	transition: transform var(--t-base) var(--ease-standard), box-shadow var(--t-base) var(--ease-standard), border-color var(--t-base) var(--ease-standard);
}

.ats-card-direction:hover,
.ats-card-service:hover,
.ats-card-vehicle:hover,
.ats-card-review:hover,
.ats-card-case:hover,
.ats-card-post:hover {
	transform: translateY(-4px);
	box-shadow: var(--shadow-md);
	border-color: var(--border-strong);
}

/* Изображения карточек — фиксированные пропорции против layout shift (CLS) */
.ats-card-direction img,
.ats-card-service img,
.ats-card-vehicle img,
.ats-card-review img,
.ats-card-case img,
.ats-card-post img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

/* =====================================================
   Бейджи .ats-badge
   ===================================================== */

.ats-badge {
	display: inline-flex;
	align-items: center;
	gap: var(--space-1);
	padding: 2px var(--space-3);
	border-radius: var(--r-full);
	background: var(--surface-sunken);
	color: var(--text-secondary);
	font-size: .75rem;
	font-weight: 600;
	line-height: 1.5;
	white-space: nowrap;
}

.ats-badge--brand { background: var(--surface-brand-soft); color: var(--brand-700); }
.ats-badge--accent { background: var(--surface-accent-soft); color: var(--accent-text); }
/* Текст бейджей — затемнённые *-text: яркие статусные цвета на своих же
   светлых подложках давали 2.37-4.23:1 при норме 4.5:1 для мелкого кегля. */
.ats-badge--success { background: var(--success-bg); color: var(--success-text); }
.ats-badge--warning { background: var(--warning-bg); color: var(--warning-text); }
.ats-badge--error { background: var(--error-bg); color: var(--error-text); }

/* =====================================================
   Аккордеон (обобщённый паттерн, переиспользуется в .ats-faq__item)
   ===================================================== */

/**
 * Решение: раскрытие панели анимируется только opacity/transform
 * (CWV-требование), а фактическое схлопывание (display:none) переключается
 * атрибутом [hidden] на стороне JS — это не задача данного файла,
 * здесь только визуальный переход между состояниями.
 */
.ats-accordion__item {
	border-bottom: 1px solid var(--border-default);
}

.ats-accordion__trigger {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	padding: var(--space-4) 0;
	background: none;
	border: none;
	text-align: left;
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 1rem;
	color: var(--text-primary);
	cursor: pointer;
}

.ats-accordion__trigger:focus-visible {
	outline: none;
	box-shadow: var(--focus-ring);
	border-radius: var(--r-sm);
}

.ats-accordion__icon {
	flex-shrink: 0;
	transition: transform var(--t-base) var(--ease-standard);
}

.ats-accordion__trigger[aria-expanded="true"] .ats-accordion__icon {
	/* Плюс -> крест: поворот 45°, не 180° (было для chevron) — по спеке. */
	transform: rotate(45deg);
}

.ats-accordion__panel {
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity var(--t-base) var(--ease-standard), transform var(--t-base) var(--ease-standard);
}

/*
 * Классовый селектор по родителю ".ats-accordion__item", а не sibling-combinator
 * от триггера — та же причина, что и у .ats-faq__item в blocks.css: если
 * триггер окажется вложен в отдельный заголовок (как в конкретной реализации
 * FAQ), он перестаёт быть прямым соседом панели и "~" не сработает. Этот
 * компонент пока нигде не инстанцирован напрямую (см. .ats-faq__item в
 * blocks.css — конкретная реализация), но исправлено для консистентности на
 * случай, если он будет использован как есть.
 */
.ats-accordion__item.is-open .ats-accordion__panel {
	opacity: 1;
	transform: translateY(0);
}

.ats-accordion__panel[hidden] {
	display: none;
}

/* =====================================================
   Хлебные крошки .ats-breadcrumbs
   (позиционирование внутри конкретных шаблонов — в pages.css/blocks.css)
   ===================================================== */

.ats-breadcrumbs {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-1);
	font-size: .8125rem;
	color: var(--text-muted);
	list-style: none;
}

.ats-breadcrumbs li {
	display: flex;
	align-items: center;
	gap: var(--space-1);
}

.ats-breadcrumbs li:not(:last-child)::after {
	content: "/";
	opacity: .5;
	margin-inline-start: var(--space-1);
}

.ats-breadcrumbs a {
	color: var(--text-muted);
	text-decoration: none;
}

.ats-breadcrumbs a:hover {
	color: var(--text-link);
	text-decoration: underline;
}

.ats-breadcrumbs [aria-current="page"] {
	color: var(--text-primary);
	font-weight: 600;
}
