/* ══════════════════════════════════════════════════════════════════
   SANTUÁRIO DE INVOCAÇÃO — a tela da Deusa (#3xx)

   Remontagem do desenho do Gabriel com material NOSSO: a figura é o ator de
   malha (`/potato/ator/`), e cenário, arco, círculo mágico e cartas são CSS.
   Nenhum pedaço da imagem de referência entra aqui — ela é print de outro jogo.

   🚨 HERDA as variáveis do tema (`assets/index-*.css`): navy + ouro. Todo
   `var()` leva valor de reserva porque este arquivo também é carregado no palco
   de teste, onde o CSS do jogo pode não estar.

   Convenção de nomes: `inv-` em tudo. Sem `!important`, sem tocar em nada de
   fora do overlay — o resto do webroot é de outros módulos.
   ══════════════════════════════════════════════════════════════════ */

.inv {
  position: fixed;
  inset: 0;
  /*
   * 🚨 Acima de `.tal-overlay` (z-index 60) porque esta tela ABRE POR CIMA da
   * página da Deusa dentro de Talentos, e acima do painel de Afinidade
   * (2147483000). Fica abaixo do overlay do CAPTCHA (2147483647), que precisa
   * cobrir tudo.
   */
  z-index: 2147483100;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  /* 🚨 `minmax(0, …)` na coluna: cabeçalho e rodapé têm conteúdo `nowrap` e sem
     isto a coluna implícita nasce do `min-content` e transborda no celular. */
  grid-template-columns: minmax(0, 1fr);
  overflow: hidden;
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  color: var(--text, #e9edf6);
  background:
    radial-gradient(120% 78% at 50% 100%, rgb(63 41 122 / 0.55) 0%, rgb(6 10 28 / 0) 62%),
    radial-gradient(90% 60% at 50% 4%, rgb(12 40 82 / 0.5) 0%, rgb(1 6 15 / 0) 70%),
    linear-gradient(180deg, #06081a 0%, #0a0a20 42%, #05060f 100%);
  -webkit-user-select: none;
  user-select: none;
  animation: inv-entrar 220ms var(--ease-out, cubic-bezier(0.2, 0.8, 0.25, 1)) both;
}

@keyframes inv-entrar {
  from {
    opacity: 0;
    scale: 1.015;
  }
}

.inv[hidden] {
  display: none;
}

/* ══ CENÁRIO ═══════════════════════════════════════════════════════
   Quatro camadas, todas sem imagem: estrelas, arco de pedra, facho de luz
   e o halo atrás da figura. */

.inv-fundo {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}

/* Estrelas: equivalente ao `.tal-ceu` dos Talentos, escrito aqui de novo
   (posições e cores próprias) porque aquele arquivo é de outro agente. */
.inv-ceu::before,
.inv-ceu::after {
  content: '';
  position: absolute;
  inset: -25%;
}

.inv-ceu::before {
  background:
    radial-gradient(1.5px 1.5px at 12% 18%, #dbe8ff 50%, transparent 51%),
    radial-gradient(1.2px 1.2px at 27% 62%, #fff0c8 50%, transparent 51%),
    radial-gradient(1.7px 1.7px at 44% 9%, #b9e0ff 50%, transparent 51%),
    radial-gradient(1.1px 1.1px at 58% 44%, #ffffff 50%, transparent 51%),
    radial-gradient(1.6px 1.6px at 73% 25%, #e6d2ff 50%, transparent 51%),
    radial-gradient(1.2px 1.2px at 88% 71%, #cfe3ff 50%, transparent 51%),
    radial-gradient(1.4px 1.4px at 6% 84%, #fff0c8 50%, transparent 51%),
    radial-gradient(1.1px 1.1px at 95% 33%, #ffffff 50%, transparent 51%);
  background-size: 240px 240px;
  opacity: 0.6;
  animation: inv-cintilar 6s ease-in-out infinite;
}

.inv-ceu::after {
  /* Poeira mais fina e mais lenta: dá profundidade sem virar chuvisco. */
  background:
    radial-gradient(1px 1px at 34% 31%, #a9c6ff 50%, transparent 51%),
    radial-gradient(1px 1px at 66% 78%, #ffe9b0 50%, transparent 51%),
    radial-gradient(1px 1px at 82% 12%, #ffffff 50%, transparent 51%);
  background-size: 130px 130px;
  opacity: 0.35;
  animation: inv-cintilar 9s ease-in-out infinite reverse;
}

@keyframes inv-cintilar {
  50% {
    opacity: 0.28;
  }
}

/*
 * O ARCO. Na referência a figura está dentro de um portal de pedra com dois
 * arcos concêntricos. Aqui é uma caixa com o topo arredondado e sem borda
 * inferior — dois deles, o de fora mais apagado.
 */
.inv-arco {
  position: absolute;
  left: 50%;
  bottom: -2%;
  /* 🚨 56% -> 72% da largura em 1180 px: na referência o portal ENCOSTA nas
     colunas dos dois lados, e era ele que deixava a tela com ar de vazia. */
  width: min(72vw, 880px);
  height: min(90%, 780px);
  translate: -50% 0;
  border: 2px solid rgb(138 90 28 / 0.3);
  border-bottom: none;
  border-radius: 50% 50% 0 0 / 40% 40% 0 0;
  background:
    radial-gradient(110% 80% at 50% 100%, rgb(74 52 138 / 0.42) 0%, rgb(10 10 30 / 0) 72%),
    linear-gradient(180deg, rgb(22 18 48 / 0.55), rgb(8 8 22 / 0) 55%);
  box-shadow:
    inset 0 0 90px rgb(126 96 216 / 0.16),
    0 0 40px rgb(138 90 28 / 0.1);
}

.inv-arco--fora {
  width: min(90vw, 1040px);
  height: min(99%, 860px);
  border-color: rgb(138 90 28 / 0.16);
  box-shadow: inset 0 0 120px rgb(126 96 216 / 0.1);
}

/* Facho de luz subindo do chão, atrás da figura. */
.inv-facho {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: min(54vw, 560px);
  height: 82%;
  translate: -50% 0;
  background: linear-gradient(
    180deg,
    rgb(140 200 255 / 0) 0%,
    rgb(150 190 255 / 0.05) 50%,
    rgb(190 220 255 / 0.13) 100%
  );
  clip-path: polygon(40% 0, 60% 0, 100% 100%, 0 100%);
  /* 🚨 Desfoque alto de propósito: com pouco desfoque o `clip-path` mostrava as
     DUAS RETAS do cone e virava lanterna em vez de luz. */
  filter: blur(22px);
}

/* Halo atrás da figura: violeta por fora, ciano no miolo. */
.inv-halo {
  position: absolute;
  left: 50%;
  bottom: 6%;
  width: min(66vw, 720px);
  aspect-ratio: 1;
  translate: -50% 0;
  border-radius: 50%;
  background:
    radial-gradient(circle, rgb(150 220 255 / 0.22) 0%, rgb(150 220 255 / 0) 38%),
    radial-gradient(circle, rgb(150 110 255 / 0.2) 0%, rgb(90 60 190 / 0) 62%);
  animation: inv-pulsar 7s ease-in-out infinite;
}

@keyframes inv-pulsar {
  50% {
    scale: 1.06;
    opacity: 0.82;
  }
}

/* ══ CABEÇALHO ═════════════════════════════════════════════════════ */

.inv-topo {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px clamp(10px, 1.6vw, 20px);
}

.inv-topo__titulo {
  margin: 0;
  font-family: var(--font-display, Georgia, serif);
  font-size: clamp(15px, 2.4vmin, 22px);
  font-weight: 900;
  letter-spacing: 0.18em;
  text-indent: 0.18em;
  text-transform: uppercase;
  color: var(--gold-100, #fff3cf);
  text-shadow: 0 0 22px rgb(220 145 30 / 0.55);
  white-space: nowrap;
}

.inv-topo__espaco {
  flex: 1 1 auto;
}

.inv-contadores {
  display: flex;
  align-items: center;
  gap: 8px;
}

.inv-cont {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 102px;
  padding: 6px 13px 6px 9px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid rgb(138 90 28 / 0.55);
  background: linear-gradient(180deg, rgb(6 26 43 / 0.92), rgb(1 6 15 / 0.94));
  box-shadow:
    inset 0 1px 0 rgb(242 208 137 / 0.12),
    0 2px 0 rgb(0 0 0 / 0.5);
}

.inv-cont img {
  width: 22px;
  height: 22px;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.6));
}

.inv-cont b {
  font-size: var(--fs-500, 15px);
  font-weight: 800;
  color: var(--gold-100, #fff3cf);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/*
 * O X DO JOGO — a receita é a do `.tal-fechar` (Talentos, e igual em Correio e
 * Ranks): caixa de 40×40 com moldura fria, fundo navy e o ícone de 18 px DENTRO.
 *
 * 🚨 Não é gosto: esta tela abre POR CIMA de Talentos, então os dois X ficam na
 * MESMA PILHA. O de antes desenhava o `xRounded.png` a 100% de 38 px, chapado e
 * sem moldura — 2,1× o ícone do vizinho e um desenho de outra família.
 */
.inv-x {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  /* 🚨 44 px TAMBÉM no desktop: era o alvo mais apertado da tela lá (40) e o
     pedido é justamente "tudo um pouco maior". O ícone dentro cresce junto. */
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--line-cool-2, #1d4463);
  border-radius: var(--r-md, 12px);
  background: rgb(6 26 43 / 0.8);
  cursor: pointer;
  transition:
    border-color var(--dur-base, 0.18s) ease,
    background var(--dur-base, 0.18s) ease;
}

.inv-x:hover,
.inv-x:focus-visible {
  border-color: var(--gold-500, #dc911e);
  background: rgb(52 28 0 / 0.6);
}

.inv-x img {
  width: 20px;
  height: 20px;
  object-fit: contain;
}

/* ══ PALCO (3 colunas) ═════════════════════════════════════════════ */

.inv-palco {
  position: relative;
  z-index: 2;
  display: grid;
  /*
   * 256 px na coluna da esquerda, e o número não é gosto: MEDIDO no palco, o
   * rótulo "Bilhete de Habilidade" pede 146 px, mais ✦ 12, contador 49, dois
   * vãos de 7 e 20 de recheio = 241. Com 246 dava 247 — UM pixel a mais, e a
   * pílula de ouro quebrava em duas linhas.
   */
  /* 🚨 O rótulo "Bilhete de Habilidade" pede 241 px medidos: 268 dá folga e a
     pílula continua em UMA linha. À direita, 368 px são os ~31% da referência. */
  grid-template-columns: minmax(0, 268px) minmax(0, 1fr) minmax(0, 368px);
  gap: clamp(8px, 1.4vw, 18px);
  padding: 0 clamp(10px, 1.6vw, 22px) 4px;
  min-height: 0;
}

/* ── ESQUERDA: o que invocar ─────────────────────────────────────── */

.inv-tipos {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(14px, 3vh, 34px);
  min-width: 0;
}

/* A linha pontilhada da referência, com um ponto por seletor. */
.inv-tipos::before {
  content: '';
  position: absolute;
  top: 8%;
  bottom: 8%;
  right: 0;
  border-left: 1px dashed rgb(242 208 137 / 0.22);
}

.inv-tipo {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  /*
   * 🚨 MOLDURA DISCRETA NAS TRÊS. Sem ela (borda transparente e fundo nenhum) a
   * não-escolhida era texto solto no meio do cenário e a de ouro parecia o único
   * botão da coluna. A cor é a dos controles inativos do jogo (a mesma da
   * `.inv-aba`), então as duas fileiras combinam.
   */
  border: 1px solid rgb(29 68 99 / 0.85);
  border-radius: var(--r-pill, 999px);
  background: linear-gradient(180deg, rgb(6 26 43 / 0.62), rgb(1 6 15 / 0.72));
  color: var(--text, #e9edf6);
  font: inherit;
  font-size: var(--fs-400, 13px);
  font-weight: 700;
  text-align: left;
  cursor: pointer;
  transition:
    background var(--dur-base, 0.18s) ease,
    border-color var(--dur-base, 0.18s) ease,
    color var(--dur-base, 0.18s) ease,
    box-shadow var(--dur-base, 0.18s) ease;
}

/* O ponto na linha, alinhado com o seletor. */
.inv-tipo::after {
  content: '';
  position: absolute;
  right: -4px;
  top: 50%;
  width: 9px;
  height: 9px;
  translate: 0 -50%;
  border-radius: 50%;
  background: #e8873a;
  box-shadow: 0 0 8px rgb(232 135 58 / 0.8);
}

.inv-tipo__marca {
  flex: 0 0 auto;
  font-size: 14px;
  line-height: 1;
  color: var(--gold-300, #f2d089);
  text-shadow: 0 0 10px rgb(242 208 137 / 0.7);
}

.inv-tipo__nome {
  flex: 1 1 auto;
  min-width: 0;
  /* Uma linha sempre. Se um dia a fonte do sistema for mais larga que a medida,
     a válvula é o "…" e não uma pílula de duas alturas. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* O rótulo curto do celular. Existem os dois no HTML e o CSS escolhe: trocar
   texto por JS obrigaria a repintar a tela em cada giro do aparelho. */
.inv-tipo__curto {
  display: none;
}

.inv-tipo__n {
  flex: 0 0 auto;
  min-width: 22px;
  padding: 1px 6px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid rgb(138 90 28 / 0.5);
  background: rgb(1 6 15 / 0.6);
  color: var(--gold-100, #fff3cf);
  font-size: var(--fs-200, 11px);
  font-weight: 800;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.inv-tipo:hover:not([aria-pressed='true']):not([disabled]),
.inv-tipo:focus-visible:not([aria-pressed='true']) {
  border-color: rgb(242 208 137 / 0.55);
  background: linear-gradient(180deg, rgb(30 44 62 / 0.75), rgb(8 16 30 / 0.8));
}

/* Escolhido: pílula de ouro com texto escuro, como na referência. */
.inv-tipo[aria-pressed='true'] {
  border-color: rgb(255 243 207 / 0.9);
  background: linear-gradient(
    180deg,
    var(--gold-100, #fff3cf) 0%,
    var(--gold-300, #f2d089) 52%,
    #e0b863 100%
  );
  color: var(--on-gold, #2a1a02);
  box-shadow:
    0 0 22px -3px rgb(242 208 137 / 0.6),
    0 2px 0 rgb(0 0 0 / 0.45);
}

.inv-tipo[aria-pressed='true'] .inv-tipo__marca {
  color: #7a4c05;
  text-shadow: none;
}

.inv-tipo[aria-pressed='true'] .inv-tipo__n {
  border-color: rgb(122 76 5 / 0.45);
  background: rgb(255 255 255 / 0.4);
  color: #4a2e02;
}

/*
 * 🚨 `data-inerte` e não `aria-disabled`: o seletor de Skin é o ÚNICO lugar onde
 * o jogador lê por que ela não funciona, então ele precisa receber o clique e
 * ser ativável por teclado e leitor de tela. Quem se anuncia desabilitado não é
 * acionado por nenhum dos dois. Aqui só se pinta o estado.
 */
.inv-tipo[disabled],
.inv-tipo[data-inerte='1'] {
  cursor: help;
  border-color: rgb(29 68 99 / 0.5);
  color: var(--faint, #55688a);
}

.inv-tipo[disabled] .inv-tipo__marca,
.inv-tipo[data-inerte='1'] .inv-tipo__marca {
  color: var(--faint, #55688a);
  text-shadow: none;
}

.inv-tipo[disabled]::after,
.inv-tipo[data-inerte='1']::after {
  background: #3b4a63;
  box-shadow: none;
}

/* ── CENTRO: a Deusa ─────────────────────────────────────────────── */

.inv-centro {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  min-width: 0;
  min-height: 0;
}

.inv-figura {
  position: relative;
  /* A figura é o coração da tela: ocupa o que sobrar, com teto para não
     esticar em monitor grande. */
  height: min(100%, 620px);
  aspect-ratio: 46 / 62;
  /*
   * 🚨 A MARGEM CARREGA A RESERVA DO AVISO (os 30 px do `min-height` dele).
   *
   * O aviso saiu do fluxo — como irmão nesta coluna ele empurrava a figura toda
   * vez que a frase quebrava em duas linhas (medido: 8 px em 360×640 e 320×568,
   * 11 px em 667×375). Só que a reserva tem de continuar saindo do MESMO lugar de
   * onde saía, senão a figura muda de tamanho: aqui a soma `margem + aviso`
   * era 2 + 26 no celular, e agora é 28 + 0. Idêntica — a figura fica com os
   * mesmos 293,6 px de 390×760 da base aprovada, e uma segunda linha de recado
   * cresce para cima, sobre o círculo (decoração, atrás da pílula opaca), em vez
   * de mexer nela.
   *
   * 🚨 NÃO usar `padding-bottom` na `.inv-centro` para isso: o `min(100%, …)` da
   * figura se resolve contra a coluna e o recheio entrava DUAS vezes na conta —
   * medido, a figura caía de 293,6 para 267,6 px em 390×760.
   */
  /* 🚨 O TETO DA MARGEM CAIU DE 26 PARA 20 px (a reserva de 30 px do aviso
     continua intacta): o rodapé cresceu 10 px com os botões maiores e a figura
     do desktop tinha perdido 5 px de altura (620 → 615, medido: o topo também
     cresceu 3,5). Com 13 px a figura volta EXATAMENTE aos 620 px aprovados. O celular e o deitado têm margem própria nos
     blocos de baixo, então nada muda lá. */
  margin-bottom: calc(clamp(6px, 2vh, 13px) + 30px);
  /*
   * 🚨 A FIGURA NÃO PODE RECEBER TOQUE. Ela é decoração inteira (canvas do ator,
   * círculo mágico, luz da invocação) e no celular a caixa dela é mais alta que a
   * coluna do meio, então ela AVANÇA por cima da fileira de fichas. Medido: o
   * canvas engolia o toque na ficha "Pet" (o Playwright acusou
   * "canvas.inv-arte intercepts pointer events" e o clique nem chegava ao botão).
   * Transparente aos ponteiros, ela desenha por cima sem roubar nada.
   */
  pointer-events: none;
}

/* Deusa liberta (chibi): a caixa da animação dela é quase quadrada — retrato
   deixaria metade da caixa vazia. Medido: 80,0% × 70,9% num canvas quadrado. */
.inv-figura[data-forma='larga'] {
  aspect-ratio: 1 / 1;
  height: min(100%, 520px);
}

.inv-arte {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  /* 🚨 O canvas fica TRANSPARENTE: o brilho vem das camadas de trás. Pôr fundo
     aqui criaria um retângulo visível em volta da figura. */
  background: none;
}

.inv-reserva {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 8px 24px rgb(0 0 0 / 0.55));
}

/* O CÍRCULO MÁGICO.
   Achatar por `scaleY` num invólucro e girar os anéis dentro dele: girar uma
   elipse direto faz ela bambear em vez de rodar no chão. */
.inv-circulo {
  position: absolute;
  left: 50%;
  top: 95%;
  width: 122%;
  aspect-ratio: 1;
  translate: -50% -50%;
  z-index: 0;
  pointer-events: none;
}

/*
 * 🚨 O CÍRCULO SEGUE OS PÉS, e os pés mudam com a figura. Medido: a estátua
 * termina a 96% da caixa (por isso `top: 95%`), mas a Deusa chibi termina a
 * 82% — com o mesmo 95% ela ficava FLUTUANDO 65 px acima do círculo. E a
 * elipse encolhe: o corpo dela ocupa muito menos da caixa que a estátua.
 */
.inv-figura[data-forma='larga'] .inv-circulo {
  top: 86%;
  width: 94%;
}

.inv-circulo--frente {
  /* A metade de baixo passa NA FRENTE dos pés: é o que dá a sensação de que
     ela está dentro do círculo, e não colada num adesivo. */
  z-index: 2;
  clip-path: polygon(0 52%, 100% 52%, 100% 100%, 0 100%);
}

.inv-circulo__achatar {
  position: absolute;
  inset: 0;
  transform: scaleY(0.3);
}

.inv-circulo__anel {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  animation: inv-girar 34s linear infinite;
}

.inv-circulo__anel--1 {
  border: 3px solid rgb(150 220 255 / 0.45);
  box-shadow:
    0 0 24px rgb(120 190 255 / 0.35),
    inset 0 0 30px rgb(120 190 255 / 0.16);
}

.inv-circulo__anel--2 {
  inset: 9%;
  border: 1px dashed rgb(242 208 137 / 0.5);
  animation-duration: 22s;
  animation-direction: reverse;
}

.inv-circulo__anel--3 {
  inset: 19%;
  border: 2px solid rgb(190 150 255 / 0.4);
  animation-duration: 48s;
}

/* Marcas na borda: doze traços, feitos com gradiente cônico e um recorte de
   anel. Sem imagem, sem 12 elementos. */
.inv-circulo__marcas {
  position: absolute;
  inset: 3%;
  border-radius: 50%;
  background: repeating-conic-gradient(
    from 0deg,
    rgb(210 235 255 / 0.55) 0deg 1.2deg,
    transparent 1.2deg 30deg
  );
  -webkit-mask: radial-gradient(circle, transparent 0 62%, #000 64% 72%, transparent 74%);
  mask: radial-gradient(circle, transparent 0 62%, #000 64% 72%, transparent 74%);
  animation: inv-girar 60s linear infinite;
}

.inv-circulo__nucleo {
  position: absolute;
  inset: 22%;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(215 240 255 / 0.3) 0%, rgb(120 170 255 / 0) 70%);
}

@keyframes inv-girar {
  to {
    rotate: 360deg;
  }
}

/* Cartas flutuando. Rombo de CSS com um brilho dentro — a carta da referência
   é arte do outro jogo, então esta é nossa. */
.inv-cartas {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

.inv-carta {
  position: absolute;
  /* 15% maiores: na referência as cartas voando são peças grandes, e aqui elas
     estavam quase invisíveis no desktop. O celular mantém a redução de 0,68. */
  width: calc(var(--l, 42px) * 1.15);
  height: calc(var(--l, 42px) * 1.52);
  border-radius: 5px;
  border: 1px solid rgb(255 255 255 / 0.5);
  background: linear-gradient(
    148deg,
    rgb(255 255 255 / 0.55) 0%,
    rgb(200 220 255 / 0.22) 45%,
    rgb(150 110 255 / 0.16) 100%
  );
  box-shadow: 0 0 16px rgb(160 190 255 / 0.35);
  transform: rotate(var(--g, -16deg)) skewY(-10deg);
  animation: inv-flutuar var(--t, 8s) ease-in-out var(--d, 0s) infinite;
  opacity: 0.75;
}

.inv-carta--roxa {
  border-color: rgb(214 170 255 / 0.6);
  background: linear-gradient(
    148deg,
    rgb(196 132 252 / 0.45) 0%,
    rgb(120 60 200 / 0.24) 55%,
    rgb(40 20 80 / 0.18) 100%
  );
  box-shadow: 0 0 18px rgb(180 120 255 / 0.4);
}

/* A marca no meio da carta: um losango com um risco, como um selo. */
.inv-carta::before {
  content: '';
  position: absolute;
  inset: 26% 30%;
  border: 1px solid rgb(255 255 255 / 0.55);
  border-radius: 2px;
  rotate: 45deg;
}

@keyframes inv-flutuar {
  0%,
  100% {
    translate: 0 0;
  }
  50% {
    translate: 0 -16px;
  }
}

/* ── DIREITA: recompensa e explicações ───────────────────────────── */

.inv-lado {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  min-height: 0;
  padding: 4px 0 6px;
}

.inv-painel {
  border-radius: var(--r-md, 12px);
  border: 1px solid rgb(138 90 28 / 0.45);
  background: linear-gradient(180deg, rgb(6 26 43 / 0.86), rgb(1 6 15 / 0.9));
  box-shadow:
    var(--e-3, 0 18px 40px -12px rgb(0 0 0 / 0.9)),
    inset 0 1px 0 rgb(242 208 137 / 0.1);
}

/* Nível de bênção + prêmio do próximo nível */
.inv-recompensa {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
}

.inv-nivel {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
}

/* A medalha recortada da referência (nonágono festonado) sai de `clip-path`. */
.inv-medalha {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  clip-path: polygon(
    50% 0%,
    68% 8%,
    87% 6%,
    93% 25%,
    100% 50%,
    93% 75%,
    87% 94%,
    68% 92%,
    50% 100%,
    32% 92%,
    13% 94%,
    7% 75%,
    0% 50%,
    7% 25%,
    13% 6%,
    32% 8%
  );
  background: linear-gradient(180deg, var(--gold-100, #fff3cf), var(--gold-500, #dc911e));
  color: #40260a;
  font-family: var(--font-display, Georgia, serif);
  font-size: 21px;
  font-weight: 900;
  line-height: 1;
  text-shadow: 0 1px 0 rgb(255 255 255 / 0.45);
  filter: drop-shadow(0 0 12px rgb(242 208 137 / 0.45));
}

.inv-nivel__col {
  flex: 1 1 auto;
  min-width: 0;
}

.inv-nivel__rot {
  display: block;
  margin-bottom: 4px;
  /* Uma linha: no painel de 264 px do deitado "NÍVEL DE RECOMPENSA" quebrava. */
  white-space: nowrap;
  font-size: var(--fs-200, 11px);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-300, #f2d089);
  opacity: 0.85;
}

.inv-barra {
  position: relative;
  height: 20px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid rgb(138 90 28 / 0.6);
  background: rgb(0 6 16 / 0.85);
  overflow: hidden;
}

.inv-barra__fill {
  display: block;
  height: 100%;
  border-radius: var(--r-pill, 999px);
  background: linear-gradient(180deg, #ffd98a, var(--gold-500, #dc911e));
  box-shadow: 0 0 12px rgb(242 208 137 / 0.5);
  transition: width var(--dur-slow, 0.26s) ease;
}

/*
 * 🚨 O texto ATRAVESSA a borda do preenchimento: metade cai sobre o ouro e
 * metade sobre o navy. Escuro com sombra clara lia bem no ouro e DESAPARECIA no
 * fundo (medido na captura: o "/ 100" sumia). Creme com sombra preta lê nos
 * dois — é o único par que funciona sem saber onde a barra está.
 */
.inv-barra__txt {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: var(--fs-200, 11px);
  font-weight: 800;
  color: var(--gold-100, #fff3cf);
  font-variant-numeric: tabular-nums;
  text-shadow:
    0 1px 2px rgb(0 0 0 / 0.95),
    0 0 6px rgb(0 0 0 / 0.8);
}

.inv-barra[data-vazia='1'] .inv-barra__txt {
  color: var(--muted, #8ea3bd);
  text-shadow: none;
}

.inv-premio {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}

.inv-premio__rot {
  font-size: var(--fs-100, 10px);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted, #8ea3bd);
}

.inv-premio__carta {
  position: relative;
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  border-radius: var(--r-sm, 8px);
  border: 1px solid rgb(138 90 28 / 0.55);
  background: linear-gradient(180deg, rgb(12 34 56 / 0.9), rgb(1 8 18 / 0.95));
  box-shadow: inset 0 0 18px rgb(120 190 255 / 0.12);
}

.inv-premio__carta img {
  width: 38px;
  height: 38px;
  object-fit: contain;
}

.inv-premio__carta b {
  position: absolute;
  right: 3px;
  bottom: 1px;
  font-size: var(--fs-300, 12px);
  font-weight: 900;
  color: var(--gold-100, #fff3cf);
  text-shadow: 0 1px 2px #000;
  font-variant-numeric: tabular-nums;
}

/* Abas Skills / Pets / Skins */
.inv-abas {
  display: flex;
  gap: 8px;
}

.inv-aba {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* 🚨 44 px de alvo no desktop também (media 38 antes) — mesma razão do ✕. */
  min-height: 44px;
  padding: 8px 4px;
  border-radius: var(--r-sm, 8px);
  border: 1px solid rgb(29 68 99 / 0.9);
  background: linear-gradient(180deg, rgb(6 26 43 / 0.9), rgb(1 6 15 / 0.92));
  color: var(--text, #e9edf6);
  font: inherit;
  font-size: var(--fs-300, 12px);
  font-weight: 800;
  cursor: pointer;
  transition:
    border-color var(--dur-base, 0.18s) ease,
    box-shadow var(--dur-base, 0.18s) ease;
}

.inv-aba img {
  width: 24px;
  height: 24px;
  object-fit: contain;
}

.inv-aba[aria-selected='true'] {
  border-color: var(--gold-300, #f2d089);
  box-shadow:
    0 0 18px -4px rgb(242 208 137 / 0.55),
    inset 0 0 12px rgb(242 208 137 / 0.1);
  color: var(--gold-100, #fff3cf);
}

.inv-aba[data-inerte='1'] {
  color: var(--muted, #8ea3bd);
}

.inv-aba[data-inerte='1'] img {
  opacity: 0.65;
}

/*
 * O bloco de explicação ABRAÇA O TEXTO (`flex: 0 1 auto`) em vez de esticar
 * até o rodapé.
 *
 * 🚨 Medido na primeira captura: com `flex: 1` o painel virava um retângulo
 * escuro de ~600 px com 150 px de texto e 450 px de vazio — a coisa mais feia
 * da tela. Na referência ele também termina no meio, e embaixo é só céu.
 */
.inv-texto {
  position: relative;
  flex: 0 1 auto;
  min-height: 0;
  max-height: 100%;
  overflow-y: auto;
  padding: 12px 14px 14px;
}

/* ── "i" das chances (16/09) — mesmo espírito do botão de fusão do Pet ── */
.inv-texto__i {
  position: absolute;
  top: 10px;
  right: 12px;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  border: 1px solid rgb(255 243 207 / 0.5);
  background: rgb(20 14 6 / 0.6);
  color: var(--gold-100, #fff3cf);
  font-family: Georgia, serif;
  font-style: italic;
  font-weight: 900;
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  z-index: 2;
}
.inv-texto__i:hover { background: rgb(138 90 28 / 0.5); }

.inv-chances {
  margin-top: 10px;
  padding: 10px;
  border-radius: 8px;
  border: 1px solid rgb(138 90 28 / 0.4);
  background: rgb(10 7 3 / 0.55);
}
.inv-chances__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
  color: var(--gold-100, #fff3cf);
  font-size: 12px;
}
.inv-chances__x {
  border: none;
  background: none;
  color: var(--muted, #8ea3bd);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.inv-chances__tab { width: 100%; border-collapse: collapse; font-size: 11px; }
.inv-chances__tab th {
  text-align: left;
  padding: 3px 6px;
  color: var(--muted, #8ea3bd);
  font-weight: 700;
  border-bottom: 1px solid rgb(138 90 28 / 0.4);
}
.inv-chances__tab td {
  padding: 3px 6px;
  color: #cfdcee;
  border-bottom: 1px solid rgb(255 255 255 / 0.06);
}
.inv-chances__qtd { color: var(--muted, #8ea3bd); font-size: 10px; }

.inv-texto__intro {
  margin: 0 0 10px;
  font-size: var(--fs-400, 13px);
  line-height: var(--lh-base, 1.35);
  color: var(--muted, #8ea3bd);
}

.inv-texto__titulo {
  margin: 0 0 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgb(138 90 28 / 0.4);
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--fs-600, 17px);
  font-weight: 900;
  letter-spacing: 0.04em;
  text-align: center;
  color: var(--gold-100, #fff3cf);
}

.inv-texto__corpo {
  margin: 0;
  font-size: var(--fs-400, 13px);
  line-height: 1.55;
  color: #cfdcee;
}

.inv-texto__nota {
  margin: 8px 0 0;
  font-size: var(--fs-200, 11px);
  line-height: 1.45;
  color: var(--gold-300, #f2d089);
  opacity: 0.9;
}

/* ══ RODAPÉ: os quatro botões ══════════════════════════════════════ */

.inv-rodape {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(6px, 1vw, 14px);
  padding: clamp(8px, 1.6vh, 16px) clamp(10px, 1.6vw, 22px) clamp(10px, 2vh, 20px);
}

.inv-bt {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 6px;
  min-width: 0;
  /* 🚨 138x52 -> 172x62: na referência o botão tem 12,6% da largura e 8,5% da
     altura da tela; em 1180x820 isso é 149x70. Os 172x62 ficam no meio do
     caminho SEM roubar altura da figura (que já usa 98% da coluna). */
  flex: 0 1 172px;
  height: 62px;
  padding: 0 16px;
  border-radius: 10px;
  border: 1px solid rgb(122 76 5 / 0.9);
  background: linear-gradient(
    180deg,
    var(--gold-100, #fff3cf) 0%,
    var(--gold-300, #f2d089) 46%,
    #dfb35e 100%
  );
  color: var(--on-gold, #2a1a02);
  font: inherit;
  font-weight: 900;
  cursor: pointer;
  box-shadow:
    0 3px 0 rgb(96 58 6 / 0.9),
    0 8px 18px -8px rgb(0 0 0 / 0.9),
    inset 0 1px 0 rgb(255 255 255 / 0.55);
  transition:
    translate var(--dur-fast, 0.12s) ease,
    box-shadow var(--dur-fast, 0.12s) ease,
    filter var(--dur-fast, 0.12s) ease;
}

.inv-bt__rot {
  font-size: var(--fs-400, 13px);
  font-weight: 800;
  opacity: 0.85;
}

.inv-bt__n {
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--fs-700, 21px);
  font-weight: 900;
  letter-spacing: 0.02em;
}

/* O X1 é verde na referência — é a porta de entrada, e a cor a separa das
   outras três. */
.inv-bt--verde {
  border-color: rgb(24 96 52 / 0.95);
  background: linear-gradient(180deg, #8ef0ac 0%, #4ade80 44%, #2fa85c 100%);
  color: #06240f;
  box-shadow:
    0 3px 0 rgb(14 66 34 / 0.95),
    0 8px 18px -8px rgb(0 0 0 / 0.9),
    inset 0 1px 0 rgb(255 255 255 / 0.5);
}

/*
 * 🚨 `:not([data-inerte])` e `:not([aria-disabled='true'])` no hover: o Especial
 * não tem mais `disabled` (precisa receber o clique), e sem estas exclusões o
 * `filter: brightness(1.05)` do hover APAGAVA o filtro apagado dele — medido:
 * com o mouse em cima o Especial voltava a ser um botão dourado inteiro, igual
 * ao X10. O que se conserta na cor não pode voltar pela porta do hover.
 */
.inv-bt:hover:not([disabled]):not([aria-disabled='true']):not([data-inerte='1']) {
  translate: 0 -1px;
  filter: brightness(1.05);
}

.inv-bt:active:not([disabled]):not([aria-disabled='true']):not([data-inerte='1']) {
  translate: 0 2px;
  box-shadow:
    0 1px 0 rgb(96 58 6 / 0.9),
    inset 0 2px 6px rgb(0 0 0 / 0.3);
}

/* Os três de invocar usam `disabled` de verdade (não têm nada a dizer quando
   falta bilhete: o `title` já diz). O Especial usa `data-inerte`, porque ele
   RESPONDE ao clique. Mesmo desenho para os dois casos. */
.inv-bt[disabled],
.inv-bt[aria-disabled='true'],
.inv-bt[data-inerte='1'] {
  cursor: not-allowed;
  filter: grayscale(0.72) brightness(0.62);
  box-shadow: 0 2px 0 rgb(0 0 0 / 0.5);
}

.inv-bt[aria-disabled='true']:hover,
.inv-bt[data-inerte='1']:hover {
  translate: 0 0;
}

/*
 * O ESPECIAL é uma promessa, não um botão quebrado — por isso não vira o
 * cinza-morto dos outros desabilitados.
 *
 * 🚨 Mas `saturate(.82) brightness(.92)` deixava ele QUASE IGUAL ao X10 e ao
 * X50, que gastam bilhete. Num gacha isso é armadilha: o dedo vai no botão
 * errado. Agora o dourado cai o suficiente para se ler à distância como "outro
 * tipo de botão", e a palavra "Em breve" abaixo do nome fecha a dúvida.
 */
.inv-bt--especial {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}

.inv-bt--especial[data-inerte='1'] {
  filter: saturate(0.34) brightness(0.74);
  /* Clicável de propósito: o clique é o que explica. */
  cursor: help;
}

.inv-bt__breve {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-100, 10px);
  font-weight: 900;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #3d2903;
  white-space: nowrap;
}

/* O aviso laranja do canto: na referência ele marca o que tem novidade. Aqui
   marca o botão ESPECIAL, que é o banner que ainda vai existir. */
.inv-bt--especial::after {
  content: '';
  position: absolute;
  top: -4px;
  right: -4px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid #1a1205;
  background: #e8873a;
}

.inv-bt__cadeado {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  object-fit: contain;
  /*
   * 🚨 O cadeado era OURO CLARO SOBRE OURO, a 12 px, no canto, com
   * `opacity: .75` — contraste quase nulo, e era o único sinal de que o botão
   * não funciona. `brightness(0)` faz dele uma silhueta escura, que é o que lê
   * em qualquer tom do dourado, e ele saiu do canto para andar junto do texto.
   */
  filter: brightness(0) saturate(0);
  opacity: 0.72;
}

/* ══ RESULTADO DA INVOCAÇÃO ════════════════════════════════════════ */

/*
 * 🚨 O BLOQUEANTE DO X50. Este diálogo era filho da `.inv-centro` e valia
 * `max-height: 82%` DAQUELA COLUNA — 148 a 294 px no empilhamento do celular.
 * Os irmãos fixos (título 21 + prêmio 44 + Continuar 44 + vãos 24 + recheio 28)
 * somam ~161 px e a lista é o único filho flexível com `min-height: 0`, então
 * ela absorvia todo o déficit: MEDIDO, 0 px de 1130 em 320×568 e 3 px de 1004 em
 * 360×640 — o jogador não via NENHUMA das 50 recompensas, com ~470 px de tela
 * sobrando sem uso.
 *
 * Agora ele é filho da `.inv` (a raiz `position: fixed; inset: 0`), então o
 * `100%` dos limites abaixo é o da TELA, não o de uma coluna. Um absoluto é
 * fora do fluxo: não cria linha nova na grade da raiz nem mexe no palco.
 *
 * 🚨 `z-index: 10` e não 4: dentro da `.inv-centro` ele estava preso ao contexto
 * de empilhamento do `.inv-palco` (z-index 2) e o `.inv-rodape` (z-index 3) era
 * pintado POR CIMA dele. Como irmão do topo, do palco e do rodapé, 10 põe a
 * comemoração acima dos três — e tudo isto continua DENTRO da `.inv`, que
 * mantém o z-index 2147483100 dela (acima de Talentos). Nenhum z-index novo
 * escapa para a página.
 */
.inv-resultado {
  position: absolute;
  z-index: 10;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  /* 🚨 460 -> 720 px: agora que os repetidos vêm AGRUPADOS (×N), a lista tem
     poucas cartas e o problema deixou de ser "caber 50 linhas" e passou a ser
     "usar a tela". Em 1180 px isso dá 4 colunas de carta em vez de 3, e o
     diálogo continua encolhendo até o conteúdo (é `flex` em coluna). */
  width: min(94%, 720px);
  /* 8 px de folga de cada lado contra a borda da tela. */
  max-height: calc(100% - 16px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  /* Ele nasce por cima da figura: sem opacidade alta atrás, os nomes das cartas
     competiam com o desenho da estátua.
     🚨 SAIU o `backdrop-filter: blur(6px)`. Ele fazia sentido numa caixinha de
     ~460×290 no meio da tela; agora que o diálogo ocupa QUASE A TELA TODA, era
     desfocar a tela inteira a cada quadro — e por trás de um fundo de 97% de
     opacidade, que não deixa ver o desfoque. MEDIDO no palco (renderização por
     software, que é o pior caso do celular fraco): com o desfoque a página não
     entregava um quadro estável nem em 30 s e a animação de entrada ficava
     travada em `scale: .94`; sem ele, o quadro sai na hora. Os 2 pontos de
     opacidade a mais pagam o que o desfoque escondia.
     🚨 E OPACO, não 96%: cobrindo quase a tela toda, os 4% deixavam o ✕ e as
     pílulas de contador do topo APARECEREM COMO FANTASMA atrás dos nomes das
     recompensas (visto na captura de 360×760). A cena continua à vista na moldura
     de 8 px que sobra em volta. */
  background: linear-gradient(180deg, #061a2b, #01060f);
  animation: inv-surgir 260ms var(--ease-out, cubic-bezier(0.2, 0.8, 0.25, 1)) both;
}

@keyframes inv-surgir {
  from {
    opacity: 0;
    scale: 0.94;
  }
}

.inv-resultado__titulo {
  margin: 0;
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--fs-600, 17px);
  font-weight: 900;
  text-align: center;
  color: var(--gold-100, #fff3cf);
}

/*
 * A CONTA DO LOTE — "50 invocações · 20 recompensas".
 *
 * 🚨 Ela existe porque agrupar repetidos ESCONDE peça: sem os dois números o
 * jogador de um X50 vê 20 cartas e acha que perdeu 30. A soma dos ×N fecha com o
 * primeiro número, sempre (é a mesma lista contada de duas formas).
 *
 * 🚨 Na MESMA linha do título (é um `<small>` dentro do `<h2>`): linha nova aqui
 * é linha de carta a menos na lista.
 */
.inv-resultado__conta {
  display: inline-block;
  margin-left: 8px;
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  font-size: var(--fs-200, 11px);
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--muted, #8ea3bd);
}

.inv-resultado__lista {
  display: grid;
  /* 🚨 120 -> 152 px: a carta agora tem miniatura (30) + nome + ×N, e num terço
     de 120 px o nome quebrava em três linhas. Medido: com 152 o nome de duas
     palavras cabe em duas linhas e nada é cortado. */
  /* 🚨 145 e não 152: MEDIDO em 667×375, com 152 px a lista saía em 3 colunas e
     15 cartas à vista; com 145 saem 4 colunas e as 20 cabem. O nome continua com
     66 px (duas linhas, nada cortado — conferido nas 7 telas). */
  grid-template-columns: repeat(auto-fill, minmax(145px, 1fr));
  gap: 6px;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
  min-height: 0;
}

/* O `li` é só o lugar da carta: quem tem moldura, fundo e toque é o botão. */
.inv-resultado__lista li {
  display: flex;
  min-width: 0;
}

.inv-resultado__vazio {
  padding: 6px 9px;
  border-radius: var(--r-xs, 4px);
  border: 1px solid rgb(29 68 99 / 0.9);
  background: rgb(1 8 18 / 0.7);
  font-size: var(--fs-300, 12px);
}

/*
 * A CARTA DA RECOMPENSA (pedido do Gabriel, 13/08): miniatura + nome + ×N, e
 * clicar amplia.
 *
 * 🚨 É um `<button>`, não uma `div` com clique: é assim que a ampliação responde
 * ao teclado e ao leitor de tela, e é assim que o laço de foco a enxerga.
 */
.inv-peca {
  display: flex;
  align-items: center;
  gap: 7px;
  width: 100%;
  min-width: 0;
  padding: 4px 6px;
  border-radius: var(--r-sm, 8px);
  border: 1px solid rgb(29 68 99 / 0.9);
  background: rgb(1 8 18 / 0.7);
  color: var(--text, #e9edf6);
  font: inherit;
  font-size: var(--fs-300, 12px);
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--dur-fast, 0.12s) ease,
    background var(--dur-fast, 0.12s) ease;
}

.inv-peca:hover,
.inv-peca:focus-visible {
  border-color: var(--gold-300, #f2d089);
  background: rgb(12 34 56 / 0.85);
}

/*
 * O SELO DE RARIDADE É A MOLDURA DA MINIATURA.
 *
 * 🚨 A placa oficial (`ui/skillgrade/…`) entra como FUNDO da miniatura em vez de
 * virar um ícone a mais: a cor da raridade aparece sem gastar um pixel de altura
 * de linha — e altura de linha é o que decide quantas cartas caem na tela.
 */
.inv-peca__selo {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--r-xs, 4px);
  background: rgb(0 0 0 / 0.35) center / 100% 100% no-repeat;
}

.inv-peca__arte {
  width: 24px;
  height: 24px;
  object-fit: contain;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.6));
}

.inv-peca__arte--glifo {
  display: grid;
  place-items: center;
  font-size: 17px;
  line-height: 1;
}

.inv-peca__nome {
  flex: 1 1 auto;
  min-width: 0;
  line-height: 1.2;
  /* 🚨 `break-word` e NADA de `line-clamp`: o inspetor procura texto cortado, e
     cortar por baixo é tão cortado quanto cortar de lado. Nome comprido faz a
     carta CRESCER (a linha da grade acompanha), nunca esconde letra. */
  overflow-wrap: break-word;
}

.inv-peca__x {
  flex: 0 0 auto;
  padding: 1px 5px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid rgb(138 90 28 / 0.5);
  background: rgb(1 6 15 / 0.6);
  color: var(--gold-100, #fff3cf);
  font-size: var(--fs-200, 11px);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}

/*
 * ÊNFASE PROPORCIONAL À RARIDADE (o pedido: comum discreto, raro memorável).
 * Grau 0/1/2 ficam com a moldura fria de sempre; de EPICO (3) para cima a carta
 * assume a COR QUE O SERVIDOR MANDOU e ganha brilho — quanto mais alto, mais.
 */
.inv-resultado__lista li[data-grau='3'] .inv-peca,
.inv-resultado__lista li[data-grau='4'] .inv-peca,
.inv-resultado__lista li[data-grau='5'] .inv-peca {
  border-color: var(--rar, #9aa0a6);
  box-shadow:
    0 0 12px -4px var(--rar, #9aa0a6),
    inset 0 0 14px -8px var(--rar, #9aa0a6);
}

.inv-resultado__lista li[data-grau='5'] .inv-peca {
  box-shadow:
    0 0 20px -4px var(--rar, #9aa0a6),
    inset 0 0 22px -8px var(--rar, #9aa0a6);
}

/* Novidade: um ponto de ouro no canto da miniatura (sem gastar linha). */
.inv-resultado__lista li[data-novo='1'] .inv-peca__selo::after {
  content: '';
  position: absolute;
  top: -3px;
  right: -3px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1px solid #1a1205;
  background: linear-gradient(180deg, #fff3cf, var(--gold-500, #dc911e));
}

.inv-resultado__premio {
  margin: 0;
  padding: 7px 10px;
  border-radius: var(--r-sm, 8px);
  border: 1px solid rgb(242 208 137 / 0.45);
  background: rgb(242 208 137 / 0.08);
  font-size: var(--fs-300, 12px);
  font-weight: 700;
  text-align: center;
  color: var(--gold-100, #fff3cf);
}

.inv-resultado__erro {
  color: var(--error, #ff5f6a);
}

.inv-resultado__ok {
  align-self: center;
  min-width: 140px;
  /* 🚨 Media 39 px. É o botão que fecha a comemoração de um X50: erro de toque
     aqui devolve o jogador para a tela sem ele ter lido o que ganhou. */
  min-height: 44px;
  padding: 9px 18px;
  border-radius: var(--r-sm, 8px);
  border: 1px solid rgb(122 76 5 / 0.9);
  background: linear-gradient(180deg, var(--gold-100, #fff3cf), var(--gold-300, #f2d089) 60%, #dfb35e);
  color: var(--on-gold, #2a1a02);
  font: inherit;
  font-weight: 900;
  cursor: pointer;
}

/* Aviso curto no pé do palco (falta de bilhete, rota fora do ar…). */
.inv-aviso {
  /*
   * 🚨 FORA DO FLUXO, ancorado no pé da coluna do meio.
   *
   * Reservar "a caixa de uma linha" só resolvia enquanto TODO recado caísse em
   * uma linha — e não cai: *"Os números aparecem quando o servidor responder."*
   * quebra em duas a partir de 360 px, e como irmão da figura ele a empurrava
   * 8 px (360×640 e 320×568) e 11 px (667×375). Fora do fluxo ele não tem como
   * empurrar NADA, qualquer que seja o tamanho da frase: a reserva de uma linha
   * vive em `padding-bottom` da `.inv-centro` e a segunda linha cresce para
   * cima, sobre o círculo (decoração), atrás desta pílula opaca.
   *
   * 🚨 `left/right: 0` + `margin-inline: auto` + `width: fit-content` para
   * centrar: com `left: 50%` a largura disponível de um absoluto passa a ser
   * METADE da coluna e a frase quebraria ainda mais cedo — o contrário do que
   * este bloco quer.
   */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  width: fit-content;
  min-height: 30px;
  max-width: min(100%, 520px);
  margin: 0 auto;
  padding: 5px 12px;
  /*
   * 🚨 E ele é escrito EM CIMA DA PARTE CLARA do círculo mágico: o texto ocupava
   * y 707–735 e a elipse vai até ~743. Dourado sobre luz azul-clara não lê. A
   * caixa própria resolve a leitura e o pulo de uma vez.
   */
  border: 1px solid rgb(138 90 28 / 0.55);
  border-radius: var(--r-pill, 999px);
  background: rgb(3 10 22 / 0.9);
  box-shadow: 0 6px 18px -8px rgb(0 0 0 / 0.9);
  font-size: var(--fs-300, 12px);
  font-weight: 700;
  text-align: center;
  color: var(--gold-300, #f2d089);
}

/*
 * A DICA DE ONDE CONSEGUIR BILHETE: discreta de propósito. Ela mora na mesma
 * pílula do aviso (que é fora do fluxo e não empurra nada), mas em tom de
 * recado de apoio — não é erro nem comemoração.
 */
.inv-aviso[data-tom='dica'] {
  border-color: rgb(29 68 99 / 0.9);
  color: var(--muted, #8ea3bd);
  font-weight: 600;
}

.inv-aviso[data-tom='ruim'] {
  border-color: rgb(255 95 106 / 0.5);
  color: var(--error, #ff5f6a);
}

/* Vazio é o estado NORMAL da tela: guarda a altura e não desenha caixa nenhuma.
   🚨 Depois de `[data-tom]` de propósito — mesma especificidade, quem vem depois
   ganha, e um recado limpo não pode deixar a moldura vermelha para trás. */
.inv-aviso:empty {
  border-color: transparent;
  background: none;
  box-shadow: none;
}

/* ══ AFORDÂNCIA DE ROLAGEM ═════════════════════════════════════════
   Os dois lugares que rolam: o painel de explicação e a lista de recompensas.

   🚨 MEDIDO: a barra saía com 0 px de calha e ~2 px de traço — no celular a
   última linha lia como texto FATIADO, não como "tem mais abaixo". Duas
   afordâncias, porque uma só não bastou:
     1. barra de 9 px, dourada, com calha própria (não sobreposta), sempre
        desenhada quando há o que rolar;
     2. a borda de baixo APAGA o conteúdo — e só quando ainda falta conteúdo
        lá embaixo (`data-mais="1"`, escrito pelo JS no `scroll` e a cada
        repintura). Apagar sempre seria mentira no fim da rolagem.

   🚨 A máscara vai no CONTENEDOR que rola, não no conteúdo: assim ela fica
   parada na borda inferior enquanto o texto passa por baixo. */
.inv-texto,
.inv-resultado__lista {
  /* 🚨 `scrollbar-width: thin` VENCE `::-webkit-scrollbar` no Chromium: com ele
     declarado os 9 px abaixo são ignorados e a barra volta ao traço de 2 px. */
  scrollbar-width: auto;
  scrollbar-color: rgb(242 208 137 / 0.55) rgb(255 255 255 / 0.07);
  overscroll-behavior: contain;
}

.inv-texto::-webkit-scrollbar,
.inv-resultado__lista::-webkit-scrollbar {
  width: 9px;
}

.inv-texto::-webkit-scrollbar-track,
.inv-resultado__lista::-webkit-scrollbar-track {
  border-radius: var(--r-pill, 999px);
  background: rgb(255 255 255 / 0.07);
}

.inv-texto::-webkit-scrollbar-thumb,
.inv-resultado__lista::-webkit-scrollbar-thumb {
  border-radius: var(--r-pill, 999px);
  background: linear-gradient(180deg, #ffd98a, var(--gold-500, #dc911e));
  box-shadow: inset 0 0 0 1px rgb(122 76 5 / 0.75);
}

.inv-texto[data-mais='1'],
.inv-resultado__lista[data-mais='1'] {
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 22px), rgb(0 0 0 / 0.18) 100%);
  mask-image: linear-gradient(180deg, #000 calc(100% - 22px), rgb(0 0 0 / 0.18) 100%);
}

/* A luz que sobe enquanto o servidor responde. */
.inv-fx {
  position: absolute;
  left: 50%;
  bottom: 0;
  z-index: 3;
  width: min(70%, 380px);
  height: 92%;
  translate: -50% 0;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgb(255 255 255 / 0) 0%,
    rgb(200 230 255 / 0.14) 40%,
    rgb(255 255 255 / 0.4) 100%
  );
  filter: blur(10px);
  animation: inv-subir 900ms ease-in-out infinite alternate;
}

@keyframes inv-subir {
  from {
    opacity: 0.35;
  }
  to {
    opacity: 0.95;
  }
}


/* ══ A ENCENAÇÃO DA INVOCAÇÃO ══════════════════════════════════════
   Três atos: carga → estouro → revelação (cascata + herói). O JS de `anim.js`
   só desenha o canvas e troca `data-fase`; TODO o resto do movimento está aqui,
   em `transform`/`opacity`, para o navegador animar sem passar por layout.

   🚨 Nada de `backdrop-filter` e nada de sombra em elemento grande de tela
   cheia: foi o desfoque que já derrubou esta tela (a página não entregava quadro
   em 30 s na renderização por software). O escurecimento é um `fillRect` no
   canvas, que custa um preenchimento e não uma releitura da tela. */

/*
 * 🚨 O ESCUDO DE SAÍDA (13/08). A cena pulada fica no documento por 450 ms,
 * invisível mas ENGOLINDO ponteiro — é o que impede o `click` de compatibilidade
 * do toque de cair no botão de invocar atrás e COBRAR 50 BILHETES de novo
 * (medido: pointerdown t+0, click t+28 ms no X50). `opacity: 0` e não
 * `display: none`, porque `display: none` sai do teste de acerto e o clique
 * voltaria a atravessar. `visibility` também não serve pelo mesmo motivo.
 */
.inv-cena--escudo {
  opacity: 0;
  pointer-events: auto !important;
  /* Sem transição: desaparecer é instantâneo; o que dura é a guarda invisível. */
  transition: none !important;
}

.inv-cena {
  position: absolute;
  inset: 0;
  /* 🚨 Acima do palco (2), do rodapé (3) e do resultado (10) — e ABAIXO da
     ampliação (14). A pilha inteira continua dentro da `.inv`: nenhum z-index
     novo escapa para a página. */
  z-index: 12;
  display: grid;
  /* Uma área só: a grade de chips e o herói ficam CENTRADOS UM SOBRE O OUTRO. */
  grid-template-areas: 'meio';
  place-items: center;
  overflow: hidden;
  /* Cor de reserva: se o servidor não mandar cor, a cena fica cinza discreta. */
  --rar: #9aa0a6;
  --rar-luz: #ffffff;
  --tremor: 0px;
  cursor: pointer;
}

.inv-cena__fx {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  /* 🚨 O BUFFER É MENOR QUE A CAIXA (teto de 640 px, ver `anim.js`) e o
     navegador estica: tudo que ele desenha é brilho difuso, então a diferença
     não aparece e o custo cai com o quadrado da escala. */
}

/* O TREMOR do estouro — só de EPICO (grau 3) para cima, e uma vez só.
   🚨 `data-bateu` é um atributo que NUNCA volta atrás: preso ao `data-fase`, a
   troca de fase seguinte cancelava a animação no meio do tranco. */
.inv-cena[data-bateu='1'] {
  animation: inv-tremer 0.34s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.inv-cena[data-grau='4'] {
  --tremor: 5px;
}

.inv-cena[data-grau='5'] {
  --tremor: 8px;
  animation-duration: 0.5s;
}

@keyframes inv-tremer {
  0%, 100% { translate: 0 0; }
  12% { translate: calc(var(--tremor, 3px) * -1) calc(var(--tremor, 3px) * 0.4); }
  28% { translate: var(--tremor, 3px) calc(var(--tremor, 3px) * -0.5); }
  46% { translate: calc(var(--tremor, 3px) * -0.7) 0; }
  68% { translate: calc(var(--tremor, 3px) * 0.5) calc(var(--tremor, 3px) * 0.3); }
  86% { translate: calc(var(--tremor, 3px) * -0.2) 0; }
}

/* ── a cascata: uma peça por vez, rápido ─────────────────────────── */

.inv-cena__grade {
  grid-area: meio;
  display: grid;
  /* Trilha de tamanho fixo + `justify-content: center`: a grade se centra sozinha
     em qualquer largura sem eu ter de calcular colunas por tela. */
  --c: clamp(30px, 9vmin, 58px);
  --vao: clamp(4px, 1.1vmin, 9px);
  grid-template-columns: repeat(auto-fit, var(--c));
  justify-content: center;
  align-content: center;
  gap: var(--vao);
  /* 🚨 A LARGURA É O NÚMERO DE COLUNAS (`--cols` vem do JS, pela quantidade de
     peças): com a largura toda, um lote de 10 virava uma fileira solta de 9 e o
     bloco não lia como "as peças chegando". O `min(90%, …)` mantém a tela como
     teto — em 320 px quem manda continua sendo a tela. */
  width: min(90%, calc(var(--cols, 6) * (var(--c) + var(--vao))));
  max-height: 70%;
  transition: opacity 0.2s ease;
}

/* Ela existe desde o começo (as imagens decodificam durante a carga), mas só
   APARECE na revelação — e sai de cena quando o herói entra. */
.inv-cena[data-fase='carga'] .inv-cena__grade,
.inv-cena[data-fase='estouro'] .inv-cena__grade,
.inv-cena[data-fase='heroi'] .inv-cena__grade {
  opacity: 0;
}

.inv-cena__chip {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--c);
  height: var(--c);
  border-radius: var(--r-sm, 8px);
  border: 1px solid var(--rar, #9aa0a6);
  background: rgb(2 8 20 / 0.78);
  box-shadow: 0 0 10px -4px var(--rar, #9aa0a6);
  opacity: 0;
  scale: 0.45;
  rotate: -10deg;
  transition:
    opacity 0.16s ease,
    scale 0.16s cubic-bezier(0.2, 1.6, 0.4, 1),
    rotate 0.16s ease;
}

.inv-cena__chip[data-on='1'] {
  opacity: 1;
  scale: 1;
  rotate: 0deg;
}

.inv-cena__chip img {
  width: 76%;
  height: 76%;
  object-fit: contain;
}

/* Raro pipoca mais forte que comum: o chip de grau alto ganha halo. */
.inv-cena__chip[data-grau='4'],
.inv-cena__chip[data-grau='5'] {
  box-shadow:
    0 0 16px -2px var(--rar, #9aa0a6),
    inset 0 0 14px -6px var(--rar, #9aa0a6);
}

.inv-cena__chip b {
  position: absolute;
  right: -3px;
  bottom: -4px;
  padding: 0 3px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid rgb(122 76 5 / 0.9);
  background: linear-gradient(180deg, #fff3cf, var(--gold-300, #f2d089));
  color: #3d2903;
  font-size: clamp(8px, 1.7vmin, 10px);
  font-weight: 900;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}

/* ── o herói: a melhor peça do lote, grande ───────────────────────── */

.inv-cena__heroi {
  grid-area: meio;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(2px, 0.8vh, 8px);
  width: min(94%, 560px);
  opacity: 0;
  pointer-events: none;
}

.inv-cena[data-fase='heroi'] .inv-cena__heroi {
  /* 🚨 De 0,35 a 1 com passagem de 1,08: o "estufa e assenta" é o que faz a peça
     parecer que CHEGOU, em vez de aparecer. Uma animação só, no compositor. */
  animation: inv-entra-heroi 0.34s cubic-bezier(0.15, 1.45, 0.4, 1) both;
}

@keyframes inv-entra-heroi {
  from {
    opacity: 0;
    scale: 0.35;
  }
  to {
    opacity: 1;
    scale: 1;
  }
}

.inv-cena__moldura {
  position: relative;
  display: grid;
  place-items: center;
  /* 🚨 `vw` e não `vmin`: em 390×760 o `vmin` é a LARGURA e 40vmin dava 156 px
     de moldura — pequeno para o momento mais importante da tela. Com 52vw são
     203 px no celular e 320 no desktop, e a altura sobra nas duas. */
  width: clamp(140px, 52vw, 320px);
  height: clamp(140px, 52vw, 320px);
  border-radius: 50%;
  /* O halo é gradiente (custa um preenchimento), não sombra desfocada. */
  background:
    radial-gradient(circle, rgb(255 255 255 / 0.2) 0%, rgb(255 255 255 / 0) 62%),
    radial-gradient(circle, var(--rar, #9aa0a6) 0%, rgb(0 0 0 / 0) 72%);
}

.inv-cena__arte {
  /*
   * 🚨 `width`, NÃO `max-width`: com `max-width` a arte ficava no TAMANHO
   * NATURAL (ícone de habilidade tem 128 px) e boiava dentro de uma moldura de
   * 320 px no desktop. E com teto de 200 px porque acima disso o ícone de 128
   * começa a mostrar o pixel — a peça tem de crescer, não estourar.
   */
  width: min(78%, 200px);
  height: min(78%, 200px);
  object-fit: contain;
  filter: drop-shadow(0 6px 16px rgb(0 0 0 / 0.65));
}

.inv-cena__glifo {
  font-size: clamp(52px, 18vmin, 130px);
  line-height: 1;
  filter: drop-shadow(0 4px 12px rgb(0 0 0 / 0.7));
}

/* MOLDURA DOURADA + PULSO: de LENDARIO (grau 4) para cima. É o "tratamento
   extra" pedido para as raridades altas, e ele NÃO existe no comum. */
.inv-cena[data-grau='4'] .inv-cena__moldura,
.inv-cena[data-grau='5'] .inv-cena__moldura {
  box-shadow:
    0 0 0 2px rgb(255 243 207 / 0.45),
    0 0 46px -8px var(--rar, #9aa0a6);
  animation: inv-pulso-rar 1.7s ease-in-out infinite;
}

@keyframes inv-pulso-rar {
  50% {
    box-shadow:
      0 0 0 3px rgb(255 243 207 / 0.7),
      0 0 64px -6px var(--rar, #9aa0a6);
  }
}

.inv-cena__selo {
  width: clamp(46px, 13vw, 78px);
  height: auto;
  margin-top: -4px;
  filter: drop-shadow(0 2px 6px rgb(0 0 0 / 0.8));
}

.inv-cena__rar {
  font-family: var(--font-display, Georgia, serif);
  /* A palavra da RARIDADE é o texto mais alto da cena: é a informação que o
     jogador está esperando. 25 px no celular, 34 no desktop. */
  font-size: clamp(18px, 6.4vw, 34px);
  font-weight: 900;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  color: var(--rar-luz, #fff);
  text-shadow:
    0 0 18px var(--rar, #9aa0a6),
    0 2px 4px rgb(0 0 0 / 0.9);
  white-space: nowrap;
}

.inv-cena__nome {
  max-width: 100%;
  font-size: clamp(15px, 4.6vw, 26px);
  font-weight: 800;
  line-height: 1.2;
  text-align: center;
  color: #fff;
  text-shadow: 0 2px 6px rgb(0 0 0 / 0.9);
  overflow-wrap: break-word;
}

.inv-cena__pe {
  font-size: clamp(12px, 3vw, 16px);
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--gold-300, #f2d089);
  text-shadow: 0 2px 4px rgb(0 0 0 / 0.9);
}

/*
 * PULAR — obrigatório: ninguém assiste 50 animações.
 *
 * 🚨 O toque vale em QUALQUER lugar da cena (`pointerdown` na `.inv-cena`); este
 * botão existe para (1) dizer que dá para pular e (2) ser o alvo de teclado e de
 * leitor de tela. 44 px de altura porque é o único controle da cena e o dedo vai
 * nele com a tela tremendo.
 */
/*
 * 🚨 O BOTÃO DE PULAR SAIU DE CIMA DOS BOTÕES QUE GASTAM (13/08).
 *
 * Ele ficava no RODAPÉ da cena, exatamente sobre o X1/X10/X50 — sobreposição
 * medida de 74,9% a 88,6% da área do botão. Mesmo com as outras defesas, empilhar
 * um controle de "descartar" sobre um controle de "comprar" é convite a erro.
 * Agora vive no ALTO da cena, onde não há nada atrás que cobre bilhete.
 */
.inv-cena__pular {
  position: absolute;
  left: 50%;
  top: clamp(10px, 3.4vh, 30px);
  bottom: auto;
  translate: -50% 0;
  min-height: 44px;
  min-width: 156px;
  padding: 10px 20px;
  border-radius: var(--r-pill, 999px);
  border: 1px solid rgb(242 208 137 / 0.45);
  background: rgb(3 10 22 / 0.82);
  color: var(--gold-100, #fff3cf);
  font: inherit;
  font-size: var(--fs-300, 12px);
  font-weight: 800;
  letter-spacing: 0.06em;
  cursor: pointer;
  animation: inv-piscar-pular 2.4s ease-in-out infinite;
}

@keyframes inv-piscar-pular {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 1; }
}

.inv-cena__pular:hover,
.inv-cena__pular:focus-visible {
  border-color: var(--gold-300, #f2d089);
  background: rgb(52 28 0 / 0.7);
  animation: none;
  opacity: 1;
}

/* ══ A CARTA DE PERTO (a ampliação) ════════════════════════════════
   Pedido do Gabriel: *"caso o player queira, ele clica e vai para a tela onde
   ficam grandes para ver de perto — ou você amplia para ele quando ele clicar"*.

   🚨 Camada própria pendurada na RAIZ (não dentro do diálogo): assim o limite de
   tamanho é a TELA, que foi exatamente o que consertou o diálogo do X50. */

.inv-zoom {
  position: absolute;
  inset: 0;
  z-index: 14;
  display: grid;
  place-items: center;
  padding: 8px;
  /* Escurece o resultado atrás SEM desfocar nada (o desfoque é proibido aqui). */
  background: rgb(2 5 14 / 0.86);
  animation: inv-surgir 180ms var(--ease-out, cubic-bezier(0.2, 0.8, 0.25, 1)) both;
}

.inv-zoom__caixa {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(4px, 1.2vh, 10px);
  width: min(94%, 480px);
  max-height: 100%;
  padding: 14px;
  overflow-y: auto;
  border-color: var(--rar, rgb(138 90 28 / 0.45));
  box-shadow:
    var(--e-3, 0 18px 40px -12px rgb(0 0 0 / 0.9)),
    0 0 40px -14px var(--rar, #9aa0a6);
  text-align: center;
}

.inv-zoom__moldura {
  display: grid;
  place-items: center;
  width: min(58vmin, 300px);
  aspect-ratio: 1;
  border-radius: 50%;
  background:
    radial-gradient(circle, rgb(255 255 255 / 0.16) 0%, rgb(255 255 255 / 0) 62%),
    radial-gradient(circle, var(--rar, #9aa0a6) 0%, rgb(0 0 0 / 0) 74%);
}

.inv-zoom__arte {
  /* Mesma razão da cena: a carta de perto tem de MOSTRAR a peça grande. */
  width: min(82%, 230px);
  height: min(82%, 230px);
  object-fit: contain;
  filter: drop-shadow(0 6px 16px rgb(0 0 0 / 0.7));
}

.inv-zoom__glifo {
  font-size: min(26vmin, 130px);
  line-height: 1;
}

.inv-zoom__selo {
  width: clamp(38px, 9vmin, 64px);
  height: auto;
  margin-top: -6px;
  filter: drop-shadow(0 2px 6px rgb(0 0 0 / 0.8));
}

.inv-zoom__rar {
  font-family: var(--font-display, Georgia, serif);
  font-size: clamp(14px, 3.6vmin, 24px);
  font-weight: 900;
  letter-spacing: 0.18em;
  text-indent: 0.18em;
  text-transform: uppercase;
  color: var(--rar, #fff);
  text-shadow: 0 2px 6px rgb(0 0 0 / 0.9);
}

.inv-zoom__nome {
  font-size: clamp(15px, 3.4vmin, 22px);
  font-weight: 900;
  line-height: 1.2;
  color: var(--gold-100, #fff3cf);
  overflow-wrap: break-word;
}

.inv-zoom__meta {
  font-size: var(--fs-300, 12px);
  font-weight: 700;
  color: var(--muted, #8ea3bd);
}

.inv-zoom__ok {
  margin-top: 2px;
}

/* ══ CELULAR ═══════════════════════════════════════════════════════
   390×760 é o alvo (o jogo é jogado no celular). A tela deixa de ser três
   colunas e vira uma pilha; nada de rolagem na página, só dentro do texto. */

@media (max-width: 880px) {
  /*
   * 🚨 ORÇAMENTO DE ALTURA. Os alvos de 44 px (ficha +11, aba +14, X +12) e a
   * caixa reservada do aviso somam ~50 px, e no celular tudo isso sai da FIGURA,
   * que é o coração da tela. Cada valor apertado daqui para baixo existe para
   * devolver esses pixels: medido, a figura volta a 293 px em 390×760 (o mesmo
   * da base aprovada) e sobe de 183 para 199 px em 360×640.
   */
  .inv-topo {
    padding: 5px 10px;
    gap: 6px;
  }

  .inv-topo__titulo {
    display: none; /* o espaço é dos contadores */
  }

  /* O espaçador existe para empurrar os contadores no desktop. No celular o
     título sai, os contadores já se centram sozinhos e ele só gasta um vão de
     6 px — que em 320 px de largura é o que fazia o X passar da borda. */
  .inv-topo__espaco {
    display: none;
  }

  .inv-contadores {
    flex: 1 1 auto;
    justify-content: center;
    gap: 5px;
  }

  .inv-cont {
    min-width: 0;
    padding: 4px 9px 4px 6px;
    gap: 5px;
  }

  .inv-cont img {
    width: 17px;
    height: 17px;
  }

  .inv-cont b {
    font-size: var(--fs-300, 12px);
  }

  /*
   * 🚨 ALVO DE TOQUE DE 44 px nos controles mais tocados. Medido antes em 390×760
   * e 360×640: ficha 33, aba 30, X 32×32, "Continuar" 39 — 8 dos 12 controles
   * abaixo do mínimo, e só os botões de invocar (48) passavam. A base do jogo
   * está no celular; erro de toque aqui é bilhete gasto por engano.
   */
  .inv-x {
    width: 44px;
    height: 44px;
  }

  .inv-palco {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: 5px;
    padding: 0 10px;
  }

  /* Os seletores viram uma fileira de três fichas. */
  .inv-tipos {
    flex-direction: row;
    gap: 6px;
  }

  .inv-tipos::before {
    display: none;
  }

  .inv-tipo {
    /*
     * 🚨 `min-width: 0` junto com `flex: 1 1 0`: sem ele o CONTEÚDO é o piso da
     * ficha e as três saíam com larguras diferentes (a escolhida com 130 px e as
     * outras com 114, medido). Com o piso zerado cada uma fica com um terço
     * exato da fileira.
     *
     * 🚨 E em DUAS LINHAS (rótulo em cima, conta embaixo): num terço de 360 px
     * sobram 44 px para o texto e "Habilidade" pede 66 — lado a lado ele saía
     * cortado em "Habilid…". Empilhado cabe inteiro, e os 44 px de alvo de toque
     * já pagam a altura das duas linhas.
     */
    flex: 1 1 0;
    min-width: 0;
    min-height: 44px;
    flex-direction: column;
    justify-content: center;
    gap: 1px;
    padding: 5px 4px;
    border-radius: var(--r-sm, 8px);
    font-size: var(--fs-200, 11px);
    text-align: center;
  }

  .inv-tipo::after,
  .inv-tipo__marca {
    display: none; /* o ✦ e o ponto da trilha são enfeite de coluna */
  }

  /*
   * 🚨 No celular vale o rótulo CURTO. Medido na captura de 390×760: "Bilhete de
   * Habilidade" quebrava em duas linhas e a ficha inteira ia a 140 px de altura,
   * roubando da figura — que é o coração da tela.
   */
  .inv-tipo__nome {
    display: none;
  }

  .inv-tipo__curto {
    display: block;
    flex: 0 1 auto;
    min-width: 0;
    line-height: 1.15;
    /* Válvula do "um terço exato": se a fonte do sistema for mais larga que a
       medida, quem cede é o rótulo — não a largura da ficha. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .inv-figura {
    /* 🚨 470 -> 560: este teto só MORDE em tela alta (tablet 744x1133, onde a
       coluna do meio tem ~597 px). Em 390x760 a coluna dá 293 px e nada muda —
       o orçamento de altura do celular fica intacto, medido antes e depois. */
    height: min(100%, 560px);
    /* 2 px de margem + os 26 px de reserva do aviso: a MESMA soma de antes, para
       a figura ter exatamente a altura da base aprovada. */
    margin-bottom: 28px;
  }

  /* Cartas menores e menos numerosas: na tela estreita elas passavam por cima
     da figura. */
  .inv-carta {
    width: calc(var(--l, 42px) * 0.68);
    height: calc(var(--l, 42px) * 0.9);
  }

  .inv-carta:nth-child(4),
  .inv-carta:nth-child(8),
  .inv-carta:nth-child(9) {
    display: none;
  }

  .inv-lado {
    padding: 0;
    gap: 4px;
  }

  .inv-recompensa {
    padding: 4px 9px;
    gap: 8px;
  }

  .inv-medalha {
    width: 38px;
    height: 38px;
    font-size: 16px;
  }

  .inv-premio__carta {
    width: 38px;
    height: 38px;
  }

  .inv-premio__carta img {
    width: 26px;
    height: 26px;
  }

  .inv-aba {
    min-height: 44px;
    padding: 5px 2px;
    font-size: var(--fs-200, 11px);
  }

  .inv-aba img {
    width: 18px;
    height: 18px;
  }

  .inv-texto {
    /*
     * ALTURA FIXA na pilha do celular, não "até 24vh".
     *
     * 🚨 Medido: com o painel crescendo conforme o texto, trocar de aba mudava a
     * altura dele, a coluna do meio recebia o resto e a FIGURA pulava 22 px —
     * o mesmo defeito do aviso, por outra porta. Travado, a figura tem o mesmo
     * tamanho em Skills, Pets e Skins, e o texto que não couber rola dentro do
     * painel (é para isso que ele tem `overflow-y: auto`).
     *
     * 🚨 `box-sizing` declarado aqui: o resto do jogo põe `border-box` em tudo,
     * mas esta folha também roda no palco de teste, e sem ele os 18 px de recheio
     * entrariam FORA dos 24vh.
     */
    box-sizing: border-box;
    flex: 0 0 auto;
    height: 24vh;
    max-height: 24vh;
    padding: 8px 11px 10px;
  }

  /* Corpo em 11 px no celular: uma linha a menos no painel, e a mesma medida que
     as telas bem estreitas já usavam. */
  .inv-texto__intro,
  .inv-texto__corpo {
    font-size: var(--fs-200, 11px);
  }

  .inv-texto__intro {
    margin-bottom: 6px;
  }

  .inv-rodape {
    gap: 6px;
    padding: 6px 10px 8px;
  }

  .inv-bt {
    flex: 1 1 0;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    height: 48px;
    padding: 0 4px;
  }

  .inv-bt__rot {
    font-size: var(--fs-100, 10px);
  }

  .inv-bt__n {
    font-size: var(--fs-500, 15px);
  }

  /* Um quarto de 360 px dá 80 px de botão: aqui a faixa aperta o espacejamento
     em vez de estourar a caixa. */
  .inv-bt__breve {
    gap: 3px;
    font-size: 9px;
    letter-spacing: 0.03em;
  }

  .inv-bt__cadeado {
    width: 13px;
    height: 13px;
  }

  .inv-aviso {
    min-height: 26px;
    padding: 3px 10px;
    font-size: var(--fs-200, 11px);
  }

  /*
   * A COMEMORAÇÃO no celular: quase a tela toda. Na hora em que ela aparece é a
   * única coisa que importa, e cada pixel de recheio economizado aqui é uma
   * recompensa a mais visível na lista.
   */
  .inv-resultado {
    width: min(96%, 460px);
    max-height: calc(100% - 12px);
    gap: 6px;
    padding: 10px;
  }

  .inv-resultado__lista {
    gap: 5px;
  }

  .inv-peca {
    padding: 3px 5px;
    gap: 6px;
    font-size: var(--fs-200, 11px);
  }

  .inv-peca__selo {
    width: 30px;
    height: 30px;
  }

  .inv-peca__arte {
    width: 22px;
    height: 22px;
  }

  /* No celular o rodapé da cena é onde o polegar está: o botão de pular sobe
     um pouco para não brigar com a barra do navegador. */
  .inv-cena__pular {
    bottom: clamp(8px, 2.4vh, 20px);
    min-width: 148px;
  }
}

/*
 * CELULAR DEITADO (e qualquer janela baixa e larga).
 *
 * 🚨 MEDIDO em 740×360: a pilha do celular empilhava fichas + figura +
 * recompensa + abas + texto + rodapé em 360 px de altura e a FIGURA sobrava com
 * 2 px — sumia da tela. Deitado o que falta é altura, não largura: volta o
 * desenho de três colunas, em tamanho reduzido.
 *
 * Vem DEPOIS do bloco do celular de propósito: precisa desfazer o que ele fez.
 */
@media (max-height: 560px) and (min-width: 620px) {
  .inv-palco {
    grid-template-columns: minmax(0, 176px) minmax(0, 1fr) minmax(0, 264px);
    grid-template-rows: minmax(0, 1fr);
    gap: 8px;
  }

  .inv-tipos {
    flex-direction: column;
    gap: 6px;
  }

  .inv-tipo {
    /* 🚨 `flex: 1 1 0` vem do bloco do celular e serve para a FILEIRA. Numa
       coluna ele estica cada ficha até encher a altura, e a pílula de ouro
       virava um bloco de 90 px (visto na captura de 740×360). */
    flex: 0 0 auto;
    /* Aqui a coluna tem 176 px: o rótulo e a conta voltam a caber lado a lado —
       empilhar só existe para o terço de 360 px da fileira em pé. */
    flex-direction: row;
    gap: 6px;
    padding: 6px 10px;
    justify-content: flex-start;
    text-align: left;
  }

  .inv-figura {
    height: min(100%, 300px);
    /* 2 px de margem + os 36 px de reserva do aviso deitado (duas linhas). */
    margin-bottom: 38px;
  }

  .inv-lado {
    gap: 5px;
  }

  .inv-texto {
    /*
     * 🚨 O BLOQUEANTE do deitado. O bloco do celular põe `flex: 0 0 auto` (certo
     * para a PILHA, onde o painel tem altura própria); aqui a coluna da direita é
     * curta e, sem encolhimento, o painel passava POR BAIXO DO RODAPÉ — 18 px em
     * 740×360 e 3 px em 667×375. `0 1 auto` devolve o shrink e o `overflow-y`
     * do próprio painel rola o que não couber.
     */
    flex: 0 1 auto;
    height: auto;
    max-height: 100%;
    padding: 7px 9px 9px;
  }

  .inv-texto__intro {
    display: none; /* a frase de abertura é a primeira coisa a ceder espaço */
  }

  .inv-aviso {
    /* 🚨 DUAS linhas reservadas: a coluna do meio tem 264 px e "Os trajes ainda
       dormem no baú da Deusa." já quebra. */
    min-height: 36px;
    padding: 3px 8px;
    font-size: var(--fs-200, 11px);
  }

  .inv-rodape {
    padding: 6px 10px 8px;
  }

  .inv-bt {
    height: 44px;
  }
}

/* Janela baixa E estreita (celular deitado pequeno): sem colunas, só encolher. */
@media (max-height: 520px) and (max-width: 619px) {
  .inv-figura {
    height: min(100%, 200px);
  }

  .inv-texto {
    height: auto;
    max-height: 26vh;
  }
}

/*
 * A COMEMORAÇÃO EM TELA BAIXA.
 *
 * 🚨 Com o limite agora sendo a TELA, o que ainda aperta em 360–568 px de altura
 * é a conta linhas × colunas: alargar rende muito mais que apertar a altura.
 * MEDIDO em 667×375: com 460 px de largura a lista sai em 3 colunas e 17 linhas;
 * com 620 px, em 4 colunas e 13 linhas — e a tela deitada tem essa largura de
 * sobra. Depois do bloco do celular de propósito: precisa vencê-lo.
 */
@media (max-height: 620px) {
  .inv-resultado {
    width: min(96%, 620px);
    max-height: calc(100% - 10px);
    gap: 6px;
    padding: 10px 12px;
  }

  /*
   * 🚨 DEITADO, A COLUNA DA CARTA CEDE MAIS. Medido em 667×375 e 740×360: com
   * 145 px de trilha sobravam 3 colunas e 15 das 20 cartas à vista; com 132 px
   * saem 4 colunas e as 20 aparecem sem rolar. O nome fica com 60 px a 11 px de
   * fonte — a mesma folga que as telas de 320 px já usam sem cortar letra.
   */
  .inv-resultado__lista {
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  }
}

/*
 * TABLET E JANELA GRANDE DE CELULAR EM PÉ (as duas plataformas contam agora).
 *
 * 🚨 O bloco do celular limita o diálogo a 460 px, o que em 744×1133 deixava
 * 2 colunas de carta e 280 px de tela sobrando de cada lado. Aqui ele volta a
 * crescer: 654 px em 744, quatro colunas. Vem DEPOIS do bloco do celular de
 * propósito (precisa vencê-lo) e ANTES do de tela baixa, que continua mandando
 * no deitado.
 */
@media (min-width: 600px) and (min-height: 700px) {
  .inv-resultado {
    width: min(88%, 680px);
  }
}

/*
 * TELAS BEM ESTREITAS (320 px ainda existe entre os jogadores).
 *
 * 🚨 MEDIDO em 320×568: com o X de 44 px (o alvo de toque), as três pílulas de
 * contador + o X pediam 328 px e o X passava da borda direita. Aqui as pílulas
 * cedem o recheio — o alvo de toque não cede.
 */
@media (max-width: 380px) {
  .inv-topo {
    padding: 5px 8px;
    gap: 4px;
  }

  .inv-cont {
    padding: 3px 7px 3px 5px;
    gap: 4px;
  }

  .inv-cont img {
    width: 15px;
    height: 15px;
  }

  .inv-cont b {
    font-size: var(--fs-200, 11px);
  }

  /*
   * 🚨 A FAIXA "EM BREVE" TRANSBORDAVA 7 px em 320×568, cortando o "E" final e
   * um pedaço do cadeado. MEDIDO: um quarto de 320 px dá 70,5 px de botão, menos
   * os 4 px de recheio de cada lado sobram 62,5 px de caixa — e cadeado 13 +
   * vão 3 + "EM BREVE" a 9 px com 0,1em de espacejamento pedem 69,5. Aqui o
   * botão devolve 4 px de recheio e a faixa cede letra, vão e cadeado. O alvo de
   * toque (48 px de altura) não muda.
   */
  .inv-bt {
    padding: 0 2px;
  }

  .inv-bt__breve {
    gap: 2px;
    font-size: 8px;
    letter-spacing: 0;
  }

  .inv-bt__cadeado {
    width: 11px;
    height: 11px;
  }

  /*
   * 🚨 EM 320 px A CARTA CEDE 26 px DE COLUNA. O diálogo tem 307 px úteis: com
   * 152 px de trilha caberia UMA coluna e a lista viraria uma tira. Com 126 px
   * saem DUAS, e o nome (11 px) ainda quebra em duas linhas sem cortar letra —
   * medido nas duas telas estreitas.
   */
  .inv-resultado__lista {
    grid-template-columns: repeat(auto-fill, minmax(126px, 1fr));
  }

  .inv-peca__selo {
    width: 28px;
    height: 28px;
  }

  .inv-peca__arte {
    width: 21px;
    height: 21px;
  }

  /* "Especial" a 15 px pedia 62 px na mesma caixa: sem folga nenhuma. */
  .inv-bt--especial .inv-bt__n {
    font-size: var(--fs-400, 13px);
  }

  /*
   * 🚨 O PAINEL DE TEXTO ESCONDIA 55 px (Skills/Pets) e 79 px (Skins) aqui —
   * pior que os 21/44 de 360×640, e é a tela mais apertada. A frase de abertura
   * é a primeira a ceder espaço (o deitado já faz isso pelo mesmo motivo): ela é
   * a MESMA em todas as abas, enquanto o texto do bilhete escolhido é o que o
   * jogador veio ler. Com ela fora, o que sobra escondido cabe na rolagem — e
   * agora a rolagem se ANUNCIA (barra de 9 px + borda que apaga).
   */
  .inv-texto__intro {
    display: none;
  }
}

/* Quem pediu menos movimento no sistema não recebe nada girando. */
@media (prefers-reduced-motion: reduce) {
  .inv,
  .inv-ceu::before,
  .inv-ceu::after,
  .inv-halo,
  .inv-circulo__anel,
  .inv-circulo__marcas,
  .inv-carta,
  .inv-fx,
  .inv-resultado,
  /* 🚨 A cena nem é criada quando o sistema pede menos movimento (o `index.js`
     vai direto ao resultado). Estas linhas são cinto e suspensório: se um dia
     alguém chamar a encenação nesse modo, ela não pisca nem treme. */
  .inv-cena,
  .inv-cena__chip,
  .inv-cena__heroi,
  .inv-cena__moldura,
  .inv-cena__pular,
  .inv-zoom {
    animation: none;
  }

  /* Sem animação, o chip e o herói precisam NASCER visíveis: os dois começam
     apagados de propósito e é a animação que os traz — sem ela, ficariam
     invisíveis para sempre. */
  .inv-cena__chip,
  .inv-cena__heroi {
    opacity: 1;
    scale: 1;
    rotate: 0deg;
  }
}

/* ── Relacionamento com a Deusa (#398) ─────────────────────────────
   Pedido do Gabriel: a barra que já existe no painel ✦ também aqui, que é a
   tela da Deusa que ele abre de verdade.

   🚨 Reusa `.inv-barra` de propósito. Uma barra desenhada só para este painel
   ficaria com outro brilho e outra altura ao lado da barra de nível, a 10px de
   distância — e duas barras quase iguais chamam mais atenção do que duas
   iguais. */

.inv-relacao {
  display: grid;
  gap: 6px;
  padding: 10px 12px;
}

.inv-relacao__topo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

.inv-relacao__rot {
  /* Mesma voz do rótulo do nível, ao lado. */
  white-space: nowrap;
  font-size: var(--fs-200, 11px);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold-300, #f2d089);
  opacity: 0.85;
}

.inv-relacao__n {
  flex: 0 0 auto;
  font-size: 18px;
  font-weight: 900;
  line-height: 1;
  color: var(--gold-100, #fff3cf);
  font-variant-numeric: tabular-nums;
}

.inv-relacao__n i {
  font-size: 11px;
  font-style: normal;
  font-weight: 700;
  color: var(--muted, #8ea3bd);
}

.inv-relacao__nota {
  margin: 0;
  font-size: var(--fs-200, 11px);
  line-height: 1.3;
  color: var(--muted, #8ea3bd);
}

/* Vazio (sem `state.deusa`): apaga em vez de mostrar zero. */
.inv-relacao:has([data-papel='rel-barra'][data-vazia='1']) .inv-relacao__n {
  color: var(--muted, #8ea3bd);
}


/* ══════════════════════════════════════════════════════════════════
 * O X100 NO LUGAR DO "ESPECIAL" (#1068)
 * ══════════════════════════════════════════════════════════════════
 *
 * *"Agora que temos o botão de 100x, pode substituir o botão que está escrito
 * Especial na Deusa pelo o de 100x."*
 *
 * Ele fica com o destaque que era do Especial — é o maior lote, e merece se
 * distinguir do X1/X10/X50 — mas sem nada do ar de "travado": o cadeado, o
 * "Em breve" e o filtro apagado eram justamente o que dizia ao jogador para não
 * tentar. Aqui é o contrário: este cobra bilhete e funciona.
 */
.inv-bt--cem {
  border-color: var(--gold-500, #dc911e);
  background: linear-gradient(180deg, #dc911e, #8a5a1c);
  color: #2a1a02;
}
.inv-bt--cem .inv-bt__rot { opacity: 0.85; }
.inv-bt--cem .inv-bt__n { color: #2a1a02; }
.inv-bt--cem:disabled { opacity: 0.45; }

/*
 * ── Botões de invocação menores (#1115, 24/08) ──────────────────
 *
 * *"diminui os botões de invocação e acrescenta um de 500x… e foque em
 * deixá-los com a mesma cor dos outros"*.
 *
 * 🚨 Eram 172x62 calibrados para QUATRO botões (o comentário do bloco original
 * explica de onde vieram os números). Agora são CINCO: mantendo aquele tamanho
 * o X500 empurraria a linha e quebraria o rodapé em telas estreitas. O
 * `flex-basis` menor com `flex-shrink` deixa os cinco caberem e encolherem
 * juntos, em vez de um deles cair para a linha de baixo.
 */
.inv-rodape .inv-bt {
  flex: 1 1 118px;
  height: 52px;
  padding: 0 10px;
  gap: 4px;
}
.inv-rodape .inv-bt__rot { font-size: 0.72rem; }
.inv-rodape .inv-bt__n { font-size: 0.95rem; }
