/*
 * AntiSetki — базовые компоненты.
 *
 * Кнопки, поля форм, стеклянные карточки и пилюли-теги. Всё, что повторяется
 * на нескольких страницах, живёт здесь; уникальная вёрстка блока остаётся
 * в его шаблоне.
 *
 * Цвета и размеры берутся из переменных main.css — HEX и пиксели числом
 * в этом файле не появляются. Переходы только по opacity, transform,
 * background-color и border-color: они не вызывают перерасчёт раскладки.
 *
 * Разделы: 1. Кнопки · 2. Формы · 3. Флажки и переключатели · 4. Карточки ·
 * 5. Теги и пилюли.
 */

/* ==========================================================================
   1. Кнопки
   Высота 48px, радиус 12px. Основная залита акцентом, вторичная контурная.
   Работает и на <button>, и на <a>: разметка выбирается по смыслу действия.
   ========================================================================== */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    min-height: var(--control-height);
    padding: var(--space-1) var(--space-3);
    border: 1px solid transparent;
    border-radius: var(--radius-button);
    background-color: transparent;
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-base);
    line-height: var(--line-height-h4);
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition:
        background-color var(--transition),
        border-color var(--transition),
        transform var(--transition),
        opacity var(--transition);
}

/* Иконка внутри кнопки не тянет строку вверх и наследует цвет текста. */
.btn > svg {
    flex: 0 0 auto;
    width: var(--space-3);
    height: var(--space-3);
}

/* Основная: единственное акцентное пятно в секции. */
.btn--primary {
    background-color: var(--color-accent);
    color: var(--color-on-accent);
}

.btn--primary:hover {
    background-color: var(--color-accent-hover);
    color: var(--color-on-accent);
}

.btn--primary:active {
    background-color: var(--color-accent-active);
    transform: translateY(1px);
}

/* Вторичная: контур по границе, фон прозрачный. */
.btn--outline {
    border-color: var(--color-border);
    color: var(--color-text);
}

.btn--outline:hover {
    background-color: var(--color-surface-raised);
    border-color: var(--color-glass-border-strong);
    color: var(--color-text);
}

.btn--outline:active {
    background-color: var(--color-surface);
    transform: translateY(1px);
}

/* Третья по важности: без рамки, для «Подробнее» и действий в карточках. */
.btn--ghost {
    padding-left: var(--space-2);
    padding-right: var(--space-2);
    color: var(--color-accent);
}

.btn--ghost:hover {
    background-color: var(--color-accent-soft);
    color: var(--color-accent-hover);
}

.btn--ghost:active {
    transform: translateY(1px);
}

/* Пилюля — форма для шапки и фильтров, заливка задаётся отдельным классом. */
.btn--pill {
    border-radius: var(--radius-pill);
}

/* Уменьшенная кнопка: фильтры, действия в строке таблицы. */
.btn--sm {
    min-height: var(--space-5);
    padding-left: var(--space-2);
    padding-right: var(--space-2);
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
}

/* Во всю ширину — в узких формах и на мобильном. */
.btn--block {
    display: flex;
    width: 100%;
}

.btn:disabled,
.btn.is-disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* Ряд кнопок героя и карточек: на узком экране разворачивается в столбик. */
.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

@media (max-width: 480px) {
    .btn-row {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ==========================================================================
   2. Формы
   Поле высотой 48px на поверхности #171B22, подпись сверху 13px,
   при фокусе граница акцентная, при ошибке — красная с подсказкой снизу.
   ========================================================================== */

.form {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    /* После ошибки посетитель возвращается на форму по якорю `#form-<id>`.
       Отступ поднимает её из-под липкой шапки: иначе первое поле с ошибкой
       оказывается ровно под ней. */
    scroll-margin-top: calc(var(--header-height) + var(--space-3));
}

/* Поля в две колонки: имя и телефон рядом, ниже 768px — друг под другом.
   Число колонок задаётся классом, а не inline-стилем: инлайн перебил бы
   мобильное правило, и на 360px поля остались бы полосками в три ряда. */
.form__grid {
    display: grid;
    gap: var(--space-3);
    grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr));
}

.form__grid--1 {
    --cols: 1;
}

.form__grid--3 {
    --cols: 3;
}

.form__grid--4 {
    --cols: 4;
}

/* Пять ячеек — форма в строку со всеми дополнительными полями:
   имя, телефон, тип объекта, этаж и кнопка. */
.form__grid--5 {
    --cols: 5;
}

/* Четыре и пять ячеек на планшете дают поля шириной в два слова. */
@media (max-width: 1024px) {
    .form__grid--4,
    .form__grid--5 {
        --cols: 2;
    }
}

@media (max-width: 767.98px) {
    .form__grid,
    .form__grid--1,
    .form__grid--3,
    .form__grid--4,
    .form__grid--5 {
        --cols: 1;
    }
}

/* Форма в одну строку — финальная плашка на главной. Число колонок задаёт
   шаблон переменной --cols, ниже 768px .form__grid сам разворачивает поля
   в столбик, и кнопка встаёт под ними во всю ширину. */
.form--row {
    gap: var(--space-2);
}

/* Кнопка отправки — такая же ячейка грида, как поле: пустая подпись сверху
   ставит её вровень с полями, а не выше на высоту строки. */
.field--submit {
    justify-content: flex-end;
}

@media (max-width: 767.98px) {
    .field--submit .field__label {
        display: none;
    }

    /* Строка распалась в столбик, и кнопка оказывалась выше согласия: на
       телефоне посетитель жал «Заказать замер», не увидев флажка, который
       браузер тут же требует поставить. Грид растворяется (`display: contents`),
       его ячейки становятся ячейками самой формы, и кнопка уходит в конец
       порядком. Разметка при этом не меняется — на широком экране кнопка
       по-прежнему стоит в одной строке с полями. */
    .form--row .form__grid {
        display: contents;
    }

    .form--row .field--submit {
        order: 1;
    }
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.field__label {
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    font-weight: 500;
    color: var(--color-muted);
}

/* Звёздочка обязательного поля — единственный акцент внутри формы, кроме кнопки. */
.field__required {
    color: var(--color-accent);
}

.field__control {
    width: 100%;
    min-height: var(--control-height);
    padding: var(--space-1) var(--space-2);
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-button);
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-base);
    line-height: var(--line-height-base);
    appearance: none;
    transition:
        background-color var(--transition),
        border-color var(--transition);
}

.field__control::placeholder {
    color: var(--color-muted);
    opacity: 1;
}

.field__control:hover {
    border-color: var(--color-glass-border-strong);
}

.field__control:focus {
    border-color: var(--color-accent);
    background-color: var(--color-surface-raised);
}

/* Рамка фокуса ложится ровно на границу поля, а не отступает от неё. */
.field__control:focus-visible {
    outline-offset: 0;
}

.field__control:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

textarea.field__control {
    min-height: calc(var(--control-height) * 2.5);
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
    resize: vertical;
}

/* Телефоны и суммы — табличными цифрами, чтобы не «прыгали» при вводе. */
.field__control--num {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}

/* Список выбора: своя стрелка вместо системной, она у каждого браузера разная. */
.select {
    position: relative;
    display: block;
}

.select .field__control {
    padding-right: var(--space-5);
    cursor: pointer;
}

.select::after {
    content: '';
    position: absolute;
    top: 50%;
    right: var(--space-2);
    width: var(--space-1);
    height: var(--space-1);
    border-right: 2px solid var(--color-muted);
    border-bottom: 2px solid var(--color-muted);
    transform: translateY(-70%) rotate(45deg);
    pointer-events: none;
}

/* На Windows раскрытый список рисуется системными цветами — задаём свои. */
.field__control option {
    background-color: var(--color-surface);
    color: var(--color-text);
}

.field__hint {
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    color: var(--color-muted);
}

.field__error {
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    color: var(--color-danger);
}

.field--invalid .field__control {
    border-color: var(--color-danger);
    background-color: var(--color-danger-soft);
}

.field--invalid .field__control:focus {
    border-color: var(--color-danger);
}

/* Ловушка для ботов: поле есть в разметке, но недоступно ни глазу, ни фокусу. */
.field--trap {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ==========================================================================
   3. Флажки и переключатели
   Настоящий input с appearance: none — клик по подписи и фокус с клавиатуры
   работают сами, без JS.
   ========================================================================== */

.check {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    cursor: pointer;
}

.check__input {
    flex: 0 0 auto;
    width: var(--space-3);
    height: var(--space-3);
    margin: 0;
    display: grid;
    place-content: center;
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-small);
    appearance: none;
    cursor: pointer;
    transition:
        background-color var(--transition),
        border-color var(--transition);
}

.check__input[type='radio'] {
    border-radius: var(--radius-pill);
}

.check__input::before {
    content: '';
    width: 10px;
    height: 6px;
    border-left: 2px solid var(--color-on-accent);
    border-bottom: 2px solid var(--color-on-accent);
    transform: rotate(-45deg) scale(0);
    transition: transform var(--transition);
}

.check__input[type='radio']::before {
    width: var(--space-1);
    height: var(--space-1);
    border: 0;
    border-radius: var(--radius-pill);
    background-color: var(--color-on-accent);
    transform: scale(0);
}

.check__input:hover {
    border-color: var(--color-glass-border-strong);
}

.check__input:checked {
    background-color: var(--color-accent);
    border-color: var(--color-accent);
}

.check__input:checked::before {
    transform: rotate(-45deg) scale(1);
}

.check__input[type='radio']:checked::before {
    transform: scale(1);
}

.check__input:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.check__text {
    min-width: 0;
}

/* Согласие на обработку данных набирается подписью — текст длинный и служебный. */
.check--small .check__text {
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    color: var(--color-muted);
}

.check--invalid .check__input {
    border-color: var(--color-danger);
}

/* Причина отказа стоит под текстом согласия: внутри подписи она инлайновая,
   поэтому строку разрываем сами. */
.check__error {
    display: block;
    margin-top: var(--space-1);
}

/* ==========================================================================
   4. Карточки
   Полупрозрачная поверхность с размытием, светлая линия по верхнему краю.
   Наведение осветляет фон, нажатие притапливает на 1px.
   ========================================================================== */

.card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3);
    background-color: var(--color-glass);
    border: 1px solid var(--color-border);
    border-top-color: var(--color-glass-border);
    border-radius: var(--radius-card);
    backdrop-filter: blur(var(--blur-glass));
    -webkit-backdrop-filter: blur(var(--blur-glass));
    transition:
        background-color var(--transition),
        border-color var(--transition),
        transform var(--transition);
}

/* Без поддержки размытия карточка остаётся читаемой — фон становится плотным. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .card {
        background-color: var(--color-surface);
    }
}

/* Плотная карточка — там, где под ней нет фотографии и размывать нечего. */
.card--flat {
    background-color: var(--color-surface);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* Крупная плашка: форма заявки, CTA-полоса, таблица характеристик. */
.card--section {
    padding: var(--space-5);
    border-radius: var(--radius-section);
}

@media (max-width: 767.98px) {
    .card--section {
        padding: var(--space-3);
    }
}

/* Кликабельная карточка целиком: ссылка обёрнута вокруг содержимого. */
.card--link {
    text-decoration: none;
    color: inherit;
}

.card--link:hover {
    background-color: var(--color-glass-raised);
    border-color: var(--color-glass-border-strong);
    color: inherit;
}

.card--link:active {
    transform: translateY(1px);
}

/* Карточка без обводки: рамка прозрачная, но своё место в раскладке
   сохраняет — ширина остаётся прежней, ряд не сдвигается на пиксель.
   Правило идёт после `.card--link`, чтобы гасить и подсветку рамки
   при наведении. */
.card--plain,
.card--plain:hover {
    border-color: transparent;
}

/* Изображение карточки: 4:3 у товаров, пропорция меняется модификатором. */
.card__media {
    margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) 0;
    overflow: hidden;
    border-radius: calc(var(--radius-card) - 1px) calc(var(--radius-card) - 1px) 0 0;
    background-color: var(--color-surface-raised);
    aspect-ratio: var(--ratio, 4 / 3);
}

.card__media--wide {
    --ratio: 16 / 9;
}

.card__media--square {
    --ratio: 1 / 1;
}

.card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Снимка ещё нет (карточка заполнена, фотография не загружена): вместо пустого
   прямоугольника — неяркая ячеистая подложка, намёк на полотно сетки. */
.card__media--empty {
    /* Подложка ниже фотографии: пустая ячейка не должна занимать экран. */
    --ratio: 16 / 9;
    background-image:
        repeating-linear-gradient(0deg, var(--color-border) 0 1px, transparent 1px 16px),
        repeating-linear-gradient(90deg, var(--color-border) 0 1px, transparent 1px 16px);
}

/* Иконка в квадрате — карточки «что задерживает сетка» и шаги работы. */
.card__icon {
    display: grid;
    place-content: center;
    width: var(--space-6);
    height: var(--space-6);
    border-radius: var(--radius-button);
    background-color: var(--color-accent-soft);
    color: var(--color-accent);
}

.card__icon svg {
    width: var(--space-3);
    height: var(--space-3);
}

.card__title {
    font-size: var(--font-size-h3);
    line-height: var(--line-height-h3);
    font-weight: 600;
    letter-spacing: -0.01em;
}

.card__text {
    color: var(--color-muted);
}

/* Подвал карточки прижимается к низу — в ряду карточки выравниваются по кнопке. */
.card__foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-top: auto;
    padding-top: var(--space-2);
    border-top: 1px solid var(--color-border);
}

.card__price {
    font-size: var(--font-size-h3);
    line-height: var(--line-height-h3);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
    white-space: nowrap;
}

.card__price small {
    display: inline;
    font-size: var(--font-size-caption);
    font-weight: 400;
}

/* Карточка «пока ничего нет»: пустой каталог, выдача фильтра без совпадений,
   лента блога до наполнения. Ширина ограничена строкой — это объяснение
   для человека, а не полоса текста через весь экран. */
.empty-state {
    max-width: var(--measure);
    --stack-gap: var(--space-3);
}

.empty-state__title {
    font-size: var(--font-size-h3);
    line-height: var(--line-height-h3);
    font-weight: 600;
}

.empty-state__text {
    color: var(--color-muted);
}

/* ==========================================================================
   5. Теги и пилюли
   Метки категорий, характеристик и назначения. Кликабельный вариант —
   фильтр каталога: тот же вид плюс состояния наведения и выбора.
   ========================================================================== */

.tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.tag {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    min-height: var(--space-4);
    padding: 0 var(--space-2);
    background-color: var(--color-surface-raised);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-pill);
    color: var(--color-muted);
    font-size: var(--font-size-caption);
    line-height: var(--line-height-caption);
    text-decoration: none;
    white-space: nowrap;
}

.tag--accent {
    background-color: var(--color-accent-soft);
    border-color: transparent;
    color: var(--color-accent);
}

.tag--success {
    background-color: var(--color-success-soft);
    border-color: transparent;
    color: var(--color-success);
}

.tag--danger {
    background-color: var(--color-danger-soft);
    border-color: transparent;
    color: var(--color-danger);
}

/* Пилюля-действие: фильтр, сортировка, переключатель вкладки. */
.tag--link {
    cursor: pointer;
    transition:
        background-color var(--transition),
        border-color var(--transition),
        transform var(--transition);
}

.tag--link:hover {
    background-color: var(--color-glass-raised);
    border-color: var(--color-glass-border-strong);
    color: var(--color-text);
}

.tag--link:active {
    transform: translateY(1px);
}

.tag--link.is-active {
    background-color: var(--color-accent);
    border-color: var(--color-accent);
    color: var(--color-on-accent);
}
