/* O AVISO NO CANTO — a resposta do sistema a uma ação (decisão [84] do dono,
   08/10/2026).

   Antes, o recado do servidor (o flash) era uma caixa NO TOPO da página, que
   empurrava a tela para baixo, e o recado do JavaScript (mostrarFeedback) era
   um MODAL com "OK". Agora os dois são o mesmo aviso, SOBREPOSTO no canto
   superior direito: não ocupa lugar no fluxo, então nada da tela se mexe
   quando ele aparece ou some.

   - Sucesso: some sozinho em 5 s, com a barrinha diminuindo; o mouse (ou o
     foco) em cima para a barra.
   - Erro, alerta e informativa: ficam até a pessoa fechar no X.
   - Celular (até 576 px): no topo, na largura toda, por cima do cabeçalho.

   Quem monta e liga o aviso é o ui_feedback.js (o JS do flash e o do
   mostrarFeedback são um só). A caixa por dentro é a mesma `.alert-flash` da
   macro alertas.html, com a cor de cada tipo; aqui ela só ganha o lugar, o
   fundo opaco (o tom translúcido do .alert sobre a tela de baixo ficaria
   ilegível) e a sombra.

   Z-INDEX 10040: acima de TUDO que a tela abre — o modal do Bootstrap (1055),
   os overlays das galerias (2000) e o spinner (9998/9999) —, porque o aviso que
   nasce de dentro de um modal tem de aparecer e ser clicável (até 07/2026 o
   aviso nascia ATRÁS dos overlays e ninguém o via; memória
   overlay-fora-do-modal). Ele é pequeno e fica num canto: não cobre a ação.
   Abaixo, só do aviso de sessão expirada (csrf_helper.js, 10055/10060), que
   é o único que manda na tela inteira.

   Página standalone (sem base.css nem tema.css): as cores caem nos valores
   de reserva de cada var(), os do tema claro — e o ui_feedback.js põe
   data-bs-theme="light" na pilha, para o X do Bootstrap ser o do tema claro
   também na página escura. */

.aviso-pilha {
    --aviso-topo: 1rem;
    /* O ui_feedback.js desce a pilha para baixo do que ela cobriria e que a
       pessoa precisa alcançar enquanto o erro fica: o botão de ação do título
       da tela e, com um modal aberto, o cabeçalho dele (o X). */
    --aviso-topo-efetivo: max(var(--aviso-topo), var(--aviso-topo-da-tela, 0px));
    /* A ALTURA que a pilha inteira pode ocupar: até 1rem do pé da janela (no
       celular, a metade de cima da tela). Cada aviso fica com a sua parte
       (--aviso-n, posto pelo ui_feedback.js) e rola por dentro: três avisos
       com lista não empurram o mais velho — e o X dele — para fora da tela. */
    --aviso-altura: calc(100vh - var(--aviso-topo-efetivo) - 1rem);
    position: fixed;
    top: var(--aviso-topo-efetivo);
    right: 1rem;
    z-index: 10040;
    width: min(400px, calc(100vw - 2rem));
    display: flex;
    /* O mais novo em cima: no DOM a ordem é a de chegada (a do flash do
       servidor também), e a pilha a inverte na tela. */
    flex-direction: column-reverse;
    gap: 0.5rem;
    /* O vão entre os avisos e o que fica abaixo deles continua clicável. */
    pointer-events: none;
}

/* Com o cabeçalho do sistema (sticky, 65 px), o aviso nasce logo abaixo dele
   e não cobre o menu do usuário. Em px: o rem das telas internas é 14 px. */
.navbar-custom ~ .aviso-pilha {
    --aviso-topo: 77px;
}

.aviso-pilha > .alert-flash {
    --aviso-cor: var(--primary, #2563EB);
    --aviso-tinta: rgba(37, 99, 235, 0.08);
    --aviso-texto: var(--texto-soft-primary, #1D4ED8);

    pointer-events: auto;
    position: relative;
    overflow: hidden;
    max-width: none;
    width: 100%;
    margin: 0;
    padding: 0.85rem 2.75rem 0.85rem 1rem;
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    border: 0;
    border-left: 4px solid var(--aviso-cor);
    border-radius: 0.75rem;
    color: var(--aviso-texto);
    background: linear-gradient(var(--aviso-tinta), var(--aviso-tinta)),
                var(--cor-superficie, #FFFFFF);
    box-shadow: 0 12px 32px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.10);
    font-size: 0.95rem;
    line-height: 1.4;
    animation: aviso-entra 0.2s ease-out;
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.aviso-pilha > .alert-success {
    --aviso-cor: var(--success, #10B981);
    --aviso-tinta: rgba(16, 185, 129, 0.10);
    --aviso-texto: var(--texto-soft-success, #065F46);
}

.aviso-pilha > .alert-danger {
    --aviso-cor: var(--danger, #EF4444);
    --aviso-tinta: rgba(239, 68, 68, 0.10);
    --aviso-texto: var(--texto-soft-danger, #B91C1C);
}

.aviso-pilha > .alert-warning {
    --aviso-cor: var(--warning, #F59E0B);
    --aviso-tinta: rgba(245, 158, 11, 0.12);
    --aviso-texto: var(--texto-soft-warning, #B45309);
}

/* O ícone na cor do tipo, alinhado à primeira linha do texto. */
.aviso-pilha > .alert-flash > .fas,
.aviso-pilha > .alert-flash > .fa-solid {
    color: var(--aviso-cor);
    margin: 0.15rem 0 0 !important;
    flex: 0 0 auto;
}

.aviso-pilha .aviso-corpo {
    flex: 1 1 auto;
    min-width: 0;
    /* A mensagem longa rola por dentro: o aviso nunca cobre a tela inteira.
       A parte de cada um é a altura da pilha dividida pelos que estão nela,
       menos os vãos entre eles e o padding da caixa (0,85rem em cima e
       embaixo, com folga). */
    max-height: min(40vh, 22rem,
                    calc((var(--aviso-altura) - (var(--aviso-n, 1) - 1) * 0.5rem)
                         / var(--aviso-n, 1) - 1.9rem));
    overflow-y: auto;
    overflow-wrap: anywhere;
}

.aviso-pilha .aviso-titulo {
    display: block;
    font-weight: 600;
    margin-bottom: 0.15rem;
}

/* A quebra de linha da mensagem vale (era o `white-space: pre-line` do modal). */
.aviso-pilha .aviso-texto {
    white-space: pre-line;
}

/* A lista de ressalvas (`opts.alertas` do mostrarFeedback). */
.aviso-pilha .aviso-alertas {
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px solid rgba(127, 127, 127, 0.3);
    font-size: 0.875rem;
}

.aviso-pilha .aviso-alertas-titulo {
    font-weight: 600;
    margin-bottom: 0.25rem;
}

.aviso-pilha .aviso-alertas ul {
    margin: 0;
    padding-left: 1.1rem;
}

.aviso-pilha > .alert-flash > .btn-close {
    position: absolute;
    top: 0.55rem;
    right: 0.55rem;
    padding: 0.5rem;
    z-index: 1;
}

/* A barrinha do sucesso: vai diminuindo até o aviso sumir. O tempo é o do JS
   (--aviso-duracao); o mouse ou o foco em cima a param junto com o relógio. */
.aviso-pilha .aviso-barra {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 3px;
    background: var(--aviso-cor);
    transform-origin: left center;
    animation: aviso-barra var(--aviso-duracao, 5000ms) linear forwards;
}

.aviso-pilha > .aviso-parado .aviso-barra {
    animation-play-state: paused;
}

.aviso-pilha > .aviso-saindo {
    opacity: 0;
    transform: translateX(1rem);
}

@keyframes aviso-entra {
    from { opacity: 0; transform: translateX(1rem); }
    to   { opacity: 1; transform: none; }
}

@keyframes aviso-barra {
    from { transform: scaleX(1); }
    to   { transform: scaleX(0); }
}

/* Celular: no topo, na largura toda, por cima do cabeçalho. */
@media (max-width: 576px) {
    .aviso-pilha,
    .navbar-custom ~ .aviso-pilha {
        --aviso-topo: 0px;
        /* A metade de baixo da tela fica à vista, com quantos avisos houver. */
        --aviso-altura: 50vh;
        left: 0;
        right: 0;
        width: auto;
        gap: 1px;
    }

    .aviso-pilha > .alert-flash {
        border-radius: 0;
    }
}

/* Sem movimento para quem pediu: o aviso aparece e some sem deslizar, e a
   barra não anda (o sucesso continua sumindo nos 5 s). */
@media (prefers-reduced-motion: reduce) {
    .aviso-pilha > .alert-flash,
    .aviso-pilha > .aviso-saindo {
        animation: none;
        transition: none;
        transform: none;
    }

    .aviso-pilha .aviso-barra {
        animation: none;
        visibility: hidden;
    }
}

@media print {
    .aviso-pilha {
        display: none !important;
    }
}
