/* ======================================================================
   MOVIMENTO — o visual dos efeitos de static/src/efeitos.

   Carrega por ultimo e so ACRESCENTA. Quase tudo aqui depende de
   html.efx-ligado, classe que o modulo de efeitos poe quando esta rodando
   E as animacoes estao valendo (interruptor das Configuracoes, html
   .sem-animacao e prefers-reduced-motion, tudo em tempo real). Sem a
   classe — modulo nao carregou, animacao desligada — o app e o de antes,
   sem uma regra sequer deste arquivo em vigor. A unica excecao e o menu
   lateral no desktop (secao 7): la o deslize e do app.js, nao do modulo de
   efeitos, e a regra que desliga a transicao de width do legado vale sempre.

   Regra da casa: so transform e opacity se movem. Nenhum filter animado,
   nenhum box-shadow animado, nenhuma propriedade de layout em transicao.
   (O recorte do <main> no mesmo menu lateral e a excecao, explicada la.)
   ====================================================================== */

/* ------------------------------------------------------------ camada propria
   Onda de toque, reflexo do cartao, mensagem em voo: tudo efemero mora aqui,
   fora do #app, e nada disto recebe toque. Acima dos avisos (z 500). */
#efx-camada{position:fixed;inset:0;z-index:600;pointer-events:none;overflow:hidden;contain:strict}
#efx-camada *{pointer-events:none}

/* ------------------------------------------------------------ 1. inclinacao + reflexo */
/* Entrada ja terminada que ainda "segura" o transform (fill:both): sai, para
   a inclinacao poder aparecer. O ultimo quadro dela e o proprio repouso. */
.efx-assentado{animation:none!important}
.efx-reflexo-clipe{position:absolute;overflow:hidden}
.efx-reflexo{position:absolute;overflow:hidden;opacity:0;will-change:transform,opacity}
.efx-reflexo-luz,.efx-reflexo-breu{position:absolute;left:-230px;top:-230px;width:460px;height:460px;border-radius:50%;will-change:transform}
.efx-reflexo-luz{background:radial-gradient(circle,rgba(255,243,214,.17) 0,rgba(239,214,166,.085) 30%,rgba(239,214,166,0) 66%)}
.efx-reflexo-breu{background:radial-gradient(circle,rgba(0,0,0,.24) 0,rgba(0,0,0,.11) 36%,rgba(0,0,0,0) 68%)}

/* ------------------------------------------------------------ 2. troca de aba */
/* A entrada antiga (abaNoite) anima filter:blur numa aba inteira. Com os
   efeitos ligados, quem entra e a .efx-entrando: mesma ideia, sem filtro. */
html.efx-ligado .aba.visivel{animation:none}
html.efx-ligado .aba.visivel.efx-entrando{animation:efx-aba-entra .54s var(--suave) backwards}
@keyframes efx-aba-entra{
  from{opacity:0;transform:perspective(1400px) translate3d(calc(var(--efx-dir,1) * 36px),0,70px)}
  to{opacity:1;transform:none}}
/* O fantasma da aba que saiu: fixo onde ela estava (geometria posta pelo JS),
   recua para o fundo e apaga. !important porque .aba sem .visivel e display:none. */
html.efx-ligado .aba.efx-saindo{display:block!important;animation:efx-aba-sai .34s cubic-bezier(.4,0,.7,1) both!important}
@keyframes efx-aba-sai{
  from{opacity:1;transform:none}
  to{opacity:0;transform:perspective(1400px) translate3d(calc(var(--efx-dir,1) * -30px),0,-110px)}}

/* Modo opcional com View Transitions (iniciar({viewTransition:true})): so o
   <main> entra na captura; ceu, cabecalho e barra seguem vivos por baixo. */
html.efx-vt{view-transition-name:none}
html.efx-vt main{view-transition-name:efx-aba}
::view-transition-group(efx-aba){animation-duration:.45s}
::view-transition-old(efx-aba){animation:efx-vt-sai .32s cubic-bezier(.4,0,.7,1) both}
::view-transition-new(efx-aba){animation:efx-vt-entra .5s cubic-bezier(.16,1,.3,1) both}
@keyframes efx-vt-sai{to{opacity:0;transform:translate3d(calc(var(--efx-dir,1) * -30px),0,0) scale(.93)}}
@keyframes efx-vt-entra{from{opacity:0;transform:translate3d(calc(var(--efx-dir,1) * 36px),0,0) scale(1.05)}}

/* ------------------------------------------------------------ 3. chat */
/* Mensagem em voo: a entrada padrao (desfoque) sai de cena, no clone e na bolha. */
.bolha.efx-voo{animation:none!important}
#efx-camada .bolha.efx-voo{will-change:transform,opacity}

/* Resposta que chega inteira: linha a linha. Span inline so conhece
   opacidade; .item e pre sao bloco e tambem sobem. */
html.efx-ligado .bolha .efx-ln{animation:efx-linha .7s var(--suave) backwards;animation-delay:calc(var(--i,0) * 70ms + 90ms)}
@keyframes efx-linha{from{opacity:0;transform:translate3d(0,9px,0)}to{opacity:1;transform:none}}

/* Pensando: tres estrelas em orbita inclinada em volta da bussola (30 px,
   a 6 px do topo: centro em 15,21). */
.efx-orbita{display:none}
html.efx-ligado .carregando-chat{position:relative}
html.efx-ligado .carregando-chat .efx-orbita{display:block;position:absolute;left:-9px;top:-3px;width:48px;height:48px;
  pointer-events:none;transform:rotate(-22deg) scaleY(.5)}
html.efx-ligado .carregando-chat.passos-prontos .efx-orbita{display:none}
.efx-orbita i{position:absolute;inset:0;border-radius:50%;animation:efx-orbitar 2.6s linear infinite}
.efx-orbita i:nth-child(2){inset:5px;animation-duration:3.5s;animation-delay:-1.2s;animation-direction:reverse}
.efx-orbita i:nth-child(3){inset:-4px;animation-duration:4.6s;animation-delay:-2.9s}
.efx-orbita i::before{content:'';position:absolute;left:50%;top:-2.5px;width:5px;height:5px;margin-left:-2.5px;border-radius:50%;
  background:radial-gradient(circle,#fff3d6 0 30%,rgba(239,214,166,.85) 45%,rgba(209,171,116,0) 72%);
  box-shadow:0 0 8px 1px rgba(239,214,166,.55)}
.efx-orbita i:nth-child(2)::before{width:4px;height:4px;margin-left:-2px;top:-2px;opacity:.8}
.efx-orbita i:nth-child(3)::before{width:3.5px;height:3.5px;opacity:.65}
@keyframes efx-orbitar{to{transform:rotate(360deg)}}

/* Botoes de opcao: sobem em escada, com mola. */
html.efx-ligado .opcoes-guiadas.efx-escada .opcao-guiada{animation:efx-degrau .58s var(--mola) backwards;
  animation-delay:calc(var(--i,0) * 65ms + 140ms)}
@keyframes efx-degrau{from{opacity:0;transform:translate3d(0,14px,0) scale(.955)}to{opacity:1;transform:none}}

/* O aro do enviar. */
.efx-pulso{position:absolute;border:1.5px solid rgba(239,214,166,.85);box-shadow:0 0 16px rgba(209,171,116,.45),inset 0 0 10px rgba(239,214,166,.25);
  animation:efx-pulso .72s cubic-bezier(.16,1,.3,1) forwards}
@keyframes efx-pulso{from{transform:scale(1);opacity:.95}to{transform:scale(2.15);opacity:0}}

/* ------------------------------------------------------------ 4. odometro
   A coluna mede um algarismo de verdade (invisivel) para ter a largura e a
   linha de base certas; a fita 0-9 0-9 corre por cima dela. clip-path, e nao
   overflow: overflow:hidden mudaria a linha de base do inline-block e o
   numero daria um degrau em relacao ao "R$". */
.efx-odo{white-space:nowrap;font-variant-numeric:tabular-nums}
.efx-odo-col{display:inline-block;position:relative;clip-path:inset(0)}
.efx-odo-medida{visibility:hidden}
.efx-odo-fita{position:absolute;left:0;top:0;width:100%;height:2000%;display:flex;flex-direction:column;will-change:transform}
.efx-odo-fita b{flex:1 1 0;min-height:0;display:block;font:inherit;font-weight:inherit;text-align:center}

/* ------------------------------------------------------------ 5. onda de toque */
.efx-onda-caixa{position:absolute;overflow:hidden}
.efx-onda{position:absolute;border-radius:50%;transform:scale(.04);will-change:transform,opacity;
  background:radial-gradient(circle,rgba(255,243,214,.30) 0,rgba(209,171,116,.20) 42%,rgba(209,171,116,.05) 66%,rgba(209,171,116,0) 72%);
  animation:efx-onda .64s cubic-bezier(.16,1,.3,1) forwards}
.efx-onda.forte{background:radial-gradient(circle,rgba(255,243,214,.5) 0,rgba(209,171,116,.3) 42%,rgba(209,171,116,0) 72%)}
@keyframes efx-onda{from{transform:scale(.04);opacity:1}55%{opacity:.75}to{transform:scale(1);opacity:0}}
/* A onda ja responde ao toque: o clarao cinza do navegador sobra. */
html.efx-ligado button,html.efx-ligado [role="button"],html.efx-ligado summary,html.efx-ligado a{-webkit-tap-highlight-color:transparent}

/* ------------------------------------------------------------ 6. revelar ao rolar */
html.efx-ligado .efx-oculto{opacity:0;transform:translate3d(0,22px,0)}
html.efx-ligado .efx-revelado{animation:efx-revela .72s var(--suave) backwards}
@keyframes efx-revela{from{opacity:0;transform:translate3d(0,22px,0) scale(.985)}to{opacity:1;transform:none}}

/* ------------------------------------------------------------ 7. janelas e menu lateral */
/* Abertura: a janela vem do fundo, levemente deitada, e assenta. Sem blur. */
html.efx-ligado .overlay.aberto .modal{animation:efx-modal-abre .52s var(--suave) backwards}
@keyframes efx-modal-abre{
  from{opacity:0;transform:perspective(1200px) translate3d(0,30px,-90px) rotateX(6deg)}
  to{opacity:1;transform:none}}
/* Fechamento: onde o navegador sabe transicionar `display` (allow-discrete),
   o veu apaga e a janela recua antes de sumir. Onde nao sabe, a segunda
   declaracao e descartada inteira e o fechamento e o corte seco de sempre. */
html.efx-ligado .overlay{transition:opacity .26s ease-out}
html.efx-ligado .overlay{transition:opacity .26s ease-out,display .26s allow-discrete,overlay .26s allow-discrete}
html.efx-ligado .overlay:not(.aberto){opacity:0;pointer-events:none}
html.efx-ligado .overlay.aberto{opacity:1}
@starting-style{html.efx-ligado .overlay.aberto{opacity:0}}
html.efx-ligado .overlay:not(.aberto) .modal{transform:translate3d(0,22px,0) scale(.965);transition:transform .26s cubic-bezier(.4,0,1,1)}
/* Fechada por arrasto: a folha ja saiu da tela pela mao dele. */
.overlay.efx-sem-saida,.overlay.efx-sem-saida .modal{transition:none!important}

/* O fundo recua e escurece enquanto ha janela aberta. So o <main>: o
   cabecalho fica parado porque o indicador das abas e medido em pixels de
   tela, e uma escala nele sairia errada se o idioma mudasse com a janela aberta. */
html.efx-ligado main{transition:transform .55s var(--suave),opacity .55s var(--suave)}
/* noite.css da ao main do chat uma transicao propria (o veu da conversa): as duas juntas. */
html.efx-ligado main:has(#dialogo.visivel){transition:--veu-chat .65s cubic-bezier(.22,.8,.24,1),transform .55s var(--suave),opacity .55s var(--suave)}
html.efx-ligado body:has(.overlay.aberto) main{transform:scale(.962);opacity:.5}

@media (max-width:640px){
  html.efx-ligado .overlay.aberto .modal{animation:efx-folha-sobe .55s var(--suave) backwards}
  @keyframes efx-folha-sobe{from{transform:translate3d(0,46%,0);opacity:.4}to{transform:none;opacity:1}}
  html.efx-ligado .overlay:not(.aberto) .modal{transform:translate3d(0,38%,0)}
}

/* Menu lateral no celular: o legado anima WIDTH (layout a cada quadro). Aqui
   ele ja nasce com a largura final e desliza por transform; o conteudo
   recua para o fundo enquanto o menu esta aberto. No desktop o menu empurra
   a pagina (e layout de verdade): fica como esta. */
@media (max-width:768px){
  html.efx-ligado #lateral{width:min(84vw,290px);transform:translate3d(-105%,0,0);visibility:hidden;
    transition:transform .5s var(--suave),visibility 0s linear .5s}
  html.efx-ligado #lateral.aberta{transform:none;visibility:visible;transition:transform .5s var(--suave),visibility 0s}
  html.efx-ligado .corpo:has(#lateral.aberta) main{transform:translate3d(22px,0,0) scale(.955);opacity:.42}
}

/* Menu lateral no desktop: ele EMPURRA a pagina, e o legado animava width —
   o <main> mudava de largura a cada quadro e o chat inteiro requebrava as
   linhas (mais cada canvas com ResizeObserver realocando o buffer). O layout
   agora muda de uma vez e o deslize e de alternarLateral() (app.js), com o
   mesmo tempo e a mesma curva: transform na lateral e na aba visivel, e um
   recorte (clip-path) na borda esquerda do <main>. O recorte e a unica
   excecao a regra da casa, e de proposito: mover o <main> por transform tirava
   do lugar a borda direita do painel do chat, que nunca se mexeu; clip-path e
   so pintura, num elemento, por 220 ms — nenhum layout.
   Este bloco vale com ou sem efx-ligado (a outra excecao ao cabecalho do
   arquivo): sem ele a transicao de width do legado voltaria junto com o
   deslize. Com as animacoes desligadas o menu abre seco, como antes.
   .lat-sobre: enquanto desliza, a lateral fica sobreposta, fora do fluxo, e o
   <main> ocupa a caixa inteira (a mesma geometria do celular, no legado).
   will-change so durante o deslize (.lat-movendo): camada propria parada e
   memoria de GPU a toa. */
@media (min-width:769px){
  #lateral{transition:none}
  #lateral.lat-sobre{position:absolute;top:0;bottom:0;left:0;z-index:120;width:264px;border-right-width:1px}
  #lateral.lat-movendo,main > .aba.lat-movendo{will-change:transform}
}

/* ------------------------------------------------------------ 8. cursor de luz
   Entre o ceu (z 0) e o #app (z 1): aparece atraves do vidro, nunca sobre o texto. */
#efx-cursor{position:fixed;left:-320px;top:-320px;width:640px;height:640px;z-index:0;pointer-events:none;border-radius:50%;
  opacity:0;transition:opacity .9s ease-out;will-change:transform;
  background:radial-gradient(circle,rgba(239,214,166,.085) 0,rgba(209,171,116,.045) 34%,rgba(209,171,116,0) 68%)}
html.efx-ligado #efx-cursor.aceso{opacity:1}
@media (hover:none),(pointer:coarse){#efx-cursor{display:none}}

/* ------------------------------------------------------------ sem animacao
   html.efx-ligado ja cai sozinha nesses casos; isto e o cinto com suspensorio
   para o que e criado pelo JS e poderia estar na tela no instante da troca. */
html.sem-animacao #efx-camada,html.sem-animacao #efx-cursor,html.sem-animacao .efx-orbita{display:none!important}
@media (prefers-reduced-motion:reduce){
  #efx-camada,#efx-cursor,.efx-orbita{display:none!important}
}

/* A BUSSOLA EM 3D. O palco e um quadrado: por baixo o SVG de sempre (e o que
   aparece sem WebGL, sem animacao, e enquanto o modulo carrega); por cima o
   canvas, que o proprio modulo poe e acende no primeiro quadro. */
.bussola-palco{position:relative;flex:0 0 auto;display:block;-webkit-tap-highlight-color:transparent}
.bussola-palco > svg{position:absolute;inset:0;width:100%;height:100%;margin:0;
  transition:opacity .5s var(--suave),visibility 0s linear .5s}
/* Com o 3D de pe o SVG some E para: agulha girando invisivel ainda custa. */
.bussola-palco.tem3d > svg{opacity:0;visibility:hidden}
.bussola-palco.tem3d > svg .compass-needle{animation:none}

/* Hero: grande. A entrada (entraHero) passa do SVG para o palco, para os dois
   subirem juntos. O halo e um gradiente parado atras: drop-shadow num canvas
   que redesenha a 60 fps refaria o filtro a cada quadro. */
.bussola-palco-hero{width:220px;height:220px;margin-bottom:18px;cursor:pointer;
  animation:entraHero 1.4s var(--suave) both}
.bussola-palco-hero::before{content:"";position:absolute;inset:-18%;border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(209,171,116,.22),rgba(209,171,116,.07) 55%,transparent 72%)}
.entrada-hero .bussola-palco-hero > .logo-login{width:100%;height:100%;margin:0;animation:none}
.bussola-palco-hero.tem3d > .logo-login{filter:none}
@media (max-width:560px){ .bussola-palco-hero{width:168px;height:168px} }
html.sem-animacao .bussola-palco-hero{animation:none;transform:none;opacity:1}

/* Carregamento da conversa. */
.bussola-palco-carga{width:120px;height:120px}
.bussola-palco-carga > svg.bussola-carregando{width:100%;height:100%}
