/* ════════════════════════════════════════════════════════════════
   O PORTÃO DE FERRO — a tela de login como uma peça só que se abre
   (2026-09-19)

   Um card maciço, partido ao meio por uma junta. A metade esquerda é o
   formulário; a direita traz a marca cravada no ferro e o contato.
   Fechado, lê como uma peça só — a junta é a linha central, como a de
   um portão de verdade.

   O QUE AS DUAS METADES FAZEM, e por quê:

     repouso    fechadas, encostadas. Nada atrás delas à vista.
     validando  ABREM. O vão revela o holograma, que fica CIANO enquanto
                o servidor responde.
     liberado   holograma VERDE, a trava vira um visto, as placas se
                escancaram e a página troca.
     negado     holograma VERMELHO e o portão CONTINUA ABERTO — quem
                errou precisa poder corrigir sem que a tela se feche na
                cara dele.
     retomando  ao tocar num campo depois da recusa, as placas fecham
                UM POUCO. Não até o fim: só o bastante para o formulário
                voltar a ficar confortável de preencher.

   Tudo aqui é aparência. Nenhuma regra lê senha, valida código ou
   navega — quem faz isso é login.js, e o portão só é avisado.
   ════════════════════════════════════════════════════════════════ */

.wrap-portao {
  /* Abrindo por rotacao o portao ocupa MENOS largura, nunca mais: nao
     ha risco de estourar a janela como havia quando as folhas
     deslizavam para os lados. */
  width: min(860px, calc(100vw - 32px));

  --holo: #2fd4e0;
  --holo-forte: #b4f8fc;
  --holo-brilho: rgba(47, 212, 224, 0.45);
}

body:has(.wrap-portao) { overflow-x: clip; }

.portao {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: stretch;
  isolation: isolate;
  perspective: 1500px;
}

/* ── Os cinco estados ──
   Uma variável de abertura e uma de cor; o resto do arquivo obedece. */

/* --gonzo e o angulo do gonzo. A fenda nasce SOZINHA da rotacao: uma
   folha de 380px girada 34 graus mede 380*cos(34) = 315px de frente,
   entao cada lado recolhe 65px e o vao no meio abre 130px sem ninguem
   deslizar. E assim que porta de duas folhas abre de verdade. */
.portao.validando {
  --gonzo: 34deg;
  --luz-folha: 0.9;
}

.portao.negado {
  --gonzo: 34deg;
  --holo: #ff4d6d;
  --holo-forte: #ffd0d9;
  --holo-brilho: rgba(255, 77, 109, 0.5);
  --luz-folha: 0.9;
}

/* A recusa não fecha a tela na cara de quem errou: ela só encosta as
   placas o suficiente para o formulário voltar a ficar cômodo. */
.portao.retomando {
  --gonzo: 15deg;
  --holo: #ff8da0;
  --holo-forte: #ffd9e0;
  --holo-brilho: rgba(255, 141, 160, 0.38);
  --luz-folha: 0.96;
}

/* DOIS ATOS, e nao um.
   `aprovado` e o veredito: o holograma fica verde, a trava abre e vira
   um visto, o clarao sai. Ninguem se move de lugar.
   `liberado` vem DEPOIS e so faz uma coisa: a camera mergulha.

   Estavam juntos, e o resultado era entrar e ficar verde ao mesmo
   tempo — ninguem via o sim, so o corte. Agora da para ver: aprova, e
   ai entra. */
.portao.aprovado {
  --gonzo: 34deg;
  --holo: #00e5a0;
  --holo-forte: #c2ffec;
  --holo-brilho: rgba(0, 229, 160, 0.6);
  --luz-folha: 0.9;
}


/* ════════════════════════════════════════════════════════════════
   1. AS DUAS METADES
   ════════════════════════════════════════════════════════════════ */

.placa {
  position: relative;
  z-index: 2;
  flex: 0 0 380px;
  max-width: 380px;
  border: 1px solid rgba(245, 166, 35, 0.34);
  backface-visibility: hidden;
  transition:
    transform 640ms cubic-bezier(0.32, 0.72, 0.2, 1),
    filter 640ms cubic-bezier(0.32, 0.72, 0.2, 1),
    box-shadow 480ms var(--ease-mec, ease);

  /* AÇO ESCOVADO. Quatro planos empilhados, do mais fino ao corpo:
     microescovado vertical, sulco horizontal mais largo, um especular
     diagonal, e o gradiente do material. Sem imagem: textura de metal
     é repetição irregular de linha, e gradiente repetido faz isso. */
  background:
    repeating-linear-gradient(90deg,
      rgba(255, 255, 255, 0.017) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg,
      rgba(0, 0, 0, 0.11) 0 2px, transparent 2px 5px),
    linear-gradient(118deg,
      rgba(255, 255, 255, 0.055) 0%,
      transparent 26%,
      transparent 60%,
      rgba(255, 255, 255, 0.03) 76%,
      transparent 100%),
    linear-gradient(155deg, #1a1509 0%, #0d0a06 58%, #080705 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 0 40px rgba(245, 166, 35, 0.07),
    0 34px 70px rgba(0, 0, 0, 0.58);
}

/* ── A TEXTURA É O GRÃO DA CHAPA, LADRILHADO ──────────────────────
   Tentei usar a antepara do pré-carregamento como textura destas
   folhas. Não funciona, e o motivo não é de ajuste: aquela foto tem
   COMPOSIÇÃO — uma escotilha no meio, chapas perfuradas nas pontas,
   chanfros diagonais grandes. Recortada atrás de um card de outra
   forma, esses traços terminam de estalo na borda do card e leem como
   defeito de renderização, não como material. Duas rodadas de
   reposicionamento e opacidade só mudaram ONDE o corte incomodava.

   Textura de fundo precisa ser indiferente ao enquadramento — ladrilho
   ou gradiente. A foto continua onde ela é a peça inteira e o
   enquadramento é dela: a eclusa da saída.

   A saída foi EXTRAIR o grão daquela mesma foto em vez de recortá-la.
   Um script varreu a imagem atrás do retalho mais liso que ainda tem
   grão — fora da escotilha, fora da chapa perfurada, e julgado pelo
   PICO de contraste local, não pela média: bastava um rebite ou uma
   aresta entrar no retalho para ele voltar a ter assunto. O escolhido
   saiu em 1048,752, com pico de 9 níveis.

   Desse retalho sobra só a alta frequência (o degrade grande é
   subtraído, senão o ladrilho mostraria faixas), com ganho de 2,6x
   porque o grão original é sutil demais para sobreviver a uma camada
   translúcida. Fica costurado por espelhamento nas duas direções, o
   que garante ladrilho sem emenda: 20KB de PNG cinza.

   Agora é textura de verdade — indiferente ao enquadramento. Pode ser
   cortada em qualquer tamanho de card que não aparece corte nenhum,
   que era exatamente o que faltava na tentativa anterior.

   Junto ficam as linhas finíssimas que já existiam. A regra vale para
   as DUAS folhas — a da direita não é .login-card e não herdaria a do
   auth-ui.css. */
.placa::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background-image:
    url("../assets/chapa-grao.png"),
    repeating-linear-gradient(
      0deg,
      rgba(255, 255, 255, 0.022) 0 1px,
      transparent 1px 3px
    );
  /* Esticado na horizontal: ruído isotrópico lê como grão de filme, e
     grão de filme não é metal. A mesma amostra achatada a 320x180 ganha
     direção — e direção é o que faz uma superfície parecer escovada. */
  background-size: 320px 180px, auto;
  background-repeat: repeat, repeat;
  /* SEM mix-blend-mode. O grao agora e alfa — pontos de luz sobre
     transparente — e nao cinza medio. `overlay` sobre um fundo quase
     preto multiplica tudo por um número minúsculo e a textura
     simplesmente não aparecia; com alfa ela existe sobre qualquer
     fundo, sem depender do que está embaixo. */
  /* 0,85 virava lixa: a chapa perdia o preto e lia como concreto. A
     28% o grao aparece quando se olha e some quando nao se olha, que e
     o unico lugar onde textura de fundo deve ficar. */
  opacity: 0.28;
}

/* ── A junta ──
   Fechado, o encontro das duas metades é uma linha só: a esquerda não
   tem borda direita, a direita não tem borda esquerda, e os cantos
   internos são retos. É isso que faz ler como UMA peça partida, e não
   como dois cards lado a lado. */
/* O GONZO FICA NA BORDA DE FORA, como em porta de verdade. Girando ali,
   a borda de dentro recua para o fundo da cena e o vao aparece no meio
   — sem ninguem deslizar para lado nenhum. Era o que faltava para as
   folhas lerem como objeto e nao como dois retangulos se afastando.

   A folha escurece conforme vira: superficie que se afasta da luz
   recebe menos luz. Sem isso a rotacao fica plana mesmo em 3D. */
.placa-esq {
  border-radius: 16px 0 0 16px;
  border-right-color: transparent;
  transform-origin: left center;
  transform: rotateY(var(--gonzo, 0deg));
  filter: brightness(var(--luz-folha, 1));
}

.placa-dir {
  border-radius: 0 16px 16px 0;
  border-left-color: transparent;
  transform-origin: right center;
  transform: rotateY(calc(var(--gonzo, 0deg) * -1));
  filter: brightness(var(--luz-folha, 1));
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 3vh, 26px);
  padding: clamp(24px, 4vh, 44px) clamp(18px, 2.2vw, 28px);
  overflow: hidden;
}

/* ── 1.1 A CAMERA ENTRA NO HOLOGRAMA ────────────────────────────────
   Autorizado, as folhas NAO se mexem mais. Elas ficam onde estao e
   quem anda e o ponto de vista: a cena inteira cresce a partir do
   centro — que e exatamente onde o holograma esta — e as folhas saem
   de quadro por estarem nas beiradas, nao por terem deslizado.

   A curva acelera: comeca devagar e termina rapido, como quem mergulha.
   Desacelerar no fim daria a impressao de parar antes de chegar, e nao
   se chega a lugar nenhum — a pagina troca no meio do mergulho. */
/* Segundo ato: so o mergulho. As cores e a trava ja vieram do
   `aprovado`, que continua aplicado. */
.portao.liberado {
  animation: cameraEntra 760ms cubic-bezier(0.55, 0, 0.9, 0.85) forwards;
}

@keyframes cameraEntra {
  from { transform: scale(1);   opacity: 1; }
  60%  { opacity: 1; }
  to   { transform: scale(5.2); opacity: 0; }
}

.portao.aprovado .placa {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 0 60px rgba(0, 229, 160, 0.16),
    0 34px 70px rgba(0, 0, 0, 0.58);
}

/* O card do formulário É a metade esquerda, e a regra .placa-esq acima
   já traz o deslocamento. A inclinação pelo cursor sai nesta tela: o
   portão tem eixo próprio, e dois sistemas de rotação no mesmo elemento
   brigam pelo mesmo transform. */
.wrap-portao .login-card {
  --inc-x: 0deg;
  --inc-y: 0deg;
  --inc-z: 0px;
  --abre-x: 0px;
}

/* ── O ferrolho da junta ──
   Um trinco no meio da linha central, visível só com o portão fechado.
   É o detalhe que diz que aquilo abre.

   Mora no .portao, não numa das placas, por dois motivos: .login-card
   tem `overflow: hidden` e cortava o trinco fora da borda, e o ::after
   dele já é a textura de placa do auth-ui.css — usá-lo aqui apagaria a
   textura da metade esquerda. */
.portao::before {
  content: '';
  position: absolute;
  z-index: 3;
  top: 50%;
  left: 50%;
  width: 12px;
  height: 48px;
  margin: -24px 0 0 -6px;
  border-radius: 3px;
  background: linear-gradient(90deg, #322a18, #17120a 60%, #221c10);
  border: 1px solid rgba(245, 166, 35, 0.45);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 2px 10px rgba(0, 0, 0, 0.6);
  pointer-events: none;
  transition: opacity 240ms var(--ease-mec, ease), transform 300ms var(--ease-mec, ease);
}

/* Abrindo, o trinco recolhe antes das folhas se moverem — é ele que
   estava segurando. */
.portao.validando::before,
.portao.negado::before,
.portao.retomando::before,
.portao.aprovado::before,
.portao.liberado::before {
  opacity: 0;
  transform: scaleY(0.2);
}


/* ════════════════════════════════════════════════════════════════
   2. A MARCA CRAVADA

   Gravada no ferro, não colada por cima: dessaturada, escurecida, e com
   uma linha de luz de 1px caindo por baixo do contorno. É assim que uma
   superfície rebaixada se comporta quando a luz vem de cima — a aresta
   de baixo acende, a de cima fica na sombra.
   ════════════════════════════════════════════════════════════════ */

.marca-cravada {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(8px, 1.6vh, 15px);
  filter:
    grayscale(1)
    brightness(0.62)
    contrast(1.15)
    drop-shadow(0 1px 0 rgba(255, 228, 176, 0.22))
    drop-shadow(0 -1px 0 rgba(0, 0, 0, 0.85));
  opacity: 0.92;
}

/* O portão liberado acende a marca: o ferro deixa de ser só ferro no
   único instante em que houve veredito. */
.portao.aprovado .marca-cravada {
  filter:
    grayscale(0.3)
    brightness(1)
    drop-shadow(0 0 18px rgba(0, 229, 160, 0.32));
  opacity: 1;
  transition: filter 620ms var(--ease-saida, ease), opacity 620ms;
}

/* Cada peca e uma JANELA sobre o mesmo arquivo. A conta: para exibir a
   aguia com largura --w, a imagem inteira precisa ser escalada por
   --w/802 (a largura da aguia no original), e a posicao recuada na
   mesma proporcao. Trocar a arte depois muda so estes seis numeros. */
.marca-aguia,
.marca-letreiro {
  display: block;
  background-image: url("../assets/logo-harpiontech.webp");
  background-repeat: no-repeat;
}

/* aguia: x 85..887, y 162..599 do original de 1672x941 */
/* A AGUIA OCUPA A PLACA. A folha tem 380px e o respiro interno varia
   entre 20 e 32px de cada lado, entao a faixa util e de 316 a 333px.
   A marca TRANSBORDA o respiro de proposito: com 352px numa folha de
   380 as pontas das asas param a 14px da borda — quase encostando, que
   foi o pedido. Como a folha tem overflow oculto e 352 < 380, nada e
   cortado; o que sobra invade so o respiro lateral, e respiro existe
   para o texto, nao para a marca.

   Valor fixo, e nao em vw: a folha tambem e fixa, e amarrar a marca a
   largura da JANELA a faria encolher numa peca que nao encolheu. */
.marca-aguia {
  --w: 352px;
  width: var(--w);
  height: calc(var(--w) * 437 / 802);
  background-size: calc(var(--w) * 1672 / 802) auto;
  background-position: calc(var(--w) * -85 / 802) calc(var(--w) * -162 / 802);
}

/* letreiro: x 887..1590, y 166..419 */
.marca-letreiro {
  --w: clamp(148px, 19vw, 212px);
  width: var(--w);
  height: calc(var(--w) * 253 / 703);
  background-size: calc(var(--w) * 1672 / 703) auto;
  background-position: calc(var(--w) * -887 / 703) calc(var(--w) * -166 / 703);
}

.contato-cravado {
  text-align: center;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--text-dim, #A89B82);
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.7);
}

.contato-cravado span { display: block; }

.contato-cravado a {
  color: var(--accent, #F5A623);
  text-decoration: none;
  font-weight: 600;
  display: inline-block;
}


/* ════════════════════════════════════════════════════════════════
   3. O HOLOGRAMA — atrás das placas, revelado pelo vão

   z-index 1 contra 2 das placas: fechado ele existe e está escondido;
   abrindo, aparece porque o ferro saiu da frente. Nada de opacidade
   fingindo revelação — o que revela é a geometria.
   ════════════════════════════════════════════════════════════════ */

.holo {
  position: absolute;
  z-index: 1;
  top: 6%;
  bottom: 6%;
  left: 50%;
  width: 150px;
  margin-left: -75px;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.88);
  transition:
    opacity 420ms var(--ease-saida, ease),
    transform 540ms var(--ease-saida, ease);
}

.portao.validando .holo,
.portao.negado .holo,
.portao.retomando .holo,
.portao.aprovado .holo,
.portao.liberado .holo {
  opacity: 1;
  transform: scale(1);
}

.holo-eixo {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    transparent,
    color-mix(in srgb, var(--holo) 12%, transparent) 34%,
    color-mix(in srgb, var(--holo) 12%, transparent) 66%,
    transparent);
  transition: background 420ms var(--ease-mec, ease);
}

.holo-eixo::before {
  content: '';
  position: absolute;
  left: calc(50% - 1px);
  top: 0;
  width: 2px;
  height: 100%;
  background: linear-gradient(transparent,
    var(--holo) 16%, var(--holo-forte) 50%, var(--holo) 84%, transparent);
  box-shadow: 0 0 16px var(--holo-brilho);
  /* O FEIXE ABRE PARA O MECANISMO. Antes ele atravessava o cadeado de
     ponta a ponta e o desenho aparecia riscado no meio — o Victor viu.
     A mascara corta um vao no centro, do tamanho do aro externo, e o
     fio volta a existir logo abaixo. Um feixe interrompido pela peca
     que ele atravessa e o que faz a peca parecer estar DENTRO dele. */
  -webkit-mask-image: linear-gradient(to bottom,
    #000 0 36%, transparent 40% 60%, #000 64% 100%);
          mask-image: linear-gradient(to bottom,
    #000 0 36%, transparent 40% 60%, #000 64% 100%);
  transition: background 420ms var(--ease-mec, ease), box-shadow 420ms;
}

.holo-base {
  position: absolute;
  left: 50%;
  width: 108px;
  height: 27px;
  margin-left: -54px;
  border: 1px solid var(--holo);
  border-radius: 50%;
  opacity: 0.7;
  box-shadow: 0 0 20px var(--holo-brilho), inset 0 0 18px var(--holo-brilho);
  transition: border-color 420ms var(--ease-mec, ease), box-shadow 420ms;
}

.holo-base::after {
  content: '';
  position: absolute;
  inset: 7px 23px;
  border: 1px solid var(--holo-forte);
  border-radius: 50%;
  opacity: 0.75;
}

.holo-base.topo { top: 0; }
.holo-base.pe   { bottom: 0; }

/* O halo no pé da coluna: a luz batendo no chão. */
.holo-base.pe::before {
  content: '';
  position: absolute;
  left: -40px;
  right: -40px;
  top: -26px;
  height: 76px;
  background: radial-gradient(ellipse, var(--holo-brilho), transparent 66%);
  opacity: 0.5;
}

/* ── O TUBO DE PARTICULAS ─────────────────────────────────────────
   O holograma era uma coluna lisa com um fio no meio. A referencia
   mostra um TUBO: um volume feito de pontos subindo.

   Tres camadas de pontos, cada uma com tamanho, espacamento e
   velocidade proprios — e a diferenca entre elas que produz
   profundidade, porque as de tras sobem mais devagar. Cada camada e um
   radial-gradient repetido: um campo de pontos inteiro num elemento so,
   deslocado por transform, que e composited e nao repinta.

   A CURVATURA vem da mascara horizontal: denso nas bordas, ralo no
   meio. E assim que a superficie de um cilindro se distribui vista de
   frente, e e o que separa um tubo de um retangulo com pontinhos. */
.holo-tubo {
  position: absolute;
  inset: 3% 0;
  overflow: hidden;
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 14%, rgba(0,0,0,0.3) 50%, #000 86%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 12%, #000 88%, transparent 100%);
          mask-image:
    linear-gradient(90deg, transparent 0, #000 14%, rgba(0,0,0,0.3) 50%, #000 86%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 12%, #000 88%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}

.holo-tubo i {
  position: absolute;
  left: 0;
  right: 0;
  top: -100%;
  height: 300%;
  background-repeat: repeat;
  will-change: transform;
}

.holo-tubo .p1 {
  background-image: radial-gradient(circle, var(--holo-forte) 0 1.1px, transparent 1.6px);
  background-size: 19px 26px;
  opacity: 0.85;
  animation: particulasSobem 7s linear infinite;
}

.holo-tubo .p2 {
  background-image: radial-gradient(circle, var(--holo) 0 0.9px, transparent 1.4px);
  background-size: 13px 19px;
  opacity: 0.55;
  animation: particulasSobem 11s linear infinite;
}

.holo-tubo .p3 {
  background-image: radial-gradient(circle, var(--holo) 0 0.6px, transparent 1.1px);
  background-size: 9px 13px;
  opacity: 0.32;
  animation: particulasSobem 17s linear infinite;
}

/* O passo e multiplo do ladrilho de cada camada, entao a volta e
   invisivel: o campo de pontos e o mesmo no fim e no comeco. */
@keyframes particulasSobem {
  from { transform: translateY(0); }
  to   { transform: translateY(-104px); }
}

.holo-mecanismo {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100px;
  height: 100px;
  margin: -50px 0 0 -50px;
  display: grid;
  place-items: center;
}

.holo-orbe {
  position: absolute;
  inset: 12px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 44%, var(--holo-brilho), transparent 68%);
  transition: background 420ms var(--ease-mec, ease);
}

.holo-aro {
  position: absolute;
  border: 1px solid var(--holo);
  border-radius: 50%;
  opacity: 0.68;
  transition: border-color 420ms var(--ease-mec, ease);
}

.holo-aro-1 { inset: 0; }
.holo-aro-2 { inset: 15px; border-style: dashed; }

/* Os aros só giram enquanto há pergunta em curso. Parados nos outros
   estados: giro sem espera do outro lado é ruído. */
.portao.validando .holo-aro-1 { animation: aroGira 3.2s linear infinite; }
.portao.validando .holo-aro-2 { animation: aroGira 2.1s linear infinite reverse; }

@keyframes aroGira { to { transform: rotate(360deg); } }

.holo-trava {
  width: 40px;
  height: 44px;
  overflow: visible;
}

.holo-trava path,
.holo-trava rect,
.holo-trava circle {
  fill: none;
  stroke: var(--holo-forte);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 5px var(--holo-brilho));
  transition: stroke 420ms var(--ease-mec, ease), opacity 200ms;
}

.holo-trava .arco {
  transform-origin: 26px 19px;
  transition: transform 520ms cubic-bezier(0.16, 1, 0.3, 1);
}

.holo-trava .holo-check {
  opacity: 0;
  stroke-width: 2.6;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

/* Liberado: a trava abre, o cadeado some e o visto é DESENHADO no lugar
   dele. O traço se escreve, não aparece pronto — mesma gramática do
   selo da tela de confirmação. */
.portao.aprovado .holo-trava .arco { transform: rotate(-28deg) translateY(-2px); }

.portao.aprovado .holo-trava .arco,
.portao.aprovado .holo-trava rect,
.portao.aprovado .holo-trava circle,
.portao.aprovado .holo-trava path:not(.holo-check) {
  opacity: 0;
  transition-delay: 300ms;
}

.portao.aprovado .holo-trava .holo-check {
  opacity: 1;
  stroke-dashoffset: 0;
  transition:
    opacity 120ms linear 380ms,
    stroke-dashoffset 420ms var(--ease-saida, ease) 380ms;
}

/* O clarão do veredito. Um só, nunca repetido. */
.holo-pulso {
  position: absolute;
  inset: 44px;
  border: 1px solid var(--holo);
  border-radius: 50%;
  opacity: 0;
}

.portao.aprovado .holo-pulso,
.portao.negado .holo-pulso {
  animation: pulsoHolo 820ms var(--ease-saida, ease) both;
}

@keyframes pulsoHolo {
  from { transform: scale(1); opacity: 0.85; }
  to   { transform: scale(9); opacity: 0; }
}

/* A varredura sobe pela coluna só enquanto o servidor não respondeu. */
.holo-varredura {
  position: absolute;
  left: 50%;
  width: 96px;
  margin-left: -48px;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--holo-forte), transparent);
  box-shadow: 0 0 12px var(--holo-brilho);
  opacity: 0;
}

.portao.validando .holo-varredura {
  animation: varreColuna 1.5s var(--ease-mec, ease) infinite;
}

@keyframes varreColuna {
  0%   { top: 92%; opacity: 0; }
  12%  { opacity: 0.9; }
  84%  { opacity: 0.9; }
  100% { top: 2%;  opacity: 0; }
}


/* ════════════════════════════════════════════════════════════════
   4. TELAS ESTREITAS

   Duas metades lado a lado precisam de 760px só para ficarem fechadas.
   Abaixo disso o portão vira empilhado: a marca em cima, o formulário
   embaixo, sem abertura e sem holograma. É a mesma disposição que o
   login sempre teve no celular, e é a que já estava verificada.
   ════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  .wrap-portao {
    width: min(430px, calc(100vw - 32px));
    --gonzo: 0deg;
  }

  .portao {
    flex-direction: column;
    perspective: none;
  }

  .holo { display: none; }

  .placa {
    flex: 0 0 auto;
    max-width: none;
    transform: none;
    transition: none;
  }

  .placa-esq {
    order: 2;
    border-radius: 16px;
    border-right-color: rgba(245, 166, 35, 0.34);
  }

  /* Empilhada, a metade da marca vira o cabeçalho: sem moldura, sem
     fundo, só a marca sobre o fundo da página. Uma caixa de ferro em
     cima de outra lê como dois cards, não como um portão — e portão
     empilhado não existe mesmo. */
  .placa-dir {
    order: 1;
    border: none;
    box-shadow: none;
    background: none;
    padding: 0 0 clamp(10px, 2vh, 18px);
    gap: clamp(8px, 1.6vh, 14px);
  }

  .portao::before { display: none; }

  .marca-cravada {
    filter: none;
    opacity: 1;
  }

  .marca-aguia    { --w: min(78vw, 300px); }
  .marca-letreiro { --w: min(48vw, 188px); }

  /* ── AO ENTRAR, SO O CADEADO ──────────────────────────────────────
     No desktop o veredito aparece no vao entre as folhas. No celular
     nao ha vao: as metades estao empilhadas. Entao a tela faz o que
     cabe numa coluna so — o formulario apaga e o mecanismo ocupa o
     lugar dele.

     Os campos APAGAM, nao somem: `opacity` preserva a altura, e o card
     nao encolhe e cresce de volta no meio da espera. A mensagem de erro
     fica, porque e ela que diz o que houve. */
  .portao.validando #loginForm > *,
  .portao.aprovado  #loginForm > *,
  .portao.liberado  #loginForm > *,
  .portao.negado    #loginForm > *:not(.error-msg),
  .portao.retomando #loginForm > *:not(.error-msg) {
    opacity: 0;
    pointer-events: none;
    transition: opacity 260ms var(--ease-mec, ease);
  }

  /* De volta a digitar: os campos reaparecem e o cadeado sai. */
  .portao.retomando #loginForm > *:not(.error-msg) {
    opacity: 1;
    pointer-events: auto;
  }

  .portao.validando .holo,
  .portao.negado .holo,
  .portao.aprovado .holo,
  .portao.liberado .holo {
    display: block;
    position: absolute;
    inset: 0;
    width: auto;
    margin: 0;
    z-index: 5;
  }

  /* Do holograma sobra so o mecanismo: tubo, feixe e discos precisam de
     uma coluna alta que aqui nao existe. */
  .portao .holo-tubo,
  .portao .holo-eixo,
  .portao .holo-base,
  .portao .holo-varredura {
    display: none;
  }

  /* 66% da altura do portao cai dentro do formulario — a metade da
     marca ocupa o terco de cima. */
  .portao .holo-mecanismo {
    top: 66%;
  }
}


/* ════════════════════════════════════════════════════════════════
   5. MOVIMENTO REDUZIDO

   O portão continua abrindo — a abertura É a informação de que o
   sistema respondeu, e a cor do holograma é o veredito. O que sai é o
   que gira, pulsa e varre sozinho.
   ════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .placa,
  .holo {
    transition-duration: 1ms;
  }

  .portao.validando .holo-aro-1,
  .portao.validando .holo-aro-2,
  .portao.validando .holo-varredura,
  .portao.aprovado .holo-pulso,
  .portao.negado .holo-pulso {
    animation: none;
  }

  .portao.liberado { animation: none; opacity: 0; }
}
