/* =========================================================
   DAVI · LEVEL 10 UNLOCKED
   Uma mini fase de videogame construída em LEGO, com o Davi
   como personagem principal.

   Decisões registradas no Obsidian que este arquivo respeita:
   sem emoji, sem convite infantil genérico, sem fotorrealismo,
   base azul-marinho/preto de HUD, mobile first.
   ========================================================= */

:root {
  --vermelho: #e5342b;
  --azul:     #1b8ce3;
  --amarelo:  #ffc60a;
  --verde:    #35b04a;

  --fundo:   #070b16;
  --fundo-2: #0d1426;
  --carta:   #151d33;
  --linha:   #27324e;

  --texto:   #f2f5fa;
  --texto-2: #95a3c0;

  --display: 'Russo One', system-ui, sans-serif;
  --corpo:   'Outfit', system-ui, -apple-system, sans-serif;

  --raio: 14px;
  --gutter: 20px;
  --max: 560px;
}

*, *::before, *::after { box-sizing: border-box; }

/* O atributo hidden vence qualquer display daqui. Sem isto o "display:grid"
   do formulário do RSVP aparece antes de a pessoa escolher "EU VOU!". */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fundo);
  color: var(--texto);
  font-family: var(--corpo);
  font-size: 16px;
  line-height: 1.55;
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }

/* =====================================================================
   FASE 0 · ABERTURA ARCADE
   ===================================================================== */

.arcade {
  display: none; /* o JS liga. Sem script, o convite abre direto. */
  position: fixed;
  inset: 0;
  z-index: 100;
  background: radial-gradient(90% 70% at 50% 40%, #101a33 0%, #05070f 75%);
  align-items: center;
  justify-content: center;
  text-align: center;
  cursor: pointer;
}
.arcade--ativa { display: flex; }
.arcade--saindo { animation: sairArcade .6s ease forwards; }
@keyframes sairArcade { to { opacity: 0; visibility: hidden; } }

/* Linhas de varredura, o jeito mais barato de dizer "tela de fliperama". */
.arcade__varredura {
  position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background: repeating-linear-gradient(180deg, transparent 0 2px, rgba(0,0,0,.35) 2px 4px);
}

.arcade__palco { position: relative; width: 100%; padding: 0 24px; }

.etapa { display: none; }
.etapa--ativa { display: block; animation: entrarEtapa .45s ease both; }
@keyframes entrarEtapa { from { opacity: 0; transform: translateY(14px) scale(.96); } }

.arcade__texto {
  margin: 18px 0 0;
  font-family: var(--display);
  font-size: clamp(1.3rem, 8vw, 2rem);
  letter-spacing: .18em;
  color: var(--amarelo);
}
.arcade__texto--player { color: var(--azul); }

.arcade__nome {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(3.6rem, 22vw, 6.5rem);
  line-height: .9;
  background: linear-gradient(180deg, #fff 25%, #8fb6e8 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: zoomNome .8s cubic-bezier(.2,1.4,.4,1) both;
}
@keyframes zoomNome { from { opacity: 0; transform: scale(.4); } }

.arcade__dica {
  margin: 12px 0 0;
  font-size: .78rem; letter-spacing: .22em; color: var(--texto-2);
  text-transform: uppercase;
}

.piscar { animation: piscar 1s steps(2, end) infinite; }
@keyframes piscar { 50% { opacity: .12; } }

/* A moeda. Gira de verdade e cai quando a pessoa toca. */
.moeda-grande {
  width: 92px; height: 92px; margin: 0 auto;
  filter: drop-shadow(0 8px 18px rgba(255,198,10,.4));
  animation: girar 2.4s linear infinite;
}
@keyframes girar { 50% { transform: rotateY(180deg) scaleX(.12); } }

.arcade--inserindo .moeda-grande { animation: cair .7s cubic-bezier(.5,0,.9,.6) forwards; }
@keyframes cair {
  60%  { transform: translateY(40px) rotateY(540deg) scale(.7); opacity: 1; }
  100% { transform: translateY(150px) rotateY(900deg) scale(.2); opacity: 0; }
}

/* Barra de "carregando" do PLAYER 1. */
.arcade__barra {
  width: min(220px, 62vw); height: 8px; margin: 20px auto 0;
  border: 2px solid var(--linha); border-radius: 99px; overflow: hidden;
}
.arcade__barra span {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, var(--azul), var(--amarelo));
  transform: scaleX(0); transform-origin: left center;
  animation: carregar .95s ease-out forwards;
}
@keyframes carregar { to { transform: scaleX(1); } }

/* "pular abertura" e "entrar sem som", lado a lado no rodapé da abertura. */
.arcade__acoes {
  position: absolute; bottom: 26px; left: 0; right: 0;
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; padding: 0 16px;
}
.arcade__pular {
  background: none; border: 1px solid var(--linha); border-radius: 99px;
  color: var(--texto-2); font-family: var(--corpo); font-size: .76rem;
  padding: 8px 18px; cursor: pointer; letter-spacing: .1em;
}
.arcade__pular:hover { color: var(--texto); border-color: var(--texto-2); }

/* =====================================================================
   HUD
   ===================================================================== */

/* Absoluto de verdade: a regra genérica de .fase > * deixa o HUD e a seta de fora.
   Centralizado por left + translateX pra valer também em tela larga. */
.hud {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%); z-index: 5;
  width: min(100%, 720px);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 8px;
  padding: 12px var(--gutter);
  font-size: .64rem; letter-spacing: .14em;
}
/* Convite nominal: segunda linha do HUD com o nome das crianças (PLAYER 2). */
.hud__p2 {
  flex-basis: 100%; padding-top: 2px;
  font-family: var(--display); font-size: .62rem; letter-spacing: .14em; line-height: 1;
  color: var(--azul); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hud__item { display: inline-flex; align-items: center; gap: 6px; color: var(--amarelo); font-family: var(--display); }
.hud__item--volta { color: var(--texto-2); letter-spacing: .16em; }
.hud__item--volta strong { color: var(--amarelo); }
.hud .ico { width: 16px; height: 16px; }
.hud__som {
  position: relative;
  background: none; border: 1px solid var(--linha); border-radius: 99px;
  color: var(--texto-2); font-family: var(--corpo); font-size: .6rem;
  letter-spacing: .12em; padding: 5px 11px; cursor: pointer;
}
/* Área de toque de 84x44 sem mexer na altura do HUD (calculada pra caber acima da blocada):
   o desenho segue 72x24, o dedo ganha 10px em cima e embaixo e 6px nos lados. */
.hud__som::before { content: ''; position: absolute; inset: -10px -6px; }
.hud__som[aria-pressed="true"] { color: var(--verde); border-color: var(--verde); }

/* Avatar do piloto: rosto do Davi num círculo com borda amarela. Tamanho vem daqui, não da imagem. */
.avatar { display: block; flex: none; border-radius: 50%; overflow: hidden; border: 1.5px solid var(--amarelo); background: #0b1120; }
.avatar img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; transform: scale(.92); }
.avatar--hud { width: 28px; height: 28px; }
.avatar--ficha { width: 52px; height: 52px; border-width: 2px; }

/* =====================================================================
   FASES
   ===================================================================== */

.fase {
  position: relative;
  padding: 70px var(--gutter);
  text-align: center;
}
/* Ficam de fora os absolutos: pista, bandeira, brilho, estrelinhas, o .premio (salta do bloco
   ou do TOTAL), o HUD e a seta. Esta regra pesa mais que a de cada um deles. */
.fase > *:not(.pista):not(.bandeira):not(.brilho):not(.estrelinhas):not(.premio):not(.hud):not(.descer) {
  position: relative; z-index: 2;
  max-width: var(--max); margin-left: auto; margin-right: auto;
}

.fase__selo {
  margin: 0 0 6px;
  font-size: .64rem; letter-spacing: .28em; font-weight: 800; color: var(--azul);
}
.fase__titulo {
  margin: 0 0 10px;
  font-family: var(--display);
  font-size: clamp(1.45rem, 7.4vw, 2.1rem);
  letter-spacing: .03em;
  overflow-wrap: anywhere; /* último recurso em tela estreita; com o clamp as palavras cabem inteiras */
}
.fase__apoio { margin: 0 0 26px; color: var(--texto-2); font-size: .94rem; }
/* Título com um NPC pequeno ao lado (Mario 3D na pergunta do RSVP).
   O WebP tem alpha real (108x198): entra direto sobre o fundo, com a mesma sombra dos outros NPCs. */
.fase__titulo--npc { display: flex; align-items: center; justify-content: center; gap: 10px; }
.fase__titulo--npc span { min-width: 0; }
.npc--mario3d { flex: none; width: 54px; height: 99px; }

/* ---------------------- FASE 1 · HERO ---------------------- */

/* A primeira tela cabe em 100svh com a arte inteira. --hero-resto é a soma de tudo que não é a arte
   (padding, blocada, nome, level, frase, margens): a largura da arte sai de 100svh menos isso.
   O padding-bottom de 64px reserva a faixa do rótulo .descer (caixa de 42px em bottom:14px), assim
   a arte em repouso termina acima dele em qualquer altura de tela.
   Com convite nominal entram a linha PLAYER 2 no HUD e a frase do convidado: resto maior. */
.fase--hero {
  --hero-resto: 336px;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  padding: 56px var(--gutter) 64px;
  overflow: hidden;
  background: linear-gradient(180deg, #0a1122 0%, #070b16 100%);
}
body.convidado .fase--hero { --hero-resto: 384px; padding-top: 76px; }
/* Frase do convidado em duas linhas (nome longo em 360px): mais 21px de resto, a arte encolhe e não passa do rótulo. */
body.convidado--longo .fase--hero { --hero-resto: 405px; }

.brilho {
  position: absolute; left: 50%; top: 42%; transform: translateX(-50%);
  width: 150%; height: 60%; pointer-events: none;
  background:
    radial-gradient(42% 42% at 50% 50%, rgba(27,140,227,.22), transparent 70%),
    radial-gradient(32% 32% at 28% 62%, rgba(229,52,43,.13), transparent 70%);
  filter: blur(8px);
}

/* Estrelas de fundo, geradas pelo JS. Poucas de propósito: celular primeiro. */
.estrelinhas { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.estrelinhas svg {
  position: absolute; width: 14px; height: 14px; opacity: .5;
  animation: brilhar 3.5s ease-in-out infinite;
}
@keyframes brilhar { 50% { opacity: .95; transform: scale(1.25); } }

.hero__miolo { width: 100%; position: relative; }

/* =====================================================================
   MUNDO MARIO KART
   Blocos de interrogação, pista e linha de chegada desenhados em SVG e
   CSS próprios; o Davi e os NPCs entram como sprites. A nota 05 pede
   referência forte e reconhecível, sem transformar o Davi em outro
   personagem.
   ===================================================================== */

/* Fileira da fase: Davi pulando (56x84) ao lado dos três blocos (46px, alinhados no topo).
   Altura fixa de 84px: nada que carregue depois muda a primeira tela. */
.blocada {
  position: relative; z-index: 1;
  display: flex; align-items: flex-start; justify-content: center; gap: 14px;
  height: 84px; margin: 0 0 6px; overflow-anchor: none;
}

/* z-index 1: o Yoshi (z 0) nasce atrás do bloco e sobe com a metade de baixo escondida por ele. */
.tijolo {
  position: relative; z-index: 1;
  width: 46px; height: 46px; padding: 0;
  background: none; border: 0; cursor: pointer;
  filter: drop-shadow(0 6px 10px rgba(0,0,0,.5));
  animation: balancar 3.2s ease-in-out infinite;
}
.tijolo:nth-of-type(2) { animation-delay: .35s; }
.tijolo:nth-of-type(3) { animation-delay: .7s; }
.tijolo:focus-visible { outline: 3px solid var(--amarelo); outline-offset: 4px; border-radius: 8px; }
@keyframes balancar { 50% { transform: translateY(-5px); } }

/* A batida: o bloco sobe, volta e fica gasto. */
.tijolo--batido { animation: bater .35s ease; }
.tijolo--gasto { filter: grayscale(.75) brightness(.72) drop-shadow(0 4px 8px rgba(0,0,0,.4)); cursor: default; }
@keyframes bater {
  35% { transform: translateY(-16px) scale(1.06); }
  70% { transform: translateY(3px) scale(.97); }
}

/* O prêmio que salta do bloco. */
.premio {
  position: absolute; width: 26px; height: 26px;
  pointer-events: none; z-index: 6;
  animation: saltar .85s cubic-bezier(.2,.8,.4,1) forwards;
}
@keyframes saltar {
  0%   { opacity: 0; transform: translateY(0) scale(.5); }
  25%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-64px) scale(1.15); }
}

/* Trecho de pista com o kart atravessando, entre as fases. 150px: o kart inteiro (caixa de 115px
   a 8px do chão) cabe sem cortar. contain + overflow-anchor: nada aqui mexe no resto da página. */
.trecho { position: relative; height: 150px; margin-top: 30px; overflow: hidden; contain: layout paint; overflow-anchor: none; }
.trecho__asfalto {
  position: absolute; left: 0; right: 0; bottom: 0; height: 26px; overflow: hidden;
  background: linear-gradient(180deg, #1a2138, #0d1426);
  border-top: 2px solid var(--linha);
}
/* Faixa central do asfalto: período de 44px, anda um período por volta, só com transform. */
.trecho__asfalto::before {
  content: ''; position: absolute; left: 0; top: 50%; width: calc(100% + 44px); height: 3px; margin-top: -2px;
  background: repeating-linear-gradient(90deg, transparent 0 26px, rgba(255,255,255,.35) 26px 44px);
  will-change: transform;
  animation: faixas .7s linear infinite;
}
@keyframes faixas { to { transform: translateX(-44px); } }

/* O comboio (rival atrás, Davi na frente) atravessa a pista só com transform: o percentual
   é a largura do próprio wrapper, que é a da pista. Nada anima left ou top.
   z-index 2: passa na frente das moedas; pointer-events none: as moedas continuam tocáveis. */
.comboio {
  position: absolute; left: 0; right: 0; top: 0; bottom: 0; z-index: 2;
  pointer-events: none; will-change: transform;
  animation: atravessar 5.2s linear infinite;
}
@keyframes atravessar { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.comboio--chegada { animation-duration: 3.8s; }

/* Linha de chegada, no fim da experiência. Mesma altura fixa da pista: o kart chegando não muda o documento. */
.chegada { position: relative; height: 150px; margin-top: 26px; overflow: hidden; contain: layout paint; overflow-anchor: none; }
.chegada__faixa {
  position: absolute; left: 0; right: 0; bottom: 0; height: 22px;
  background: repeating-conic-gradient(#f2f5fa 0% 25%, #12182a 0% 50%) 0 0 / 14px 14px;
  border-radius: 3px;
}
/* Davi no kart: caixa fixa de 160x115 (46% de 350). Dentro dela o estático e, quando chega, o vivo,
   os dois absolutos e alinhados embaixo: a troca não move nada. Viaja com o comboio; aqui só o balanço. */
.kart-real {
  position: absolute; left: 118px; bottom: 8px; width: 160px; height: 115px;
  filter: drop-shadow(0 6px 10px rgba(0,0,0,.55));
  will-change: transform;
  animation: balancoKart .7s ease-in-out infinite;
}
.kart-real picture, .kart-real img, .kart-real video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; object-position: center bottom;
}
.comboio--chegada .kart-real { left: 118px; bottom: 6px; }
/* Rival: Mario 3D no kart, atrás e menor que o Davi (104 contra 160). */
.npc--rival { position: absolute; left: 0; bottom: 10px; width: 104px; height: 80px; }
.comboio--chegada .npc--rival { bottom: 8px; }
@keyframes balancoKart { 0%, 100% { transform: rotate(-1deg); } 50% { transform: rotate(1deg) translateY(-2px); } }
/* Linhas de velocidade atrás do kart: só opacity e scaleX. */
.kart-real::before, .kart-real::after {
  content: ""; position: absolute; right: 100%; height: 3px; border-radius: 2px;
  transform-origin: right center;
  animation: rastro .38s ease-in-out infinite alternate;
}
.kart-real::before { bottom: 30%; width: 44px; margin-right: 6px; background: linear-gradient(90deg, transparent, rgba(255,255,255,.75)); }
.kart-real::after  { bottom: 52%; width: 28px; margin-right: 14px; animation-delay: .15s; background: linear-gradient(90deg, transparent, rgba(255,198,10,.7)); }
@keyframes rastro { from { opacity: .25; transform: scaleX(.5); } to { opacity: .85; transform: scaleX(1); } }

/* Itens correndo na pista, coletáveis. z-index abaixo do comboio: passam atrás do kart, e continuam
   tocáveis porque o comboio não recebe toque. */
.corrida-itens {
  position: absolute; left: 0; right: 0; bottom: 32px; height: 30px; z-index: 1;
  pointer-events: none;
}
.item {
  position: absolute; bottom: 0; left: 0; transform: translateX(-40px);
  width: 30px; height: 30px; padding: 0;
  background: none; border: 0; cursor: pointer; pointer-events: auto;
  filter: drop-shadow(0 4px 6px rgba(0,0,0,.5));
  will-change: transform;
  animation: correrItem 6s linear infinite;
}
.item:nth-child(2) { animation-delay: 1.5s; }
.item:nth-child(3) { animation-delay: 3s; }
.item:nth-child(4) { animation-delay: 4.5s; }
.item svg { width: 100%; height: 100%; animation: girar 1.4s linear infinite; }
.item--estrela svg { animation: brilhar 1.2s ease-in-out infinite; }
.item:focus-visible { outline: 2px solid var(--amarelo); border-radius: 50%; }
@keyframes correrItem { from { transform: translateX(-40px); } to { transform: translateX(min(110vw, 800px)); } }

/* Ao pegar: some pra cima de onde estava (--x gravado no toque pelo app.js), e na próxima volta reaparece. */
.item--pega { animation: pegar .5s ease-out forwards !important; }
@keyframes pegar {
  from { transform: translateX(var(--x, -40px)); }
  to   { opacity: 0; transform: translate(var(--x, -40px), -46px) scale(1.4); }
}

/* Davi pulando, na fileira dos blocos. Caixa fixa de 56x84 (a altura da fileira); dentro dela o estático
   e, quando carrega, o vivo, os dois absolutos e alinhados embaixo. */
.pulo { position: relative; flex: none; width: 56px; height: 84px; filter: drop-shadow(0 8px 14px rgba(0,0,0,.55)); }
.pulo picture, .pulo img, .pulo video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; object-position: center bottom;
}
.pulo--pulando { animation: pularDavi .5s cubic-bezier(.3,1.5,.6,1); }
@keyframes pularDavi { 40% { transform: translateY(-30px); } }

/* Davi vivo (webm ou WebP animado), criado pelo app.js dentro da mesma caixa do estático.
   Entra por opacity: o estático é o poster e nada muda de tamanho. */
.pulo-vivo, .kart-vivo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; object-position: center bottom;
  opacity: 0; pointer-events: none;
}
.kart-vivo { transition: opacity .3s ease; }
.pulo--vivo .pulo-vivo, .kart-real--vivo .kart-vivo { opacity: 1; }
.pulo--vivo picture, .kart-real--vivo .kart-real__foto { opacity: 0; }

/* Vidas no HUD. */
.hud__item--vidas { gap: 3px; }
.hud__item--vidas i {
  display: block; width: 11px; height: 11px; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #8df0a0, #35b04a 55%, #1d6b2b);
  box-shadow: 0 0 6px rgba(53,176,74,.6);
}
.hud__item--vidas i.nova { animation: ganharVida .5s cubic-bezier(.3,1.6,.6,1); }
@keyframes ganharVida { from { transform: scale(0); } }

/* Sprites opcionais (data-sprite). O encaixe fica invisível, com o espaço reservado, até a imagem
   carregar; o app.js põe .sprite--ok. Sem o arquivo o site segue sem ele. */
[data-sprite]:not(.sprite--ok) { visibility: hidden; }

/* NPCs do cenário (Yoshi, Toad, Mario), sempre menores que o Davi da mesma cena. */
.npc { filter: drop-shadow(0 6px 10px rgba(0,0,0,.55)); object-fit: contain; }

/* Yoshi sai de dentro do 3º bloco: absoluto na fileira, o app.js grava o left no toque (centro do bloco).
   Pixel art de 200px em 72px: pixelated, sem borrão. Sobe 44px: a metade de baixo fica atrás do bloco. */
.npc--yoshi {
  position: absolute; top: 0; left: 50%; z-index: 0;
  width: 72px; height: 72px; image-rendering: pixelated; pointer-events: none;
  opacity: 0; transform: translate(-50%, 10px) scale(.2);
}
.npc--yoshi.npc--sair { animation: sairYoshi 2.4s cubic-bezier(.2,1.3,.4,1) forwards; }
@keyframes sairYoshi {
  0%   { opacity: 0; transform: translate(-50%, 10px) scale(.2); }
  22%  { opacity: 1; transform: translate(-50%, -44px) scale(1); }
  78%  { opacity: 1; transform: translate(-50%, -40px) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -60px) scale(.9); }
}

.nome {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(2.8rem, 15vw, 4.8rem);
  line-height: .9;
  background: linear-gradient(180deg, #fff 30%, #9fbde4 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: 0 10px 40px rgba(27,140,227,.3);
}

.level { display: flex; align-items: center; gap: 10px; margin: 8px 0 2px; }
.level__risco { flex: 1; height: 2px; background: linear-gradient(90deg, transparent, var(--amarelo)); }
.level__risco:last-child { background: linear-gradient(90deg, var(--amarelo), transparent); }
.level__texto {
  font-family: var(--display);
  font-size: clamp(.8rem, 3.6vw, 1.02rem);
  letter-spacing: .15em; color: var(--amarelo); white-space: nowrap;
}
.level__texto strong {
  display: inline-block; padding: 0 6px; border-radius: 5px;
  background: var(--amarelo); color: #0b0e14; transform: skewX(-8deg);
}
.level.destravar .level__texto { animation: piscar .45s steps(2) 3; }

.hero__frase { margin: 6px 0 0; color: var(--texto-2); font-size: .94rem; line-height: 1.4; }
/* Convite nominal: "E você, {nome}, está convidado(a)!". Com body.convidado a linha já reserva
   o lugar antes de a API responder: nada salta quando o nome chega. */
.hero__convite { margin: 4px 0 0; color: var(--amarelo); font-weight: 600; font-size: .94rem; line-height: 1.4; }
body.convidado .hero__convite[hidden] { display: block !important; visibility: hidden; min-height: 1.4em; }

/* A ARTE DO DAVI. Cena fechada: entra inteira, sem corte, sem texto por cima.
   Largura = o que sobra de 100svh depois do resto do hero, vezes a proporção 1087/1446 (0,7517).
   Navegador sem svh ignora a segunda largura e fica com 100%. */
.arte {
  display: block; position: relative;
  width: 100%; max-width: 400px;
  width: min(100%, 400px, calc((100svh - var(--hero-resto)) * .7517));
  margin: 10px auto 0;
  border-radius: 18px;
  animation: flutuar 5s ease-in-out infinite;
}
@keyframes flutuar { 50% { transform: translateY(-7px); } }

.arte img {
  width: 100%; height: auto; border-radius: 18px;
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 0 0 4px rgba(7,11,22,.9), 0 18px 50px rgba(27,140,227,.3), 0 30px 70px rgba(0,0,0,.55);
}
/* A base emenda com o fundo. Leve: mais que isso escurece o kart e o sapato. */
.arte::after {
  content: ''; position: absolute; left: 1px; right: 1px; bottom: 0; height: 9%;
  border-radius: 0 0 18px 18px; pointer-events: none;
  background: linear-gradient(180deg, transparent, rgba(7,11,22,.6));
}
.arte.sem-arte img {
  border: 2px dashed var(--linha); box-shadow: none;
  background: repeating-linear-gradient(45deg, #121a2e 0 12px, #151d33 12px 24px);
}
.arte.sem-arte::after { display: none; }

/* Pista em perspectiva, no rodapé do hero. */
.pista { position: absolute; left: 0; right: 0; bottom: 12px; height: 90px; overflow: hidden; z-index: 1; }
.pista__chao {
  position: absolute; left: 50%; bottom: 0;
  width: 240%; height: 190px; overflow: hidden;
  transform: translateX(-50%) perspective(220px) rotateX(62deg);
  transform-origin: bottom center;
  background: linear-gradient(180deg, #0d1426, #1a2138);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 55%);
          mask-image: linear-gradient(180deg, transparent, #000 55%);
}
/* As faixas do chão andam num filho, só com transform (período de 54px). O chão fica com a perspectiva. */
.pista__chao::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: 0; width: calc(100% + 54px);
  background: repeating-linear-gradient(90deg, transparent 0 46px, rgba(255,255,255,.2) 46px 54px);
  will-change: transform;
  animation: correr .55s linear infinite;
}
@keyframes correr { to { transform: translateX(-54px); } }

.bandeira {
  height: 12px; opacity: .8; border-radius: 2px;
  background: repeating-conic-gradient(#f2f5fa 0% 25%, #070b16 0% 50%) 0 0 / 12px 12px;
}
/* No hero a faixa e a seta são absolutas no rodapé: não entram na conta de altura da primeira tela. */
.fase--hero .bandeira { position: absolute; left: 0; right: 0; bottom: 0; margin: 0; z-index: 2; }

/* Rótulo com a seta embaixo: diz que o convite continua. Absoluto, mas o padding-bottom do hero reserva sua faixa;
   só a seta pula (transform), o texto fica parado. Área de toque de uns 44px. */
.descer {
  position: absolute; left: 0; right: 0; bottom: 14px; z-index: 3;
  width: max-content; margin: 0 auto; padding: 6px 12px;
  display: block; text-align: center; text-decoration: none;
  font-size: .6rem; letter-spacing: .18em; color: var(--texto-2);
}
.descer span {
  display: block; width: 11px; height: 11px; margin: 4px auto 0;
  border-right: 2px solid var(--texto-2); border-bottom: 2px solid var(--texto-2);
  transform: rotate(45deg);
  animation: pular 1.8s ease-in-out infinite;
}
@keyframes pular { 50% { transform: rotate(45deg) translate(5px, 5px); } }

/* ---------------------- FASE 2 · PRÓXIMA CORRIDA ---------------------- */

.fase--corrida { background: var(--fundo-2); }

.placar {
  border: 1px solid var(--linha); border-radius: var(--raio);
  background: linear-gradient(180deg, var(--carta), #111827);
  overflow: hidden; margin-bottom: 18px;
}
.placar__linha {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 15px 18px; border-bottom: 1px solid var(--linha); text-align: left;
}
.placar__linha:last-child { border-bottom: 0; }
.placar__linha--local { flex-direction: column; align-items: flex-start; gap: 2px; }
.placar__rotulo { font-size: .62rem; letter-spacing: .2em; color: var(--texto-2); }
/* min-width 0 + overflow-wrap: em tela estreita o valor encolhe e quebra, nunca estoura o cartão. */
.placar__valor  { font-family: var(--display); font-size: 1.16rem; min-width: 0; overflow-wrap: anywhere; }
.placar__extra  { color: var(--texto-2); font-size: .88rem; }

/* Blocos LEGO como rodapé da fase: o mundo é construído com eles. */
.blocos { display: flex; justify-content: center; gap: 6px; margin-top: 26px; }
.blocos .bloco { width: 54px; height: 38px; animation: assentar .6s ease both; }
.blocos .bloco:nth-child(2) { animation-delay: .1s; }
.blocos .bloco:nth-child(3) { animation-delay: .2s; }
.blocos .bloco:nth-child(4) { animation-delay: .3s; }
@keyframes assentar { from { opacity: 0; transform: translateY(-24px); } }

/* ---------------------- FASE 3 · DICA PARA O PLAYER ------------------- */

.ficha {
  border: 1px solid var(--linha); border-radius: var(--raio);
  background: linear-gradient(180deg, var(--carta), #111827);
  overflow: hidden; text-align: left;
}
.ficha__topo {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px; border-bottom: 1px solid var(--linha);
  background: linear-gradient(90deg, rgba(27,140,227,.16), transparent);
}
.ficha__nome { display: block; font-family: var(--display); font-size: 1.05rem; }
.ficha__sub  { font-size: .74rem; color: var(--texto-2); letter-spacing: .06em; }
.ficha__nivel {
  margin-left: auto; font-family: var(--display); font-size: 1.5rem;
  color: var(--amarelo); border: 2px solid var(--amarelo);
  border-radius: 10px; padding: 1px 11px;
}

.atributos { margin: 0; padding: 6px 18px 18px; }
.atributo { padding: 13px 0 0; }
.atributo dt { font-size: .62rem; letter-spacing: .18em; color: var(--texto-2); }
.atributo dd { margin: 2px 0 7px; font-size: 1.04rem; font-weight: 600; }
.barra { display: block; height: 7px; border-radius: 99px; background: #0b1120; overflow: hidden; }
.barra i {
  display: block; height: 100%; border-radius: 99px;
  background: linear-gradient(90deg, var(--cor), #fff6);
  transform: scaleX(0); transform-origin: left;
}
.visivel .barra i, .surgir.visivel .barra i { animation: encher .9s ease-out forwards; }
@keyframes encher { to { transform: scaleX(1); } }

/* ---------------------- FASE 4 · RSVP ---------------------- */

.fase--rsvp { background: var(--fundo-2); }
.rsvp { margin-top: 24px; }
.rsvp__escolha { display: grid; gap: 12px; }

.botao {
  display: block; width: 100%;
  padding: 17px 20px; border: 0; border-radius: var(--raio);
  font-family: var(--display); font-size: 1rem; letter-spacing: .08em;
  text-align: center; text-decoration: none; cursor: pointer;
  box-shadow: 0 5px 0 rgba(0,0,0,.45);
  transition: transform .12s ease, filter .12s ease;
}
.botao:active { transform: translateY(4px); box-shadow: 0 1px 0 rgba(0,0,0,.45); }
.botao:focus-visible { outline: 3px solid var(--amarelo); outline-offset: 3px; }
.botao--verde { background: var(--verde); color: #06210c; }
.botao--azul  { background: var(--azul);  color: #04203a; }
.botao--vazio { background: var(--carta); color: var(--texto-2); border: 1px solid var(--linha); box-shadow: none; }
.botao[disabled] { filter: grayscale(.6) brightness(.8); cursor: progress; }

.rsvp__form { margin-top: 18px; text-align: left; display: grid; gap: 14px; }
.campo label {
  display: block; margin-bottom: 6px; text-transform: uppercase;
  font-size: .66rem; letter-spacing: .16em; color: var(--texto-2);
}
.campo input {
  width: 100%; min-width: 0; padding: 14px 15px;
  border: 1px solid var(--linha); border-radius: 11px;
  background: #0a0f1d; color: var(--texto);
  font-family: var(--corpo); font-size: 1rem;
}
.campo input:focus { outline: none; border-color: var(--azul); box-shadow: 0 0 0 3px rgba(27,140,227,.22); }
/* minmax(0, 1fr): o tamanho nativo do input não alarga a coluna em 320px. */
.campo--duplo { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
/* Linha de explicação abaixo do campo (convite nominal: por que o nome do responsável). */
.campo__dica { display: block; margin-top: 6px; font-size: .78rem; color: var(--texto-2); }

.erro {
  margin: 0; padding: 11px 14px; border-radius: 10px;
  background: rgba(229,52,43,.12); border: 1px solid rgba(229,52,43,.4);
  color: #ff9a94; font-size: .88rem;
}
.voltar {
  background: none; border: 0; color: var(--texto-2); cursor: pointer;
  font-family: var(--corpo); font-size: .88rem; text-decoration: underline; padding: 6px;
}

.rsvp__fim {
  padding: 28px 20px; border: 1px solid var(--linha);
  border-radius: var(--raio); background: var(--carta);
}
.fim__ico { width: 54px; height: 54px; margin: 0 auto; animation: pulsar 1.6s ease-in-out infinite; }
@keyframes pulsar { 50% { transform: scale(1.12); } }
.rsvp__fim h3 { margin: 12px 0 6px; font-family: var(--display); font-size: 1.16rem; }
.rsvp__fim p  { margin: 0; color: var(--texto-2); }
/* "alterar resposta" do convite já respondido. */
.rsvp__fim .voltar { display: inline-block; margin-top: 12px; }

/* =====================================================================
   FASE CONCLUÍDA
   Cartão em modo fase concluída: a tela de resultado do fim da corrida.
   Só transform e opacity animam, pra rodar leve no celular.
   ===================================================================== */
.rsvp__fim--fase { position: relative; overflow: hidden; padding-top: 34px; scroll-margin-top: 12px; }
.rsvp__fim--fase h3 { color: var(--amarelo); font-size: 1.35rem; letter-spacing: .06em; }
/* O texto final da fase concluída é a confirmação de verdade: em branco, não em cinza apagado. */
.rsvp__fim--fase p { color: var(--texto); }

/* Decorações só existem no modo fase. */
.rsvp__fim:not(.rsvp__fim--fase) .fim__faixa,
.rsvp__fim:not(.rsvp__fim--fase) .fim__bandeira,
.rsvp__fim:not(.rsvp__fim--fase) .fim__fogos,
.rsvp__fim:not(.rsvp__fim--fase) .fim__davi { display: none; }

/* Passos da sequência: começam invisíveis e o JS liga um a um. */
.rsvp__fim--fase .fim__passo { opacity: 0; transform: translateY(8px); }
.rsvp__fim--fase .fim__passo--ok { opacity: 1; transform: none; transition: opacity .25s ease, transform .25s ease; }

/* Linha de chegada cruzando o topo do cartão. */
.fim__faixa {
  position: absolute; top: 0; left: 0; right: 0; height: 12px;
  background: repeating-conic-gradient(#f2f5fa 0% 25%, #070b16 0% 50%) 0 0 / 12px 12px;
  transform: translateX(-100%);
}
.rsvp__fim--fase .fim__faixa { animation: cruzar .45s ease-out forwards; }
@keyframes cruzar { to { transform: translateX(0); } }

/* Bandeirinha no mastro, acena 4 vezes e para. */
.fim__bandeira {
  position: absolute; top: 18px; right: 14px; width: 30px; height: 20px; border-radius: 2px;
  background: repeating-conic-gradient(#f2f5fa 0% 25%, #070b16 0% 50%) 0 0 / 10px 10px;
  transform-origin: left center;
}
.fim__bandeira::before { content: ''; position: absolute; left: -3px; top: -4px; width: 2px; height: 34px; background: var(--texto-2); }
.rsvp__fim--fase .fim__bandeira { animation: acenar .5s ease-in-out .45s 4; }
@keyframes acenar { 50% { transform: skewY(6deg) scaleX(.92); } }

/* Palco: sprite do Davi comemorando ou, sem arquivo, o troféu.
   Altura fixa: a imagem chegando não pula o layout. */
.fim__palco { display: flex; align-items: center; justify-content: center; }
.rsvp__fim--fase .fim__palco { height: 130px; }
/* 84px de largura: 126px de altura, dentro dos 130px do palco. Maior que qualquer NPC da fase. */
.fim__davi { display: block; width: 84px; filter: drop-shadow(0 8px 14px rgba(0,0,0,.55)); }
.fim__davi img { width: 100%; height: auto; }
.rsvp__fim--fase .fim__davi.sprite--ok ~ .fim__ico { display: none; }
.rsvp__fim--fase .fim__palco.fim__passo--ok { animation: chegar .45s cubic-bezier(.2,1.4,.4,1) both; }
@keyframes chegar { from { opacity: 0; transform: scale(.6); } }
/* Os pulinhos vêm depois do chegar; mesma especificidade, esta regra vem por último e vence. */
.rsvp__fim--fase .fim__palco.fim__palco--festa { animation: comemorar .55s ease-in-out 2; }
@keyframes comemorar { 50% { transform: translateY(-14px); } }
.fim__ico--parado { animation: none; }

/* Placa 1º e título carimbando. */
.fim__placa { display: inline-block; margin: 8px auto 0; }
.fim__placa b {
  display: inline-block; padding: 0 10px; border-radius: 5px;
  background: var(--amarelo); color: #0b0e14; font-family: var(--display); font-size: 1.1rem;
  transform: skewX(-8deg);
}
.rsvp__fim--fase h3.fim__passo--ok { animation: carimbar .35s cubic-bezier(.2,1.2,.4,1) both; }
@keyframes carimbar { from { opacity: 0; transform: scale(1.6); } }

/* Tela de resultado: reaproveita .placar__linha/.placar__rotulo/.placar__valor, sem borda externa. */
.fim__placar { margin: 14px 0 12px; border-top: 1px solid var(--linha); }
.fim__linha { padding: 10px 2px; }
.fim__linha .placar__rotulo { display: flex; align-items: center; }
/* O flex engole o espaço antes do contador x3; sem isto lê "EQUIPEx3". */
.fim__linha .placar__rotulo b { margin-left: .35em; }
.fim__col { display: flex; flex-direction: column; gap: 4px; text-align: left; }
.placar__valor--num { color: var(--amarelo); font-variant-numeric: tabular-nums; min-width: 5ch; text-align: right; }
.fim__linha--total { border-top: 2px solid rgba(255,198,10,.5); }
.fim__linha--total .placar__valor { font-size: 1.4rem; }
.fim__total--fecha { animation: fechar .4s ease-out; text-shadow: 0 0 14px rgba(255,198,10,.7); }
@keyframes fechar { from { transform: scale(1.25); } }

/* Emblema do piloto: círculo branco com o D, como o boné. */
.fim__emblema {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-right: 7px; border-radius: 50%;
  background: #fff; border: 2px solid var(--vermelho); color: var(--vermelho);
  font-family: var(--display); font-size: .72rem; line-height: 1; letter-spacing: 0;
}

/* Nome do PLAYER 2, escrito letra a letra com cursor de bloco.
   O nome usa o espaço livre ao lado do rótulo; se não couber (a Russo One é larga
   e o JS deixa 16 letras), desce pra linha de baixo em largura total. As
   reticências ficam só como último recurso. */
.fim__linha[data-linha="player"] { flex-wrap: wrap; row-gap: 2px; }
.fim__nome {
  flex: 1 1 auto; min-width: 0; max-width: 100%;
  font-size: 1rem; text-transform: uppercase;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis; text-align: right;
}
.fim__nome--digitando::after {
  content: ''; display: inline-block; width: .55em; height: 1em; margin-left: 3px; vertical-align: -.15em;
  background: var(--amarelo); animation: piscar .6s steps(2, end) infinite;
}

/* Ícones da equipe: moeda por adulto, estrela por criança. */
.fim__equipe { display: flex; gap: 3px; min-height: 14px; }
.fim__pessoa { width: 14px; height: 14px; opacity: 0; }
.fim__pessoa--ok { opacity: 1; animation: ganharVida .5s cubic-bezier(.3,1.6,.6,1); }

/* 1UP ao lado do TOTAL, usa o saltar do prêmio. */
.fim__up { display: inline-block; margin-left: 8px; opacity: 0; color: var(--verde); font-family: var(--display); font-size: .7rem; }
.fim__up--vai { animation: saltar .85s cubic-bezier(.2,.8,.4,1) forwards; }

/* Fogos: três estouros nas cores da marca. A sombra é estática, só transform e opacity animam. */
.fim__fogos { position: absolute; inset: 0; pointer-events: none; }
.fim__fogos i {
  position: absolute; width: 6px; height: 6px; border-radius: 50%; opacity: 0; background: var(--amarelo);
  box-shadow: 0 -26px 0 var(--vermelho), 18px -18px 0 var(--azul), 26px 0 0 var(--amarelo), 18px 18px 0 var(--verde),
              0 26px 0 var(--vermelho), -18px 18px 0 var(--azul), -26px 0 0 var(--amarelo), -18px -18px 0 var(--verde);
}
.fim__fogos i:nth-child(1) { left: 20%; top: 22%; }
.fim__fogos i:nth-child(2) { left: 50%; top: 10%; animation-delay: .35s; }
.fim__fogos i:nth-child(3) { left: 78%; top: 26%; animation-delay: .7s; }
.fim__fogos--ativo i { animation: estourar .7s ease-out forwards; }
@keyframes estourar { from { opacity: 1; transform: scale(.1); } to { opacity: 0; transform: scale(1.6); } }

/* ---------------------- FASE 5 · FINAL ---------------------- */

/* Contagem com o Toad torcendo ao lado. Em 360px sobram 252px pras quatro células. */
.contagem { display: flex; align-items: flex-end; gap: 10px; }
.relogio { flex: 1 1 auto; min-width: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.npc--toad { flex: none; width: 58px; height: 71px; }
.relogio__item {
  padding: 12px 2px; border: 1px solid var(--linha); border-radius: 12px;
  background: linear-gradient(180deg, var(--carta), #0d1426);
}
.relogio__item strong {
  display: block; font-family: var(--display); font-size: clamp(1.15rem, 5.4vw, 1.5rem);
  color: var(--amarelo); font-variant-numeric: tabular-nums;
}
.relogio__item span { font-size: .52rem; letter-spacing: .08em; color: var(--texto-2); }

.prepare {
  margin: 26px 0 0;
  font-family: var(--display);
  font-size: clamp(1rem, 5.6vw, 1.5rem);
  letter-spacing: .06em;
  overflow-wrap: anywhere;
  background: linear-gradient(90deg, var(--vermelho), var(--amarelo), var(--verde), var(--azul));
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text; color: transparent;
  animation: correrCor 6s linear infinite;
}
@keyframes correrCor { to { background-position: 300% 0; } }

.moedinhas { display: flex; justify-content: center; gap: 14px; margin-top: 24px; }
.moedinhas svg { width: 30px; height: 30px; animation: girar 2.2s linear infinite; }
.moedinhas svg:nth-child(2) { animation-delay: .25s; }
.moedinhas svg:nth-child(3) { animation-delay: .5s; }

/* ---------------------- RODAPÉ ---------------------- */

.rodape { padding: 0 var(--gutter) 30px; text-align: center; }
.rodape p { margin: 18px 0 0; font-size: .68rem; letter-spacing: .2em; color: var(--texto-2); }

/* Faixa do rodapé com o Mario montado no Yoshi (pixel art) atravessando. Altura fixa, só transform. */
.rodape__pista { position: relative; height: 56px; overflow: hidden; contain: layout paint; overflow-anchor: none; }
.rodape__pista .bandeira { position: absolute; left: 0; right: 0; bottom: 0; }
.rodape__andarilho { position: absolute; inset: 0; will-change: transform; animation: andar 11s linear infinite; }
@keyframes andar { from { transform: translateX(-52px); } to { transform: translateX(100%); } }
.npc--yoshi-mario { position: absolute; left: 0; bottom: 12px; width: 44px; height: 44px; image-rendering: pixelated; }

/* Logo Super Mario como selo pequeno (abertura arcade inteira e rodapé). Nunca acima de 150px, nunca principal. */
.selo { display: block; width: 120px; margin: 0 auto; opacity: .92; filter: drop-shadow(0 4px 10px rgba(0,0,0,.5)); }
.selo img { width: 100%; height: auto; }
.selo--arcade { margin-top: 26px; }
/* No rodapé vai no teto da nota (150px): é a única cópia que quem pula a abertura vê. */
.selo--rodape { width: 150px; margin: 22px auto 0; }

/* ---------------------- ENTRADA DAS FASES ---------------------- */

.surgir { opacity: 0; transform: translateY(20px); transition: opacity .6s ease, transform .6s ease; }
.surgir.visivel { opacity: 1; transform: none; }

/* ---------------------- TELAS MAIORES ---------------------- */

@media (min-width: 720px) {
  :root { --max: 600px; }
  .arte { max-width: 430px; }
  .fase { padding: 84px var(--gutter); }
  .rsvp__fim--fase .fim__palco { height: 150px; }
  .fim__davi { width: 100px; }
}

/* ---------------------- TELAS ESTREITAS (até 359px) ---------------------- */

/* Em 320px nada pode estourar na horizontal: gutter, fontes e espaçamentos encolhem um pouco.
   As alturas fixas (blocada, pista, chegada) não mudam, então a primeira tela segue cabendo. */
@media (max-width: 359px) {
  :root { --gutter: 16px; }
  .hud { padding: 10px 12px; font-size: .58rem; gap: 4px 6px; }
  .hud__som { font-size: .56rem; padding: 4px 8px; }
  .avatar--hud { width: 24px; height: 24px; }
  .arcade__acoes { gap: 8px; }
  .arcade__pular { font-size: .7rem; letter-spacing: .06em; padding: 7px 12px; }
  .blocada { gap: 10px; }
  .level__texto { letter-spacing: .1em; }
  .fase__titulo { letter-spacing: .02em; }
  .placar__linha { padding: 13px 14px; gap: 10px; }
  .placar__valor { font-size: 1.04rem; }
  .ficha__topo { padding: 14px; }
  .atributos { padding: 6px 14px 16px; }
  .botao { padding: 15px 14px; font-size: .92rem; letter-spacing: .06em; }
  .rsvp__fim { padding: 26px 14px; }
  .fim__pessoa { width: 12px; height: 12px; }
  .contagem { gap: 8px; }
  .relogio { gap: 6px; }
  .relogio__item { padding: 10px 1px; }
  .relogio__item strong { font-size: 1.05rem; }
  .relogio__item span { font-size: .46rem; letter-spacing: .04em; }
  .npc--toad { width: 46px; height: 56px; }
  .prepare { letter-spacing: .04em; }
}

/* ---------------------- MOVIMENTO REDUZIDO ---------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  .surgir { opacity: 1; transform: none; }
  .barra i { transform: scaleX(1); }
  /* Fase concluída: o que nasce em opacity 0 aparece de uma vez, sem fogos nem cursor. */
  .rsvp__fim--fase .fim__passo { opacity: 1; transform: none; }
  .rsvp__fim--fase .fim__faixa { transform: none; }
  .fim__fogos, .fim__up { display: none; }
  .fim__nome--digitando::after { display: none; }
  /* Pista parada: kart, rival, moedas e o andarilho do rodapé ficam no lugar, sem rastro.
     O Davi vivo não é criado pelo app.js; se existir, fica escondido e o estático aparece. */
  .kart-real::before, .kart-real::after { display: none; }
  .pulo-vivo, .kart-vivo { display: none; }
  .kart-real--vivo .kart-real__foto, .pulo--vivo picture { opacity: 1; }
  .rodape__andarilho { transform: translateX(30%); }
  /* O Yoshi aparece parado, saindo do bloco, ao bater. */
  .npc--yoshi.npc--sair { opacity: 1; transform: translate(-50%, -44px); }
}
