/* ============================================================
 * virtus-login-fx.css — Camada de ambiente das telas de login
 * ------------------------------------------------------------
 * Acoplável: não redefine layout, tipografia, cores de texto nem
 * dimensões do painel. Só acrescenta camadas de fundo (atrás de
 * tudo, z-index negativo) e efeitos ADITIVOS (box-shadow, glow).
 *
 * Por que z-index negativo em vez de um wrapper: assim o painel
 * existente continua no fluxo normal e passa por cima das camadas
 * sem eu precisar reestruturar o HTML de login.php.
 *
 * Usa em: aluno/login.php, admin/login.php, esqueci-senha.php,
 *         reset-senha.php
 * ============================================================ */

:root{
  /* Paleta extraída da própria imagem de fundo */
  --vfx-abismo:  #03081a;
  --vfx-navy:    #0a1435;
  --vfx-eletrico:#3b82f6;
  --vfx-ciano:   #22d3ee;
  --vfx-violeta: #8b5cf6;

  /* Deslocamento do mouse, escrito pelo JS. Sem JS fica 0 e nada quebra. */
  --vfx-mx: 0;
  --vfx-my: 0;
}

/* O <body> precisa de contexto de empilhamento próprio, senão as
   camadas negativas somem atrás do background do body. */
body.vfx-on{
  background-color: var(--vfx-abismo);
  isolation: isolate;   /* cria o contexto; NÃO uso position:relative
                           aqui para não mudar a âncora de elementos
                           absolutos que a página já tenha. */
}

/* ---------- Camada 1: a imagem, o mais distante ---------- */
.vfx-bg{
  position: fixed;
  inset: -3%;                     /* folga para o parallax não mostrar borda */
  z-index: -6;
  background-image: url('../img/virtus-login-bg.jpg');
  background-size: cover;
  background-position: center 60%;
  transform: translate3d(calc(var(--vfx-mx) * -5px), calc(var(--vfx-my) * -5px), 0);
  will-change: transform;
  pointer-events: none;
}

/* Vinheta: escurece o miolo para o painel ganhar contraste e mantém
   as laterais (globo à esquerda, curvas à direita) vivas. */
.vfx-bg::after{
  content:'';
  position:absolute; inset:0;
  background:
    radial-gradient(ellipse 62% 70% at 50% 52%, rgba(3,8,26,.86) 0%, rgba(3,8,26,.55) 45%, transparent 78%),
    linear-gradient(to bottom, rgba(3,8,26,.55) 0%, transparent 22%, transparent 76%, rgba(3,8,26,.65) 100%);
}

/* ---------- Camada 2: malha de pontos à deriva ---------- */
/* Quase invisível de propósito — dá textura, não desenho. */
.vfx-mesh{
  position: fixed;
  inset: -60px;
  z-index: -5;
  background-image: radial-gradient(circle, rgba(140,190,255,.35) .6px, transparent .6px);
  background-size: 46px 46px;
  opacity: .07;
  mask-image: radial-gradient(ellipse 80% 70% at 50% 50%, transparent 20%, #000 85%);
  -webkit-mask-image: radial-gradient(ellipse 80% 70% at 50% 50%, transparent 20%, #000 85%);
  animation: vfx-mesh-drift 90s linear infinite;
  pointer-events: none;
}
@keyframes vfx-mesh-drift{
  to{ background-position: 46px 46px; }
}

/* ---------- Camada 3: canvas (partículas e fluxo) ---------- */
.vfx-canvas{
  position: fixed;
  inset: 0;
  z-index: -4;
  pointer-events: none;
  transform: translate3d(calc(var(--vfx-mx) * -11px), calc(var(--vfx-my) * -11px), 0);
  will-change: transform;
}

/* ---------- Camada 5: fluxo que converge para o símbolo ---------- */
/* Precisa ficar ACIMA do painel: o logo da Virtus está dentro do
   cartão, então partículas desenhadas atrás nunca seriam vistas
   chegando. É só a convergência — o ambiente continua no fundo. */
.vfx-fluxo{
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

/* ---------- Camada 4: halo que respira atrás do painel ---------- */
.vfx-halo{
  position: fixed;
  z-index: -3;
  pointer-events: none;
  border-radius: 50%;
  background:
    radial-gradient(circle, rgba(59,130,246,.26) 0%, rgba(139,92,246,.15) 38%, transparent 70%);
  filter: blur(50px);
  opacity: 0;
  transform: translate3d(calc(var(--vfx-mx) * 7px), calc(var(--vfx-my) * 7px), 0) scale(1);
  will-change: transform, opacity;
}
body.vfx-ready .vfx-halo{
  animation: vfx-respirar 7.5s ease-in-out 1s infinite;
}
@keyframes vfx-respirar{
  0%, 100% { opacity: .55; }
  50%      { opacity: 1;   }
}

/* ---------- Onda rara: o "pulso de dados" ---------- */
/* Fica em z-index -3: passa atrás do painel, que a corta. */
.vfx-pulso{
  position: fixed;
  top: -10%; bottom: -10%;
  width: 34vw; left: -40vw;
  z-index: -3;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(100deg,
      transparent 0%,
      rgba(34,211,238,.05) 35%,
      rgba(99,160,255,.13) 50%,
      rgba(139,92,246,.05) 65%,
      transparent 100%);
  filter: blur(26px);
}
body.vfx-ready .vfx-pulso{
  animation: vfx-varrer 26s cubic-bezier(.45,0,.55,1) 12s infinite;
}
@keyframes vfx-varrer{
  0%        { transform: translateX(0);     opacity: 0; }
  6%        { opacity: .9; }
  26%       { opacity: .9; }
  32%       { transform: translateX(180vw); opacity: 0; }
  100%      { transform: translateX(180vw); opacity: 0; }
}

/* ---------- Entrada do painel ---------- */
/* .vfx-entrar-t inclui translate; .vfx-entrar-s é a versão sem
   transform, usada quando o painel já tem um transform próprio
   (senão eu sobrescreveria o layout dele). */
.vfx-entrar-t{ animation: vfx-subir 860ms cubic-bezier(.16,1,.3,1) both; }
.vfx-entrar-s{ animation: vfx-surgir 860ms cubic-bezier(.16,1,.3,1) both; }

@keyframes vfx-subir{
  from{ opacity:0; transform: translateY(11px); filter: blur(7px); }
  60% { filter: blur(1.5px); }
  to  { opacity:1; transform: translateY(0);    filter: blur(0); }
}
@keyframes vfx-surgir{
  from{ opacity:0; filter: blur(7px); }
  60% { filter: blur(1.5px); }
  to  { opacity:1; filter: blur(0); }
}

/* ---------- Campos ---------- */
/* Só box-shadow: aditivo, não disputa borda/fundo com o CSS atual. */
.vfx-on input:where([type="text"],[type="email"],[type="password"],[type="tel"]),
.vfx-on select,
.vfx-on textarea{
  transition: box-shadow 260ms ease, border-color 260ms ease;
}
.vfx-on input:where([type="text"],[type="email"],[type="password"],[type="tel"]):hover,
.vfx-on select:hover,
.vfx-on textarea:hover{
  box-shadow:
    0 0 0 1px rgba(34,211,238,.22),
    0 0 16px -4px rgba(34,211,238,.35),
    inset 0 1px 6px rgba(3,8,26,.35);
}
/* Anel de foco em dois tons — imita um gradiente azul→violeta,
   porque box-shadow não aceita gradiente de verdade. */
.vfx-on input:where([type="text"],[type="email"],[type="password"],[type="tel"]):focus,
.vfx-on select:focus,
.vfx-on textarea:focus{
  box-shadow:
    0 0 0 1.5px rgba(59,130,246,.75),
    0 0 0 4px rgba(139,92,246,.22),
    0 0 22px -6px rgba(99,160,255,.55),
    inset 0 1px 6px rgba(3,8,26,.30);
}

/* ---------- Botão principal ---------- */
.vfx-cta{
  position: relative;
  overflow: hidden;
  transition: transform 250ms cubic-bezier(.16,1,.3,1), box-shadow 250ms ease;
}
.vfx-cta:hover{
  transform: translateY(-2px);
  box-shadow: 0 14px 34px -12px rgba(99,102,241,.75), 0 0 24px -10px rgba(34,211,238,.5);
}
.vfx-cta:active{ transform: translateY(0); }

/* Brilho interno permanente, discreto */
.vfx-cta::before{
  content:'';
  position:absolute; inset:0;
  background: linear-gradient(to bottom, rgba(255,255,255,.16), transparent 55%);
  pointer-events:none;
}

/* Reflexo que atravessa — a cada ~6s, não contínuo */
.vfx-brilho{
  position:absolute; top:-60%; bottom:-60%;
  width: 42%; left:-60%;
  pointer-events:none;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.30), transparent);
  filter: blur(7px);
  transform: skewX(-14deg);
}
body.vfx-ready .vfx-brilho{
  animation: vfx-reflexo 6.5s cubic-bezier(.6,0,.4,1) 3s infinite;
}
@keyframes vfx-reflexo{
  0%   { left:-60%; opacity:0; }
  8%   { opacity:.9; }
  26%  { left:130%;  opacity:0; }
  100% { left:130%;  opacity:0; }
}

/* A seta do botão avança no hover, se existir */
.vfx-cta :where(svg, .vfx-seta){ transition: transform 250ms cubic-bezier(.16,1,.3,1); }
.vfx-cta:hover :where(svg, .vfx-seta){ transform: translateX(3px); }

/* ---------- Órbita do logo ---------- */
.vfx-orbita{
  position: fixed;
  z-index: 4;                     /* o símbolo está dentro do painel:
                                     a órbita tem que passar por cima */
  pointer-events: none;
  opacity: 0;
  transition: opacity 600ms ease;
}
body.vfx-ready .vfx-orbita{ opacity: 1; }

.vfx-orbita i{
  position:absolute; top:50%; left:50%;
  width:3px; height:3px; border-radius:50%;
  background: var(--vfx-ciano);
  box-shadow: 0 0 8px 2px rgba(34,211,238,.7);
  margin:-1.5px 0 0 -1.5px;
  animation: vfx-orbitar 5s linear infinite;
}
.vfx-orbita i:nth-child(2){ animation-delay:-1.7s; background: var(--vfx-violeta); box-shadow:0 0 8px 2px rgba(139,92,246,.7); }
.vfx-orbita i:nth-child(3){ animation-delay:-3.4s; background: var(--vfx-eletrico); box-shadow:0 0 8px 2px rgba(59,130,246,.7); }

@keyframes vfx-orbitar{
  from{ transform: rotate(0deg)   translateX(var(--vfx-raio,26px)) rotate(0deg)   scale(.6); opacity:.35; }
  25% { opacity:1; }
  50% { transform: rotate(180deg) translateX(var(--vfx-raio,26px)) rotate(-180deg) scale(1); opacity:.9; }
  75% { opacity:.4; }
  to  { transform: rotate(360deg) translateX(var(--vfx-raio,26px)) rotate(-360deg) scale(.6); opacity:.35; }
}

/* Lâmina de luz ciano cruzando o símbolo */
.vfx-orbita span{
  position:absolute; inset:0;
  overflow:hidden;
  border-radius:14px;
}
.vfx-orbita span::after{
  content:'';
  position:absolute; top:-40%; bottom:-40%; width:28%;
  left:-40%;
  background: linear-gradient(100deg, transparent, rgba(34,211,238,.55), transparent);
  filter: blur(5px);
  transform: skewX(-16deg);
  mix-blend-mode: screen;
  animation: vfx-lamina 5s cubic-bezier(.6,0,.4,1) infinite;
}
@keyframes vfx-lamina{
  0%   { left:-40%; opacity:0; }
  12%  { opacity:1; }
  40%  { left:120%; opacity:0; }
  100% { left:120%; opacity:0; }
}

/* ---------- Telas menores ---------- */
@media (max-width: 820px){
  .vfx-bg{
    background-image: url('../img/virtus-login-bg-mobile.jpg');
    /* No retrato, o recorte central da imagem fica vazio. Puxando
       para a direita entram as curvas de luz, que dão profundidade. */
    background-position: 76% 62%;
  }
  .vfx-mesh{ display:none; }        /* textura invisível no celular: só custa bateria */
  .vfx-pulso{ display:none; }
}

/* ---------- Acessibilidade: movimento reduzido ---------- */
/* O JS também checa isso e nem inicia o canvas. Aqui é a garantia
   para o caso de o CSS carregar sem o JS. */
@media (prefers-reduced-motion: reduce){
  .vfx-mesh,
  .vfx-canvas,
  .vfx-fluxo,
  .vfx-pulso,
  .vfx-orbita{ display: none !important; }

  body.vfx-ready .vfx-halo{ animation: none; opacity: .7; }
  body.vfx-ready .vfx-brilho{ animation: none; opacity: 0; }
  .vfx-entrar-t, .vfx-entrar-s{ animation: none; opacity: 1; filter: none; }
  .vfx-cta:hover{ transform: none; }
  .vfx-bg, .vfx-canvas, .vfx-halo{ transform: none !important; }
}
