/* ══════════════════════════════════════════════════════════════════
   O PORTÃO — a folha de estilo da fenda

   O card antigo era um retângulo com o ícone da dungeon dentro. Aqui
   não existe moldura em volta do portal: ele flutua no escuro da
   página, e a única coisa com borda é a lápide de vidro embaixo.
   Enquadrar a fenda num retângulo arredondado era o que a matava.

   SOBRE O CUSTO. Dez dungeons são dez portais respirando ao mesmo
   tempo, e brilho é caro. Três decisões seguram isso:

     · OS FILTROS SÃO UM SÓ. `#ptNeon` e `#ptNeonLargo` vivem num SVG
       oculto no documento e são referenciados por todos os portões. Um
       filtro por portão multiplicaria o trabalho do compositor por dez
       sem mudar um pixel.
     · SÓ QUEM ESTÁ NA TELA SE MEXE. O JS põe `.pt-vivo` via
       IntersectionObserver; sem essa classe, nenhuma animação roda.
     · `transform` e `opacity` APENAS. Nada que force layout.

   E quem pediu menos movimento fica com o portão inteiro, parado.
   ══════════════════════════════════════════════════════════════════ */

/* ── A GRADE ─────────────────────────────────────────────────────── */
.pt-grade {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(248px, 1fr));
  gap: 1.6rem 1.1rem;
  align-items: start;
}

/* ── O PORTÃO ────────────────────────────────────────────────────── */
.pt {
  --pt-nuc: #63b3ff;
  --pt-fra: #7a6cff;
  position: relative;
  display: flex; flex-direction: column;
  /* SEM moldura, SEM fundo. O portal é a peça; o resto é o escuro. */
  background: none;
  border: none;
  padding: 0;
  animation: pt-chega .5s cubic-bezier(.2, .9, .3, 1.05) backwards;
  animation-delay: calc(var(--i, 0) * 70ms);
}
@keyframes pt-chega {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.pt-fenda {
  position: relative;
  line-height: 0;
  /* a aura sangra para fora do quadro do SVG */
  margin: 0 -6px -2px;
}
.pt-svg { display: block; width: 100%; height: auto; overflow: visible; }

/* ── A RESPIRAÇÃO ────────────────────────────────────────────────── */
/* Só com `.pt-vivo`: fora da tela, o portal é um desenho parado. */
.pt-vivo .pt-bafo { animation: pt-respira 5.5s ease-in-out infinite; transform-origin: 50% 78%; }
.pt-vivo .pt-halo { animation: pt-respira 4.2s ease-in-out infinite reverse; transform-origin: 50% 78%; }
.pt-vivo .pt-iris { animation: pt-pulso 3.1s ease-in-out infinite; transform-origin: 50% 50%; }
.pt-vivo .pt-poca { animation: pt-pulso 5.5s ease-in-out infinite; transform-origin: 50% 50%; }
.pt-vivo .pt-greta { animation: pt-cintila 2.4s ease-in-out infinite; }

@keyframes pt-respira {
  0%, 100% { opacity: .82; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.05); }
}
@keyframes pt-pulso {
  0%, 100% { opacity: .78; transform: scale(.97); }
  50%      { opacity: 1;   transform: scale(1.06); }
}
@keyframes pt-cintila {
  0%, 100% { opacity: .55; }
  50%      { opacity: 1; }
}

/* AS BRASAS sobem da greta e esfriam no caminho. Cada uma tem a sua
   duração e o seu atraso negativo, postos pelo JS — sem isso as vinte e
   seis subiriam em formação, que é o contrário de brasa. */
.pt-vivo .pt-brasa {
  animation: pt-sobe var(--d, 5s) linear infinite;
  animation-delay: var(--a, 0s);
}
@keyframes pt-sobe {
  0%   { transform: translateY(14px); opacity: 0; }
  14%  { opacity: 1; }
  78%  { opacity: .55; }
  100% { transform: translateY(-58px); opacity: 0; }
}

/* AS LASCAS giram devagar, cada uma no seu tempo. A rotação é em torno
   do próprio centro — por isso o `transform-box: fill-box`, senão ela
   giraria em volta da origem do SVG e atravessaria a tela. */
.pt-vivo .pt-lasca {
  transform-box: fill-box;
  transform-origin: center;
  animation: pt-flutua var(--d, 20s) linear infinite;
  animation-delay: var(--a, 0s);
}
@keyframes pt-flutua {
  0%   { rotate: 0deg;   translate: 0 0; }
  50%  { rotate: 180deg; translate: 0 -7px; }
  100% { rotate: 360deg; translate: 0 0; }
}

/* O ARO: o miolo branco escorre devagar pelo trecho aceso, como carga
   percorrendo um tubo. O comprimento do traço não muda — quem manda
   nele é o `stroke-dasharray` inline, que é o prazo. */
.pt-vivo .pt-aro-miolo { animation: pt-corrente 3.4s linear infinite; }
@keyframes pt-corrente {
  from { stroke-dashoffset: 0; }
  to   { stroke-dashoffset: -22; }
}
.pt-vivo .pt-aro-bafo { animation: pt-cintila 3.8s ease-in-out infinite; }

/* ── O SELO DE ESTADO ────────────────────────────────────────────── */
.pt-selo {
  --sc: #5cf2a0;
  position: absolute; left: 50%; bottom: 15%;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: .3rem .85rem;
  font-family: var(--font-section, inherit);
  font-size: .58rem; font-weight: 700; letter-spacing: .16em;
  line-height: 1.1;
  color: var(--sc);
  background: rgba(5, 5, 12, .62);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  border: 1px solid color-mix(in srgb, var(--sc) 70%, transparent);
  /* cantos chanfrados: nada de raio no mundo do Sistema */
  clip-path: polygon(7px 0, 100% 0, calc(100% - 7px) 100%, 0 100%);
  box-shadow: 0 0 18px color-mix(in srgb, var(--sc) 30%, transparent);
  text-shadow: 0 0 10px color-mix(in srgb, var(--sc) 55%, transparent);
}

/* ── A LÁPIDE DE VIDRO ───────────────────────────────────────────── */
.pt-lapide {
  position: relative;
  padding: .75rem .85rem .8rem;
  /* A luz do portal entra por cima e morre em metade da altura. Descendo
     até o fim, a lápide inteira ficava cor de barro — vidro sujo, não
     vidro iluminado. */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--pt-nuc) 16%, transparent) 0%,
      color-mix(in srgb, var(--pt-nuc) 5%, transparent) 18%,
      rgba(11, 11, 22, .88) 46%,
      rgba(6, 6, 14, .95) 100%);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
  border: 1px solid color-mix(in srgb, var(--pt-nuc) 34%, transparent);
  clip-path: polygon(15px 0, 100% 0, 100% calc(100% - 15px),
                     calc(100% - 15px) 100%, 0 100%, 0 15px);
}
/* o chanfro aceso — é ele que dá leitura de vidro, mais que o desfoque */
.pt-lapide::before {
  content: ''; position: absolute; left: -1px; top: 15px;
  width: 22px; height: 2.4px;
  background: var(--pt-nuc);
  transform: rotate(-45deg); transform-origin: left center;
  box-shadow: 0 0 12px var(--pt-nuc), 0 0 4px #fff;
}
/* o fio de luz no topo */
.pt-lapide::after {
  content: ''; position: absolute; left: 15px; right: 0; top: 0;
  height: 1px; background: rgba(255, 255, 255, .13);
}

.pt-titulo {
  margin: 0; font-size: 1.02rem; font-weight: 700;
  color: #fff; line-height: 1.2;
  overflow-wrap: anywhere;
}
.pt-sub {
  margin: .2rem 0 0; font-size: .68rem;
  color: #8286a0; text-transform: capitalize;
}
.pt-inf { color: var(--pt-nuc); text-transform: none; }

.pt-prazo {
  margin: .55rem 0 0;
  font-size: .68rem; font-weight: 600; letter-spacing: .02em;
  color: var(--pt-nuc);
  text-shadow: 0 0 12px color-mix(in srgb, var(--pt-nuc) 35%, transparent);
}
.pt-m-selado .pt-prazo, .pt-m-perdido .pt-prazo { text-shadow: none; }

/* ── O RODAPÉ DA LÁPIDE ──────────────────────────────────────────
   AS FERRAMENTAS MORAVAM SOBRE O TÍTULO, em `position:absolute` no
   canto. Funcionava com "Estúdio" e quebrava com "Libanus Restaurante":
   o nome passava por baixo dos botões e os dois viravam um borrão.
   Nenhum `padding-right` resolve isso, porque o número de botões muda
   (o Arquiteto vê cinco) e o nome é do hunter.

   Agora elas têm linha própria, no pé da lápide, longe do nome e longe
   do botão de atravessar. Sem sobreposição possível e sem salto de
   layout quando aparecem. */
.pt-rodape {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: .5rem; margin-top: .5rem;
}
.pt-selos { display: flex; flex-wrap: wrap; gap: .3rem; flex: 1; min-width: 0; }
.pt-selo-min {
  font-size: .6rem; color: #aab0c4;
  padding: .17rem .45rem;
  background: color-mix(in srgb, var(--pt-nuc) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--pt-nuc) 28%, transparent);
  clip-path: polygon(4px 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
}

/* ── AS FERRAMENTAS ──────────────────────────────────────────────── */
/* Quietas até a mão chegar perto — mas SEMPRE ocupando o espaço delas.
   Aparecer via `opacity`, e não via `display`, é o que evita o salto de
   layout: a lápide tem a mesma altura com e sem o cursor em cima. */
.pt-ferramentas {
  display: flex; gap: .15rem; flex: 0 0 auto;
  opacity: .28; transition: opacity .2s ease;
}
.pt:hover .pt-ferramentas,
.pt:focus-within .pt-ferramentas { opacity: 1; }
@media (hover: none) { .pt-ferramentas { opacity: .75; } }

.pt-fer {
  width: 24px; height: 24px; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .1);
  color: #8286a0;
  transition: all .15s ease;
}
.pt-fer svg { display: block; }
.pt-fer:hover {
  color: #fff;
  border-color: color-mix(in srgb, var(--pt-nuc) 55%, transparent);
  background: color-mix(in srgb, var(--pt-nuc) 18%, transparent);
}
.pt-fer.perigo:hover { color: #ff4d6a; border-color: rgba(255, 77, 106, .5); background: rgba(255, 77, 106, .12); }

/* ── A AÇÃO ──────────────────────────────────────────────────────── */
.pt-acao {
  position: relative;
  margin-top: .5rem;
  padding: .62rem .8rem;
  font-family: var(--font-section, inherit);
  font-size: .74rem; font-weight: 800; letter-spacing: .13em;
  color: #0a0a12; cursor: pointer;
  border: none;
  background: linear-gradient(135deg, var(--pt-nuc), var(--pt-fra));
  clip-path: polygon(10px 0, 100% 0, calc(100% - 10px) 100%, 0 100%);
  box-shadow: 0 0 22px color-mix(in srgb, var(--pt-fra) 40%, transparent);
  transition: filter .16s ease, box-shadow .2s ease, transform .1s ease;
}
.pt-acao::before {
  content: ''; position: absolute; left: 10px; right: 0; top: 0;
  height: 1.2px; background: rgba(255, 255, 255, .4);
}
.pt-acao:hover:not(:disabled) {
  filter: brightness(1.14);
  box-shadow: 0 0 34px color-mix(in srgb, var(--pt-fra) 60%, transparent);
}
.pt-acao:active:not(:disabled) { transform: translateY(1px); }
.pt-acao:disabled {
  cursor: not-allowed;
  color: #63637a;
  background: rgba(255, 255, 255, .035);
  border: 1px solid color-mix(in srgb, var(--pt-nuc) 22%, transparent);
  box-shadow: none;
}
.pt-acao:disabled::before { display: none; }

/* ══════════════════════════════════════════════════════════════════
   O HOVER — o portão percebe a mão

   A ideia inteira está numa coisa: UMA LUZ DÁ A VOLTA NO ARO. Um traço
   curto e branco correndo o contorno todo, de baixo a baixo.

   Ele é curto de propósito. O prazo também vive no aro, mas é um arco
   LONGO e PARADO; se o hover usasse a mesma linguagem, o hunter leria
   "o tempo pulou" toda vez que passasse o mouse. Curto e em movimento
   não se confunde com comprido e imóvel.

   O resto acompanha em volume, sem inventar gesto novo: a fenda inspira,
   a aura incha, a íris acende, as brasas sobem mais rápido e a lápide
   clareia. Portão morto não reage — pedra não percebe ninguém.
   ══════════════════════════════════════════════════════════════════ */
.pt-lampejo {
  opacity: 0;
  stroke-dashoffset: 0;
  pointer-events: none;
}
.pt:hover .pt-lampejo,
.pt:focus-within .pt-lampejo {
  opacity: .95;
  animation: pt-volta 1.15s cubic-bezier(.45, 0, .25, 1) infinite;
}
.pt:hover .pt-lampejo-cor,
.pt:focus-within .pt-lampejo-cor { opacity: .5; }
@keyframes pt-volta {
  from { stroke-dashoffset: calc(var(--larc, 700) * 1px); }
  to   { stroke-dashoffset: 0; }
}

/* A FENDA INSPIRA. Escala mínima e de propósito: o portal é feito de
   luz difusa, e crescer demais o transformaria num cartaz. */
.pt-fenda {
  transition: transform .35s cubic-bezier(.2, .9, .3, 1.1),
              filter .35s ease;
}
.pt:hover .pt-fenda { transform: scale(1.035) translateY(-3px); }
.pt-m-selado:hover .pt-fenda,
.pt-m-perdido:hover .pt-fenda { transform: none; }

/* A aura incha e a íris acende — mais volume, mesmo gesto. */
.pt:hover .pt-bafo { animation-duration: 3.4s; opacity: 1; }
.pt:hover .pt-halo { animation-duration: 2.8s; }
.pt:hover .pt-iris { animation-duration: 1.7s; }
.pt:hover .pt-brasa { animation-duration: calc(var(--d, 5s) * .6); }
.pt:hover .pt-greta { animation-duration: 1.2s; }

/* A lápide clareia e o botão puxa a atenção. */
.pt-lapide { transition: border-color .3s ease, box-shadow .3s ease; }
.pt:hover .pt-lapide {
  border-color: color-mix(in srgb, var(--pt-nuc) 62%, transparent);
  box-shadow: 0 0 26px color-mix(in srgb, var(--pt-fra) 18%, transparent);
}
.pt:hover .pt-acao:not(:disabled) {
  filter: brightness(1.1);
  box-shadow: 0 0 30px color-mix(in srgb, var(--pt-fra) 52%, transparent);
}

/* ══════════════════════════════════════════════════════════════════
   A TRAVESSIA — o portal SE ABRE

   A VERSÃO ANTERIOR CLONAVA A FENDA DA GRADE E DAVA `scale()` NELA.
   O Arquiteto: "não está simétrica, ela simplesmente dá um zoom no
   portal, fica feio, soa mal feito". Os dois defeitos eram estruturais:

     · a âncora era a base do portão CLICADO, em qualquer canto da
       tela. Crescer a partir dali é assimétrico por construção —
       nenhum easing conserta um ponto de fuga fora do centro;
     · ampliar um desenho feito para 272px expõe tudo: traço grosso,
       brasas do tamanho de moedas, gradiente esticado. Zoom não
       esconde, zoom REVELA.

   Aqui não há ampliação de coisa nenhuma. Um portão NOVO é desenhado
   no centro, já no tamanho final, e ele SE ABRE. O palco é `grid` com
   `place-items:center`: o centro é o centro da tela, sem conta de
   pixel para errar.
   ══════════════════════════════════════════════════════════════════ */
#pt-travessia {
  position: fixed; inset: 0; z-index: 9000;
  pointer-events: none; overflow: hidden;
  display: grid; place-items: center;
  background: #05050b;
  opacity: 0;
}
#pt-travessia.on { animation: tv-veu .3s ease forwards; }
@keyframes tv-veu { to { opacity: 1; } }

.tv-palco {
  width: min(78vh, 78vw, 620px);
  aspect-ratio: 1;
  line-height: 0;
}
.tv-svg { width: 100%; height: 100%; overflow: visible; }

/* ── 1. A COSTURA ────────────────────────────────────────────────
   Um fio de luz rasga o centro, crescendo para CIMA E PARA BAIXO ao
   mesmo tempo. `transform-origin: center` no eixo Y é o que garante
   isso: um só elemento, dois sentidos, simetria sem esforço. */
.tv-costura {
  transform-box: fill-box; transform-origin: center;
  transform: scaleY(0); opacity: 0;
}
#pt-travessia.on .tv-costura {
  animation: tv-rasga .42s cubic-bezier(.25, .8, .3, 1) .06s forwards;
}
@keyframes tv-rasga {
  0%   { transform: scaleY(0)    scaleX(1); opacity: 0; }
  18%  { opacity: 1; }
  60%  { transform: scaleY(1)    scaleX(1); opacity: 1; }
  100% { transform: scaleY(1)    scaleX(.3); opacity: 0; }
}

/* ── 2. O ARCO SE DESENHA ────────────────────────────────────────
   As duas metades partem da BASE e sobem juntas até o ápice. Mesmo
   `animation`, mesmo tempo, caminhos espelhados: a simetria é do
   desenho, não de ajuste. `pathLength="100"` no SVG normaliza os dois
   comprimentos — sem ele, uma metade chegaria ao topo antes da outra
   por diferença de arredondamento, e seria justamente o defeito que
   o Arquiteto apontou. */
.tv-metade {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  opacity: 0;
}
#pt-travessia.on .tv-metade {
  animation: tv-desenha .52s cubic-bezier(.3, .7, .25, 1) .30s forwards;
}
@keyframes tv-desenha {
  0%   { stroke-dashoffset: 100; opacity: 0; }
  10%  { opacity: 1; }
  100% { stroke-dashoffset: 0;   opacity: 1; }
}

/* A soleira: o chão do portal, que se abre do centro para os lados. */
.tv-soleira {
  transform-box: fill-box; transform-origin: center;
  transform: scaleX(0); opacity: 0;
}
#pt-travessia.on .tv-soleira {
  animation: tv-soleira .4s cubic-bezier(.25, .8, .3, 1) .26s forwards;
}
@keyframes tv-soleira {
  0%   { transform: scaleX(0); opacity: 0; }
  30%  { opacity: 1; }
  100% { transform: scaleX(1); opacity: .85; }
}

/* ── 3. O VAZIO SE ACENDE ────────────────────────────────────────
   De baixo para cima, de onde a luz nasce — o mesmo gradiente do
   portão da grade, para a travessia não apresentar outro portal. */
.tv-vazio, .tv-iris {
  transform-box: fill-box; transform-origin: 50% 100%;
  transform: scaleY(.05); opacity: 0;
}
#pt-travessia.on .tv-vazio {
  animation: tv-acende .55s cubic-bezier(.3, .8, .3, 1) .44s forwards;
}
#pt-travessia.on .tv-iris {
  animation: tv-acende .5s cubic-bezier(.3, .8, .3, 1) .58s forwards;
}
@keyframes tv-acende {
  0%   { transform: scaleY(.05); opacity: 0; }
  100% { transform: scaleY(1);   opacity: 1; }
}

/* ── 4. O PORTAL SE ABRE ─────────────────────────────────────────
   O arco se afasta e some. Escala pequena, de propósito: o que inunda
   a tela é a LUZ, não o desenho. Ampliar o arco até cobrir tudo seria
   voltar ao zoom que foi recusado. */
#pt-travessia.on .tv-palco {
  animation: tv-abre .42s cubic-bezier(.5, 0, .4, 1) .86s forwards;
}
@keyframes tv-abre {
  0%   { transform: scale(1);    opacity: 1; }
  100% { transform: scale(1.35); opacity: 0; }
}

/* A luz que inunda: um disco na cor do portão, do centro às bordas.
   `scale` de um círculo a partir do centro é simétrico por definição —
   é a mesma ideia da onda anterior, mas ancorada onde devia estar. */
.tv-inunda {
  position: absolute; left: 50%; top: 50%;
  width: 40vmax; height: 40vmax; margin: -20vmax 0 0 -20vmax;
  border-radius: 50%;
  background: radial-gradient(circle,
    #fff 0%,
    color-mix(in srgb, var(--pt-nuc) 88%, #fff) 22%,
    var(--pt-nuc) 46%,
    color-mix(in srgb, var(--pt-fra) 85%, transparent) 72%,
    transparent 100%);
  transform: scale(0); opacity: 0;
}
#pt-travessia.on .tv-inunda {
  animation: tv-inunda .58s cubic-bezier(.4, 0, .3, 1) .82s forwards;
}
@keyframes tv-inunda {
  0%   { transform: scale(0);   opacity: 0; }
  22%  { opacity: .95; }
  100% { transform: scale(4.2); opacity: 1; }
}

/* O clarão do instante de atravessar. */
.tv-clarao {
  position: absolute; inset: 0;
  background: #fff;
  opacity: 0;
}
#pt-travessia.on .tv-clarao {
  animation: tv-clarao .34s ease-out 1.02s forwards;
}
@keyframes tv-clarao {
  0%   { opacity: 0; }
  45%  { opacity: .88; }
  100% { opacity: 1; }
}

/* O portão de origem recua: sem isso ele continuaria visível atrás do
   véu por um instante, e a grade "piscaria" no meio da cerimônia. */
.pt-atravessando { opacity: 0; transition: opacity .22s ease; }

/* A VERSÃO SECA. Quem pediu menos movimento não pode ficar preso a um
   segundo e meio de cerimônia a cada entrada — leva o corte, só isso. */
#pt-travessia.seco {
  background: #05050b;
  opacity: 0; transition: opacity .12s linear;
}
#pt-travessia.seco.on { opacity: 1; }

/* ── QUEM PEDIU MENOS MOVIMENTO ──────────────────────────────────── */
/* Fica com o portão inteiro — aura, brasas, lascas e aro — parado. */
@media (prefers-reduced-motion: reduce) {
  .pt { animation: none; }
  .pt-vivo .pt-bafo, .pt-vivo .pt-halo, .pt-vivo .pt-iris,
  .pt-vivo .pt-poca, .pt-vivo .pt-greta, .pt-vivo .pt-brasa,
  .pt-vivo .pt-lasca, .pt-vivo .pt-aro-miolo, .pt-vivo .pt-aro-bafo {
    animation: none;
  }
  /* O hover e a travessia continuam EXISTINDO, sem o movimento: o
     lampejo vira um aro aceso parado, a fenda não escala e a entrada é
     um corte. Tirar o retorno visual junto com a animação deixaria a
     interface muda para quem já vê menos pistas. */
  .pt:hover .pt-lampejo,
  .pt:focus-within .pt-lampejo { animation: none; opacity: .5; stroke-dasharray: none; }
  .pt:hover .pt-fenda { transform: none; }
  #pt-travessia.on .tv-palco,
  #pt-travessia.on .tv-costura, #pt-travessia.on .tv-soleira,
  #pt-travessia.on .tv-metade,  #pt-travessia.on .tv-vazio,
  #pt-travessia.on .tv-iris,    #pt-travessia.on .tv-inunda,
  #pt-travessia.on .tv-clarao { animation: none; }
  #pt-travessia.on { animation: none; opacity: 1; }
}
