/*
 * Единый слой отклика на клик (см. js/lt-helpers.js: ltBusy/ltDone/ltFail/ltToast).
 * До этого AJAX-действия темы не давали мгновенной обратной связи: «В корзину»
 * молчала ~3,5 с, а лоадер каталога .con-pre-loader лежит в сайдбаре фильтров —
 * при клике по «Показать ещё» внизу страницы его не видно вовсе.
 *
 * Классы намеренно в пространстве lt-*, как и остальные добавления темы: на проде
 * поверх подключается /assets/js/scripts.js, и пересекаться с ним по селекторам
 * нельзя.
 *
 * Анимации — только transform/opacity; при prefers-reduced-motion вращение и
 * сдвиги отключаются, состояние остаётся читаемым по тексту и прозрачности.
 */

/* ------------------------------------------------------------------ *
 * Состояние загрузки
 * ------------------------------------------------------------------ */

.lt-is-loading {
    position: relative;
    /* Клик не должен доходить до обработчика повторно, пока запрос в полёте.
       Сам guard живёт в JS (ltIsBusy) — это лишь визуальная страховка. */
    pointer-events: none;
    cursor: default;
    /* !important — в каталоге кнопка «В корзину» скрыта до наведения на
       карточку; без него состояние загрузки исчезало бы, уведи пользователь
       курсор с карточки, пока идёт запрос. Парное правило .lt-is-icon ниже
       тоже с !important: иначе это, как более важное, перебило бы его. */
    opacity: 0.75 !important;
    transition: opacity 0.15s linear;
}

/* Спиннер: рисуется псевдоэлементом, чтобы не трогать разметку кнопок,
   которых в теме десятки и все с разным внутренним содержимым. */
.lt-is-loading::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 14px;
    margin: -7px 0 0 -7px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    opacity: 0.9;
    animation: lt-spin 0.6s linear infinite;
}

/* Текстовые кнопки темы: подпись подменяется на «ДОБАВЛЯЕМ…»/«ЗАГРУЖАЕМ…».
   Подпись со спиннером выстраиваются в одну центрированную группу — если
   вместо этого прибить спиннер к правому краю и отвести под него padding,
   текст уезжает из центра кнопки, а на узких экранах (там у .main-btn боковые
   отступы падают до 10px) ещё и наезжает на спиннер. */
.lt-is-loading.lt-has-label {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.lt-is-loading.lt-has-label::after {
    position: static;
    margin: 0;
    flex: 0 0 auto;
}

/* Иконочные кнопки (сердечко «в избранное», +/− и крестик в корзине):
   подписи нет, поэтому содержимое приглушается, а спиннер идёт по центру. */
.lt-is-loading.lt-is-icon {
    opacity: 1 !important;
}

.lt-is-loading.lt-is-icon > * {
    opacity: 0.25 !important;
    transition: opacity 0.15s linear;
}

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

/* ------------------------------------------------------------------ *
 * Короткое подтверждение успеха
 * ------------------------------------------------------------------ */

.lt-is-done {
    /* Фирменный бордовый как заливка — состояние читается и на аутлайн-кнопке
       (.main-btn), и на залитой (.main-adds-btn). */
    background: #a50021 !important;
    border-color: #a50021 !important;
    color: #fff !important;
    pointer-events: none;
    cursor: default;
}

/* Подтверждение («ДОБАВЛЕНО ✓») центрируем так же, как состояние загрузки:
   у части кнопок темы содержимое инлайновое и без явного text-align. */
.lt-is-done.lt-has-label {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

.lt-is-done svg path {
    fill: #fff !important;
    stroke: #fff !important;
}

/* Сердечко в каталоге: успех показываем закраской, а не подменой текста —
   ровно тем же цветом, каким ltMarkFavorites() красит избранное после
   перезагрузки страницы (см. page-catalog.php). */
.lt-is-done.lt-is-icon {
    background: none !important;
    border-color: transparent !important;
}

.lt-fav-pulse {
    animation: lt-pulse 0.4s ease-out;
}

@keyframes lt-pulse {
    0% {
        transform: scale(1);
    }
    45% {
        transform: scale(1.28);
    }
    100% {
        transform: scale(1);
    }
}

/* ------------------------------------------------------------------ *
 * Пересчёт выдачи каталога по фильтру
 *
 * .con-pre-loader накрывает только сайдбар фильтров, поэтому сама сетка
 * оставалась яркой и «живой» всё время запроса. Гасим её — признак того,
 * что показанные карточки уже неактуальны.
 * ------------------------------------------------------------------ */

.lt-grid-busy {
    opacity: 0.4;
    pointer-events: none;
    transition: opacity 0.15s linear;
}

/* Позиция корзины, по которой идёт запрос (удаление, массовые операции). */
.lt-row-busy {
    opacity: 0.45;
    pointer-events: none;
    transition: opacity 0.15s linear;
}

/* Суммы на время пересчёта: число количества меняется мгновенно, а цены
   приходят с сервера — без этого они секунду показывают старые значения,
   и клик по +/− читается как несработавший. */
.lt-recalc {
    opacity: 0.35;
    transition: opacity 0.15s linear;
}

@media (prefers-reduced-motion: reduce) {
    .lt-row-busy,
    .lt-recalc {
        transition: none;
    }
}

/* ------------------------------------------------------------------ *
 * Плавное появление догруженных карточек («Показать ещё»)
 * ------------------------------------------------------------------ */

.lt-appear {
    opacity: 0;
    transform: translateY(12px);
}

.lt-appear.lt-appear-in {
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.35s ease-out, transform 0.35s ease-out;
}

/* ------------------------------------------------------------------ *
 * Ненавязчивые сообщения (вместо alert и вместо Swal на фоновых сбоях)
 * ------------------------------------------------------------------ */

.lt-toast-wrap {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 100000;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    /* Контейнер не должен перехватывать клики по странице под ним. */
    pointer-events: none;
}

.lt-toast {
    max-width: 320px;
    padding: 12px 18px;
    border: 1px solid #a50021;
    border-left-width: 3px;
    background: #fff;
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.12);
    font-size: 13px;
    line-height: 1.4;
    color: #1a1a1a;
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 0.25s ease-out, transform 0.25s ease-out;
    pointer-events: auto;
}

.lt-toast.lt-toast-in {
    opacity: 1;
    transform: translateY(0);
}

.lt-toast-success {
    border-color: #2e7d32;
}

.lt-toast-title {
    display: block;
    margin-bottom: 2px;
    font-weight: 600;
    text-transform: uppercase;
    font-size: 12px;
    letter-spacing: 0.02em;
    color: #a50021;
}

.lt-toast-success .lt-toast-title {
    color: #2e7d32;
}

@media (max-width: 767px) {
    .lt-toast-wrap {
        right: 12px;
        left: 12px;
        bottom: 12px;
        align-items: stretch;
    }

    .lt-toast {
        max-width: none;
    }
}

/* ------------------------------------------------------------------ *
 * prefers-reduced-motion: движение выключаем, смысл состояний оставляем
 * ------------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
    .lt-is-loading::after {
        animation: none;
        /* без вращения кольцо-огрызок читается как артефакт — показываем
           замкнутый контур, роль индикатора берёт на себя подпись кнопки */
        border-right-color: currentColor;
        opacity: 0.5;
    }

    .lt-fav-pulse {
        animation: none;
    }

    .lt-appear,
    .lt-appear.lt-appear-in {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .lt-grid-busy {
        transition: none;
    }

    .lt-toast {
        transition: none;
        opacity: 1;
        transform: none;
    }
}
