/* =============================================================================
 * GAMIFICAÇÃO — os dados e o carrossel de cartelas (rota /v/{token})
 * -----------------------------------------------------------------------------
 * O que é isto: a tela de escolher dezenas ganhou dois brinquedos. Um botão que
 * ROLA OS DADOS — cinco bolas de bingo girando ao mesmo tempo e parando com as
 * cinco dezenas do filtro, num gesto só — e um "Cartela aleatória", que abre um
 * desfile de cartelas dentro de uma janelinha e vai desacelerando até parar em
 * uma. É a tela onde a venda fecha — o movimento aqui não é enfeite, é o que faz
 * a pessoa querer continuar.
 *
 * 📌 HISTÓRICO, porque muda como se lê o arquivo: a primeira versão era uma
 *    ROLETA de UMA bola por vez. O giro agradou e a linguagem visual da esfera
 *    ficou intacta; o que virou dado foram as CINCO de uma vez. Por isso os
 *    nomes `.gami-bola*` continuam os mesmos, e quem cuida de haver cinco na
 *    fileira é a `.gami-dados` — a bola não sabe que tem irmãs.
 *
 * Por que este arquivo existe e não é Tailwind:
 *
 * 🔑 O CSS do painel é compilado pelo Vite, e nenhuma máquina daqui tem
 *    `node_modules` para rebuildar. Classe nova de Tailwind no Blade não vira
 *    NADA em produção — os botões sairiam sem cor e o modal sem posição, sem
 *    erro nenhum no caminho. Então o desenho mora aqui, em CSS de verdade.
 *
 * 🔑 Ele entra pela URL versionada (`App\Support\Arte::url(...)`) porque a
 *    hospedagem guarda uma cópia gzipada do estático por SETE DIAS: arquivo
 *    trocado sem trocar a URL não chega no celular do cliente.
 *
 * 🔑 Nenhuma cor de marca escrita à mão. Tudo sai das variáveis do tema
 *    (`--ct-*`), porque esta tela roda nos três temas do sistema (padrão,
 *    claro e escuro). Preto e branco translúcidos aparecem, sim — mas só como
 *    LUZ e SOMBRA (volume da esfera, profundidade do modal), que é a mesma
 *    licença que o `bolas.css` já tomou e funciona nos três temas.
 *
 * 🔑 CONVIVÊNCIA COM O `bolas.css`: a bola grande da roleta (`.gami-bola`) usa
 *    a MESMA receita de esfera de lá, mas em tamanho de palco. Este arquivo
 *    NUNCA redeclara `.bola-dezena`. Onde havia risco de as duas folhas
 *    disputarem a mesma propriedade (tamanho da fonte, sombra, fundo), a regra
 *    daqui vem com a classe repetida (`.gami-bola.gami-bola`) ou combinada
 *    (`.bola-dezena.gami-bola`): dois nomes de classe ganham de um só,
 *    independentemente de qual folha o navegador carregou por último. Sem isso
 *    o `font-size: 12px` da grade viraria o tamanho do número da roleta.
 *
 * ⚠️ QUEM ANIMA O QUÊ, no carrossel: o Blade/Alpine troca só o `transform`
 *    inline do `.gami-trilho`. A DESACELERAÇÃO é daqui, do easing — está
 *    documentada no lugar dela, mais abaixo.
 *
 * ⚠️ A barra do carrinho é fixa no rodapé com `z-index: 30`. O modal precisa
 *    passar por cima dela: veja a escolha do `z-index` em `.gami-modal`.
 * ========================================================================== */

/* -----------------------------------------------------------------------------
 * A FAIXA DOS DOIS BOTÕES
 * -----------------------------------------------------------------------------
 * Fica dentro do card "Seus números da sorte", entre o texto de instrução e a
 * grade das 50 dezenas — é o convite antes da tarefa.
 *
 * Os dois dividem a linha em partes iguais (`flex: 1 1 0`) e NENHUM deles pode
 * ocupar 100%: botão de largura cheia lê como "o próximo passo da compra", e o
 * próximo passo desta tela é escolher dezena, não girar roleta. Lado a lado
 * eles se anunciam como duas alternativas de diversão.
 *
 * `min-width: 0` é o que impede o rótulo (que é `nowrap`) de estourar a linha
 * e empurrar o segundo botão para fora da tela em 320px.
 * -------------------------------------------------------------------------- */
.gami-faixa {
    display: flex;
    align-items: stretch;
    gap: 8px;
    margin: 0 0 12px;
}

.gami-faixa > .gami-btn {
    flex: 1 1 0;
    min-width: 0;
}

/* -----------------------------------------------------------------------------
 * O BOTÃO
 * -----------------------------------------------------------------------------
 * Base comum. 44px de altura mínima porque é o alvo que o dedo acerta de
 * primeira — abaixo disso o cliente erra, acha que a tela travou e desiste do
 * brinquedo. O ícone e o rótulo ficam na MESMA linha (`nowrap`), sob pena de
 * "Cartela aleatória" quebrar em duas e desalinhar a altura dos dois botões.
 * -------------------------------------------------------------------------- */
.gami-btn {
    /* `inline-flex` e não `flex`: assim o botão continua se comportando se o
       Blade o usar solto, fora da `.gami-faixa`. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;

    box-sizing: border-box;
    min-height: 44px;
    padding: 9px 12px;
    border: 1px solid transparent;
    border-radius: 12px;

    font-size: 13px;
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: 0.01em;
    /* O rótulo não quebra, e o que sobra some com elegância em telas muito
       estreitas em vez de deformar a faixa. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

    cursor: pointer;
    transition:
        transform 140ms cubic-bezier(0.34, 1.4, 0.64, 1),
        box-shadow 140ms ease,
        background-color 140ms ease,
        border-color 140ms ease,
        opacity 140ms ease;

    /* Toque de celular sem atraso e sem o quadrado cinza do Android — mesma
       receita da bola. */
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
}

/* O ícone do Lucide entra como `<i data-lucide>` e é trocado por um `<svg>` em
   tempo de execução. As duas formas ganham o mesmo tamanho e `flex: none`, para
   o SVG não esticar junto com o botão quando o rótulo é curto. */
.gami-btn i,
.gami-btn svg {
    flex: none;
    width: 16px;
    height: 16px;
}

.gami-btn:active {
    transform: scale(0.97);
}

.gami-btn:focus-visible {
    outline: 2px solid var(--ct-primaria);
    outline-offset: 2px;
}

/* O CONVITE — o botão que ROLA OS DADOS.
   O nome da classe continua `--roleta` porque é o que o Blade já usa em
   produção e renomear classe entre duas folhas vivas é apagar o estilo no ar;
   o RÓTULO é que virou "Rolar os dados".
   Cheio, na cor primária, com um véu de luz em cima e sombra embaixo: é o
   único elemento desta faixa que tem volume, e é o que o olho pega primeiro. */
.gami-btn--roleta {
    background-color: var(--ct-primaria);
    color: var(--ct-primaria-texto);
    /* Volume em camada TRANSPARENTE, igual à bola: se um dia a primária mudar
       de tom (ou de tema), o degradê continua correto sozinho. */
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.2) 0%,
        rgba(255, 255, 255, 0.04) 52%,
        rgba(0, 0, 0, 0.1) 100%
    );
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.28),
        0 2px 5px rgba(18, 21, 40, 0.22);
}

.gami-btn--roleta:hover {
    /* Sem variável nova: uma camada branca a mais clareia a primária de
       qualquer tema. */
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.3) 0%,
        rgba(255, 255, 255, 0.12) 52%,
        rgba(0, 0, 0, 0.06) 100%
    );
}

/* O SEGUNDO ATALHO — "Cartela aleatória".

   🔴 ERA SÓ CONTORNO, e virou CHEIO em 20/09/2026, por ordem dele: *"vamos
      adicionar uma cor diferente no botão de cartela aleatória, o fundo
      preenchido e o texto branco, do mesmo jeito que é o Rolar os dados (…) uma
      cor mais para o lado do amarelo, mas sem ser amarelo de fato — entre o
      amarelo e um laranja"*.

   🎨 O tom é âmbar/laranja (#f0a020 → #dd7d09), não amarelo puro: amarelo com
      texto branco não tem contraste suficiente para ler no sol, que é onde esta
      tela é usada. Este âmbar mantém a família e sustenta o branco.

   📌 O raciocínio antigo — *"dois botões cheios lado a lado empatam a decisão"* —
      continua valendo para COR IGUAL. Com cores diferentes, cada um diz o que é:
      azul é rolar os dados, âmbar é sortear a cartela. */
.gami-btn--carrossel {
    background-color: #e68a0a;
    color: #ffffff;
    border-color: transparent;

    /* Mesmo volume do primário, em camada transparente: um degradê pronto
       continuaria certo se o tom mudar um dia. */
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.24) 0%,
        rgba(255, 255, 255, 0.05) 52%,
        rgba(0, 0, 0, 0.12) 100%
    );
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.3),
        0 2px 5px rgba(80, 45, 0, 0.26);
}

.gami-btn--carrossel:hover {
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.34) 0%,
        rgba(255, 255, 255, 0.14) 52%,
        rgba(0, 0, 0, 0.06) 100%
    );
    color: #ffffff;
}

/* APAGADO — sem vaga, sem cartela para sortear, ou pedido em curso.
   Sem cursor de clique e sem resposta ao toque: o botão tem que PARECER
   desligado, senão o cliente insiste e acha que a tela quebrou. */
.gami-btn[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: none;
    background-image: none;
}

.gami-btn[disabled]:active {
    transform: none;
}

/* -----------------------------------------------------------------------------
 * O PALCO DOS DADOS
 * -----------------------------------------------------------------------------
 * As bolas só existem durante o giro e no instante em que cravam os números.
 * Sem um lugar com altura reservada, elas aparecem e a grade das 50 dezenas
 * PULA para baixo — e pular grade no meio de um toque faz o cliente marcar a
 * dezena errada. Então o palco guarda o espaço e centraliza a fileira.
 *
 * ⚠️ ALTURA É ORÇAMENTO NESTA TELA: a grade das dezenas tem que continuar acima
 *    da dobra. O palco era 96px fixo quando a bola tinha 72px. Com as cinco
 *    bolas a esfera passou a ser CALCULADA (uns 45px em 320px, 57px em 390px,
 *    64px no computador), então o reservado também virou curva, na mesma
 *    proporção — 72px na tela de 390px, e nem um pixel a mais nas estreitas.
 *    Um valor fixo aqui ou sobraria 19px de ar em 320px, ou faltaria no
 *    computador.
 *
 *    A conta do reservado é `bola × 1,2`: o 1,2 é o estufadinho do pop (a
 *    esfera chega a 1,18 no meio da animação) e o pouco de folga para a onda de
 *    brilho não nascer encostada na grade de baixo. Quem mexer no tamanho da
 *    bola em `.gami-dados` mexe aqui também — são os dois lados da mesma conta.
 *
 * 🔑 `min-height` é PISO, não altura: se a fileira for maior, o palco cresce e
 *    nada é cortado. O piso segura a fileira estável enquanto as cinco bolas
 *    chacoalham e cravam — bola em movimento não pode fazer o bloco respirar.
 *
 * ⚠️ ESTE PISO NÃO VALE MAIS PARA O PALCO VAZIO (mudou em 17/08/2026). Quem
 *    esconde o palco antes do primeiro rolo é o `x-show="caras.length > 0"` do
 *    Blade, que aplica `display: none` — e `display: none` não reserva altura
 *    nenhuma, então o `min-height` daqui simplesmente não entra na conta. Era
 *    ele que produzia o vão branco chumbado acima dos botões, que ele mandou
 *    tirar. Se um dia o vão voltar, o problema está no `x-show` do Blade, não
 *    neste piso.
 * -------------------------------------------------------------------------- */
.gami-palco {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: clamp(56px, 18.5vw, 80px);
    margin: 0 0 12px;
}

/* -----------------------------------------------------------------------------
 * A BOLA — uma dos dados
 * -----------------------------------------------------------------------------
 * É a bola de sorteio de bingo do `bolas.css`, em tamanho de palco: branca,
 * brilho especular no alto à esquerda, o miolo claro escurecendo até a borda de
 * baixo, e a sombra projetada no chão. A receita é a mesma de lá, com as
 * camadas um pouco mais fundas — sombra que convence num círculo de 25px fica
 * fraca num de 72px.
 *
 * ⚠️ ESTE BLOCO É A BOLA SOLTA, de 72px. É o tamanho de quando ela aparece
 *    sozinha. Na fileira dos dados são cinco, e aí quem manda no tamanho (e no
 *    peso da sombra) é a `.gami-dados`, logo depois — a bola não sabe quantas
 *    irmãs tem, e é bom que continue não sabendo.
 *
 * O centro do número é resolvido com `justify-content`/`align-items` (e não só
 * com `place-items`), porque essas duas propriedades centralizam TANTO em grid
 * quanto em flex: se o Blade colar uma classe de display por cima, o número
 * continua no meio da esfera.
 * -------------------------------------------------------------------------- */
.gami-bola {
    position: relative;
    box-sizing: border-box;

    display: grid;
    justify-content: center;
    align-items: center;
    place-items: center;

    width: 72px;
    height: 72px;
    /* `flex: none` para a bola não achatar se o palco virar uma linha com
       texto ao lado. */
    flex: none;
    border: 0;
    border-radius: 50%;
    padding: 0;

    background-color: #f2f3f7;
    background-image:
        radial-gradient(
            ellipse 42% 34% at 30% 23%,
            rgba(255, 255, 255, 0.98) 0%,
            rgba(255, 255, 255, 0.6) 44%,
            rgba(255, 255, 255, 0) 100%
        ),
        radial-gradient(
            circle at 50% 38%,
            rgba(255, 255, 255, 0.34) 0%,
            rgba(255, 255, 255, 0.06) 46%,
            rgba(0, 0, 0, 0.12) 72%,
            rgba(0, 0, 0, 0.32) 100%
        );
    background-repeat: no-repeat;

    color: #1b1f33;
    font-size: 30px;
    font-weight: 900;
    line-height: 1;
    letter-spacing: 0.01em;
    /* `tabular-nums`: o número troca dezenas de vezes por segundo durante o
       giro. Sem largura fixa de dígito, o "11" e o "50" fazem o texto dançar
       dentro da esfera e o efeito vira defeito. */
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1, 'lnum' 1;

    box-shadow:
        inset 0 2px 2px rgba(255, 255, 255, 0.9),
        inset 0 -5px 8px rgba(0, 0, 0, 0.2),
        0 4px 8px rgba(18, 21, 40, 0.24),
        0 10px 20px rgba(18, 21, 40, 0.16);

    -webkit-user-select: none;
    user-select: none;
}

/* A TRAVA DE CONVIVÊNCIA.
   Se o Blade escrever `class="bola-dezena gami-bola"` (é tentador, e é
   legítimo), o `bolas.css` traria `font-size: 12px` e a sombra curta da grade.
   Duas classes ganham de uma: aqui as três propriedades que se atropelam
   voltam para o tamanho de palco, sem depender da ordem das folhas. */
.bola-dezena.gami-bola,
.gami-bola.gami-bola {
    width: 72px;
    height: 72px;
    font-size: 30px;
    box-shadow:
        inset 0 2px 2px rgba(255, 255, 255, 0.9),
        inset 0 -5px 8px rgba(0, 0, 0, 0.2),
        0 4px 8px rgba(18, 21, 40, 0.24),
        0 10px 20px rgba(18, 21, 40, 0.16);
}

/* Em tela grande a bola SOLTA cresce um degrau — no computador a mesma esfera de
   72px fica pequena no meio de um card largo. Isto vale para a bola usada
   sozinha; dentro da `.gami-dados` quem manda no tamanho é a conta da fileira,
   logo abaixo, e ela vence esta regra por especificidade. */
@media (min-width: 640px) {
    .bola-dezena.gami-bola,
    .gami-bola.gami-bola {
        width: 84px;
        height: 84px;
        font-size: 35px;
    }

    /* ⚠️ O `.gami-palco` NÃO tem degrau aqui, e é intencional: o `clamp()` da
       altura já chegou no teto (80px) antes desta largura. Repetir o valor
       criaria duas fontes de verdade para a mesma conta, e um dia alguém
       mexeria em uma só. */
}

/* -----------------------------------------------------------------------------
 * OS DADOS — a fileira das CINCO bolas
 * -----------------------------------------------------------------------------
 * Um gesto só: ele rola os dados, as cinco giram juntas e param com as cinco
 * dezenas do filtro. A fileira vive dentro do `.gami-palco`.
 *
 * 🔑 A REGRA QUE MANDA AQUI: são 5 bolas + 4 vãos, e isso NUNCA pode quebrar
 *    linha nem furar a tela. Cinco bolas de 72px pedem 360px só de esfera —
 *    dentro do card, num aparelho de 320px, sobram uns 248px. Então o tamanho
 *    da bola não é escolhido, é CALCULADO a partir do espaço que existe:
 *
 *        largura da bola = (100% - 4 vãos) / 5
 *
 *    Por ser porcentagem da própria fileira, a conta se acerta sozinha em
 *    qualquer largura — 320px, 390px, tablet — e por construção a soma nunca
 *    passa de 100%. Não há pixel fixo para estourar. O `max-width` só impede
 *    que no computador a esfera vire um balão.
 *
 * ⚠️ Por isso a fileira é `width: 100%` e não largura de conteúdo: porcentagem
 *    dentro de um pai que se encolhe ao conteúdo é referência circular, e o
 *    navegador desiste da conta. Com 100% a largura é definida e a divisão
 *    fecha.
 *
 * ⚠️ `flex-wrap: nowrap` é explícito de propósito. Cinco dezenas em duas linhas
 *    não são um dado rolado, são uma lista — e o palco tem altura reservada
 *    para UMA fileira: quebrar a linha faz a grade das 50 dezenas pular, que é
 *    exatamente o que o palco existe para evitar.
 * -------------------------------------------------------------------------- */
.gami-dados {
    /* O vão em um lugar só: ele entra no `gap` E na conta da largura da bola,
       e os dois têm que ser o MESMO número, senão a fileira sobra ou falta.
       Cresce com a tela: ~6px em 320px, ~8px em 390px, 12px no computador. */
    --gami-vao: clamp(5px, 2vw, 12px);

    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
    gap: var(--gami-vao);

    /* Largura definida (veja o aviso acima) e trava no computador: 5×64 + 4×12
       = 368px é a fileira em tamanho cheio; passar disso é só ar. */
    width: 100%;
    max-width: 368px;
    margin: 0 auto;
}

/* A BOLA DENTRO DA FILEIRA.
 * Três classes no seletor (`.gami-dados .gami-bola.gami-bola`) porque a trava
 * de convivência lá em cima tem duas, e inclusive dentro de `@media`: com duas
 * classes daria empate e o tamanho dependeria da ordem do arquivo. Aqui a
 * fileira ganha sempre — que é o correto, porque quem sabe quanto espaço existe
 * é ela, não a bola.
 *
 * `aspect-ratio` no lugar de altura fixa: a largura é calculada, e a esfera
 * copia a própria largura para continuar redonda em qualquer aparelho. Sem
 * isso a bola vira ovo assim que a conta muda de resultado.
 *
 * `flex: 0 1 auto` (e não `flex: none`, que é o da bola solta): a soma dá
 * exatamente 100%, e arredondamento de subpixel pode passar uma fração. Deixar
 * encolher significa perder 0,2px em silêncio em vez de empurrar a quinta bola
 * para fora do card. */
.gami-dados .gami-bola.gami-bola {
    flex: 0 1 auto;
    width: calc((100% - 4 * var(--gami-vao)) / 5);
    /* No computador a fileira para de crescer: 64px por esfera. */
    max-width: 64px;
    height: auto;
    aspect-ratio: 1 / 1;

    /* O número acompanha a esfera. `clamp` em `vw` porque tipografia não aceita
       porcentagem da largura do pai: ~19px em 320px, ~23px em 390px, travado em
       25px no computador — sempre perto de 40% do diâmetro, que é a proporção
       do número na bola de sorteio de verdade. Os dois dígitos continuam
       inteiros e legíveis à distância de braço. */
    font-size: clamp(16px, 5.9vw, 25px);

    /* O VOLUME, PROPORCIONAL. A sombra da bola solta foi desenhada para 72px:
       um `inset -5px` era 7% do diâmetro lá e viraria 11% numa esfera de 45px —
       a metade de baixo fica encardida e a bola parece uma pedra. Aqui as
       camadas encolhem junto, na mesma proporção. É o mesmo cuidado que o
       `bolas.css` teve ao criar a `--mini`. */
    box-shadow:
        inset 0 1px 2px rgba(255, 255, 255, 0.9),
        inset 0 -3px 6px rgba(0, 0, 0, 0.2),
        0 2px 5px rgba(18, 21, 40, 0.24),
        0 6px 14px rgba(18, 21, 40, 0.14);
}

/* ⚠️ AMARRAÇÃO OBRIGATÓRIA — não apague esta regra achando que é repetição.
 * A regra de cima é mais específica (três classes) do que a que desenha o anel
 * do resultado (`.gami-bola.gami-bola--parou`, duas classes, mais abaixo no
 * arquivo). Especificidade ganha de ordem: sem esta regra aqui, a sombra
 * proporcional apagaria o ANEL das cinco bolas e o cliente ficaria sem saber
 * quais dezenas foram sorteadas. O anel também afinou de 3px para 2px — em
 * esfera de 45px um anel de 3px come a borda da bola. */
.gami-dados .gami-bola.gami-bola--parou {
    box-shadow:
        inset 0 1px 2px rgba(255, 255, 255, 0.9),
        inset 0 -3px 6px rgba(0, 0, 0, 0.2),
        0 0 0 2px var(--ct-primaria),
        0 4px 10px rgba(18, 21, 40, 0.28);
}

/* GIRANDO — o chacoalho do globo de bingo.
 * Não é rotação limpa: bola em gaiola de sorteio pula, torce e volta. São
 * quatro tempos curtos (300ms, infinito) misturando giro pequeno, salto de 2px
 * e um empurrão lateral. Como o número está no centro geométrico, o giro não o
 * arranca do lugar — ele treme junto, que é exatamente a sensação.
 *
 * 🔑 O ESCALONAMENTO. O Blade escreve em cada bola `style="--atraso: 0ms"`,
 *    `80ms`, `160ms`, `240ms`, `320ms`. Cinco bolas chacoalhando no MESMO
 *    quadro não parecem cinco dados: parecem um bloco só se mexendo, porque o
 *    olho junta movimento idêntico numa forma única. Fora de fase, cada uma
 *    tem vida própria e a fileira ferve como gaiola de sorteio.
 *
 * ⚠️ O ATRASO ENTRA NEGATIVO aqui, e é de propósito. Atraso positivo num giro
 *    infinito deixaria a quinta bola PARADA por 320ms antes de começar — a
 *    pessoa acabou de rolar os dados e vê uma bola morta. Negativo faz o
 *    contrário: todas partem no mesmo instante, só que cada uma entrando num
 *    ponto diferente da volta. Movimento imediato E fora de sincronia.
 *
 * ⚠️ `animation-delay` vem DEPOIS do atalho `animation`. O atalho zera o atraso;
 *    invertendo as duas linhas o escalonamento desaparece sem erro nenhum. */
.gami-bola--girando {
    animation: gami-chacoalho 300ms cubic-bezier(0.36, 0.07, 0.19, 0.97) infinite;
    animation-delay: calc(var(--atraso, 0ms) * -1);
}

@keyframes gami-chacoalho {
    0% {
        transform: translate3d(0, 0, 0) rotate(0deg);
    }
    25% {
        transform: translate3d(-2px, -3px, 0) rotate(-7deg);
    }
    50% {
        transform: translate3d(2px, 1px, 0) rotate(6deg);
    }
    75% {
        transform: translate3d(-1px, -2px, 0) rotate(-4deg);
    }
    100% {
        transform: translate3d(0, 0, 0) rotate(0deg);
    }
}

/* PAROU — o instante em que crava a dezena.
 * Duas coisas ao mesmo tempo: um "pop" de 200ms (a bola estufa e volta, com
 * uma pontinha de elástico no easing) e o anel na cor primária, que fica.
 * O chacoalho morre porque esta animação substitui a outra na mesma
 * propriedade — o Blade só troca a classe.
 *
 * 🔑 AQUI O `--atraso` ENTRA POSITIVO, ao contrário do giro: é o que faz as
 *    cinco travarem UMA DEPOIS DA OUTRA, da esquerda para a direita, em 320ms.
 *    Cinco dezenas cravando no mesmo quadro o cliente lê como bug de tela; em
 *    cascata ele lê como sorteio, e ainda ganha tempo de acompanhar cada
 *    número aparecendo — que é o prazer da coisa. O valor vem do Blade
 *    (`style="--atraso: …"`); sem ele, `0ms`, e nada quebra.
 *
 * ⚠️ `animation-delay` DEPOIS do atalho `animation`, pelo mesmo motivo do giro. */
.gami-bola--parou {
    animation: gami-bola-pop 200ms cubic-bezier(0.34, 1.5, 0.64, 1);
    animation-delay: var(--atraso, 0ms);
    /* `backwards` para a bola não dar um salto de escala antes da vez dela:
       durante a espera ela já usa o primeiro quadro (escala 1), em vez do
       tamanho que estiver valendo. */
    animation-fill-mode: backwards;
}

/* O anel FICA depois do pop: é ele que diz "este é o seu número". Duas classes
   na mesma regra pelo motivo já explicado — a sombra do `bolas.css` não pode
   apagar o anel. */
.gami-bola.gami-bola--parou {
    box-shadow:
        inset 0 2px 2px rgba(255, 255, 255, 0.9),
        inset 0 -5px 8px rgba(0, 0, 0, 0.2),
        0 0 0 3px var(--ct-primaria),
        0 6px 14px rgba(18, 21, 40, 0.28);
}

@keyframes gami-bola-pop {
    0% {
        transform: scale(1);
    }
    45% {
        transform: scale(1.18);
    }
    100% {
        transform: scale(1);
    }
}

/* O BRILHO QUE SAI DA BOLA.
 * Uma onda única na cor primária, que abre e desaparece em 520ms. Ela mora num
 * `::after` porque é a única forma de FAZER A COR SUMIR sem inventar um rgba de
 * marca: o anel é sólido em `--ct-primaria` e quem esmaece é a opacidade.
 * A classe vem repetida para vencer o `button.bola-dezena::after` do
 * `bolas.css` (que é o alvo de toque da grade) caso as classes se somem. */
.gami-bola.gami-bola--parou::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    pointer-events: none;
    opacity: 0;
    animation: gami-bola-halo 520ms ease-out;
    /* A onda sai junto com o pop da própria bola — mesmo `--atraso`. Se os dois
       não andassem juntos, o brilho apareceria em uma bola e o estufadinho em
       outra, e o efeito perderia o dono. */
    animation-delay: var(--atraso, 0ms);
    animation-fill-mode: backwards;
}

/* A onda abre 12px, e não 18px como na bola solta: na fileira as esferas ficam
   a uns 6px uma da outra, e uma onda de 18px em cinco bolas quase encostadas
   fecha num borrão azul só, em que não se vê bola nenhuma. Doze abre o
   suficiente para se ver a onda de CADA uma. */
@keyframes gami-bola-halo {
    0% {
        opacity: 0.5;
        box-shadow: 0 0 0 0 var(--ct-primaria);
    }
    100% {
        opacity: 0;
        box-shadow: 0 0 0 12px var(--ct-primaria);
    }
}

/* -----------------------------------------------------------------------------
 * O PALCO DO DESFILE — a cartela aleatória, no lugar da fileira dos dados
 * -----------------------------------------------------------------------------
 * 🔑 17/08/2026, ordem dele: a cartela aleatória DEIXOU DE SER JANELA POP-UP.
 *    Palavras dele: "aquele espaço é para isso, para a gamificação... assim
 *    ficaria mais legal, mais organizado". As duas gamificações passam a
 *    dividir o MESMO palco, acima dos dois botões — acionar uma apaga a outra.
 *
 * Por que `max-width: 26rem` de novo aqui: a cartela é uma grade de 10 colunas
 * de bolinha. Esticada na largura do card no computador, cada bolinha vira um
 * disco e a cartela fica feia — o mesmo limite que a caixa do modal tinha.
 *
 * ⚠️ Sem `min-height`: o palco só existe depois do primeiro sorteio (`x-show`),
 *    e vão branco chumbado acima dos botões é regressão já reprovada por ele.
 * -------------------------------------------------------------------------- */
.gami-desfile {
    display: block;
    width: 100%;
    max-width: 26rem;
    margin: 0 auto 12px;
}

.gami-desfile__titulo {
    margin: 0 0 8px;
    font-size: 14px;
    font-weight: 800;
    line-height: 1.2;
    text-align: center;
    color: var(--ct-texto);
}

/* -----------------------------------------------------------------------------
 * O MODAL DO CARROSSEL — SEM USO DESDE 17/08/2026
 * -----------------------------------------------------------------------------
 * ⚠️ Ficou aqui de propósito, e não por esquecimento: o desfile virou palco (o
 *    bloco acima) e nenhuma tela usa mais estas classes. Está guardado porque
 *    voltar atrás é uma decisão de produto, não uma reescrita — e porque o
 *    raciocínio do `z-index` abaixo vale para qualquer coisa que um dia precise
 *    cobrir a barra do carrinho.
 *
 * 🔑 O `z-index: 60` NÃO é chute: a barra fixa do carrinho no rodapé está em
 *    `z-index: 30`. O modal tem que cobrir aquela barra, senão o botão
 *    "Continuar para o pagamento" fica flutuando por cima do desfile e o
 *    cliente clica nele por acidente no meio do sorteio. 60 deixa folga para
 *    alguém encaixar algo entre os dois no futuro sem mexer aqui.
 *
 * `100dvh` com `100vh` de reserva: no Safari do iPhone a barra de endereço
 * come parte da `vh` e a caixa sairia cortada embaixo.
 * -------------------------------------------------------------------------- */
.gami-modal {
    position: fixed;
    inset: 0;
    z-index: 60;

    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
    /* O respiro de baixo respeita o queixo do iPhone. */
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 12px);

    /* O scroll do desfile não vaza para a página atrás do modal. */
    overscroll-behavior: contain;
}

.gami-modal__veu {
    position: absolute;
    inset: 0;
    /* Preto translúcido de propósito, e não uma variável: o véu tem que
       funcionar como AUSÊNCIA DE LUZ nos três temas. `--ct-borda` no tema
       escuro deixaria a tela de trás legível e a caixa não se destacaria. */
    background-color: rgba(9, 12, 26, 0.62);
    animation: gami-veu-entra 180ms ease-out;
    cursor: pointer;
}

@keyframes gami-veu-entra {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

.gami-modal__caixa {
    position: relative;
    box-sizing: border-box;

    /* Celular: ocupa a largura que tem. Computador: para em 26rem, porque a
       cartela é uma grade de 10 colunas de bolinha — esticar isso a 800px faz
       bola gigante e cartela feia. */
    width: 100%;
    max-width: 26rem;
    /* Nunca mais alto que a tela; se a cartela for grande, rola por dentro. */
    max-height: calc(100dvh - 24px);
    overflow-y: auto;

    padding: 16px 14px 14px;
    border: 1px solid var(--ct-borda);
    border-radius: 20px;
    background-color: var(--ct-superficie);
    /* Sombra alta: é o que arranca a caixa do véu e diz "isto aqui é uma
       camada nova", não um pedaço da página. */
    box-shadow:
        0 20px 40px rgba(9, 12, 26, 0.45),
        0 4px 10px rgba(9, 12, 26, 0.3);

    animation: gami-caixa-entra 220ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

@keyframes gami-caixa-entra {
    from {
        opacity: 0;
        transform: translateY(14px) scale(0.97);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* O título. `padding-right` reserva o canto do X: sem isso um título de duas
   palavras encosta no botão de fechar e a pessoa erra o toque. */
.gami-modal__titulo {
    margin: 0 0 12px;
    padding-right: 40px;
    color: var(--ct-texto);
    font-size: 15px;
    font-weight: 800;
    line-height: 1.25;
}

.gami-modal__fechar {
    position: absolute;
    top: 10px;
    right: 10px;

    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 36px é o mínimo confortável para um X no canto — abaixo disso só acerta
       quem tem dedo fino. */
    width: 36px;
    height: 36px;
    padding: 0;

    border: 1px solid var(--ct-borda);
    border-radius: 50%;
    background-color: transparent;
    color: var(--ct-texto-suave);
    cursor: pointer;
    transition:
        color 140ms ease,
        border-color 140ms ease;

    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}

.gami-modal__fechar i,
.gami-modal__fechar svg {
    width: 16px;
    height: 16px;
}

.gami-modal__fechar:hover {
    color: var(--ct-texto);
    border-color: var(--ct-texto-suave);
}

.gami-modal__fechar:focus-visible {
    outline: 2px solid var(--ct-primaria);
    outline-offset: 2px;
}

/* -----------------------------------------------------------------------------
 * A JANELINHA E O TRILHO — o desfile
 * -----------------------------------------------------------------------------
 * A janela é o recorte: uma cartela visível por vez, o resto escondido. O
 * trilho é a fita de cartelas que corre por dentro dela.
 *
 * 🔑 A DIVISÃO DE TRABALHO COM O BLADE, que é o coração deste arquivo:
 *
 *    · o Blade/Alpine muda SÓ o `transform: translateX(-N00%)` inline do
 *      `.gami-trilho`. Ele não sabe (nem precisa saber) quanto tempo o desfile
 *      dura nem como ele para;
 *    · quem faz a DESACELERAÇÃO é o easing daqui. O `cubic-bezier` abaixo sai
 *      quase de supetão e vai perdendo força até encostar no fim — é a curva
 *      de roda de bingo que gira rápido e morre devagar, e é o que faz os
 *      últimos centímetros parecerem sorteio de verdade;
 *
 * 🔑 17/08/2026 — DE 2s PARA 5s, E A CURVA MUDOU DE FORMATO.
 *    A queixa dele: "clica em cartela aleatória, passam duas ou três cartelas
 *    e já avisa 'sua cartela da sorte'" — não dava para ver cartela sendo
 *    sorteada. Eram duas causas somadas: pouco caminho (12 cartelas) e uma
 *    curva que gastava quase todo o percurso no primeiro terço do tempo.
 *    Agora são 48 cartelas (`Vitrine::CARTELAS_NO_DESFILE`) em 5 segundos —
 *    os mesmos 5s do rolo dos dados —, e a curva anda em velocidade QUASE
 *    CONSTANTE até uns dois terços do caminho, freando só no fim. É a
 *    diferença entre uma fita passando na frente da pessoa e um número
 *    aparecendo do nada.
 *    ⚠️ Duração e quantidade de cartelas andam juntas: dobrar o tempo sem
 *    aumentar o desfile devolve o rastejo do fim; aumentar o desfile sem
 *    o tempo devolve o borrão sem freio.
 *    · por isso a animação é `transform`, NUNCA `left`/`margin`: `transform`
 *      roda na placa de vídeo e desliza liso no celular de R$ 600 do cliente.
 *      `left` recalcula layout a cada quadro e engasga justo no fim, que é o
 *      momento em que a pessoa está olhando.
 *
 * Mexer na duração é mexer só no `5s` daqui — o Blade continua igual.
 * -------------------------------------------------------------------------- */
.gami-janela {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--ct-borda);
    border-radius: 14px;
    background-color: var(--ct-fundo);
}

.gami-trilho {
    display: flex;
    /* Nenhum `gap` aqui, e é regra: com gap, `translateX(-100%)` não cai mais
       exatamente na cartela seguinte e o desfile termina torto. O respiro é
       padding do item, que vive DENTRO dos 100%. */
    gap: 0;
    /* O `will-change` avisa o navegador antes do giro; sem ele o primeiro
       quadro sai tremido em celular mais simples. */
    will-change: transform;
    /* ⏱️ 10s desde 20/09/2026 — eram 5, e ele achou curto: *"vamos adicionar
       mais cinco segundos nessa verificação de giro que sorteia a cartela"*.

       🔑 A duração NÃO é repetida em lugar nenhum: o JavaScript lê daqui
       (`getComputedStyle(trilho).transitionDuration`) para agendar o fim do
       desfile e a trilha sonora. Mudar este número muda a cena inteira. */
    /* 🎡 A CURVA DA ROLETA — refeita em 20/09/2026, com o giro já em 10s.

       Ele: *"quando a gente bota uma roleta para girar, os primeiros giros são
       sempre os mais velozes, e aí ela vai perdendo velocidade até parar. É só a
       velocidade inicial que eu gostaria que ficasse mais rápida"*.

       ⚠️ A curva antiga saía quase linear (inclinação inicial ~1,3) — em 5s isso
          passava, mas esticada para 10s o arranque ficou arrastado. A nova sai
          com inclinação ~9: roda uns 37% do caminho no primeiro segundo e gasta
          os últimos 7s percorrendo o terço final, que é o suspense.

       ⚠️ A curva mora em DOIS lugares: mexeu aqui, mexa no `CURVA` do
          `som-gamificacao.js`, senão os cliques descolam da imagem. */
    transition: transform 10s cubic-bezier(0.05, 0.45, 0.45, 1);
}

.gami-trilho__item {
    /* `0 0 100%` é o contrato com o Blade: cada cartela ocupa a janela inteira,
       então o transform é sempre um múltiplo redondo de 100%. */
    flex: 0 0 100%;
    box-sizing: border-box;
    min-width: 0;
    /* O respiro que o anel da cartela sorteada precisa para não ser cortado
       pelo `overflow: hidden` da janela. */
    padding: 8px;
}

/* -----------------------------------------------------------------------------
 * A CARTELA DO DESFILE
 * -----------------------------------------------------------------------------
 * Número do bilhete em cima, as 20 dezenas embaixo em 10 colunas. As bolinhas
 * são as `.bola-dezena--mini` do `bolas.css` — este arquivo cuida só da grade
 * e do respiro, e não toca na aparência delas.
 * -------------------------------------------------------------------------- */
.gami-cartela {
    box-sizing: border-box;
    padding: 10px;
    border: 1px solid var(--ct-borda);
    border-radius: 12px;
    background-color: var(--ct-superficie);
    transition: box-shadow 200ms ease;
}

/* O BILHETE.
   O Blade manda um rótulo pequeno e o número: `<small>BILHETE Nº</small>` e
   `<strong>1234</strong>`. Ficam na mesma linha, alinhados pela base — o
   rótulo apaga, o número pesa. */
.gami-cartela__bilhete {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 6px;
    margin: 0 0 8px;
}

.gami-cartela__bilhete small {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ct-texto-suave);
}

.gami-cartela__bilhete strong {
    color: var(--ct-texto);
    font-size: 15px;
    font-weight: 900;
    line-height: 1.1;
    /* Número de bilhete alinha em coluna de dígito, igual ao resto do sistema:
       durante o desfile ele troca a cada cartela e sem isto o texto pula. */
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1, 'lnum' 1;
}

/* AS 20 DEZENAS.
   Dez colunas iguais, como em toda a tela. `minmax(0, 1fr)` e não `1fr`: com
   `1fr` puro a coluna nunca fica menor que o conteúdo e a grade fura a caixa
   em 320px. O respiro é de 3px no celular apertado — a bolinha ainda sobra com
   uns 22px, que é o que o `bolas.css` já espera. */
.gami-cartela__dezenas {
    display: grid;
    grid-template-columns: repeat(10, minmax(0, 1fr));
    gap: 3px;
}

@media (min-width: 400px) {
    .gami-cartela__dezenas {
        gap: 4px;
    }
}

/* A QUE FICOU.
   Anel na cor de destaque (o mesmo amarelo que já marca a dezena filtrada
   dentro da cartela, então o cliente já aprendeu que amarelo é "isto aqui é
   seu") mais um brilho discreto ao redor. Entra com uma pulsada ÚNICA de
   440ms e para. Piscar infinito num modal de decisão cansa em cinco segundos e
   atrapalha justamente a leitura das dezenas. */
.gami-cartela--sorteada {
    border-color: var(--ct-destaque);
    box-shadow:
        0 0 0 2px var(--ct-destaque),
        0 6px 16px rgba(18, 21, 40, 0.2);
    animation: gami-cartela-crava 440ms ease-out;
}

@keyframes gami-cartela-crava {
    0% {
        transform: scale(0.97);
    }
    55% {
        transform: scale(1.02);
    }
    100% {
        transform: scale(1);
    }
}

/* -----------------------------------------------------------------------------
 * A DECISÃO
 * -----------------------------------------------------------------------------
 * Dois caminhos, meio a meio: aceitar ou girar de novo. Mesma lógica da faixa
 * lá em cima — nenhum ocupa a linha toda, porque aqui as duas saídas são
 * legítimas e a tela não deve empurrar nenhuma.
 * -------------------------------------------------------------------------- */
.gami-acoes {
    display: flex;
    align-items: stretch;
    gap: 8px;
    margin-top: 12px;
}

.gami-quero,
.gami-denovo {
    flex: 1 1 0;
    min-width: 0;

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;

    box-sizing: border-box;
    min-height: 44px;
    padding: 10px 12px;
    border: 1px solid transparent;
    border-radius: 12px;

    font-size: 14px;
    font-weight: 800;
    line-height: 1.15;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;

    cursor: pointer;
    transition:
        transform 140ms cubic-bezier(0.34, 1.4, 0.64, 1),
        box-shadow 140ms ease,
        border-color 140ms ease,
        opacity 140ms ease;

    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none;
    user-select: none;
}

.gami-quero i,
.gami-quero svg,
.gami-denovo i,
.gami-denovo svg {
    flex: none;
    width: 16px;
    height: 16px;
}

.gami-quero:active,
.gami-denovo:active {
    transform: scale(0.97);
}

.gami-quero:focus-visible,
.gami-denovo:focus-visible {
    outline: 2px solid var(--ct-primaria);
    outline-offset: 2px;
}

/* "QUERO ESTA" — é a ação que vira venda. Cheia, com volume, igual ao botão dos
   dados: a tela inteira aprende um só jeito de dizer "clique aqui". */
.gami-quero {
    background-color: var(--ct-primaria);
    color: var(--ct-primaria-texto);
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.2) 0%,
        rgba(255, 255, 255, 0.04) 52%,
        rgba(0, 0, 0, 0.1) 100%
    );
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.28),
        0 2px 5px rgba(18, 21, 40, 0.22);
}

/* "GIRAR DE NOVO" — contorno. Convida sem gritar. */
.gami-denovo {
    background-color: transparent;
    border-color: var(--ct-borda);
    color: var(--ct-texto);
}

.gami-denovo:hover {
    border-color: var(--ct-primaria);
    color: var(--ct-primaria);
}

.gami-quero[disabled],
.gami-denovo[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: none;
    background-image: none;
}

.gami-quero[disabled]:active,
.gami-denovo[disabled]:active {
    transform: none;
}

/* -----------------------------------------------------------------------------
 * SEM CARTELA PARA SORTEAR
 * -----------------------------------------------------------------------------
 * Acontece de verdade: o filtro de dezenas pode não sobrar nenhuma cartela, ou
 * as últimas foram vendidas enquanto o cliente decidia. O recado vem em
 * contorno tracejado, que é a convenção de "lugar vazio" — caixa cheia daria a
 * entender que ALGO deu errado, e não deu: é só não ter o que sortear.
 * -------------------------------------------------------------------------- */
.gami-vazio {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;

    margin: 0;
    padding: 26px 16px;
    border: 1px dashed var(--ct-borda);
    border-radius: 14px;
    color: var(--ct-texto-suave);
    font-size: 13px;
    line-height: 1.4;
    text-align: center;
}

.gami-vazio i,
.gami-vazio svg {
    width: 22px;
    height: 22px;
    /* O ícone é aviso, não erro: cor de atenção, que existe nos três temas. */
    color: var(--ct-atencao);
}

/* -----------------------------------------------------------------------------
 * QUEM PEDIU MENOS MOVIMENTO
 * -----------------------------------------------------------------------------
 * Obrigatório, e não é "desligar a gamificação": é entregar o MESMO RESULTADO
 * sem balanço. Quem tem labirintite ou enxaqueca vestibular passa mal com
 * chacoalho e com fita correndo na tela.
 *
 * O que sai: o chacoalho das cinco bolas, o pop, o halo, o pulso da cartela e o
 * deslizamento do trilho. O que FICA, porque é informação e não enfeite: o anel
 * primário em CADA UMA das cinco bolas e o anel de destaque na cartela
 * sorteada. As cinco dezenas já aparecem paradas, com o anel de resultado, e a
 * cartela do desfile troca instantaneamente — o resultado é idêntico, só sem a
 * viagem até ele.
 *
 * ⚠️ O `--atraso` do Blade fica inerte sozinho: `animation: none` no atalho
 *    devolve `animation-delay` ao zero, então não sobra escalonamento nem
 *    espera. Não há nada a desligar à mão.
 *
 * ⚠️ `transition: none` no trilho é intencional: o Blade continua trocando o
 *    `transform` inline e o navegador simplesmente salta para a cartela final,
 *    sem nenhum quadro intermediário.
 * -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .gami-btn,
    .gami-quero,
    .gami-denovo,
    .gami-cartela,
    .gami-modal__fechar {
        transition:
            background-color 1ms linear,
            border-color 1ms linear,
            color 1ms linear;
    }

    .gami-btn:active,
    .gami-quero:active,
    .gami-denovo:active {
        transform: none;
    }

    .gami-bola--girando,
    .gami-bola--parou,
    .gami-bola.gami-bola--parou::after,
    .gami-cartela--sorteada,
    .gami-modal__veu,
    .gami-modal__caixa {
        animation: none;
    }

    .gami-trilho {
        transition: none;
        will-change: auto;
    }
}

/* -----------------------------------------------------------------------------
 * O VERDE DO COMPRAR (17/08/2026)
 * -----------------------------------------------------------------------------
 * 🔑 ORDEM DELE, e a razão é de produto, não de gosto: o botão de COMPRAR tinha
 *    a MESMA cor do "Rolar os dados". Dois gestos completamente diferentes com a
 *    mesma roupa — "senão vai confundir o usuário e vai induzir a rolar os
 *    dados". Agora azul é gamificação, VERDE é comprar. Uma cor, um significado.
 *
 * O verde é o `#4c933a` do `.btn-green` da HOME, letra por letra: quem viu o
 * "Comprar cartela" na página pública encontra o mesmo verde na hora de fechar.
 * Cor fechada e não variável de tema de propósito — ela não pode mudar com o
 * tema escolhido, senão o significado muda junto.
 *
 * ⚠️ ESTE ARQUIVO É ESTÁTICO, e é por isso que a regra mora aqui: `.ct-btn` vem
 *    do `app.css`, que é COMPILADO pelo Vite, e nenhuma das duas máquinas tem
 *    `node_modules` para reconstruir. Editar lá não chegaria em produção.
 *
 * ⚠️ E POR ISSO O `--comprar` NÃO É CLASSE NOVA DO TAILWIND: é classe de folha
 *    de estilo comum, escrita aqui. Classe utilitária nova não existiria no
 *    pacote compilado e o botão sairia sem cor nenhuma.
 * -------------------------------------------------------------------------- */
:root {
    --ct-comprar: #4c933a;
}

.ct-btn--comprar,
.gami-comprar {
    background-color: var(--ct-comprar);
    color: #fff;
    /* O mesmo volume dos outros botões cheios, em camada transparente: se o
       verde mudar um dia, o degradê continua certo sozinho. */
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.2) 0%,
        rgba(255, 255, 255, 0.04) 52%,
        rgba(0, 0, 0, 0.1) 100%
    );
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.28),
        0 2px 5px rgba(18, 21, 40, 0.22);
    outline-color: var(--ct-comprar);
}

/* 🔊 A CHAMADA QUE FECHA A COMPRA — 20/09/2026.
   *"Aumenta a fonte, eu quero um destaque bem maior: PAGAR AGORA, simples."*
   Só o tamanho muda aqui; a cor e o volume vêm do `.ct-btn--comprar` acima, que
   é o mesmo verde dos botões de comprar cartela. */
.pg-pagar {
    min-height: 54px;
    font-size: 19px;
    font-weight: 800;
    letter-spacing: .01em;

    /* 🫧 A PULSAÇÃO — 20/09/2026, e o pedido dele define o tom: *"bem sutil (…)
       é mais como algo informativo do que apelativo"*, e *"a pulsação não deve
       ser contínua, de um jeito que apele para o cliente ficar num ciclo
       infinito a clicar"*.

       🔑 POR ISSO O CICLO É DE 4s COM 1s DE MOVIMENTO: a animação inteira dura
          quatro segundos, mas só o primeiro quarto tem algo acontecendo — os
          outros três segundos são o botão parado. É o que separa "olha, é aqui"
          de "clica logo".

       📌 O que se move é a SOMBRA e um brilho por fora, mais uma escala de 1%.
          Botão que incha de verdade empurra o layout e chama atenção demais. */
    animation: pg-pagar-pulso 4s ease-in-out 1.2s infinite;
}

@keyframes pg-pagar-pulso {
    /* 0% a 25% = o um segundo de movimento. */
    0% {
        transform: scale(1);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.28),
            0 2px 5px rgba(18, 21, 40, 0.22),
            0 0 0 0 rgba(22, 163, 74, 0.32);
    }

    12% {
        transform: scale(1.012);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.38),
            0 6px 16px rgba(18, 21, 40, 0.26),
            0 0 0 7px rgba(22, 163, 74, 0.16);
    }

    25%, 100% {
        transform: scale(1);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.28),
            0 2px 5px rgba(18, 21, 40, 0.22),
            0 0 0 0 rgba(22, 163, 74, 0);
    }
}

/* ♿ Quem pediu menos movimento no aparelho não recebe pulsação nenhuma — e o
   botão continua com o realce fixo, que é o que importa. */
@media (prefers-reduced-motion: reduce) {
    .pg-pagar {
        animation: none;
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.28),
            0 4px 12px rgba(18, 21, 40, 0.24);
    }
}

.ct-btn--comprar:hover,
.gami-comprar:hover {
    /* Clareia por camada, e não por cor nova: um verde a mais para manter é um
       verde a mais para divergir. */
    background-color: var(--ct-comprar);
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.3) 0%,
        rgba(255, 255, 255, 0.12) 52%,
        rgba(0, 0, 0, 0.06) 100%
    );
}


/* =============================================================================
 * A DECISÃO DEPOIS DO SORTEIO — COMPRAR OCUPANDO A LINHA (31/08/2026)
 * -----------------------------------------------------------------------------
 * Ordem dele: *"o botão comprar fica maior, ele ganha 100% de largura... com a
 * fonte aumentada para dar mais destaque para o usuário comprar"*, e *"coloca
 * uma animação bem sutil no botão de comprar, como se ele estivesse pulsando,
 * mas é bem sutil"*.
 *
 * 🔑 A LARGURA NÃO PRECISA DE REGRA. `.gami-acoes` já é flex e `.gami-quero` já
 *    é `flex: 1 1 0`: sozinho na linha, ele ocupa tudo. O "Girar de novo" saiu
 *    daqui e desceu para a faixa dos atalhos — não foi escondido com CSS, foi
 *    removido do Blade, que é onde a decisão de produto mora.
 *
 * ⚠️ A PULSAÇÃO É DE VERDADE SUTIL: 2% de escala e um halo que abre e fecha, em
 *    2,4s. Botão que pula na tela lê como propaganda e cansa em três repetições;
 *    o que se quer aqui é só o olho voltar para ele.
 * ========================================================================== */
.gami-acoes--decisao .gami-quero {
    min-height: 52px;
    font-size: 17px;
    letter-spacing: 0.01em;

    animation: gami-pulsa 2400ms ease-in-out infinite;

    /* A âncora da escala. Sem isto o botão cresce a partir do canto. */
    transform-origin: center;
}

.gami-acoes--decisao .gami-quero i,
.gami-acoes--decisao .gami-quero svg {
    width: 19px;
    height: 19px;
}

@keyframes gami-pulsa {
    0%,
    100% {
        transform: scale(1);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.28),
            0 2px 5px rgba(18, 21, 40, 0.22),
            0 0 0 0 rgba(80, 160, 64, 0);
    }

    50% {
        transform: scale(1.02);
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.28),
            0 3px 9px rgba(18, 21, 40, 0.26),
            0 0 0 6px rgba(80, 160, 64, 0.14);
    }
}

/* O toque continua tendo a resposta de sempre — e ela vence a pulsação porque
   `:active` vem depois na folha. */
.gami-acoes--decisao .gami-quero:active {
    animation: none;
    transform: scale(0.97);
}

/* Quem pediu menos movimento não recebe pulsação nenhuma. O destaque continua
   inteiro: o botão segue maior e ocupando a linha toda. */
@media (prefers-reduced-motion: reduce) {
    .gami-acoes--decisao .gami-quero {
        animation: none;
    }
}


/* O envoltório dos ícones que se alternam dentro de um `.gami-btn` (o atalho que
   vira "Girar de novo", 31/08/2026). Existe porque o `x-show` precisa de um
   elemento estável para esconder: o Lucide TROCA o `<i>` por um `<svg>` na carga
   da página, e o binding morreria junto com o `<i>`. O `display` mora aqui, e
   não em `style` inline, porque ao reexibir o Alpine apaga o inline. */
.gami-btn__icone {
    display: inline-flex;
    align-items: center;
    flex: none;
}

/* -----------------------------------------------------------------------------
 * 🪗 O BOTÃO DA SANFONA DAS DEZENAS (30/09/2026)
 * -----------------------------------------------------------------------------
 * Largura inteira, ACIMA dos dois atalhos, e abre/fecha a grade das 50
 * dezenas. Roxo (pedido dele, 30/09) — nem os dois atalhos (azul e laranja)
 * nem o verde do Comprar: este não sorteia nem compra, é a escolha à mão. A seta gira 180° aberta.
 * -------------------------------------------------------------------------- */
.gami-btn--dezenas {
    display: flex;
    width: 100%;
    margin: 0 0 8px;
    background-color: #7b3fc4;
    color: #ffffff;
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.24) 0%,
        rgba(255, 255, 255, 0.05) 52%,
        rgba(0, 0, 0, 0.12) 100%
    );
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.3),
        0 2px 5px rgba(50, 15, 90, 0.28);
}

.gami-btn--dezenas:hover {
    color: #ffffff;
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.34) 0%,
        rgba(255, 255, 255, 0.14) 52%,
        rgba(0, 0, 0, 0.06) 100%
    );
}

.gami-btn--dezenas__seta {
    display: inline-flex;
    transition: transform 200ms ease;
}

.gami-btn--dezenas.esta-aberto .gami-btn--dezenas__seta {
    transform: rotate(180deg);
}

/* =============================================================================
 * ⭐ A ESTRELA DAS DEZENAS FAVORITAS — 09/10/2026.
 *
 * Fica por cima do botão "Escolha 5 dezenas", à direita (onde ele marcou).
 * Toque nela marca as 5 dezenas guardadas em Minha conta. Só existe no HTML
 * para o cliente logado que tem as cinco salvas.
 * ========================================================================== */
.gami-favoritas {
    position: absolute;
    top: 50%;
    right: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.18);
    transform: translateY(-50%);
    cursor: pointer;
    transition: transform 150ms ease, background-color 150ms ease;
}

.gami-favoritas svg {
    width: 22px;
    height: 22px;
    fill: #ffd23f;
    stroke: #b7791f;
    stroke-width: 1;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}

.gami-favoritas:hover { background: rgba(255, 255, 255, 0.3); }
.gami-favoritas:active { transform: translateY(-50%) scale(0.9); }
