/* ===========================================================================
   DivisionStore — feedback visual de navegação.

   Três camadas, em ordem de intensidade:
     1. barra de progresso no topo  — aparece no clique, sempre
     2. véu + spinner               — só se o carregamento passar de 350ms
     3. transição de entrada        — conteúdo entra suave, sem "piscar"

   Nada aqui atrasa a navegação de propósito: a barra acompanha o tempo real
   e some sozinha quando a página nova assume.
   Usa os tokens de --ds-accent* definidos em loja.css.
   =========================================================================== */

/* --------------------------------------------------- 1. barra de progresso */
.ds-prog {
    position: fixed;
    inset: 0 0 auto 0;
    height: 3px;
    z-index: 20000;
    pointer-events: none;
    opacity: 0;
    transition: opacity .25s ease .1s;
    /* fica fora da transição de view para não ser "fotografada" junto */
    view-transition-name: ds-prog;
}

.ds-prog.on { opacity: 1; transition-delay: 0s; }

.ds-prog__bar {
    height: 100%;
    width: 100%;
    transform: scaleX(0);
    transform-origin: 0 50%;
    background: linear-gradient(90deg,
        var(--ds-accent-3, #7c3aed) 0%,
        var(--ds-accent,   #8b5cf6) 55%,
        var(--ds-accent-2, #a78bfa) 100%);
    box-shadow: 0 0 10px rgba(139, 92, 246, .55);
    transition: transform .2s cubic-bezier(.22, .61, .36, 1);
    will-change: transform;
}

/* ponta luminosa, dá a sensação de movimento contínuo */
.ds-prog__bar::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 90px;
    background: linear-gradient(90deg, transparent, rgba(196, 181, 253, .9));
    filter: blur(1px);
    opacity: .8;
}

/* barrinha no topo em telas com notch */
@supports (padding: env(safe-area-inset-top)) {
    .ds-prog { top: env(safe-area-inset-top, 0); }
}

/* --------------------------------------------- 2. loader central (principal) */
/* Entra imediatamente no clique, mas com fade de 180ms: numa navegação de 100ms
   o usuário percebe só um sinal leve, não um bloqueio. Em carregamento lento ele
   chega à opacidade cheia e comunica claramente "estou processando". */
.ds-veil {
    position: fixed;
    inset: 0;
    z-index: 19990;
    display: grid;
    place-items: center;
    background: radial-gradient(ellipse at center,
        color-mix(in srgb, var(--ds-bg, #0a0812) 78%, transparent) 0%,
        color-mix(in srgb, var(--ds-bg, #0a0812) 58%, transparent) 100%);
    backdrop-filter: blur(3px) saturate(.9);
    -webkit-backdrop-filter: blur(3px) saturate(.9);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;          /* nunca bloqueia o clique do usuário */
    transition: opacity .18s ease, visibility 0s linear .18s;
}

.ds-veil.on {
    opacity: 1;
    visibility: visible;
    transition: opacity .18s ease, visibility 0s;
}

.ds-veil__box {
    display: grid;
    place-items: center;
    transform: scale(.94);
    transition: transform .22s cubic-bezier(.22, .61, .36, 1);
}

.ds-veil.on .ds-veil__box { transform: scale(1); }

/* anel: trilho fraco + arco roxo girando + núcleo pulsando */
.ds-spin {
    position: relative;
    width: 58px;
    height: 58px;
    filter: drop-shadow(0 0 18px rgba(139, 92, 246, .35));
}

.ds-spin i {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    box-sizing: border-box;
}

.ds-spin i:nth-child(1) {          /* trilho */
    border: 3px solid color-mix(in srgb, var(--ds-accent, #8b5cf6) 16%, transparent);
}

.ds-spin i:nth-child(2) {          /* arco principal */
    border: 3px solid transparent;
    border-top-color: var(--ds-accent-2, #a78bfa);
    border-right-color: var(--ds-accent, #8b5cf6);
    animation: ds-spin .82s cubic-bezier(.62, .12, .38, .9) infinite;
}

.ds-spin i:nth-child(3) {          /* arco interno, mais lento e ao contrário */
    inset: 11px;
    border: 2px solid transparent;
    border-bottom-color: color-mix(in srgb, var(--ds-accent-2, #a78bfa) 55%, transparent);
    animation: ds-spin 1.5s linear infinite reverse;
}

.ds-spin i:nth-child(4) {          /* núcleo */
    inset: 24px;
    background: var(--ds-accent, #8b5cf6);
    animation: ds-pulse 1.4s ease-in-out infinite;
}

@keyframes ds-spin  { to { transform: rotate(360deg); } }
@keyframes ds-pulse {
    0%, 100% { transform: scale(.7); opacity: .55; }
    50%      { transform: scale(1);  opacity: 1; }
}

.ds-veil__txt {
    margin-top: 18px;
    font-size: .8rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--ds-text-2, #b4b4c2);
    opacity: 0;
    animation: ds-txt-in .3s ease .35s forwards;   /* só se demorar um pouco */
}

@keyframes ds-txt-in { to { opacity: .85; } }

/* telas pequenas: um pouco menor, sem encostar nas bordas */
@media (max-width: 480px) {
    .ds-spin { width: 48px; height: 48px; }
    .ds-spin i:nth-child(3) { inset: 9px; }
    .ds-spin i:nth-child(4) { inset: 20px; }
    .ds-veil__txt { font-size: .74rem; margin-top: 14px; }
}

/* ------------------------------------------- 3. transição de entrada */
/* Evita o "flash": o conteúdo sobe 6px e aparece em 220ms. */
@keyframes ds-enter {
    from { opacity: 0; transform: translate3d(0, 6px, 0); }
    to   { opacity: 1; transform: none; }
}

body.ds-anim .ds-main,
body.ds-anim .adm-main {
    animation: ds-enter .22s cubic-bezier(.22, .61, .36, 1) both;
}

/* saída: leve esmaecida enquanto a próxima página carrega */
body.ds-leaving .ds-main,
body.ds-leaving .adm-main {
    opacity: .55;
    transition: opacity .18s ease;
}

/* -------------------------------- 4. estado de carregando em botões/links */
.ds-busy {
    position: relative;
    pointer-events: none;
    opacity: .72;
}

.ds-busy > * { visibility: hidden; }

.ds-busy::after {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 16px;
    height: 16px;
    visibility: visible;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, .35);
    border-top-color: #fff;
    animation: ds-spin .6s linear infinite;
}

/* card/seção aguardando conteúdo (usado pelo catálogo ao filtrar) */
.ds-dim {
    opacity: .45;
    filter: saturate(.6);
    transition: opacity .18s ease, filter .18s ease;
    pointer-events: none;
}

/* ------------------------------------ 5. transição entre documentos (VT) */
/* Chrome/Edge modernos fazem a troca de página sem flash. Onde não houver
   suporte, a animação de entrada acima já cobre. */
@media (prefers-reduced-motion: no-preference) {
    @view-transition { navigation: auto; }
}

::view-transition-old(root) {
    animation: ds-vt-out .16s ease both;
}

::view-transition-new(root) {
    animation: ds-vt-in .22s cubic-bezier(.22, .61, .36, 1) both;
}

@keyframes ds-vt-out { to { opacity: 0; } }
@keyframes ds-vt-in  { from { opacity: 0; transform: translate3d(0, 6px, 0); } }

/* a barra de progresso não participa do cross-fade */
::view-transition-group(ds-prog) { animation: none; }

/* --------------------------------------------- 6. quem pediu menos movimento */
@media (prefers-reduced-motion: reduce) {
    .ds-prog__bar { transition: none; }
    .ds-prog__bar::after { display: none; }
    /* mantém apenas o giro do arco principal, devagar: sem ele não há sinal de
       "processando". Núcleo pulsante e arco interno saem. */
    .ds-spin i:nth-child(2) { animation-duration: 1.8s; animation-timing-function: linear; }
    .ds-spin i:nth-child(3) { animation: none; opacity: .35; }
    .ds-spin i:nth-child(4) { animation: none; opacity: .8; }
    .ds-spin { filter: none; }
    .ds-veil__box { transform: none; transition: none; }
    .ds-busy::after { animation-duration: 1.8s; }
    body.ds-anim .ds-main,
    body.ds-anim .adm-main { animation: none; }
    body.ds-leaving .ds-main,
    body.ds-leaving .adm-main { opacity: 1; transition: none; }
    .ds-veil { transition: opacity .01s; }
}
