:root {
    --ksy-loader-spinner-size: 1.2em;
    --ksy-loader-spinner-border: 2px;
    --ksy-loader-spinner-duration: 0.8s;
    --ksy-loader-overlay-bg: rgba(255, 255, 255, 0.7);
    --ksy-loader-content-opacity: 0.3;
    --ksy-loader-transition: 0.3s ease-out;
    --ksy-loader-error-bg: #dc3545;
    --ksy-loader-error-color: white;
    --ksy-loader-error-border: #dc3545;
    --ksy-loader-shake-duration: 0.4s;
    --ksy-loader-shake-offset: 6px;
    --ksy-loader-spinner-bg: rgba(255, 255, 255, 0.3);
    --ksy-loader-spinner-color: white;
}

/* Базовое состояние */
.ksy-loading-process {
    position: relative !important;
    pointer-events: none !important;
    /* Полная блокировка любых изменений размеров */
    width: var(--loader-fixed-width, auto) !important;
    height: var(--loader-fixed-height, auto) !important;
    min-width: var(--loader-fixed-width, auto) !important;
    min-height: var(--loader-fixed-height, auto) !important;
    max-width: var(--loader-fixed-width, none) !important;
    max-height: var(--loader-fixed-height, none) !important;
    box-sizing: border-box !important;
    flex-shrink: 0 !important;
    flex-grow: 0 !important;
}

/* Плавность для всех спец-элементов лоадера */
.ksy-loading-process::after,
.ksy-loading-process::before {
    transition: none !important;
    opacity: 1;
}

/* Класс для плавного исчезновения */
.ksy-loading-out::after,
.ksy-loading-out::before {
    opacity: 0 !important;
    transition: opacity 0.3s ease-out !important;
}

/* СПИННЕР */
.ksy-loading-process::after {
    content: "" !important;
    position: absolute;
    top: 50% !important; left: 50% !important;
    width: var(--ksy-loader-spinner-size);
    height: var(--ksy-loader-spinner-size);
    margin-top: calc(var(--ksy-loader-spinner-size) / -2);
    margin-left: calc(var(--ksy-loader-spinner-size) / -2);
    border: var(--ksy-loader-spinner-border) solid var(--ksy-loader-spinner-bg, rgba(255, 255, 255, 0.3));
    border-radius: 50%;
    animation: ksy-spin var(--ksy-loader-spinner-duration) linear infinite;
    z-index: 10000;
    display: block !important;
    border-top-color: var(--ksy-loader-spinner-color, white);
}

/* Для блоков и форм - темный спиннер */
div.ksy-loading-process::after,
form.ksy-loading-process::after,
section.ksy-loading-process::after {
    border-color: rgba(0, 0, 0, 0.2);
    border-top-color: #333;
}

/* Спиннер для блоков и форм в темной теме */
[data-theme-dark="true"] div.ksy-loading-process::after,
[data-theme-dark="true"] form.ksy-loading-process::after,
[data-theme-dark="true"] section.ksy-loading-process::after {
    border-color: rgba(255, 255, 255, 0.3);
    border-top-color: white;
}

/* ВУАЛЬ (ФОН) для блоков и форм */
div.ksy-loading-process::before,
form.ksy-loading-process::before,
section.ksy-loading-process::before {
    content: "" !important;
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    background: var(--ksy-loader-overlay-bg) !important;
    z-index: 9999;
    border-radius: inherit;
    display: block !important;
}

/* КОНТЕНТ КНОПОК: Скрываем без смещения */
button.ksy-loading-process,
.ksy-btn.ksy-loading-process {
    color: transparent !important;
    transition: color var(--ksy-loader-transition) ease-out;
}

button.ksy-loading-process > *,
.ksy-btn.ksy-loading-process > * {
    opacity: 0 !important;
    visibility: hidden !important;
    transition: opacity var(--ksy-loader-transition) ease-out;
}

/* Сохраняем размеры кнопки */
button.ksy-loading-process {
    text-indent: 0 !important;
    font-size: inherit !important;
    line-height: inherit !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    box-sizing: border-box !important;
    transition: all 0s !important;
}

/* Плавное восстановление */
button.ksy-loading-out {
    transition: opacity var(--ksy-loader-transition) ease-out !important;
}

/* Спиннер поверх контента */
button.ksy-loading-process::after {
    position: absolute !important;
    z-index: 1 !important;
    transition: opacity var(--ksy-loader-transition) ease-out;
}

/* КОНТЕНТ БЛОКОВ: Делаем прозрачным */
div.ksy-loading-process > *:not(::before):not(::after),
form.ksy-loading-process > *:not(::before):not(::after) {
    opacity: var(--ksy-loader-content-opacity) !important;
    transition: opacity var(--ksy-loader-transition);
}

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


/* Класс ошибки для кнопки */
button.ksy-btn-error-state,
button.ksy-btn-error-state:focus,
button.ksy-btn-error-state:active,
button.ksy-btn-error-state:hover {
    background-color: var(--ksy-loader-error-bg) !important;
    color: var(--ksy-loader-error-color) !important;
    border-color: var(--ksy-loader-error-border) !important;
    outline: 0 !important;
    box-shadow: none !important; /* Убирает синюю тень (glow) */
}

/* Анимация тряски */
@keyframes ksy-shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(calc(var(--ksy-loader-shake-offset) * -1)); }
    75% { transform: translateX(var(--ksy-loader-shake-offset)); }
}

.ksy-shake-it {
    animation: ksy-shake var(--ksy-loader-shake-duration) ease-in-out;
}

/* ── Полоса занятости (KsyProgress) ───────────────────────────
   Общий индикатор фоновой работы: KsyApi зажигает её на КАЖДЫЙ запрос, поэтому она
   должна быть видна поверх всего, что админка успела открыть, — шапки (1001),
   drawer (1200), модалки (99999), тостов (10000) и диалогов KsyAlert (1000000).
   В отличие от оверлея она ничего не перекрывает и ни на что не ловит клики. */

:root {
    --ksy-progress-z-index: 1000001;
    --ksy-progress-height: 3px;
    --ksy-progress-color: var(--ksy-blue, #3498db);
    --ksy-progress-duration: 1.1s;
}

.ksy-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--ksy-progress-height);
    z-index: var(--ksy-progress-z-index);
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
    transition: opacity .15s ease-out;
}

.ksy-progress.is-on { opacity: 1; }

.ksy-progress::before {
    content: '';
    position: absolute;
    top: 0;
    height: 100%;
    width: 34%;
    border-radius: 0 var(--ksy-progress-height) var(--ksy-progress-height) 0;
    background: var(--ksy-progress-color);
    box-shadow: 0 0 8px color-mix(in srgb, var(--ksy-progress-color) 60%, transparent);
    animation: ksy-progress-slide var(--ksy-progress-duration) ease-in-out infinite;
}

@keyframes ksy-progress-slide {
    from { left: -35%; }
    to   { left: 100%; }
}

/* Бегущая полоса — это движение ради движения; кому оно противопоказано, показываем
   тот же факт «идёт работа» пульсацией на всю ширину */
@media (prefers-reduced-motion: reduce) {
    .ksy-progress::before {
        width: 100%;
        left: 0;
        animation: ksy-progress-pulse 1.4s ease-in-out infinite;
    }
    @keyframes ksy-progress-pulse {
        0%, 100% { opacity: .35; }
        50%      { opacity: 1; }
    }
}
