/* ==========================================================
   AYW DESIGN SYSTEM
   COMPONENTS / LOADERS

   Responsabilidades:
   - spinners;
   - skeletons genéricos;
   - barras de progresso;
   - loader inline e central;
   - loader de página;
   - overlay local de carregamento;
   - estados de carregamento reutilizáveis.

   Este arquivo é a fonte única de carregamento do sistema.
   Cards, avatares, tabelas, stats e páginas não devem
   possuir animações próprias de loading.
   ========================================================== */


/* ==========================================================
   SPINNER BASE

   As variáveis internas permitem alterar tamanho, espessura
   e cores sem repetir a estrutura do componente.
   ========================================================== */

   .ayw-spinner {
    --ayw-spinner-size: 24px;
    --ayw-spinner-border-width: 3px;
    --ayw-spinner-track-color: var(--ayw-border);
    --ayw-spinner-color: var(--ayw-primary);
    --ayw-spinner-duration: 0.8s;

    display: inline-block;

    flex: 0 0 auto;

    width: var(--ayw-spinner-size);
    height: var(--ayw-spinner-size);

    border:
        var(--ayw-spinner-border-width)
        solid
        var(--ayw-spinner-track-color);

    border-top-color: var(--ayw-spinner-color);
    border-radius: 50%;

    animation:
        ayw-spin
        var(--ayw-spinner-duration)
        linear
        infinite;
}


/* ==========================================================
   TAMANHOS DO SPINNER
   ========================================================== */

.ayw-spinner-xs {
    --ayw-spinner-size: 14px;
    --ayw-spinner-border-width: 2px;
}

.ayw-spinner-sm {
    --ayw-spinner-size: 18px;
    --ayw-spinner-border-width: 2px;
}

.ayw-spinner-lg {
    --ayw-spinner-size: 40px;
    --ayw-spinner-border-width: 4px;
}


/* ==========================================================
   VARIAÇÕES DO SPINNER
   ========================================================== */

.ayw-spinner-primary {
    --ayw-spinner-color: var(--ayw-primary);
}

.ayw-spinner-success {
    --ayw-spinner-color: var(--ayw-success);
}

.ayw-spinner-danger {
    --ayw-spinner-color: var(--ayw-danger);
}

.ayw-spinner-warning {
    --ayw-spinner-color: var(--ayw-warning);
}

.ayw-spinner-info {
    --ayw-spinner-color: var(--ayw-info);
}

.ayw-spinner-light {
    --ayw-spinner-track-color: rgba(255, 255, 255, 0.35);
    --ayw-spinner-color: #ffffff;
}


/* ==========================================================
   LOADER INLINE

   Usado dentro de textos, botões, filtros e ações menores.
   ========================================================== */

.ayw-loader-inline {
    display: inline-flex;
    align-items: center;

    min-width: 0;

    gap: var(--ayw-space-2);

    color: var(--ayw-text-muted);

    font-size: var(--ayw-font-size-sm);
    font-weight: var(--ayw-font-weight-medium);
    line-height: var(--ayw-line-height-normal);
}

.ayw-loader-inline.is-center {
    justify-content: center;
}

.ayw-loader-inline.is-block {
    display: flex;

    width: 100%;
}


/* ==========================================================
   LOADER CENTRAL
   ========================================================== */

.ayw-loader-center {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    width: 100%;
    min-width: 0;
    min-height: 240px;

    gap: var(--ayw-space-4);

    padding: var(--ayw-space-8);

    color: var(--ayw-text-muted);

    text-align: center;
}

.ayw-loader-center-sm {
    min-height: 160px;

    padding: var(--ayw-space-6);
}

.ayw-loader-center-lg {
    min-height: 360px;

    padding: var(--ayw-space-10);
}

.ayw-loader-title {
    margin: 0;

    color: var(--ayw-text);

    font-size: var(--ayw-font-size-md);
    font-weight: var(--ayw-font-weight-semibold);
    line-height: var(--ayw-line-height-tight);
}

.ayw-loader-text {
    max-width: 480px;

    margin: 0;

    color: var(--ayw-text-muted);

    font-size: var(--ayw-font-size-sm);
    line-height: var(--ayw-line-height-relaxed);
}


/* ==========================================================
   LOADER DE PÁGINA
   ========================================================== */

.ayw-page-loader {
    position: fixed;
    inset: 0;
    z-index: var(--ayw-z-modal);

    display: flex;
    align-items: center;
    justify-content: center;

    padding: var(--ayw-space-6);

    background: var(--ayw-overlay);

    backdrop-filter: blur(6px);

    -webkit-backdrop-filter: blur(6px);
}

.ayw-page-loader[hidden] {
    display: none;
}

.ayw-page-loader-card {
    display: flex;
    flex-direction: column;
    align-items: center;

    width: min(100%, 320px);
    min-width: 0;

    gap: var(--ayw-space-4);

    padding: var(--ayw-space-8);

    border: 1px solid var(--ayw-border);
    border-radius: var(--ayw-radius-xl);

    background: var(--ayw-surface);

    box-shadow: var(--ayw-shadow-lg);

    text-align: center;
}


/* ==========================================================
   SKELETON BASE

   O skeleton deve receber dimensões por meio das classes
   auxiliares abaixo ou pelo contexto onde é utilizado.
   ========================================================== */

.ayw-skeleton {
    position: relative;

    display: block;

    overflow: hidden;

    border-radius: var(--ayw-radius-sm);

    background: var(--ayw-bg-muted);

    color: transparent;

    pointer-events: none;

    user-select: none;
}

.ayw-skeleton::after {
    position: absolute;
    inset: 0;

    background:
        linear-gradient(
            110deg,
            transparent 20%,
            color-mix(
                in srgb,
                var(--ayw-surface-hover) 75%,
                transparent
            ) 45%,
            transparent 70%
        );

    background-size: 200% 100%;

    content: "";

    animation:
        ayw-skeleton-shimmer
        1.4s
        linear
        infinite;
}


/* ==========================================================
   SKELETON DE TEXTO
   ========================================================== */

.ayw-skeleton-text {
    width: 100%;
    height: 14px;
}

.ayw-skeleton-text-sm {
    width: 45%;
    height: 12px;
}

.ayw-skeleton-text-md {
    width: 70%;
    height: 14px;
}

.ayw-skeleton-text-lg {
    width: 90%;
    height: 18px;
}

.ayw-skeleton-title {
    width: 60%;
    height: 24px;
}


/* ==========================================================
   SKELETON DE AVATAR
   ========================================================== */

.ayw-skeleton-avatar {
    width: 44px;
    height: 44px;

    border-radius: 50%;
}

.ayw-skeleton-avatar-sm {
    width: 36px;
    height: 36px;
}

.ayw-skeleton-avatar-lg {
    width: 64px;
    height: 64px;
}

.ayw-skeleton-avatar-xl {
    width: 96px;
    height: 96px;
}


/* ==========================================================
   SKELETON DE BOTÃO
   ========================================================== */

.ayw-skeleton-button {
    width: 120px;
    height: 44px;

    border-radius: var(--ayw-radius-md);
}

.ayw-skeleton-button-sm {
    width: 96px;
    height: 38px;
}

.ayw-skeleton-button-lg {
    width: 148px;
    height: 52px;
}


/* ==========================================================
   SKELETON DE BLOCO E IMAGEM
   ========================================================== */

.ayw-skeleton-block {
    width: 100%;
    min-height: 120px;

    border-radius: var(--ayw-radius-md);
}

.ayw-skeleton-image {
    width: 100%;
    aspect-ratio: 16 / 9;

    border-radius: var(--ayw-radius-lg);
}


/* ==========================================================
   COMPOSIÇÃO DE SKELETONS

   Evita que páginas e componentes criem layouts próprios
   para estados de carregamento.
   ========================================================== */

.ayw-skeleton-stack {
    display: flex;
    flex-direction: column;

    width: 100%;
    min-width: 0;

    gap: var(--ayw-space-3);
}

.ayw-skeleton-row {
    display: flex;
    align-items: center;

    width: 100%;
    min-width: 0;

    gap: var(--ayw-space-3);
}

.ayw-skeleton-row.is-start {
    align-items: flex-start;
}

.ayw-skeleton-content {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;

    min-width: 0;

    gap: var(--ayw-space-2);
}

.ayw-skeleton-card {
    display: flex;
    flex-direction: column;

    width: 100%;
    min-width: 0;

    gap: var(--ayw-space-4);

    padding: var(--ayw-space-5);

    border: 1px solid var(--ayw-border);
    border-radius: var(--ayw-radius-lg);

    background: var(--ayw-surface);

    box-shadow: var(--ayw-shadow-sm);
}

.ayw-skeleton-grid {
    display: grid;

    grid-template-columns:
        minmax(0, 1fr);

    width: 100%;
    min-width: 0;

    gap: var(--ayw-space-4);
}


/* ==========================================================
   PROGRESSO
   ========================================================== */

.ayw-progress {
    --ayw-progress-height: 8px;
    --ayw-progress-track: var(--ayw-bg-muted);
    --ayw-progress-color: var(--ayw-primary);

    width: 100%;
    height: var(--ayw-progress-height);

    overflow: hidden;

    border-radius: var(--ayw-radius-pill);

    background: var(--ayw-progress-track);
}

.ayw-progress-sm {
    --ayw-progress-height: 4px;
}

.ayw-progress-lg {
    --ayw-progress-height: 12px;
}

.ayw-progress-bar {
    width: var(--ayw-progress, 0%);
    max-width: 100%;
    height: 100%;

    border-radius: inherit;

    background: var(--ayw-progress-color);

    transition:
        width
        var(--ayw-transition-slow);
}

.ayw-progress-bar.is-success {
    --ayw-progress-color: var(--ayw-success);
}

.ayw-progress-bar.is-danger {
    --ayw-progress-color: var(--ayw-danger);
}

.ayw-progress-bar.is-warning {
    --ayw-progress-color: var(--ayw-warning);
}

.ayw-progress-bar.is-info {
    --ayw-progress-color: var(--ayw-info);
}


/* ==========================================================
   PROGRESSO COM RÓTULO
   ========================================================== */

.ayw-progress-group {
    display: flex;
    flex-direction: column;

    width: 100%;
    min-width: 0;

    gap: var(--ayw-space-2);
}

.ayw-progress-header {
    display: flex;
    align-items: center;
    justify-content: space-between;

    min-width: 0;

    gap: var(--ayw-space-3);
}

.ayw-progress-label {
    min-width: 0;

    color: var(--ayw-text-soft);

    font-size: var(--ayw-font-size-sm);
    font-weight: var(--ayw-font-weight-medium);
}

.ayw-progress-value {
    flex: 0 0 auto;

    color: var(--ayw-text-muted);

    font-size: var(--ayw-font-size-xs);
    font-variant-numeric: tabular-nums;
}


/* ==========================================================
   PROGRESSO INDETERMINADO
   ========================================================== */

.ayw-progress.is-indeterminate
.ayw-progress-bar {
    width: 35%;

    animation:
        ayw-progress-indeterminate
        1.2s
        ease-in-out
        infinite;
}


/* ==========================================================
   PONTOS ANIMADOS
   ========================================================== */

.ayw-loading-dots {
    display: inline-flex;
    align-items: center;

    gap: 0.3rem;

    color: currentColor;
}

.ayw-loading-dots span {
    width: 7px;
    height: 7px;

    border-radius: 50%;

    background: currentColor;

    animation:
        ayw-loading-dot
        1.1s
        ease-in-out
        infinite;
}

.ayw-loading-dots span:nth-child(2) {
    animation-delay: 0.15s;
}

.ayw-loading-dots span:nth-child(3) {
    animation-delay: 0.30s;
}


/* ==========================================================
   OVERLAY LOCAL

   O elemento pai deve usar .ayw-loading-container.
   ========================================================== */

.ayw-loading-container {
    position: relative;
}

.ayw-loading-overlay {
    position: absolute;
    inset: 0;
    z-index: 5;

    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;

    min-width: 0;

    gap: var(--ayw-space-3);

    padding: var(--ayw-space-4);

    border-radius: inherit;

    background:
        color-mix(
            in srgb,
            var(--ayw-surface) 82%,
            transparent
        );

    color: var(--ayw-text-muted);

    text-align: center;

    backdrop-filter: blur(3px);

    -webkit-backdrop-filter: blur(3px);
}

.ayw-loading-overlay[hidden] {
    display: none;
}


/* ==========================================================
   ESTADO DE CARREGAMENTO GENÉRICO

   Pode ser aplicado a um container que esteja atualizando.
   ========================================================== */

.is-loading {
    cursor: wait;
}

.ayw-loading-container.is-loading > :not(.ayw-loading-overlay) {
    pointer-events: none;
}


/* ==========================================================
   ACESSIBILIDADE

   Elementos puramente visuais devem usar aria-hidden="true".
   Textos de carregamento podem usar role="status".
   ========================================================== */

.ayw-loader-status {
    color: var(--ayw-text-muted);

    font-size: var(--ayw-font-size-sm);
    line-height: var(--ayw-line-height-relaxed);
}


/* ==========================================================
   ANIMAÇÕES
   ========================================================== */

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

@keyframes ayw-skeleton-shimmer {
    from {
        background-position: 200% 0;
    }

    to {
        background-position: -200% 0;
    }
}

@keyframes ayw-progress-indeterminate {
    0% {
        transform: translateX(-120%);
    }

    100% {
        transform: translateX(320%);
    }
}

@keyframes ayw-loading-dot {
    0%,
    80%,
    100% {
        opacity: 0.35;

        transform: scale(0.8);
    }

    40% {
        opacity: 1;

        transform: scale(1);
    }
}


/* ==========================================================
   TABLET
   ========================================================== */

@media (min-width: 768px) {
    .ayw-skeleton-grid {
        grid-template-columns:
            repeat(2, minmax(0, 1fr));

        gap: var(--ayw-space-5);
    }
}


/* ==========================================================
   DESKTOP
   ========================================================== */

@media (min-width: 992px) {
    .ayw-skeleton-grid {
        grid-template-columns:
            repeat(3, minmax(0, 1fr));
    }
}


/* ==========================================================
   MOVIMENTO REDUZIDO

   O spinner continua visualmente identificável mesmo sem
   rotação, evitando que pareça um elemento quebrado.
   ========================================================== */

@media (prefers-reduced-motion: reduce) {
    .ayw-spinner {
        animation: none;

        opacity: 0.75;
    }

    .ayw-skeleton::after {
        display: none;

        animation: none;
    }

    .ayw-progress.is-indeterminate
    .ayw-progress-bar {
        width: 100%;

        animation: none;

        opacity: 0.65;
    }

    .ayw-loading-dots span {
        animation: none;

        opacity: 0.65;
        transform: none;
    }

    .ayw-progress-bar {
        transition: none;
    }
}


/* ==========================================================
   FALLBACK PARA COLOR-MIX
   ========================================================== */

@supports not (
    color:
        color-mix(
            in srgb,
            black,
            white
        )
) {
    .ayw-skeleton::after {
        background:
            linear-gradient(
                110deg,
                transparent 20%,
                var(--ayw-surface-hover) 45%,
                transparent 70%
            );
    }

    .ayw-loading-overlay {
        background: var(--ayw-surface);
    }
}