/* Telas novas da Experiência v2: escolha do jogo, desfecho e encerramento.
 *
 * Folha SEPARADA de app.css de propósito. São telas introduzidas nesta versão e
 * mantê-las num arquivo próprio deixa claro o que é novo, evita conflito com a
 * reformulação visual dos jogos (que mexe pesado em app.css) e permite carregar
 * só onde é usado. As variáveis de cor, raio e sombra vêm todas de app.css —
 * nenhuma cor é inventada aqui, todas saem da paleta institucional.
 */

/* ==========================================================================
   Escolha do jogo
   ========================================================================== */

.tela-escolha {
    width: 100%;
}

/* GRID POR ESPAÇO REAL E POR QUANTIDADE DE CARDS.
 *
 * `repeat(auto-fit, minmax(min(100%, 17rem), 1fr))` foi medido e reprovado: com
 * três cards dava 2+1 — um quadrante vazio — e com quatro, 2+2, em TODAS as
 * resoluções de 844px para cima, inclusive em 1920x1080, onde cabem quatro lado
 * a lado com folga. `auto-fit` decide quantas colunas cabem sem saber quantos
 * itens existem; o resultado é o arranjo certo só por coincidência.
 *
 * Aqui as colunas são explícitas. `--colunas` muda por faixa de espaço, e
 * `[data-quantidade]` ajusta a faixa larga ao número real de jogos: três jogos
 * pedem 1x3, quatro pedem 1x4, e nenhum dos dois pede uma célula vazia.
 *
 * As faixas são de ESPAÇO (largura, altura e orientação), não de nome de
 * aparelho: `orientation: landscape` é `width > height`, e é o que separa
 * 1920x1080 (uma fileira) de um iPad Pro 1024x1366 (duas). */
.cartas-jogo {
    list-style: none;
    margin: 1.5rem 0 0;
    padding: 0;
    display: grid;
    gap: 1rem;
    --colunas: 1;
    grid-template-columns: repeat(var(--colunas), minmax(0, 1fr));
}

/* >= 40rem (640px): duas colunas. Abaixo disso, duas colunas dariam cards de
   159px em 390px de largura — nome de jogo em quatro linhas e alvo apertado. */
@media (min-width: 40rem) {
    .cartas-jogo {
        --colunas: 2;
        gap: 1.25rem;
    }
}

/* >= 48rem (768px) EM RETRATO — tablet em pé, o segundo aparelho do estande.
 *
 * Com TRÊS jogos, duas colunas deixariam a terceira célula vazia: um buraco no
 * canto inferior direito, que é o que este lote proíbe. Uma fileira de três
 * resolve sem inventar card nenhum, e sobra dobra: medido, os três terminam em
 * y=650 de 1024.
 *
 * Com QUATRO, 2x2 continua sendo o arranjo certo — quatro colunas dariam cards
 * de 172px, abaixo do que se lê a um metro. Por isso a regra é só para três. */
@media (min-width: 48rem) and (orientation: portrait) {
    .cartas-jogo[data-quantidade="3"] {
        --colunas: 3;
    }
}

/* >= 64rem (1024px) EM PAISAGEM: uma fileira só, com uma coluna por jogo.
   É a faixa do dispositivo principal do estande (tablet landscape, 1280, TV).
   O teto de 4 é deliberado: cinco jogos numa fileira dariam cards de 220px numa
   TV vista a um metro — nesse caso o grid volta a quebrar em duas fileiras de
   quatro, que continua legível. */
@media (min-width: 64rem) and (orientation: landscape) {
    .cartas-jogo {
        --colunas: 4;
        gap: 1.25rem;
    }

    .cartas-jogo[data-quantidade="1"] { --colunas: 1; }
    .cartas-jogo[data-quantidade="2"] { --colunas: 2; }
    .cartas-jogo[data-quantidade="3"] { --colunas: 3; }

    /* Um ou dois cards não devem esticar até 1200px: a linha de leitura do
       corpo do card ficaria longa e o CTA, largo demais para o polegar. */
    .cartas-jogo[data-quantidade="1"],
    .cartas-jogo[data-quantidade="2"] {
        max-width: 44rem;
        margin-inline: auto;
    }
}

/* PAISAGEM DE POUCA ALTURA — o discriminante aqui é a ALTURA, não a largura.
 *
 * O teto é 40rem (640px) e não 34rem, e isso fechou um buraco medido: 800x600,
 * 900x600, 1024x600 e 640x480 são paisagem, passam de 40rem de largura e não
 * chegam a 64rem. Caíam em duas colunas e produziam, com três jogos,
 * exatamente o quadrante vazio que este lote proíbe — com a segunda fileira
 * 100% fora da dobra e 2,09 telas de rolagem em 800x600. Com a fileira única
 * compacta: 248x313px de card, tudo acima da dobra, uma tela.
 *
 * O card vira COMPACTO (escala mais abaixo): um card vertical de 412px não
 * cabe uma vez sequer em 390px de altura útil. */
@media (orientation: landscape) and (max-height: 40rem) {
    .cartas-jogo {
        --colunas: 3;
        gap: 0.75rem;
        margin-top: 0.75rem;
    }

    .cartas-jogo[data-quantidade="1"] { --colunas: 1; }
    .cartas-jogo[data-quantidade="2"] { --colunas: 2; }
    .cartas-jogo[data-quantidade="4"] { --colunas: 4; }
}

/* QUATRO cards em paisagem estreita: 2x2, não 1x4.
 *
 * Medido: quatro colunas em 800px de largura dão cards de 183px, e 208px em
 * 900px — abaixo do piso de legibilidade de 216px (onde o nome do jogo passa a
 * ocupar três linhas). 2x2 compacto ali dá 374x257px, com 64% da segunda
 * fileira visível: passa o critério de dobra e mantém o card legível.
 *
 * O piso de 26rem (416px) de altura existe porque abaixo dele DUAS fileiras não
 * cabem de jeito nenhum — em 844x390 a segunda ficaria inteiramente fora da
 * tela. Ali quatro colunas estreitas continuam sendo o menos ruim, e a regra
 * acima prevalece. */
@media (orientation: landscape) and (min-height: 26rem) and (max-height: 40rem) and (max-width: 63.99rem) {
    .cartas-jogo[data-quantidade="4"] {
        --colunas: 2;
    }
}

/* O CARD RESPONDE À PRÓPRIA LARGURA, NÃO À DA JANELA.
 *
 * Media query aqui erra por construção: em 1024x768 a mesma condição
 * `min-width: 64rem` vale para um card de 317px (três jogos) e para um de 233px
 * (quatro). Medido com escala por viewport, o card de 233px recebia nome de
 * 21px, o texto quebrava em quatro linhas e o card ia a 537px de altura —
 * proporção 0,43, que é exatamente o "card esmagado" que este lote proíbe.
 *
 * `container-type: inline-size` faz a escala seguir o espaço real de cada card.
 * Três jogos e quatro jogos passam a se vestir sozinhos, sem breakpoint novo —
 * que é o que o quarto jogo vai precisar. */
.carta-jogo {
    display: flex;
    container-type: inline-size;
}

.carta-jogo__form {
    /* Âncora do alvo esticado logo abaixo. */
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    background: var(--cor-superficie);
    /* FRONTEIRA DE COMPONENTE, não separador. O card inteiro é o alvo de toque,
       e a borda é o que informa até onde ele vai. Medida em 1,30:1 sobre o fundo
       da página com `--cor-borda`, abaixo do 3:1 da WCAG 1.4.11 — o botão
       interno estava em 6,25:1, então o controle era descoberto, mas a extensão
       do alvo não era delimitada. Com `--cor-borda-forte`: **3,61:1** sobre o
       creme da página, que é onde o card de fato vive (3,85:1 sobre branco). */
    border: 1px solid var(--cor-borda-forte);
    border-radius: var(--raio-grande);
    box-shadow: var(--sombra);
    overflow: hidden;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

/* O ANEL DE FOCO ACOMPANHA O ALVO, NÃO O BOTÃO.
 *
 * O alvo de toque é o card (317px); o anel desenhava em volta do botão (279px).
 * Não é falha de 2.4.7 — o indicador existe e tem 13,1:1 —, mas quem navega por
 * teclado via um retângulo menor do que a área que responde, e num card com
 * herói colorido isso lê como "o botão está focado", não "este jogo está
 * selecionado".
 *
 * `@supports` protege o essencial: onde `:has()` não existir, o outline do
 * botão continua sendo desenhado. Trocar um indicador visível por nenhum seria
 * pior que o desalinhamento que isto corrige. */
@supports selector(:has(*)) {
    .carta-jogo__form:has(.carta-jogo__botao:focus-visible) {
        outline: 3px solid var(--cor-marrom);
        outline-offset: 2px;
    }

    .carta-jogo__form:has(.carta-jogo__botao:focus-visible) .carta-jogo__botao:focus-visible {
        outline: none;
    }
}

/* O CARD INTEIRO É O ALVO DE TOQUE.
 *
 * Até a v2 isto era só uma afirmação em comentário: o que existia era
 * `transition` no `:hover`/`:focus-within`, que é efeito visual. Medido, o card
 * respondia em 14,7% da própria área (302×380 de card, 302×56 de botão) — numa
 * TV touch a pessoa toca na arte e nada acontece.
 *
 * A correção é o botão real esticar a própria área de clique sobre o card, e
 * não um segundo elemento clicável: continua havendo UM controle, UMA parada de
 * teclado e UM rótulo acessível. Um `<a>` ou `<div onclick>` por cima criaria
 * navegação duplicada e leitura dobrada no leitor de tela. */
.carta-jogo__botao::after {
    content: "";
    position: absolute;
    inset: 0;
    /* Transparente: quem desenha o card continua sendo o conteúdo abaixo. */
    background: transparent;
    /* O raio do CARD, não o do botão. `inherit` traria os 999px da pílula e
       recortaria os cantos do alvo, tirando toque justamente das bordas. */
    border-radius: var(--raio-grande);
}

/* O BOTÃO NÃO PODE TER `transform` — nem por um instante.
 *
 * `.botao-principal:active` aplica `translateY(1px)` (app.css). Qualquer
 * `transform` diferente de `none` transforma o elemento em bloco contentor dos
 * próprios descendentes posicionados, inclusive do `::after` acima: durante a
 * pressão, `inset: 0` deixaria de resolver contra o card e passaria a resolver
 * contra o botão.
 *
 * Medido no harness, injetando o mesmo `translateY(1px)`: a área do card que
 * responde ao toque caía de 100% para 13,5% em 1024×768 e 17,5% em 1280×800 —
 * ou seja, o defeito original voltava no exato milissegundo do toque. Com mouse
 * isso chega a engolir o clique: o `mousedown` acerta o `::after`, o `:active`
 * encolhe a área, e o `mouseup` cai na arte do card, então o `click` é
 * despachado no ancestral comum e o formulário não é enviado.
 *
 * O feedback de pressão continua existindo — mudou de elemento. O card já é o
 * bloco contentor (`position: relative`), então transformá-lo não move a
 * âncora do alvo. Verificado: volta a 100% nas duas resoluções.
 *
 * O SELETOR TEM DUAS CLASSES DE PROPÓSITO. Enquanto era só
 * `.carta-jogo__botao:active` (0,2,0), ele EMPATAVA em especificidade com
 * `.botao-principal:active` (0,2,0) de app.css, e só vencia por vir depois na
 * ordem de carregamento das folhas. Trocar dois `<link>` de lugar em
 * `layout.php` — ou acrescentar a regra mais abaixo em app.css — derrubaria a
 * área clicável do card para 8,8% (medido, injetando a regressão) sem nenhum
 * teste falhar. Com `.carta-jogo .carta-jogo__botao:active` (0,3,0), a garantia
 * é da cascata e não da ordem dos arquivos. */
.carta-jogo .carta-jogo__botao:active {
    transform: none;
}

.carta-jogo__form:active {
    transform: translateY(1px);
}

.carta-jogo__form:hover,
.carta-jogo__form:focus-within {
    transform: translateY(-2px);
    box-shadow: 0 12px 28px rgba(77, 38, 36, 0.16);
}

/* ==========================================================================
   HERÓI DO CARD — o card precisa ser reconhecido ANTES de o nome ser lido
   ==========================================================================

   Até a V2 isto era uma faixa `linear-gradient` de 5,5rem: três retângulos
   monocromáticos, um por jogo, sem asset nenhum. Faixa de cor não diz o que a
   pessoa vai fazer, e a diferença entre os cards ficava toda na palavra.

   O que mudou, e a ordem importa:

   1. a identidade vem do TEMA declarado em `content/jogos.php`, não do slug do
      jogo escrito à mão na folha — um jogo novo nasce vestido;
   2. cada tema mostra o VERBO da mecânica (o par que se procura, os
      ingredientes que se alinham, o que se recolhe e o que se desvia), não um
      enfeite;
   3. logotipo e embalagem entram como ARQUIVO OFICIAL, vindo de `content/`,
      nunca desenhados ou simulados aqui.

   O que é desenho (SVG embutido) e o que é imagem, e por quê: silhueta de
   ingrediente, anel de sinal, estrela e a silhueta neutra de pet são desenho —
   escalam do celular à TV touch, pesam ~1 KB e trocam de cor por variável.
   Logotipo e packshot são arquivo oficial, porque simular marca é proibido.

   Nenhum herói leva texto: o nome do jogo é HTML, para ser lido, traduzido e
   ampliado. Nenhum leva o logo Alinutri: ele já está no cabeçalho, e repetir a
   marca em cada card a esvazia. */

.carta-jogo__arte {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    height: 7.5rem;
    overflow: hidden;
    /* Fundo do tema neutro: um jogo sem identidade declarada continua legível,
       só não ganha personalidade. É a falha segura de `CatalogoJogos::identidade`
       desenhada — card sem arte, nunca tela sem card. */
    background: linear-gradient(135deg, var(--cor-rose), var(--cor-fundo-suave));
}

/* Peça oficial (logotipo ou embalagem) posta sobre o herói. Nunca deformada:
   `object-fit: contain` preserva a proporção do arquivo, e nenhuma peça é
   ampliada além do tamanho nativo — o logo do Long Life, por exemplo, só existe
   em 115x107 e embaça acima disso. */
.carta-jogo__peca {
    display: block;
    object-fit: contain;
    max-width: 100%;
}

/* --- Tema NATURE (match-3): a fórmula, em ingredientes ------------------- */

/* Campo verde com as silhuetas de ingrediente que o tabuleiro USA DE VERDADE:
   cenoura, espinafre e mirtilo. Os `path` são recortados de
   `public/assets/js/simbolos.js` (viewBox 64×64), então quem vê o card
   reconhece a peça quando ela aparecer no tabuleiro.
 *
 * A PRIMEIRA VERSÃO DESTE HERÓI ESTAVA ERRADA e o erro era editorial, não
 * estético: desenhava peixe e gomo cítrico. `content/ingredientes.php` tem seis
 * ingredientes — cenoura, espinafre, beterraba, mirtilo, maçã e manga —, cada um
 * com `citacao` literal da composição do Nature Fórmula PRO e `fonte`. Peixe
 * pertence ao catcher, e "gomo cítrico" não existe em `simbolos.js`. Num card
 * chamado "Nature Fórmula PRO 100% Natural", desenhar um peixe é atribuir à
 * fórmula um ingrediente que o material não declara — que é exatamente o que a
 * exigência de `fonte` em `ItemConteudo` existe para impedir.
 *
 * O ladrilho REPETE em x, e isso resolve um segundo defeito medido: com as
 * silhuetas posicionadas uma vez, a pastilha do logo (136px) cobria a do meio
 * por inteiro em 1280 e 1920 — quanto maior o card, menos arte aparecia.
 * Repetindo, sempre sobram silhuetas nas laterais, em qualquer largura. */
.carta-jogo__arte--nature {
    background:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='120' fill='white' fill-opacity='.30'><g transform='translate(22 32) scale(.875)'><path d='M53.5 26.5C54.5 29.5 47.5 30 45.5 31C43 32.5 39 35 36.5 36.5C34 38 29.5 41.5 27 43C24 45 19.5 48.5 16.5 50.5C14 52.5 7.5 58 6 59C4.5 60 5 60.5 6 59C7 57.5 11.5 50.5 13.5 47.5C15 44.5 18.5 39.5 20 37C22 34 25 29.5 26.5 27C28 24.5 31 20 32.5 18C34 15.5 35.5 8 38.5 9.5C41 10.5 52.5 23.5 53.5 26.5zM45 17c-3-6-3-13 1-17 4 5 4 12 0 17zM48 19c5-5 11-6 14-3-4 5-9 7-14 3zM43 19c-6-3-11-10-11-16 6 2 11 8 12 16z'/></g><g transform='translate(122 32) scale(.875)'><path d='M32 3C40 7 47 9 51 15 55 21 55 30 50 36 47 43 41 49 34 53v9h-4v-9C23 49 17 43 14 36 9 30 9 21 13 15 17 9 24 7 32 3z'/></g><g transform='translate(222 32) scale(.875)'><path d='M20 26a13 13 0 1 0 0 26 13 13 0 1 0 0-26zM44 26a13 13 0 1 0 0 26 13 13 0 1 0 0-26zM32 8a13 13 0 1 0 0 26 13 13 0 1 0 0-26z'/></g></svg>") center / auto 100% repeat-x,
        linear-gradient(135deg, var(--cor-verde), var(--cor-verde-profundo));
}

/* O logotipo Nature é verde: sobre o campo verde ele sumiria. Entra numa
   pastilha branca — que é a aplicação correta do arquivo oficial (fundo claro)
   e, de quebra, dá ao card um ponto de leitura único a um metro de distância. */
.carta-jogo__arte--nature .carta-jogo__peca--1 {
    width: 8.5rem;
    height: auto;
    padding: 0.55rem 0.9rem;
    background: #ffffff;
    border-radius: 999px;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.22);
}

/* --- Tema MARCAS (memória): o par que se procura ------------------------- */

/* Duas cartas em leque: de um lado o logotipo, do outro a embalagem — que é
   exatamente o par da mecânica. As duas peças são de MARCAS DIFERENTES de
   propósito: o jogo não é sobre uma marca, e eleger uma no herói faria a tela
   de escolha prometer o que a partida não cumpre. */
.carta-jogo__arte--marcas {
    gap: 0;
    background:
        radial-gradient(120% 90% at 50% 115%, rgba(255, 255, 255, 0.16), transparent 60%),
        linear-gradient(135deg, var(--cor-vermelho), var(--cor-vermelho-profundo));
}

.carta-jogo__arte--marcas .carta-jogo__peca {
    width: 6rem;
    height: 4.75rem;
    background: #ffffff;
    border-radius: 0.625rem;
    box-shadow: 0 8px 18px rgba(0, 0, 0, 0.28);
}

/* AS DUAS PEÇAS PRECISAM DE RESPIROS DIFERENTES, porque os dois arquivos
   oficiais são enquadrados de forma diferente — e `object-fit: contain` respeita
   o arquivo, não o conteúdo dele.
 *
 * O logo da Ammy foi recortado na bounding box do alfa: a arte ocupa 100% do
 * arquivo. O packshot da Receita Especial é canvas cheio de 384×335 com a
 * embalagem em (76,28)-(310,319) — **39% da largura é margem vazia**. Com o
 * mesmo padding e o mesmo `contain`, o logo sangrava a carta e a embalagem
 * renderizava a 44×55px num espaço de 83px, cercada de branco: as duas cartas
 * do leque deixavam de ser um par visual.
 *
 * `cover` na peça de packshot faz a caixa ser preenchida pela embalagem em vez
 * de pela margem. O corte vertical medido é de 0,7px do topo da embalagem —
 * quase nada, porque a margem sobra justamente onde o corte acontece. */
.carta-jogo__arte--marcas .carta-jogo__peca--1 {
    padding: 0.6rem 0.7rem;
    object-fit: contain;
}

.carta-jogo__arte--marcas .carta-jogo__peca--2 {
    padding: 0.25rem;
    object-fit: cover;
}

/* O leque abre para FORA. A primeira versão aproximava as duas cartas e a de
   cima cobria metade do logotipo da de baixo — uma marca oficial recortada por
   decoração, que é uso indevido do arquivo. Aqui elas apenas encostam. */
.carta-jogo__arte--marcas .carta-jogo__peca--1 {
    transform: rotate(-7deg) translateX(-0.35rem);
}

/* A embalagem passa por cima na sobreposição: é a carta "virada" do par.
 *
 * Isso vem da ORDEM NO DOM, não de `z-index`. A primeira versão usava
 * `position: relative; z-index: 1` aqui e o alvo de toque do card caiu de 100%
 * para 97% — a imagem subia acima do `::after` que estica o botão sobre o card,
 * e os pontos sobre ela paravam de responder. Decoração de herói nunca pode
 * disputar camada com o alvo de toque. */
.carta-jogo__arte--marcas .carta-jogo__peca--2 {
    transform: rotate(7deg) translateX(0.35rem);
}

/* --- Tema PET (catcher): o que se recolhe e o que se desvia -------------- */

/* Sem imagem nenhuma, e é a decisão certa: não existe mascote no material de
   marca, e inventar um criaria identidade não aprovada. O desenho reproduz a
   cena real da partida — a silhueta neutra de pet no piso, o disco claro com
   anel VERDE (recolher), o octógono escuro com anel VERMELHO (desviar) e a
   estrela do escudo. É a mesma gramática de `public/games/proteja-pet/jogo.js`. */
/* A SILHUETA DO PET É CLARA, e isso é decisão de contraste, não de gosto: o pet
   do jogo é marrom `#3d2624`, que sobre o piso `#1a1a1a` mede **1,24:1** —
   nesta escala, dentro de um herói de 152px, ele simplesmente não existiria. Em
   Rosê institucional `#f0e2e2` sobre o mesmo piso a silhueta chega a **13,83:1**
   e é lida de relance, que é o que o card precisa fazer.
   (O contraste do pet DENTRO do jogo é outro problema, do Lote C — aqui não se
   toca em mecânica.) */
.carta-jogo__arte--pet {
    /* O HERÓI DESTE CARD PASSOU A SER O MASCOTE OFICIAL (o Ali), servido como
       imagem por `content/jogos.php` — não mais um desenho da folha.
     *
     * Saiu daqui um SVG com os anéis da mecânica e uma silhueta neutra de GATO.
     * Duas incoerências: o pet do jogo é um CÃO, e o card era o último lugar da
     * experiência que ainda desenhava um pet genérico depois de o mascote
     * entrar. Redesenhá-lo em SVG para virar cão seria reinterpretar material de
     * marca — proibido; o arquivo oficial resolve sem inventar traço nenhum.
     *
     * O que fica é só o CENÁRIO: o piso escuro e o gradiente de fundo, que são
     * decisão de composição do card e não representam bicho nenhum. */
    background:
        linear-gradient(180deg, transparent 86%, #1a1a1a 86%),
        linear-gradient(180deg, #4a4a4a, var(--cor-chumbo));
}

/* O ALI DENTRO DO CARD — enquadramento, não recorte.
 *
 * A peça do herói é posicionada por `.carta-jogo__peca` (regra genérica), e sem
 * teto próprio o mascote saía com a orelha encostando na borda de cima e a pata
 * passando da direita: medido no harness em 1280×800, o card cortava o bicho
 * nos dois lados. Cortar material de marca é o que este projeto não faz.
 *
 * `contain` + o teto de altura mantêm a proporção oficial e deixam respiro em
 * volta. Ancorado embaixo porque o card tem piso desenhado no gradiente: o Ali
 * fica em pé sobre ele, e não flutuando no meio. */
.carta-jogo__arte--pet .carta-jogo__peca--1 {
    position: absolute;
    left: 50%;
    bottom: 0;
    transform: translateX(-50%);
    width: auto;
    height: 88%;
    max-width: 74%;
    object-fit: contain;
    object-position: bottom center;
}


/* --- Tema TRILHA (quarto jogo) ------------------------------------------- */

/* Duas cordas grossas cruzando um campo limpo, com pontas nas extremidades — é
   o VERBO do jogo desenhado: arrastar e deixar rastro. Não pode ler como grade
   de peças, senão a Trilha vira "mais um match-3" justamente no card, que é
   onde a diferenciação precisa acontecer. Por isso não há célula, borda de
   quadrado nem azulejo aqui: só as cordas e o azul institucional. */
.carta-jogo__arte--trilha {
    /* DUAS ROTAS QUE SE DESVIAM, E INGREDIENTES NAS PONTAS.
     *
     * O grafismo anterior tinha dois defeitos. O primeiro: as duas curvas
     * CRUZAVAM uma pela outra no meio do card — exatamente o que a Trilha
     * proibe ("sem cruzar as trilhas"). O heroi ilustrava a jogada INVALIDA. O
     * segundo: as pontas eram circulos brancos vazios, o que dava um diagrama
     * de rede generico, sem nada da experiencia.
     *
     * Agora as rotas desviam uma da outra — a de cima ocupa a faixa y 30-58, a
     * de baixo y 74-92, sem ponto em comum — e as pontas sao os proprios
     * INGREDIENTES do jogo: mirtilo em cima, espinafre embaixo. Os dois vem de
     * `content/ingredientes.php` e tem silhueta em
     * `public/assets/js/simbolos.js`, que e a condicao que o projeto impoe para
     * desenhar item em heroi de card.
     *
     * Pecas em 36px (nao 26): a 26 o mirtilo lia como um trevo e o espinafre
     * como uma gota — em carta pequena o ingrediente sumia e sobrava o
     * diagrama, que era o defeito de origem.
     *
     * Branco sobre o azul, sem as cores de cada ingrediente: leitura mais
     * sobria, e evita que o card compita com as pecas coloridas da partida. */
    background:
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='120' fill='none' stroke-linecap='round' stroke-linejoin='round'><path d='M34 30H92V58H148V30H206' stroke='%23ffffff' stroke-opacity='.28' stroke-width='12'/><path d='M34 92H76V74H164V92H206' stroke='%23ffffff' stroke-opacity='.28' stroke-width='12'/><path d='M34 30H92V58H148V30H206' stroke='%23ffffff' stroke-opacity='.85' stroke-width='4'/><path d='M34 92H76V74H164V92H206' stroke='%23ffffff' stroke-opacity='.58' stroke-width='4'/><g transform='translate(16.0 12.0) scale(0.5625)'><path d='M20 26a13 13 0 1 0 0 26 13 13 0 1 0 0-26zM44 26a13 13 0 1 0 0 26 13 13 0 1 0 0-26zM32 8a13 13 0 1 0 0 26 13 13 0 1 0 0-26z' fill='%23ffffff' fill-opacity='1'/></g><g transform='translate(188.0 12.0) scale(0.5625)'><path d='M20 26a13 13 0 1 0 0 26 13 13 0 1 0 0-26zM44 26a13 13 0 1 0 0 26 13 13 0 1 0 0-26zM32 8a13 13 0 1 0 0 26 13 13 0 1 0 0-26z' fill='%23ffffff' fill-opacity='1'/></g><g transform='translate(16.0 74.0) scale(0.5625)'><path d='M32 3C40 7 47 9 51 15 55 21 55 30 50 36 47 43 41 49 34 53v9h-4v-9C23 49 17 43 14 36 9 30 9 21 13 15 17 9 24 7 32 3z' fill='%23ffffff' fill-opacity='.74'/></g><g transform='translate(188.0 74.0) scale(0.5625)'><path d='M32 3C40 7 47 9 51 15 55 21 55 30 50 36 47 43 41 49 34 53v9h-4v-9C23 49 17 43 14 36 9 30 9 21 13 15 17 9 24 7 32 3z' fill='%23ffffff' fill-opacity='.74'/></g></svg>") center / auto 100% no-repeat,
        linear-gradient(135deg, var(--cor-azul), #1f5f80);
}

.carta-jogo__corpo {
    padding: 1rem 1.125rem 0.5rem;
    flex: 1;
}

/* TEXTO DE CAMPANHA QUEBRA EM QUALQUER PONTO, se não houver outro.
 *
 * Nome, chamada e regra são DADO — vêm do banco e de `content/`, não do código,
 * e mudam a cada campanha sem passar por revisão de CSS. Com a quebra padrão,
 * um token longo sem espaço (um SKU, um nome composto) media `scrollWidth 549`
 * num card de 250–341px e era **cortado sem aviso**: `overflow: hidden` no card
 * engolia o resto da palavra, nos 14 viewports. `anywhere`, e não `break-word`,
 * porque só ele também encolhe a largura mínima intrínseca — sem isso o card
 * estoura o grid antes de quebrar. */
.carta-jogo__nome {
    margin: 0;
    font-size: 1.125rem;
    line-height: 1.25;
    color: var(--cor-marrom);
    overflow-wrap: anywhere;
}

.carta-jogo__chamada {
    margin: 0.375rem 0 0;
    color: var(--cor-texto-suave);
    font-size: 0.9375rem;
    line-height: 1.4;
    overflow-wrap: anywhere;
    /* Duas linhas de piso: as três chamadas raramente têm o mesmo comprimento,
       e sem isso a linha "Para vencer" começava em alturas diferentes em cada
       card da mesma fileira. Resolve quando todas cabem em duas linhas; com
       três, os cards voltam a divergir — é piso, não trava. */
    min-height: 2.8em;
}

.carta-jogo__regras {
    margin: 0.875rem 0 0;
    display: grid;
    gap: 0.5rem;
}

.carta-jogo__regra {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    border-top: 1px solid var(--cor-borda);
    padding-top: 0.5rem;
}

.carta-jogo__regra dt {
    /* 12px é pequeno para um rótulo lido a um metro numa TV touch, e como está
       em `rem` ele não crescia junto com o `font-size: 1.125rem` que o corpo
       ganha acima de 1280px. */
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--cor-texto-suave);
    margin: 0;
    /* O rótulo é fixo e curto ("Para vencer", "Duração"). Deixá-lo quebrar fazia
       "PARA / VENCER" descer duas linhas só no card cuja REGRA é longa, e as
       linhas dos três cards saíam do alinhamento entre si. */
    white-space: nowrap;
}

.carta-jogo__regra dd {
    margin: 0;
    font-weight: 600;
    color: var(--cor-marrom);
    font-size: 0.9375rem;
    text-align: right;
    /* A regra de vitória é montada a partir de `config/dificuldade.php` — texto
       de campanha, como o nome. Mesma proteção contra token sem espaço. */
    overflow-wrap: anywhere;
}

.carta-jogo__botao {
    margin: 0.875rem 1.125rem 1.125rem;
    width: auto;
    /* Quando o foco chega por teclado, o anel é desenhado em volta do CARD, mas
       quem o navegador rola para dentro da tela é o BOTÃO — e a borda de baixo
       do anel ficava cortada (94,4% visível em 390x844, 86,9% em 844x390 com
       quatro cards). A margem de rolagem é a maior distância entre o botão e a
       base do card (22px) mais a espessura do anel e seu offset. */
    scroll-margin-bottom: 1.75rem;
    scroll-margin-top: 1.75rem;
}

/* --- Escala do card, pelo espaço do PRÓPRIO card ------------------------- */

/* Card estreito (quatro jogos numa fileira em 1024px, ou o compacto de
   paisagem baixa): a tipografia encolhe junto, senão o texto quebra em quatro
   linhas e o card estica na vertical. */
@container (max-width: 16rem) {
    .carta-jogo__nome {
        font-size: 1rem;
    }

    .carta-jogo__chamada {
        font-size: 0.875rem;
    }

    .carta-jogo__regra {
        /* Rótulo e valor lado a lado não cabem em 233px sem quebrar os dois:
           empilhados, cada um fica numa linha inteira e continua legível. */
        flex-direction: column;
        align-items: flex-start;
        gap: 0.125rem;
    }

    .carta-jogo__regra dd {
        text-align: left;
    }

    .carta-jogo__corpo {
        padding: 0.875rem 0.875rem 0.5rem;
    }

    .carta-jogo__botao {
        margin: 0.75rem 0.875rem 0.875rem;
    }
}

/* DOIS DEGRAUS SEPARADOS, e a separação é o conserto de um penhasco medido.
 *
 * Enquanto tipografia e arte subiam juntas em 21rem, ganhar 23px de largura de
 * card custava 54px de altura: em 1050x700 o card fechava em 412px e cabia
 * inteiro (folga de +56px); em 1120x700 — sete por cento mais largo — pulava
 * para 466px e a última fileira passava 1,9px da dobra. Alargar a tela piorava
 * o layout, que é o oposto do que qualquer um espera.
 *
 * Agora a TIPOGRAFIA cresce cedo (17,5rem = 280px, o piso de trabalho do card)
 * e a ARTE cresce tarde (24rem = 384px, onde de fato há altura sobrando). Efeito
 * colateral que resolve outro defeito: com quatro cards a 285px em 1280 e 1920,
 * o nome do jogo era exibido a 18px — abaixo do 1,25rem exigido para leitura a
 * um metro. Passa a 21px sem custar dobra (+6,5px de altura de card). */
@container (min-width: 17.5rem) {
    .carta-jogo__nome {
        font-size: 1.3125rem;
    }

    .carta-jogo__chamada {
        font-size: 1rem;
    }

    .carta-jogo__corpo {
        padding: 1.25rem 1.375rem 0.625rem;
    }

    .carta-jogo__botao {
        margin: 1rem 1.375rem 1.375rem;
    }
}

@container (min-width: 24rem) {
    .carta-jogo__arte {
        height: 9.5rem;
    }
}

/* COLUNA ÚNICA NO CELULAR — a exceção que o container query não consegue ver.
 *
 * Num celular de 390px, o card ocupa 358px e o container o classifica como
 * "largo": tipografia de 21px e herói de 120px. Mas o que muda ali não é o
 * espaço, é a DISTÂNCIA DE LEITURA — o aparelho está a 30cm da pessoa, não a um
 * metro numa TV touch, e o container não tem como saber disso.
 *
 * Sem esta regra, o custo era medido: o card ia de 380px para 440px de altura e
 * a tela passava de 2,7 para 3,0 telas de rolagem em 320x568. Aqui a escala
 * volta à base, e a rolagem fica abaixo do que era antes deste lote. */
@media (max-width: 39.99rem) {
    .carta-jogo__arte {
        height: 6rem;
    }

    .carta-jogo__nome {
        font-size: 1.125rem;
    }

    .carta-jogo__chamada {
        font-size: 0.9375rem;
    }

    .carta-jogo__corpo {
        padding: 1rem 1.125rem 0.5rem;
    }

    .carta-jogo__botao {
        margin: 0.875rem 1.125rem 1.125rem;
    }
}

/* CARD COMPACTO — paisagem de pouca altura (celular deitado, 844x390).
 *
 * Medido: sobram cerca de 300px de palco depois do cabeçalho. Um card vertical
 * de 380px não cabe uma vez sequer, e 2x2 poria a segunda fileira inteira fora
 * da dobra. O card então deita: herói à esquerda em coluna estreita, texto à
 * direita, CTA embaixo. A arte não some — sumir é o que faria os cards voltarem
 * a ser indistinguíveis justamente na tela mais apertada. */
@media (orientation: landscape) and (max-height: 40rem) {
    .carta-jogo__arte {
        height: 3.25rem;
    }

    .carta-jogo__arte--nature .carta-jogo__peca--1 {
        width: 5.5rem;
        padding: 0.3rem 0.55rem;
    }

    .carta-jogo__arte--marcas .carta-jogo__peca {
        width: 2.75rem;
        height: 2.25rem;
        padding: 0.25rem;
    }

    .carta-jogo__corpo {
        padding: 0.625rem 0.75rem 0.375rem;
    }

    /* Só o que é VERTICAL encolhe aqui. O corpo do texto continua sob o
       comando do container: nesta mesma faixa o card vai de 248px (três jogos
       em 800x600) a 374px (quatro em 2x2), e fixar um tamanho de fonte por
       media query deixaria o card largo com letra de card estreito. */
    .carta-jogo__chamada {
        margin-top: 0.25rem;
    }

    .carta-jogo__regras {
        margin-top: 0.5rem;
        gap: 0.25rem;
    }

    .carta-jogo__regra {
        padding-top: 0.3rem;
    }

    .carta-jogo__botao {
        margin: 0.5rem 0.75rem 0.75rem;
        /* Continua acima do mínimo de toque de 44px, que é o piso inegociável
           mesmo na tela mais apertada. */
        min-height: 2.875rem;
        font-size: 1rem;
    }
}

/* ==========================================================================
   Desfecho: vitória e derrota
   ========================================================================== */

.heroi-resultado__desfecho {
    margin: 0 0 0.25rem;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: 0.01em;
    line-height: 1.15;
}

/* O desfecho é a primeira leitura da tela e precisa funcionar a um metro de
   distância. Branco sobre o herói vermelho nos dois casos: variar a cor do
   texto aqui reduziria contraste sem acrescentar informação — quem diferencia
   vitória de derrota é a palavra, não o matiz. */
.heroi-resultado__desfecho--vitoria,
.heroi-resultado__desfecho--derrota {
    color: #ffffff;
}

.mensagem-derrota {
    margin: 1rem 0 0;
    text-align: center;
    color: var(--cor-texto-suave);
    line-height: 1.45;
}

/* ==========================================================================
   Status da entrega e encerramento
   ========================================================================== */

.resgate__status {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.875rem 0 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--cor-borda);
    font-size: 0.9375rem;
    color: var(--cor-texto-suave);
}

.resgate__status-ponto {
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 50%;
    background: var(--cor-mostarda);
    flex: none;
    animation: pulso-espera 1.6s ease-in-out infinite;
}

.resgate__status--entregue {
    color: var(--cor-verde);
    font-weight: 600;
}

.resgate__status--entregue .resgate__status-ponto {
    background: var(--cor-verde);
    animation: none;
}

/* A espera automática desistiu (teto de ~10 min). O ponto para de pulsar: um
   indicador que continua animando afirma que algo ainda está acontecendo. */
.resgate__status--parado {
    color: var(--cor-vermelho-medio);
    font-weight: 600;
}

.resgate__status--parado .resgate__status-ponto {
    background: var(--cor-vermelho);
    animation: none;
}

#botao-verificar-entrega {
    margin-top: 0.75rem;
}

@keyframes pulso-espera {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

/* "Escolher outro jogo" — o CTA primário de quem está na própria vez.
 *
 * Precisa ser um `<form>` porque cria participação (POST + CSRF), e o `<a>` de
 * "Jogar novamente" que ele substitui não tinha caixa em volta. Sem zerar a
 * margem, o formulário afastaria o CTA do card de resgate e empurraria as saídas
 * secundárias para fora da dobra — que é o mesmo defeito já medido quando
 * `.acoes-secundarias` ainda empilhava em 1024×768. O botão dentro já é
 * `display: block; width: 100%`, então a caixa não precisa de mais nada. */
.form-continuar {
    margin: 0;
}

/* Quem tem adesivo PENDENTE não pode encerrar: a estação voltaria ao formulário
   com um prêmio não entregue e a pessoa iria embora sem ele. O JS revela este
   bloco quando o operador confirma. */
.form-encerrar {
    /* A margem agora é da faixa que contém as duas ações. */
    margin: 0;
}

.form-encerrar--oculto {
    display: none;
}

.botao-secundario {
    display: block;
    width: 100%;
    padding: 0.875rem 1.25rem;
    /* Fronteira visível contra o fundo, não só texto legível: `--cor-borda`
       media 1,30:1 e o botão não lia como botão (WCAG 1.4.11 pede 3:1).
       `--cor-texto-suave` mede 5,3:1 sobre a superfície clara. */
    border: 1px solid var(--cor-texto-suave);
    border-radius: var(--raio);
    background: var(--cor-fundo-suave);
    color: var(--cor-texto);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.botao-secundario:hover {
    background: var(--cor-rose);
    border-color: var(--cor-vermelho);
}

.botao-secundario:focus-visible {
    outline: 3px solid var(--cor-vermelho);
    outline-offset: 2px;
}

.botao-secundario:disabled {
    opacity: 0.6;
    cursor: default;
}

/* As duas saídas secundárias, numa faixa só onde couber.
 *
 * Empilhadas custavam 68px de dobra: medido, "Encerrar experiência" saía de
 * −2px para +66px em 1024×768 e de −16px para +52px em 1280×800 — a ação
 * conservadora exigindo rolagem enquanto a destrutiva ficava à vista.
 *
 * A ordem do DOM é a ordem visual (encerrar, depois recomeçar), então tabulação
 * e leitura acompanham o que se vê — nada de `row-reverse`. */
.acoes-secundarias {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

@media (min-width: 30rem) {
    .acoes-secundarias {
        flex-direction: row;
        align-items: stretch;
    }

    .acoes-secundarias > * {
        flex: 1 1 0;
        min-width: 0;
    }
}

/* "Não sou eu — começar do zero".
 *
 * Peso deliberadamente baixo: quem acabou de jogar não deve ser convidado a
 * descartar a própria vez, e a ação primária da tela continua sendo "Jogar
 * novamente". Mas o alvo de toque é pleno (2,75rem), porque quem precisa dela é
 * a PRÓXIMA pessoa da fila, que encontrou a tela de outra pessoa e não tem
 * outro caminho. */
.form-recomecar {
    margin: 0;
}

.botao-texto {
    display: block;
    width: 100%;
    min-height: 2.75rem;
    padding: 0.5rem 1rem;
    border: none;
    background: none;
    color: var(--cor-texto-suave);
    font: inherit;
    font-size: 0.9375rem;
    text-decoration: underline;
    text-underline-offset: 0.2em;
    cursor: pointer;
}

.botao-texto:hover {
    color: var(--cor-vermelho-medio);
}

.botao-texto:focus-visible {
    outline: 3px solid var(--cor-vermelho);
    outline-offset: 2px;
    border-radius: var(--raio);
}

/* ==========================================================================
   Consentimento por canal
   ========================================================================== */

/* DUAS armadilhas do <fieldset>, ambas medidas a 320px de largura — o aparelho
 * mais estreito da feira — e ambas corrigidas aqui:
 *
 * 1. `min-width: min-content` INTRÍNSECO. É regra do próprio navegador e
 *    ignora a largura do container: sem `min-width: 0`, o fieldset se recusa a
 *    encolher abaixo do texto da legenda e empurra a página. Custava 67px de
 *    rolagem horizontal.
 *
 * 2. `display: flex` NÃO se propaga como se espera. O fieldset herdava
 *    `display:flex; flex-direction:column` de `.campo`, mas o Chrome envolve o
 *    conteúdo de um fieldset numa caixa anônima que não recebe o
 *    `flex-direction` — resultado: os dois checkboxes ficaram lado a lado e o
 *    segundo saiu 50px para fora da tela.
 *
 * A correção é não depender de flex aqui. `display: block` com os rótulos
 * empilhando naturalmente é previsível em todos os navegadores, e este bloco
 * não precisa de flex para nada. */
.campo-consentimento--canais {
    display: block;
    min-width: 0;
    box-sizing: border-box;
    max-width: 100%;
    border: 1px solid var(--cor-borda);
    border-radius: var(--raio);
    padding: 0.875rem 1rem 0.5rem;
    margin-top: 0.25rem;
}

.campo-consentimento--canais .rotulo-checkbox {
    max-width: 100%;
}

.campo-consentimento__legenda {
    padding: 0 0.375rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--cor-marrom);
    /* A legenda participa do cálculo de min-content do fieldset; sem quebra,
     * ela sozinha define o piso de largura. */
    max-width: 100%;
    overflow-wrap: break-word;
}

.campo-consentimento--canais .rotulo-checkbox + .rotulo-checkbox {
    margin-top: 0.5rem;
}

/* ==========================================================================
   Utilitário
   ========================================================================== */

.visualmente-oculto {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Respeita quem pediu menos movimento no sistema operacional. */
@media (prefers-reduced-motion: reduce) {
    .carta-jogo__form,
    .resgate__status-ponto {
        transition: none;
        animation: none;
    }
}

/* Saída da tela de escolha quando não há nenhum jogo habilitado.
   Só aparece nesse estado — com cards, o caminho é para a frente. */
.escolha-jogo__saida {
    margin: 1.5rem 0 0;
    text-align: center;
}
