/* Arena do duelo — as animações do motor (wiki-duelo.js).
 *
 * CSS na mão e não Tailwind: estas classes entram por JS no meio da luta, e o
 * Tailwind aqui é o play CDN (só gera a regra quando VÊ a classe no DOM). Pra
 * animação que precisa valer no primeiro quadro isso é corrida perdida.
 *
 * O motor cuida da POSIÇÃO (transform no elemento do lutador, 60fps). Estas
 * regras cuidam do resto: golpe, apanhar, cair, entrar, comemorar. Por isso
 * elas mexem na SPRITE ou usam filter/opacity — nunca no transform do
 * lutador, que é do motor. Duas mãos no mesmo transform brigariam. */

/* Quem bate: dá um avanço rápido e volta. */
@keyframes dueloGolpe {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.22) translateY(-3px); }
  100% { transform: scale(1); }
}
.duelo-golpe { animation: dueloGolpe .26s ease-out; }
/* O `scaleX(-1)` de quem olha pra esquerda é inline; a animação acima
 * sobrescreveria e o bicho viraria no meio do golpe. Estas duas regras mantêm o
 * lado durante a pancada. */
[data-duelo-sprite][style*="scaleX(-1)"].duelo-golpe { animation-name: dueloGolpeEsq; }
@keyframes dueloGolpeEsq {
  0%   { transform: scaleX(-1) scale(1); }
  35%  { transform: scaleX(-1) scale(1.22) translateY(-3px); }
  100% { transform: scaleX(-1) scale(1); }
}

/* Quem apanha: pisca vermelho. `filter` não briga com o transform. */
@keyframes dueloApanha {
  0%, 100% { filter: none; }
  30%      { filter: brightness(1.9) saturate(2.2) drop-shadow(0 0 4px rgba(244,63,94,.9)); }
}
.duelo-apanha { animation: dueloApanha .26s ease-out; }

/* O número de dano subindo. */
@keyframes dueloDano {
  0%   { opacity: 0; transform: translateY(0) scale(.8); }
  20%  { opacity: 1; transform: translateY(-6px) scale(1.1); }
  100% { opacity: 0; transform: translateY(-24px) scale(1); }
}
.duelo-dano { animation: dueloDano .8s ease-out forwards; }

/*
 * CAIU: deita, embranquece e SOME — corpo e nome juntos.
 *
 * Pedido do dono: *"quando algum pokemon perder pode fazer o corpo e o nome
 * desaparecer com fade"*. Antes ficava um fantasma cinza a 28% de opacidade
 * ocupando a arena inteira ate o fim do duelo. O `opacity: 0` mantem o
 * elemento no lugar (o motor continua dono da posicao dele, sem `display`
 * mexido no meio da animacao) e o `pointer-events: none` garante que o corpo
 * invisivel nao intercepte clique.
 *
 * A queda vem primeiro e o fade depois, com atraso: a pessoa precisa VER quem
 * caiu antes de o corpo sumir.
 */
.duelo-caiu {
  opacity: 0;
  filter: grayscale(1);
  pointer-events: none;
  transition: opacity .8s ease-in .55s, filter .3s;
}
.duelo-caiu [data-duelo-sprite] {
  transform: rotate(75deg) scale(.85) !important;
  transition: transform .45s ease-in;
}

/*
 * ENTRADA: SO FADE.
 *
 * Tinha um pop de escala aqui (0 -> 1.25 -> 1) e era ele o "muda o tamanho" da
 * reclamacao: a sprite aparecia num tamanho e assentava em outro, entao a
 * entrada um-por-um nao dizia nada sobre a luta que vinha. Agora o tamanho da
 * entrada E o tamanho da luta; o brilho faz o papel do pop, sem mentir sobre o
 * tamanho nem sobre a posicao.
 *
 * Tambem nao ha `transform` em nenhum destes keyframes de proposito: quem manda
 * no transform da caixa e do sprite e o motor (posicao e o lado pra onde olha),
 * e uma animacao CSS de transform vence o style inline enquanto roda — era o
 * outro motivo do salto.
 */
@keyframes dueloEntra {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}
.duelo-entra { animation: dueloEntra .34s ease-out; }
@keyframes dueloEntraSprite {
  0%   { filter: brightness(3.2) drop-shadow(0 0 6px rgba(255,255,255,.9)); }
  100% { filter: none; }
}
.duelo-entra [data-duelo-sprite] { animation: dueloEntraSprite .5s ease-out; }

/* Desviou: pula pra tras e pisca. */
@keyframes dueloDesvia {
  0%, 100% { opacity: 1; }
  30%      { opacity: .25; }
  60%      { opacity: .8; }
}
.duelo-desvia { animation: dueloDesvia .38s ease-out; }

/* Golpe cheio: tremida mais forte e clarao. */
@keyframes dueloCritico {
  0%, 100% { filter: none; }
  20%      { filter: brightness(2.6) saturate(2); }
  50%      { filter: brightness(.4) saturate(.5); }
}
.duelo-critico { animation: dueloCritico .42s linear; }

/* Pocao: brilho verde subindo. */
@keyframes dueloCura {
  0%   { filter: none; }
  35%  { filter: brightness(1.5) drop-shadow(0 0 7px rgba(52,211,153,.95)); }
  100% { filter: none; }
}
.duelo-cura { animation: dueloCura .9s ease-out; }

/* Campeão: pulsa de leve, pra sobrar o olhar nele. */
@keyframes dueloCampeao {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(251,191,36,0)); }
  50%      { filter: drop-shadow(0 0 7px rgba(251,191,36,.95)); }
}
.duelo-campeao [data-duelo-sprite] { animation: dueloCampeao 1.1s ease-in-out infinite; }

/* A contagem regressiva. */
@keyframes dueloConta {
  0%   { transform: scale(.4); opacity: 0; }
  40%  { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.duelo-conta { animation: dueloConta .5s ease-out; }

@media (prefers-reduced-motion: reduce) {
  .duelo-golpe, .duelo-apanha, .duelo-entra, .duelo-entra [data-duelo-sprite],
  .duelo-campeao [data-duelo-sprite], .duelo-conta,
  .duelo-desvia, .duelo-critico, .duelo-cura { animation: none; }
  /* O fade da queda fica, so instantaneo: sem ele o corpo nunca sai da arena. */
  .duelo-caiu { transition: none; }
  .duelo-dano { animation: dueloDano .4s linear forwards; }
}

/*
 * O ITEM DE CURA NO CHAO.
 *
 * Ele cai, fica flutuando com uma sombrinha embaixo (pra parecer objeto no
 * chao e nao adesivo colado na tela) e some quando alguem pega. O flutuar
 * tambem serve de aviso: item parado no meio da briga passa desapercebido.
 */
@keyframes dueloItemCai {
  0%   { transform: translateY(-26px) scale(.6); opacity: 0; }
  60%  { transform: translateY(0) scale(1.15); opacity: 1; }
  100% { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes dueloItemFlutua {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}
.duelo-item {
  animation: dueloItemCai .42s ease-out, dueloItemFlutua 1.6s ease-in-out .42s infinite;
  filter: drop-shadow(0 3px 3px rgba(0, 0, 0, .45));
}
/* A sombra no chao, desenhada com ::after pra nao precisar de outro elemento. */
.duelo-item::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: -3px;
  width: 18px;
  height: 5px;
  margin-left: -9px;
  border-radius: 50%;
  background: rgba(0, 0, 0, .3);
}

/* Pegou: sobe, brilha e sai. */
@keyframes dueloItemPego {
  0%   { transform: translateY(0) scale(1); opacity: 1; }
  100% { transform: translateY(-22px) scale(1.5); opacity: 0; }
}
.duelo-item-pego {
  animation: dueloItemPego .4s ease-out forwards !important;
  filter: brightness(1.8) drop-shadow(0 0 8px rgba(52, 211, 153, .95));
}
.duelo-item-pego::after { display: none; }

@media (prefers-reduced-motion: reduce) {
  /* O item ainda aparece e ainda sai — so nao fica flutuando na tela. */
  .duelo-item { animation: none; }
  .duelo-item-pego { animation: dueloItemPego .25s linear forwards !important; }
}

/* =====================================================================
 * A CENA DA VITORIA
 *
 * Pedido do dono: *"no final quando ganhar faz uma transição mais legal do
 * pokemon vencedor"*. Antes o campeao so ganhava uma coroa e um brilho
 * piscando — o duelo acabava sem acabar.
 *
 * A cena tem cinco camadas, todas em CSS puro (o JS so posiciona o holofote e
 * liga as classes): vinheta escurecendo a arena, holofote atras do campeao,
 * raios girando, confete caindo e a faixa subindo. Nada disso usa `transform`
 * na CAIXA do lutador — quem manda no transform dela e o motor de animacao, e
 * uma keyframe competindo com ele faria a sprite saltar.
 * ===================================================================== */

/* O campeao sobe acima da vinheta: sem isto o holofote apagaria justamente
   quem ele ilumina. */
.duelo-campeao { z-index: 15; }

/* A vinheta entra devagar: e ela que "baixa as luzes" da arena. */
@keyframes dueloVinheta {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.duelo-vinheta {
  animation: dueloVinheta .7s ease-out both;
  /* Mais escuro nas bordas do que no meio, pra o olho ir pro centro. */
  mask-image: radial-gradient(circle at var(--foco-x, 50%) var(--foco-y, 50%),
              rgba(0,0,0,.15) 0%, rgba(0,0,0,.6) 28%, #000 60%);
  -webkit-mask-image: radial-gradient(circle at var(--foco-x, 50%) var(--foco-y, 50%),
              rgba(0,0,0,.15) 0%, rgba(0,0,0,.6) 28%, #000 60%);
}

/* O HOLOFOTE: um circulo de luz quente que abre atras do campeao. */
@keyframes dueloHolofote {
  0%   { transform: translate(-50%, -50%) scale(.2); opacity: 0; }
  55%  { transform: translate(-50%, -50%) scale(1.08); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1); opacity: .92; }
}
.duelo-holofote {
  width: 150px;
  height: 150px;
  border-radius: 50%;
  background: radial-gradient(circle,
              rgba(253, 230, 138, .85) 0%,
              rgba(251, 191, 36, .45) 38%,
              rgba(251, 191, 36, 0) 70%);
  animation: dueloHolofote .8s ease-out both;
}

/* OS RAIOS girando atras. `conic-gradient` com paradas duras faz as fatias sem
   precisar de um elemento por raio. */
@keyframes dueloRaios {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}
@keyframes dueloRaiosEntra {
  from { opacity: 0; }
  to   { opacity: .5; }
}
.duelo-raios {
  width: 260px;
  height: 260px;
  border-radius: 50%;
  background: conic-gradient(
      rgba(253, 230, 138, .55) 0deg 12deg, transparent 12deg 30deg,
      rgba(253, 230, 138, .55) 30deg 42deg, transparent 42deg 60deg,
      rgba(253, 230, 138, .55) 60deg 72deg, transparent 72deg 90deg,
      rgba(253, 230, 138, .55) 90deg 102deg, transparent 102deg 120deg,
      rgba(253, 230, 138, .55) 120deg 132deg, transparent 132deg 150deg,
      rgba(253, 230, 138, .55) 150deg 162deg, transparent 162deg 180deg,
      rgba(253, 230, 138, .55) 180deg 192deg, transparent 192deg 210deg,
      rgba(253, 230, 138, .55) 210deg 222deg, transparent 222deg 240deg,
      rgba(253, 230, 138, .55) 240deg 252deg, transparent 252deg 270deg,
      rgba(253, 230, 138, .55) 270deg 282deg, transparent 282deg 300deg,
      rgba(253, 230, 138, .55) 300deg 312deg, transparent 312deg 330deg,
      rgba(253, 230, 138, .55) 330deg 342deg, transparent 342deg 360deg);
  /* Esmaece pras pontas, senao o disco vira um circulo duro na arena. */
  mask-image: radial-gradient(circle, transparent 22%, #000 42%, transparent 78%);
  -webkit-mask-image: radial-gradient(circle, transparent 22%, #000 42%, transparent 78%);
  animation: dueloRaios 9s linear infinite, dueloRaiosEntra 1s ease-out both;
}

/* O CAMPEAO comemora: cresce, salta duas vezes e fica pulsando dourado.
   Tudo no SPRITE (nunca na caixa). */
@keyframes dueloVencedor {
  0%   { transform: scale(1) translateY(0); }
  18%  { transform: scale(1.45) translateY(-9px); }
  34%  { transform: scale(1.3) translateY(0); }
  50%  { transform: scale(1.4) translateY(-6px); }
  66%  { transform: scale(1.3) translateY(0); }
  100% { transform: scale(1.32) translateY(0); }
}
@keyframes dueloVencedorBrilho {
  0%, 100% { filter: drop-shadow(0 0 4px rgba(251,191,36,.8)) brightness(1.05); }
  50%      { filter: drop-shadow(0 0 12px rgba(253,230,138,1)) brightness(1.2); }
}
.duelo-vencedor [data-duelo-sprite] {
  animation: dueloVencedor 1.4s cubic-bezier(.34,1.56,.64,1) both,
             dueloVencedorBrilho 1.8s ease-in-out 1.4s infinite;
}
/* O nome do campeao ganha corpo junto. */
.duelo-vencedor [data-duelo-nome] {
  color: rgb(253 230 138);
  font-weight: 800;
  text-shadow: 0 1px 3px rgba(0,0,0,.9);
}

/* A COROA desce e assenta. */
@keyframes dueloCoroaDesce {
  0%   { transform: translateY(-26px) scale(.4) rotate(-25deg); opacity: 0; }
  60%  { transform: translateY(2px) scale(1.35) rotate(6deg); opacity: 1; }
  100% { transform: translateY(0) scale(1) rotate(0deg); opacity: 1; }
}
.duelo-vencedor [data-duelo-coroa] {
  animation: dueloCoroaDesce .75s cubic-bezier(.34,1.56,.64,1) .35s both;
}

/* CONFETE. Cada pedaco recebe posicao, cor, atraso e giro pelo style inline
   (vem do dado semeado, entao o replay solta o mesmo confete). */
@keyframes dueloConfete {
  0%   { transform: translateY(-14px) rotate(0deg); opacity: 0; }
  12%  { opacity: 1; }
  100% { transform: translateY(var(--queda, 200px)) rotate(var(--giro, 540deg)); opacity: 0; }
}
.duelo-confete {
  position: absolute;
  width: 5px;
  height: 9px;
  border-radius: 1px;
  animation: dueloConfete var(--dur, 2.4s) linear var(--atraso, 0s) both;
}

/* A FAIXA sobe de baixo. */
@keyframes dueloFaixa {
  from { transform: translateY(115%); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.duelo-faixa { animation: dueloFaixa .55s cubic-bezier(.34,1.56,.64,1) both; }

@media (prefers-reduced-motion: reduce) {
  /* A cena continua acontecendo — o campeao fica destacado, iluminado e com a
     faixa — mas sem nada girando, saltando ou caindo. */
  .duelo-vinheta, .duelo-holofote, .duelo-faixa { animation: none; }
  .duelo-raios { animation: dueloRaiosEntra 1s ease-out both; }
  .duelo-vencedor [data-duelo-sprite] {
    animation: none;
    transform: scale(1.32);
    filter: drop-shadow(0 0 8px rgba(251,191,36,.9));
  }
  .duelo-vencedor [data-duelo-coroa] { animation: none; }
  .duelo-confete { display: none; }
}

/* A faixa saindo: ela e um momento, nao um letreiro (ver `festejar`). */
@keyframes dueloFaixaSai {
  from { transform: translateY(0); opacity: 1; }
  to   { transform: translateY(115%); opacity: 0; }
}
.duelo-faixa-sai { animation: dueloFaixaSai .45s ease-in both !important; }
@media (prefers-reduced-motion: reduce) {
  .duelo-faixa-sai { animation: none; opacity: 0; }
}

/*
 * O 2x LIGADO. Classe propria (e nao utilitaria do Tailwind) porque ela entra
 * por JS: o play CDN so gera regra pra classe que esta escrita no HTML.
 */
.duelo-ritmo-2x {
  color: rgb(253 230 138);
  --tw-ring-color: rgba(252, 211, 77, .6);
  box-shadow: 0 0 0 1px rgba(252, 211, 77, .6) inset;
  background: rgba(120, 53, 15, .6);
}
