/* =========================================================================
   EpicTango — folha de estilo do site

   As cores da marca são as mesmas do aplicativo (manual da marca, §3). O que
   este arquivo acrescenta é *palco*: o site não é o app, e aqui o jogo é
   apresentado, não jogado. Por isso há profundidade (perspectiva, camadas em
   translateZ), luz (auroras de sol e lua) e movimento de entrada — coisas que
   o manual §6 mantém fora do jogo, onde o jogador está pensando.

   Três leis que o palco não quebra:

   1. Os tokens de cor continuam sendo os do app. O brilho vem de camadas
      sobrepostas, nunca de trocar o âmbar ou o azul por outro tom.
   2. Contraste de texto sempre acima de 4,5:1 — daí `--muted-forte`, que é o
      `--muted` do app um passo mais fechado (o original dá 3,47:1 no claro).
   3. Tudo que se move some com `prefers-reduced-motion`, e nada de essencial
      depende de JavaScript: sem script o site é o mesmo, apenas parado.
   ========================================================================= */

/* Ângulos e comprimentos animáveis. Sem @property o navegador interpola
   gradiente cônico em degraus; com ele, de forma contínua. */
@property --giro {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

:root {
  /* ---- Tokens do app (manual §3) ---- */
  --bg: #f3f5fb;
  --surface: #ffffff;
  --text: #2a3252;
  --muted: #79839f;
  --muted-forte: #5d6786;

  --board-bg: #e9edf7;
  --board-shadow: rgba(40, 52, 92, 0.14);
  --cell-bg: #ffffff;
  --cell-given: #dfe5f2;
  --cell-bad: #ffe1e1;
  --cell-bad-ring: #ff9a9a;
  --cell-solved: #dcf5e6;

  --clue-bg: #ffffff;
  --clue-fg: #55607c;

  --sym-0: #f5a623;
  --sym-1: #4aa3e6;

  --chip-bg: #e6eaf5;
  --btn-bg: #4a6cf7;
  --btn-fg: #ffffff;
  --elo-prosa: #3f5fe8;

  --sucesso: #1fa463;
  --erro: #e05a6b;

  --linha: rgba(42, 50, 82, 0.12);

  /* ---- Palco: céu, vidro e luz ---- */
  /* No tema claro o céu é um amanhecer: âmbar em cima à esquerda, azul embaixo
     à direita. É o sol e a lua do jogo espalhados pela página. */
  --ceu-sol: rgba(245, 166, 35, 0.3);
  --ceu-lua: rgba(74, 163, 230, 0.3);
  --ceu-acao: rgba(74, 108, 247, 0.2);
  --ceu-veu: rgba(243, 245, 251, 0.5);

  --vidro: rgba(255, 255, 255, 0.62);
  --vidro-forte: rgba(255, 255, 255, 0.88);
  --vidro-borda: rgba(255, 255, 255, 0.9);

  --sombra-perto: 0 2px 6px rgba(40, 52, 92, 0.06);
  --sombra-media: 0 18px 40px -18px rgba(40, 52, 92, 0.34);
  --sombra-longe: 0 60px 90px -46px rgba(40, 52, 92, 0.55);

  --halo-sol: rgba(245, 166, 35, 0.45);
  --halo-lua: rgba(74, 163, 230, 0.45);

  --malha: rgba(42, 50, 82, 0.1);

  /* ---- Medidas ---- */
  --largura-app: min(100%, 440px);
  --largura-texto: 62ch;
  --largura-pagina: 1120px;

  --vao: clamp(4px, 1.1vw, 7px);
  --ritmo-secao: clamp(64px, 10vw, 124px);

  /* Curvas. A primeira é o padrão de tudo que entra; a segunda tem um leve
     avanço no fim, usada só onde uma peça assenta no lugar. */
  --tempo: cubic-bezier(0.22, 1, 0.36, 1);
  --tempo-assenta: cubic-bezier(0.34, 1.32, 0.64, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #10131c;
    --surface: #1a1f2e;
    --text: #e7eaf3;
    --muted: #98a1bd;
    --muted-forte: #98a1bd;

    --board-bg: #1b2131;
    --board-shadow: rgba(0, 0, 0, 0.45);
    --cell-bg: #262e44;
    --cell-given: #1e2537;
    --cell-bad: #4b2733;
    --cell-bad-ring: #c15870;
    --cell-solved: #1f3a2c;

    --clue-bg: #2e3750;
    --clue-fg: #cbd2e6;

    --sym-0: #f6b93b;
    --sym-1: #63b3ed;

    --chip-bg: #262e44;
    --btn-bg: #5a7bff;
    --elo-prosa: #6b89ff;

    --linha: rgba(231, 234, 243, 0.14);

    /* No escuro o céu é noite: a lua domina, o sol fica como brasa distante. */
    --ceu-sol: rgba(246, 185, 59, 0.2);
    --ceu-lua: rgba(99, 179, 237, 0.24);
    --ceu-acao: rgba(90, 123, 255, 0.26);
    --ceu-veu: rgba(16, 19, 28, 0.58);

    --vidro: rgba(38, 46, 68, 0.5);
    --vidro-forte: rgba(26, 31, 46, 0.88);
    --vidro-borda: rgba(231, 234, 243, 0.14);

    --sombra-perto: 0 2px 6px rgba(0, 0, 0, 0.35);
    --sombra-media: 0 18px 40px -18px rgba(0, 0, 0, 0.7);
    --sombra-longe: 0 60px 90px -46px rgba(0, 0, 0, 0.9);

    --halo-sol: rgba(246, 185, 59, 0.4);
    --halo-lua: rgba(99, 179, 237, 0.45);

    --malha: rgba(231, 234, 243, 0.08);
  }
}

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 1rem;
  line-height: 1.6;
  font-weight: 400;
  overflow-x: hidden;
}

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

/* =========================================================================
   O céu — camadas fixas atrás de tudo
   ========================================================================= */

.ceu {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background: var(--bg);
}

.ceu__aurora {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  will-change: transform;
}

.ceu__aurora--sol {
  width: 62vmax;
  height: 62vmax;
  top: -26vmax;
  left: -14vmax;
  background: radial-gradient(circle, var(--ceu-sol) 0%, transparent 68%);
  animation: derivar-sol 38s ease-in-out infinite alternate;
}

.ceu__aurora--lua {
  width: 70vmax;
  height: 70vmax;
  top: 6vmax;
  right: -28vmax;
  background: radial-gradient(circle, var(--ceu-lua) 0%, transparent 68%);
  animation: derivar-lua 44s ease-in-out infinite alternate;
}

.ceu__aurora--acao {
  width: 54vmax;
  height: 54vmax;
  bottom: -24vmax;
  left: 26vmax;
  background: radial-gradient(circle, var(--ceu-acao) 0%, transparent 70%);
  animation: derivar-acao 52s ease-in-out infinite alternate;
}

@keyframes derivar-sol {
  from {
    transform: translate3d(0, 0, 0) scale(1);
  }
  to {
    transform: translate3d(9vmax, 7vmax, 0) scale(1.16);
  }
}

@keyframes derivar-lua {
  from {
    transform: translate3d(0, 0, 0) scale(1.1);
  }
  to {
    transform: translate3d(-11vmax, 10vmax, 0) scale(0.94);
  }
}

@keyframes derivar-acao {
  from {
    transform: translate3d(0, 0, 0) scale(0.95);
  }
  to {
    transform: translate3d(-8vmax, -9vmax, 0) scale(1.2);
  }
}

/* Os padrões do fundo. Nenhuma textura genérica: os dois astros e os selos de
   aresta são as peças do jogo, desenhadas uma vez no sprite e repetidas aqui
   com <pattern>. */
/* O céu é fixo, então o padrão apareceria com a mesma força até o rodapé —
   e a página inteira coberta de sóis vira ruído atrás do texto. `--ceu-fade`
   é escrito pelo JS conforme a rolagem: cheio no herói, zero a partir de uma
   dobra. Sem script fica no valor de repouso, que já é discreto. */
.ceu__padrao {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: calc(0.34 * var(--ceu-fade, 0.55));
}

.ceu__glifo {
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 34px;
  font-weight: 800;
  fill: var(--muted);
  opacity: 0.22;
}

/* A malha em perspectiva: o tabuleiro estendido até o horizonte. É o único
   elemento do fundo que é literalmente o produto. */
.ceu__malha {
  position: absolute;
  inset: -40% -20% 0;
  background:
    linear-gradient(to right, var(--malha) 1px, transparent 1px) 0 0 / 64px 64px,
    linear-gradient(to bottom, var(--malha) 1px, transparent 1px) 0 0 / 64px 64px;
  mask-image: radial-gradient(100% 60% at 50% 46%, #000 0%, transparent 72%);
  -webkit-mask-image: radial-gradient(100% 60% at 50% 46%, #000 0%, transparent 72%);
  transform: perspective(700px) rotateX(62deg);
  transform-origin: 50% 100%;
  opacity: var(--ceu-fade, 0.6);
  animation: correr-malha 22s linear infinite;
}

@keyframes correr-malha {
  from {
    background-position: 0 0, 0 0;
  }
  to {
    background-position: 0 64px, 0 64px;
  }
}

/* O véu devolve o fundo da marca por cima de tudo, para o texto pousar num
   plano legível. */
.ceu__veu {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    var(--ceu-veu) 52%,
    var(--bg) 100%
  );
}

/* =========================================================================
   Barra de progresso da leitura
   ========================================================================= */

.progresso {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  z-index: 40;
  pointer-events: none;
}

.progresso__barra {
  display: block;
  height: 100%;
  width: 100%;
  transform-origin: 0 50%;
  transform: scaleX(var(--avanco, 0));
  background: linear-gradient(90deg, var(--sym-0), var(--btn-bg) 55%, var(--sym-1));
}

/* =========================================================================
   Tipografia
   ========================================================================= */

h1,
h2,
h3 {
  margin: 0;
  font-weight: 800;
  line-height: 1.1;
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.15rem, 5.4vw, 3.5rem);
  letter-spacing: -0.035em;
}

h2 {
  font-size: clamp(1.6rem, 4.6vw, 2.5rem);
  letter-spacing: -0.03em;
}

h3 {
  font-size: 1.18rem;
  letter-spacing: -0.015em;
}

p {
  margin: 0;
}

a {
  color: inherit;
}

:where(a):focus-visible,
:where(button):focus-visible {
  outline: 2px solid var(--btn-bg);
  outline-offset: 3px;
  border-radius: 6px;
}

.rotulo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--muted-forte);
}

/* O ponto pulsante do rótulo: o único sinal de "ao vivo" do site. */
.rotulo::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--sym-0);
  box-shadow: 0 0 0 0 var(--halo-sol);
  animation: pulsar 2.6s ease-out infinite;
}

@keyframes pulsar {
  0% {
    box-shadow: 0 0 0 0 var(--halo-sol);
  }
  70%,
  100% {
    box-shadow: 0 0 0 9px transparent;
  }
}

/* =========================================================================
   Estrutura de página
   ========================================================================= */

.envelope {
  width: 100%;
  max-width: var(--largura-pagina);
  margin-inline: auto;
  padding-inline: 20px;
}

.medida {
  max-width: var(--largura-texto);
}

.pular {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--btn-bg);
  color: var(--btn-fg);
  padding: 12px 18px;
  border-radius: 12px;
  font-size: 1.2rem;
  font-weight: 700;
  z-index: 60;
}

.pular:focus {
  left: 12px;
  top: 12px;
}

.sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* =========================================================================
   Cabeçalho — vidro que encolhe ao rolar
   ========================================================================= */

.topo {
  position: sticky;
  top: 0;
  z-index: 30;
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--tempo), background 0.3s var(--tempo);
}

/* O vidro do cabeçalho precisa de corpo: com o tabuleiro passando por baixo,
   um véu de 50% deixava o texto do menu brigar com os símbolos. */
.topo::before {
  content: "";
  position: absolute;
  inset: 0;
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  opacity: 0;
  transition: opacity 0.3s var(--tempo);
}

body[data-rolado="sim"] .topo {
  border-bottom-color: var(--linha);
}

body[data-rolado="sim"] .topo::before {
  opacity: 1;
}

.topo__interno {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 68px;
  flex-wrap: wrap;
  padding-block: 12px;
  transition: min-height 0.3s var(--tempo);
}

body[data-rolado="sim"] .topo__interno {
  min-height: 58px;
}

.marca {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding-block: 7px;
  font-size: 1.15rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.marca__selo {
  width: 32px;
  height: 32px;
  flex: none;
  filter: drop-shadow(0 3px 8px var(--board-shadow));
  transition: transform 0.5s var(--tempo);
}

/* O selo gira no eixo Y ao passar o mouse: sol de um lado, lua do outro,
   como as duas faces da mesma peça. */
.marca:hover .marca__selo {
  transform: rotateY(180deg) scale(1.06);
}

.topo__navegacao {
  display: flex;
  align-items: center;
  gap: 6px;
}

.elo {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 999px;
  color: var(--muted-forte);
  font-size: 0.92rem;
  font-weight: 700;
  text-decoration: none;
  /* O `isolation` prende o `z-index: -1` do fundo dentro do próprio link: sem
     ele o fundo ou some atrás do cabeçalho, ou tapa o texto do link. */
  isolation: isolate;
  transition: color 0.18s var(--tempo);
}

/* O fundo entra por trás e cresce a partir do centro, em vez de piscar. */
.elo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: var(--chip-bg);
  transform: scale(0.7);
  opacity: 0;
  transition: transform 0.24s var(--tempo), opacity 0.24s var(--tempo);
}

.elo:hover {
  color: var(--text);
}

.elo:hover::before,
.elo[aria-current="page"]::before {
  transform: scale(1);
  opacity: 1;
}

.elo[aria-current="page"] {
  color: var(--text);
}

.idiomas {
  display: inline-flex;
  gap: 2px;
  margin-left: 6px;
  padding: 3px;
  align-items: center;
  border-radius: 999px;
  background: color-mix(in srgb, var(--chip-bg) 60%, transparent);
}

.idioma {
  font-size: 0.78rem;
  font-weight: 700;
  padding: 5px 8px;
  border-radius: 999px;
  color: var(--muted-forte);
  text-decoration: none;
  line-height: 1;
  transition: color 0.18s var(--tempo), background 0.18s var(--tempo);
}

.idioma:hover {
  color: var(--text);
  background: var(--chip-bg);
}

.idioma--ativo {
  color: var(--btn-fg);
  background: var(--btn-bg);
  box-shadow: var(--sombra-perto);
}

/* =========================================================================
   Botão de ação
   ========================================================================= */

/* 1,2rem em peso 700 põe o texto acima de 18,66px, faixa em que o mínimo de
   contraste cai para 3:1 — o azul da marca dá 4,4:1 sobre branco. */
.acao {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 54px;
  padding: 12px 28px;
  border: none;
  border-radius: 14px;
  background: linear-gradient(
    135deg,
    var(--btn-bg) 0%,
    color-mix(in srgb, var(--btn-bg) 78%, var(--sym-1)) 100%
  );
  color: var(--btn-fg);
  font-family: inherit;
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  isolation: isolate;
  overflow: hidden;
  box-shadow:
    0 10px 30px -10px color-mix(in srgb, var(--btn-bg) 70%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
  transition:
    transform 0.24s var(--tempo),
    box-shadow 0.24s var(--tempo);
}

/* O brilho que atravessa o botão da esquerda para a direita no hover. */
.acao::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    100deg,
    transparent 30%,
    rgba(255, 255, 255, 0.35) 50%,
    transparent 70%
  );
  transform: translateX(-100%);
  transition: transform 0.7s var(--tempo);
}

.acao:hover {
  transform: translateY(-3px);
  box-shadow:
    0 20px 40px -14px color-mix(in srgb, var(--btn-bg) 75%, transparent),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
}

.acao:hover::after {
  transform: translateX(100%);
}

.acao:active {
  transform: translateY(-1px) scale(0.985);
}

.acao__icone {
  width: 22px;
  height: 22px;
  flex: none;
  transition: transform 0.3s var(--tempo-assenta);
}

.acao:hover .acao__icone {
  transform: translateY(3px);
}

.acao--secundaria {
  background: transparent;
  color: var(--text);
  box-shadow: inset 0 0 0 2px var(--linha);
  font-size: 1rem;
  min-height: 48px;
}

.acao--secundaria:hover {
  background: var(--chip-bg);
  box-shadow: inset 0 0 0 2px var(--linha);
}

/* =========================================================================
   Entrada em cena — revelação por rolagem
   ========================================================================= */

/* A entrada usa `translate` / `rotate` / `scale`, e não `transform`.

   Não é preciosismo: a inclinação sob o ponteiro escreve `transform`, e se a
   entrada usasse a mesma propriedade uma apagaria a outra — o cartão entraria
   e nunca mais inclinaria. Como propriedades separadas, as duas se compõem. */

/* A perspectiva mora no pai: sem ela o giro de entrada vira um achatamento. */
main .envelope,
.heroi__texto,
.secao__cabeca,
.regras,
.modos,
.fatos,
.prosa,
.perdido,
.marca {
  perspective: 1200px;
}

/* O estado inicial só existe quando o JS confirma que vai animar; sem script,
   ou com movimento reduzido, o conteúdo já nasce no lugar. */
body[data-anima="sim"] [data-cena] {
  opacity: 0;
  translate: 0 34px;
  rotate: x 7deg;
  transform-origin: 50% 100%;
  transition:
    opacity 0.8s var(--tempo) var(--atraso, 0ms),
    translate 0.9s var(--tempo) var(--atraso, 0ms),
    rotate 0.9s var(--tempo) var(--atraso, 0ms);
  will-change: opacity, translate, rotate;
}

body[data-anima="sim"] [data-cena="lado"] {
  translate: -26px 0;
  rotate: y -9deg;
  transform-origin: 0% 50%;
}

body[data-anima="sim"] [data-cena].em-cena {
  opacity: 1;
  translate: none;
  rotate: none;
  will-change: auto;
}

/* =========================================================================
   Herói
   ========================================================================= */

.heroi {
  position: relative;
  padding-block: clamp(44px, 8vw, 104px) var(--ritmo-secao);
}

/* Raios de dedução: a luz do sol atravessando o tabuleiro, na diagonal. Só no
   herói — repetir isso página abaixo cansaria. */
.heroi::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    52deg,
    color-mix(in srgb, var(--sym-0) 26%, transparent) 0 1px,
    transparent 1px 74px
  );
  mask-image: radial-gradient(70% 90% at 0% 0%, #000, transparent 72%);
  -webkit-mask-image: radial-gradient(70% 90% at 0% 0%, #000, transparent 72%);
  opacity: 0.5;
}

.heroi__grade {
  position: relative;
  display: grid;
  gap: clamp(44px, 6vw, 64px);
  align-items: center;
}

/* O palco: coluna de texto larga e fixa, e o tabuleiro ocupando tudo o que
   sobra — inclusive o que passa da margem direita. */
@media (min-width: 1040px) {
  .heroi__grade {
    grid-template-columns: minmax(0, 620px) minmax(0, 1fr);
    gap: 40px;
  }
}

.heroi__texto {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* O ar entre título, promessa e botão é o conserto do banner espremido:
     antes eram 20px para tudo. */
  gap: clamp(22px, 2.6vw, 32px);
  max-width: 38rem;
}

/* O título do herói é o maior elemento do site, e agora tem entrelinha para
   respirar em vez de empilhar linhas coladas. */
.heroi h1 {
  font-size: clamp(2.4rem, 5.8vw, 4.15rem);
  line-height: 1.02;
  letter-spacing: -0.045em;
  /* O balance espremia o título em linhas curtas dentro de uma coluna larga. */
  text-wrap: pretty;
}

/* O título entra palavra por palavra, cada uma girando para cima do próprio
   eixo. As palavras são embrulhadas pelo JS; sem ele, o h1 é um h1. */
.heroi h1 .palavra {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  /* Sem folga o `overflow` corta o rabo do g e do ç. */
  padding-bottom: 0.14em;
  margin-bottom: -0.14em;
}

/* A última palavra é a que carrega a promessa — "chute", "guess", "adivinar" —
   e sai no âmbar da marca. */
.heroi h1 .palavra--fecho {
  color: var(--sym-0);
}

.heroi h1 .palavra > span {
  display: inline-block;
  transform: translateY(105%) rotate(6deg);
  transition: transform 0.9s var(--tempo) var(--atraso, 0ms);
}

body:not([data-anima="sim"]) .heroi h1 .palavra > span,
.heroi h1.em-cena .palavra > span {
  transform: none;
}

.heroi__promessa {
  font-size: clamp(1.08rem, 2.6vw, 1.26rem);
  color: var(--muted-forte);
  max-width: 42ch;
}

.heroi__acoes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.heroi__nota {
  font-size: 0.86rem;
  color: var(--muted-forte);
}

/* =========================================================================
   O tabuleiro em cena 3D
   ========================================================================= */

/* A cena é o que dá perspectiva; a moldura é o objeto que gira dentro dela.
   O JS escreve --giro-x / --giro-y conforme o ponteiro, e um leve giro de
   repouso mantém a peça viva quando ninguém está apontando. */
.cena {
  perspective: 1500px;
  perspective-origin: 50% 45%;
  width: var(--largura-app);
  margin-inline: auto;
}

/* A partir da largura em que o herói vira duas colunas, o tabuleiro deixa de
   ser uma figura ao lado do texto e passa a ser o objeto em cena: maior que a
   largura canônica do app (manual §5.2), encostado à esquerda da própria
   coluna e sangrando pela margem direita da página. O `overflow-x: hidden` do
   body é o que segura a barra de rolagem. */
@media (min-width: 1040px) {
  .cena {
    --base-x: 9deg;
    --base-y: -20deg;
    --base-z: 2deg;
    width: clamp(440px, 44vw, 580px);
    margin-inline: 0;
    justify-self: start;
  }
}

.moldura {
  position: relative;
  width: 100%;
  padding: clamp(12px, 2.6vw, 20px);
  background: var(--board-bg);
  border-radius: clamp(18px, 2.4vw, 28px);
  box-shadow:
    var(--sombra-media),
    var(--sombra-longe),
    inset 0 1px 0 rgba(255, 255, 255, 0.16);
  transform-style: preserve-3d;
  /* A pose de repouso e o ponteiro são somados, não substituídos: assim o
     tabuleiro reage ao ponteiro sem perder a inclinação de palco. */
  transform: rotateX(calc(var(--base-x, 0deg) + var(--giro-x, 0deg)))
    rotateY(calc(var(--base-y, 0deg) + var(--giro-y, 0deg)))
    rotateZ(var(--base-z, 0deg));
  transition: transform 0.5s var(--tempo);
}

/* O tabuleiro é a única peça que entra girando de verdade: chega deitado e se
   levanta. Como o giro do ponteiro ocupa `transform`, a entrada vive em
   `translate` / `scale`, que se compõem com ele. */
body[data-anima="sim"] .cena .moldura {
  opacity: 0;
  translate: 0 44px;
  scale: 0.93;
  transition:
    opacity 0.9s var(--tempo),
    translate 1s var(--tempo),
    scale 1s var(--tempo),
    transform 0.5s var(--tempo);
}

body[data-anima="sim"] .cena.em-cena .moldura {
  opacity: 1;
  translate: none;
  scale: none;
}

body[data-anima="sim"] .cena--viva .moldura {
  animation: respirar 12s ease-in-out infinite;
}

/* Sem ponteiro (celular), a moldura mantém uma oscilação mínima em volta da
   pose de repouso. A animação escreve `transform` inteiro, então a pose entra
   aqui somada de novo. */
@keyframes respirar {
  0%,
  100% {
    transform: rotateX(calc(var(--base-x, 0deg) + 2.5deg))
      rotateY(calc(var(--base-y, 0deg) - 3deg))
      rotateZ(var(--base-z, 0deg));
  }
  50% {
    transform: rotateX(calc(var(--base-x, 0deg) - 2deg))
      rotateY(calc(var(--base-y, 0deg) + 4deg))
      rotateZ(var(--base-z, 0deg));
  }
}

/* O halo por trás da moldura: sol de um lado, lua do outro. Fica atrás do
   fundo da própria moldura, então o que se vê é o anel que sobra em volta —
   que é exatamente o efeito de luz procurado. */
.moldura::before {
  content: "";
  position: absolute;
  inset: -26%;
  z-index: -1;
  border-radius: 50%;
  background:
    radial-gradient(circle at 22% 22%, var(--halo-sol) 0%, transparent 56%),
    radial-gradient(circle at 78% 78%, var(--halo-lua) 0%, transparent 56%);
  filter: blur(56px);
  transform: translateZ(-70px);
}

.tabuleiro {
  display: grid;
  grid-template-columns: repeat(5, 1fr var(--vao)) 1fr;
  grid-template-rows: repeat(5, 1fr var(--vao)) 1fr;
  transform-style: preserve-3d;
}

.cel {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  background: var(--cell-bg);
  /* Raio percentual, não em pixels: o tabuleiro é fluido (manual §5.1). */
  border-radius: 22%;
  box-shadow: var(--sombra-perto);
  transform: translateZ(0);
  transition:
    background 0.4s var(--tempo),
    box-shadow 0.4s var(--tempo),
    transform 0.5s var(--tempo);
}

/* As células preenchidas se levantam do tabuleiro e as travadas ficam no
   plano, afundadas só pela sombra interna: o tabuleiro deixa de ser um desenho
   e vira um objeto com relevo.

   Nenhuma célula vai para Z negativo. Dentro de um `preserve-3d` o fundo da
   própria `.moldura` está no plano Z = 0, e o que fica atrás dele desaparece —
   foi assim que as células travadas sumiram na primeira versão. */
.tabuleiro .cel--dada {
  background: var(--cell-given);
  box-shadow: inset 0 2px 6px var(--board-shadow);
  transform: translateZ(0);
}

.tabuleiro .cel:has(.sym):not(.cel--dada) {
  transform: translateZ(9px);
}

.cel--erro {
  background: var(--cell-bad);
  box-shadow: inset 0 0 0 2px var(--cell-bad-ring);
}

.sym {
  width: 66%;
  height: 66%;
  display: block;
}

.sym--sol {
  color: var(--sym-0);
}

.sym--lua {
  color: var(--sym-1);
}

.tabuleiro .sym {
  filter: drop-shadow(0 2px 4px var(--board-shadow));
}

/* Símbolo recém-deduzido: gira para dentro da célula e acende. */
.sym--entra {
  animation: virar-simbolo 0.6s var(--tempo-assenta) both;
}

@keyframes virar-simbolo {
  from {
    opacity: 0;
    transform: rotateX(-90deg) scale(0.5);
  }
  60% {
    opacity: 1;
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.cel--acesa {
  background: var(--cell-solved);
}

/* A varredura de vitória: uma onda que atravessa o tabuleiro na diagonal. */
.cel--onda {
  animation: onda-vitoria 0.9s var(--tempo) both;
}

@keyframes onda-vitoria {
  0% {
    transform: translateZ(9px);
  }
  40% {
    transform: translateZ(22px) scale(1.05);
    box-shadow: 0 14px 24px -10px var(--board-shadow);
  }
  100% {
    transform: translateZ(9px);
  }
}

/* O selo cai na faixa do vão, então fica exatamente sobre a aresta entre duas
   células — sem posicionamento absoluto e sem conta de porcentagem. */
.pista {
  place-self: center;
  z-index: 2;
  display: grid;
  place-items: center;
  /* O selo cresceu com o tabuleiro: num palco de 580px o antigo 22px sumia. */
  width: clamp(17px, 2.2vw, 26px);
  height: clamp(17px, 2.2vw, 26px);
  border-radius: 999px;
  background: var(--clue-bg);
  color: var(--clue-fg);
  font-size: clamp(10px, 1.25vw, 15px);
  font-weight: 800;
  line-height: 1;
  box-shadow: 0 3px 8px var(--board-shadow);
  /* Alto o bastante para o selo flutuar sobre a aresta, baixo o bastante para
     não escorregar do vão quando o tabuleiro inclina. */
  transform: translateZ(14px);
}

/* =========================================================================
   Seções
   ========================================================================= */

.secao {
  position: relative;
  padding-block: var(--ritmo-secao);
}

/* A linha divisória some nas pontas, em vez de bater na borda da tela. */
.secao::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--linha) 18%,
    var(--linha) 82%,
    transparent
  );
}

.secao__cabeca {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: var(--largura-texto);
  margin-bottom: clamp(32px, 5vw, 52px);
}

.secao__resumo {
  color: var(--muted-forte);
  font-size: 1.07rem;
}

/* =========================================================================
   Regras — três cartões de vidro que inclinam sob o ponteiro
   ========================================================================= */

.regras {
  display: grid;
  gap: clamp(20px, 3.4vw, 28px);
  perspective: 1300px;
}

/* As três figuras têm alturas diferentes, então título, figura e texto
   desalinhariam entre as colunas. O subgrid faz cada regra herdar as linhas da
   grade de fora, e as três passam a compartilhar as mesmas faixas. */
@media (min-width: 760px) {
  .regras {
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: auto auto auto;
  }

  .regra {
    grid-row: span 3;
    display: grid;
    grid-template-rows: subgrid;
  }
}

.regra {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(18px, 2.6vw, 24px);
  border-radius: 20px;
  background: var(--vidro);
  backdrop-filter: blur(12px) saturate(1.3);
  -webkit-backdrop-filter: blur(12px) saturate(1.3);
  box-shadow:
    inset 0 1px 0 var(--vidro-borda),
    0 1px 0 var(--linha),
    var(--sombra-media);
  transform-style: preserve-3d;
  transform: rotateX(var(--giro-x, 0deg)) rotateY(var(--giro-y, 0deg));
  transition:
    transform 0.5s var(--tempo),
    box-shadow 0.5s var(--tempo);
}

.regra:hover {
  box-shadow:
    inset 0 1px 0 var(--vidro-borda),
    0 1px 0 var(--linha),
    var(--sombra-longe);
}

/* O reflexo segue o ponteiro dentro do cartão. */
.regra::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(
    340px circle at var(--luz-x, 50%) var(--luz-y, 0%),
    color-mix(in srgb, var(--sym-0) 22%, transparent),
    transparent 62%
  );
  opacity: 0;
  transition: opacity 0.4s var(--tempo);
}

.regra:hover::after {
  opacity: 1;
}

.regra > * {
  transform: translateZ(20px);
}

.regra__figura {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  background: var(--board-bg);
  border-radius: 16px;
  box-shadow: inset 0 2px 8px var(--board-shadow);
}

.faixa {
  display: grid;
  grid-template-columns: repeat(var(--colunas, 6), 1fr);
  gap: var(--vao);
}

/* Na regra do equilíbrio a faixa entra célula a célula quando aparece. */
.faixa .cel {
  transition:
    transform 0.5s var(--tempo) calc(var(--celula, 0) * 60ms),
    background 0.3s var(--tempo);
}

/* Conflito: as três luas seguidas pulsam em vermelho, como o Conferir faz. */
.regra__figura .cel--erro {
  animation: piscar-conflito 3.4s ease-in-out infinite;
  animation-delay: calc(var(--celula, 0) * 90ms);
}

@keyframes piscar-conflito {
  0%,
  55%,
  100% {
    background: var(--cell-bg);
    box-shadow: inset 0 0 0 0 transparent;
  }
  15%,
  40% {
    background: var(--cell-bad);
    box-shadow: inset 0 0 0 2px var(--cell-bad-ring);
  }
}

.regra__legenda {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--muted-forte);
  display: flex;
  align-items: center;
  gap: 7px;
}

.marca-estado {
  width: 9px;
  height: 9px;
  border-radius: 999px;
  flex: none;
}

.marca-estado--ok {
  background: var(--sucesso);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sucesso) 24%, transparent);
}

.marca-estado--nao {
  background: var(--erro);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--erro) 24%, transparent);
}

.regra__texto {
  color: var(--muted-forte);
}

/* Duas células com o selo entre elas, que é como a pista aparece no tabuleiro.
   Os dois pares ficam lado a lado quando há largura e empilham quando não há. */
.pares {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
}

.par {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
  /* Sem teto, o par de células fica três vezes maior que as das outras duas
     figuras e as três deixam de parecer o mesmo tabuleiro. */
  max-width: 152px;
}

.par__selo {
  display: grid;
  place-items: center;
  width: 27px;
  height: 27px;
  flex: none;
  border-radius: 999px;
  background: var(--clue-bg);
  color: var(--clue-fg);
  font-size: 0.85rem;
  font-weight: 800;
  box-shadow: 0 3px 8px var(--board-shadow);
  animation: bater-selo 3.6s ease-in-out infinite;
}

.par:last-child .par__selo {
  animation-delay: 1.8s;
}

@keyframes bater-selo {
  0%,
  80%,
  100% {
    transform: scale(1);
  }
  88% {
    transform: scale(1.22);
  }
}

/* =========================================================================
   Modos — quatro cartões que se levantam do plano
   ========================================================================= */

.modos {
  position: relative;
  display: grid;
  gap: clamp(14px, 2vw, 20px);
  perspective: 1400px;
  counter-reset: modo;
}

/* Relevo de células: a malha do tabuleiro corre por trás dos cartões e só
   aparece nos vãos entre eles. É o que amarra os quatro modos ao jogo. */
.modos::before {
  content: "";
  position: absolute;
  inset: -6% -4%;
  z-index: -1;
  background-image:
    linear-gradient(to right, var(--malha) 1px, transparent 1px),
    linear-gradient(to bottom, var(--malha) 1px, transparent 1px);
  background-size: 44px 44px;
  transform: rotate(-9deg);
  mask-image: radial-gradient(70% 70% at 50% 50%, #000, transparent 78%);
  -webkit-mask-image: radial-gradient(70% 70% at 50% 50%, #000, transparent 78%);
}

@media (min-width: 760px) {
  .modos {
    grid-template-columns: repeat(2, 1fr);
  }
}

.modo {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: clamp(24px, 3.4vw, 34px);
  border-radius: 22px;
  background: var(--vidro-forte);
  overflow: hidden;
  isolation: isolate;
  box-shadow:
    inset 0 1px 0 var(--vidro-borda),
    var(--sombra-media);
  transform-style: preserve-3d;
  transition:
    transform 0.5s var(--tempo),
    box-shadow 0.5s var(--tempo);
}

/* A borda de luz gira devagar em volta do cartão quando ele está sob o
   ponteiro — o gradiente cônico animado pelo @property. */
.modo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: 1px;
  border-radius: inherit;
  background: conic-gradient(
    from var(--giro),
    transparent 0deg,
    var(--sym-0) 40deg,
    var(--btn-bg) 120deg,
    var(--sym-1) 200deg,
    transparent 280deg
  );
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  -webkit-mask-composite: xor;
  opacity: 0;
  transition: opacity 0.4s var(--tempo);
}

.modo:hover {
  transform: translateY(-6px) rotateX(3deg) scale(1.012);
  box-shadow:
    inset 0 1px 0 var(--vidro-borda),
    var(--sombra-longe);
}

.modo:hover::before {
  opacity: 1;
  animation: girar-borda 5s linear infinite;
}

@keyframes girar-borda {
  to {
    --giro: 360deg;
  }
}

/* O número do modo, grande e apagado, no canto. Dá ritmo à grade sem
   acrescentar uma palavra ao conteúdo. */
.modo::after {
  counter-increment: modo;
  content: counter(modo, decimal-leading-zero);
  position: absolute;
  top: clamp(10px, 1.6vw, 16px);
  right: clamp(14px, 2vw, 22px);
  z-index: -1;
  font-size: clamp(3.6rem, 7vw, 5.4rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.05em;
  color: var(--text);
  opacity: 0.06;
  transition: opacity 0.4s var(--tempo), transform 0.5s var(--tempo);
}

.modo:hover::after {
  opacity: 0.11;
  transform: translateY(-4px);
}

.modo__medida {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  padding: 5px 11px;
  border-radius: 999px;
  background: var(--chip-bg);
  color: var(--muted-forte);
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
}

.modo h3 {
  font-size: clamp(1.3rem, 2.6vw, 1.6rem);
}

.modo__texto {
  color: var(--muted-forte);
  max-width: 46ch;
}

/* =========================================================================
   Lista de fatos
   ========================================================================= */

.fatos {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

@media (min-width: 760px) {
  .fatos {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
  }
}

.fato {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 14px;
  align-items: start;
  padding: clamp(16px, 2.2vw, 22px);
  border-radius: 18px;
  background: var(--vidro);
  box-shadow: inset 0 1px 0 var(--vidro-borda), var(--sombra-perto);
  transition: transform 0.4s var(--tempo), box-shadow 0.4s var(--tempo);
}

.fato:hover {
  transform: translateY(-3px);
  box-shadow: inset 0 1px 0 var(--vidro-borda), var(--sombra-media);
}

.fato__sinal {
  width: 26px;
  height: 26px;
  padding: 4px;
  margin-top: 2px;
  flex: none;
  border-radius: 999px;
  color: var(--sucesso);
  background: color-mix(in srgb, var(--sucesso) 14%, transparent);
}

/* O traço do certo é desenhado, não aparece pronto. */
.fato__sinal path {
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
  transition: stroke-dashoffset 0.7s var(--tempo) var(--atraso, 0ms);
}

body:not([data-anima="sim"]) .fato__sinal path,
.fato.em-cena .fato__sinal path {
  stroke-dashoffset: 0;
}

.fato__titulo {
  font-weight: 700;
}

.fato__texto {
  color: var(--muted-forte);
  font-size: 0.95rem;
}

/* =========================================================================
   Chamada final
   ========================================================================= */

.fecho {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
  padding: clamp(32px, 6vw, 64px);
  border-radius: 28px;
  background: var(--vidro-forte);
  overflow: hidden;
  isolation: isolate;
  box-shadow:
    inset 0 1px 0 var(--vidro-borda),
    var(--sombra-longe);
}

/* Um tabuleiro fantasma atravessa o cartão na diagonal, em perspectiva. */
.fecho::before {
  content: "";
  position: absolute;
  inset: -30% -10%;
  z-index: -1;
  background:
    linear-gradient(to right, var(--malha) 1px, transparent 1px) 0 0 / 48px 48px,
    linear-gradient(to bottom, var(--malha) 1px, transparent 1px) 0 0 / 48px 48px;
  transform: perspective(600px) rotateX(56deg) rotate(-8deg);
  mask-image: radial-gradient(80% 70% at 80% 30%, #000, transparent 70%);
  -webkit-mask-image: radial-gradient(80% 70% at 80% 30%, #000, transparent 70%);
}

.fecho::after {
  content: "";
  position: absolute;
  z-index: -1;
  top: -40%;
  right: -10%;
  width: 46%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, var(--halo-sol), transparent 62%);
  filter: blur(50px);
}

.fecho__titulo {
  /* O itálico é o único floreio da marca e só aparece no momento da vitória
     (manual §4). Aqui ele marca o único ponto do site que pede a instalação. */
  font-style: italic;
  font-size: clamp(1.7rem, 4.6vw, 2.6rem);
  max-width: 20ch;
}

/* =========================================================================
   Rodapé
   ========================================================================= */

.rodape {
  position: relative;
  padding-block: 48px 60px;
  font-size: 0.9rem;
  color: var(--muted-forte);
}

.rodape::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--linha) 18%,
    var(--linha) 82%,
    transparent
  );
}

.rodape__interno {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 20px 40px;
}

.rodape__grupo {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Os links do rodapé ficavam com 23px de altura, abaixo do alvo mínimo de
   toque. O recuo vertical cresce a área clicável sem afastar as linhas. */
.rodape__grupo a {
  padding-block: 6px;
  width: fit-content;
  transition: transform 0.2s var(--tempo), color 0.2s var(--tempo);
}

.rodape a {
  color: var(--muted-forte);
  text-decoration-color: var(--linha);
  text-underline-offset: 3px;
}

.rodape__grupo a:hover {
  color: var(--text);
  transform: translateX(3px);
}

/* =========================================================================
   Texto corrido (política de privacidade, exclusão, 404)
   ========================================================================= */

.prosa {
  max-width: calc(var(--largura-texto) + 40px);
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.prosa h1 {
  font-size: clamp(2rem, 5.6vw, 3rem);
}

.prosa h2 {
  margin-top: 28px;
  font-size: clamp(1.3rem, 3.2vw, 1.6rem);
}

.prosa h3 {
  margin-top: 12px;
}

.prosa ul {
  margin: 0;
  padding-left: 22px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.prosa a {
  color: var(--elo-prosa);
  text-underline-offset: 3px;
}

.prosa strong {
  font-weight: 700;
}

.prosa code {
  padding: 2px 6px;
  border-radius: 6px;
  background: var(--chip-bg);
  font-size: 0.9em;
}

.destaque {
  padding: 22px 24px;
  border-radius: 20px;
  background: var(--vidro-forte);
  box-shadow:
    inset 0 1px 0 var(--vidro-borda),
    var(--sombra-media);
}

.tabela-rolagem {
  overflow-x: auto;
  max-width: 100%;
  border-radius: 16px;
  background: var(--vidro);
  box-shadow: inset 0 1px 0 var(--vidro-borda), var(--sombra-perto);
}

table {
  border-collapse: collapse;
  width: 100%;
  min-width: 420px;
  font-size: 0.92rem;
}

th,
td {
  text-align: left;
  padding: 12px 16px;
  border-bottom: 1px solid var(--linha);
  vertical-align: top;
}

tr:last-child td {
  border-bottom: none;
}

th {
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted-forte);
}

/* =========================================================================
   Página não encontrada
   ========================================================================= */

/* Vive dentro de um `.envelope`, nunca na mesma tag: as duas classes definem
   `max-width` e a que vencesse a cascata desalinharia a página do cabeçalho. */
.perdido {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 22px;
  padding-block: clamp(70px, 13vw, 140px);
  max-width: 46ch;
}

/* =========================================================================
   Movimento reduzido — o palco para, o conteúdo fica
   ========================================================================= */

/* Movimento reduzido tira o movimento, não o desenho. A inclinação do palco,
   as texturas e o relevo continuam — são estáticos. O que some é tudo que se
   mexe: derivas do céu, entradas em cena, pulsos e a partida se resolvendo
   sozinha (o script sai antes de chegar nela). */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
