/* Termômetro Emocional — protótipo mobile-first */
:root {
  --fundo: #0d1117;
  --fundo-2: #151b24;
  --fundo-3: #1d2531;
  --linha: #2a3441;
  --texto: #e7edf5;
  --texto-2: #97a3b4;
  --oceano: #0f1620;
  --terra: #232c38;

  --alegria: #f2b950;
  --tristeza: #5b8dd6;
  --raiva: #d9534f;
  --medo: #8a6fd1;
  --nojo: #6fae7a;
  --surpresa: #4fbccf;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: var(--fundo);
  color: var(--texto);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  overscroll-behavior: none;
}

body { display: flex; flex-direction: column; }

.tela { display: none; flex: 1; flex-direction: column; min-height: 0; }
.tela.ativa { display: flex; }
.oculto { display: none !important; }

/* ================= Tela 1 — linguagem de game =================
   Peças: um fundo vivo (.aura), botões com profundidade física (.cartao),
   e uma sequência de escolha que responde ao toque antes da rede responder.
   Tudo em CSS + SVG inline: sem framework, sem build, sem asset remoto. */

#tela-emocao { position: relative; overflow: hidden; }

/* ---------- fundo vivo ---------- */
.aura { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.aura b {
  position: absolute; display: block; border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, currentColor, transparent 68%);
  color: var(--surpresa);          /* trocado por JS conforme a emoção tocada */
  opacity: 0.16;
  filter: blur(30px);
  transition: color .9s ease, opacity .9s ease;
  will-change: transform;
}
.aura b:nth-child(1) {
  width: 78vw; height: 78vw; left: -18vw; top: -14vh;
  animation: derivar-a 19s ease-in-out infinite alternate;
}
.aura b:nth-child(2) {
  width: 66vw; height: 66vw; right: -16vw; bottom: -10vh;
  color: var(--alegria);
  animation: derivar-b 23s ease-in-out infinite alternate;
}
@keyframes derivar-a {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(9vw, 7vh, 0) scale(1.16); }
}
@keyframes derivar-b {
  from { transform: translate3d(0, 0, 0) scale(1.1); }
  to   { transform: translate3d(-8vw, -6vh, 0) scale(0.92); }
}

/* ---------- cabeçalho ---------- */
.cabecalho {
  position: relative; z-index: 1;
  padding: max(26px, env(safe-area-inset-top)) 24px 4px;
  text-align: center;
}
.olho {
  margin: 6px 0 12px; font-size: 0.64rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.18em;
  color: var(--texto-2); opacity: 0.7;
}
.cabecalho h1 {
  font-size: clamp(1.5rem, 6.6vw, 2rem); font-weight: 700;
  margin: 0 0 8px; letter-spacing: -0.02em; line-height: 1.15;
}
.sub { color: var(--texto-2); font-size: 0.92rem; margin: 0; }

/* ---------- grade de emoções ---------- */
.grade-emocoes {
  position: relative; z-index: 1;
  flex: 1;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  /* Dez opções, cinco linhas — e TODAS têm de caber sem rolagem. Uma opção
     abaixo da dobra é escolhida menos, e isso não é um problema de conforto:
     é viés de medida a entrar no instrumento. */
  grid-template-rows: repeat(5, minmax(72px, 1fr));
  gap: 12px;
  padding: 14px 16px;
  max-width: 520px; max-height: 640px; width: 100%;
  margin: auto;                    /* o que sobrar do teto fica dividido em cima e em baixo */
}

/* O botão tem espessura: uma "saia" escura embaixo que some ao ser premido.
   É o que faz o toque parecer mecânico em vez de plano. */
.cartao {
  position: relative;
  min-height: 72px;
  background: linear-gradient(180deg, var(--fundo-3), var(--fundo-2));
  border: 1px solid var(--linha);
  border-radius: 18px;
  padding: 11px 6px 9px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px;
  color: var(--texto); font: inherit; cursor: pointer;
  box-shadow: 0 6px 0 rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .05);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), box-shadow .09s ease,
              border-color .2s ease, opacity .25s ease, filter .25s ease;
  animation: entrar .44s cubic-bezier(.2,.85,.25,1) backwards;
  will-change: transform;
}
/* halo da cor da emoção — currentColor é definido por JS em cada cartão */
.cartao::before {
  content: ""; position: absolute; inset: 0; border-radius: 21px; pointer-events: none;
  background: radial-gradient(78% 58% at 50% 20%, currentColor, transparent 62%);
  opacity: 0.12; transition: opacity .2s ease;
}
.cartao:active, .cartao.pressionado {
  transform: translateY(6px);
  box-shadow: 0 0 0 rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .05);
}
.cartao:active::before, .cartao.pressionado::before { opacity: 0.3; }
.cartao:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

.cartao svg {
  width: 46px; height: 46px; display: block;
  animation: respirar 3.8s ease-in-out infinite;
  transition: transform .18s ease;
}
.cartao span {
  font-size: 0.82rem; font-weight: 600; letter-spacing: 0.01em;
  color: var(--texto-2); transition: color .2s ease;
}
.cartao:active span, .cartao.pressionado span { color: var(--texto); }

@keyframes entrar {
  from { opacity: 0; transform: translateY(20px) scale(.9); }
  to   { opacity: 1; transform: none; }
}
@keyframes respirar {
  0%, 100% { transform: scale(1) translateY(0); }
  50%      { transform: scale(1.05) translateY(-2px); }
}

/* ---------- sequência de escolha ---------- */
/* os não escolhidos recuam; o escolhido salta e ganha o brilho da sua cor */
.grade-emocoes.escolhendo .cartao { pointer-events: none; }
.grade-emocoes.escolhendo .cartao:not(.escolhido) {
  opacity: 0.2; transform: scale(.9); filter: saturate(.3);
}
.cartao.escolhido {
  border-color: currentColor;
  animation: saltar .5s cubic-bezier(.25,.9,.3,1.3) forwards;
  z-index: 2;
}
.cartao.escolhido::before { opacity: 0.42; }
.cartao.escolhido svg { animation: none; transform: scale(1.14); }
.cartao.escolhido span { color: var(--texto); }
@keyframes saltar {
  0%   { transform: translateY(6px) scale(1); box-shadow: 0 0 0 rgba(0,0,0,.5); }
  45%  { transform: translateY(-8px) scale(1.09); box-shadow: 0 14px 0 -4px rgba(0,0,0,.42), 0 0 34px -2px currentColor; }
  100% { transform: translateY(-3px) scale(1.05); box-shadow: 0 10px 0 -4px rgba(0,0,0,.42), 0 0 24px -4px currentColor; }
}

/* recusa: o botão treme e devolve o toque sem aceitar (janela de 20 s) */
.cartao.recusado { animation: recusar .42s ease; border-color: var(--raiva); }
@keyframes recusar {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-7px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(3px); }
}

/* ---------- onda de cor que leva ao mapa ---------- */
.onda {
  position: fixed; z-index: 60; pointer-events: none;
  width: 20px; height: 20px; margin: -10px 0 0 -10px;
  border-radius: 50%; transform: scale(0); opacity: .92;
  transition: transform .58s cubic-bezier(.4,0,.2,1), opacity .3s ease .38s;
}
.onda.abrindo { transform: scale(var(--fator, 100)); opacity: 0; }

/* ---------- partículas ---------- */
.particulas {
  position: fixed; inset: 0; z-index: 55;
  pointer-events: none; width: 100%; height: 100%;
}

/* ---------- rodapé ---------- */
.rodape-emocao {
  position: relative; z-index: 1;
  padding: 0 24px max(18px, env(safe-area-inset-bottom));
  text-align: center;
}
.selo {
  display: inline-flex; align-items: center; gap: 8px; max-width: 100%;
  margin: 0 auto 10px; padding: 8px 15px;
  background: var(--fundo-2); border: 1px solid var(--linha); border-radius: 999px;
  font-size: 0.76rem; color: var(--texto-2);
  transition: border-color .3s ease, color .3s ease;
}
.selo .pino {
  flex: none; width: 8px; height: 8px; border-radius: 50%;
  background: var(--texto-2);
  animation: procurando 1.4s ease-in-out infinite;
}
.selo.pronto { border-color: rgba(79, 188, 207, .45); color: var(--texto); }
.selo.pronto .pino { background: var(--surpresa); animation: none; box-shadow: 0 0 8px var(--surpresa); }
.selo-texto { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@keyframes procurando {
  0%, 100% { opacity: .3; transform: scale(.8); }
  50%      { opacity: 1;  transform: scale(1.15); }
}

.nota { color: var(--texto-2); font-size: 0.78rem; line-height: 1.45; margin: 6px 0; }
.fantasma {
  margin-top: 4px; padding: 12px 22px;
  background: none; border: 1px solid var(--linha); border-radius: 999px;
  color: var(--texto-2); font: inherit; font-size: 0.84rem; cursor: pointer;
  transition: transform .1s ease, border-color .2s ease, color .2s ease;
}
.fantasma:active { transform: translateY(2px) scale(.98); color: var(--texto); border-color: var(--texto-2); }

/* O lema do projeto, no rodapé da primeira tela. Some em telas baixas: as dez
   opções têm de caber sem rolagem, e essa regra vem antes desta frase — que
   continua inteira na folha "sobre". */
.lema {
  max-width: 30ch; margin: 12px auto 0;
  font-size: 0.7rem; line-height: 1.5; color: var(--texto-2); opacity: 0.62;
  text-wrap: balance;
}

/* botão principal, com a mesma espessura dos cartões */
.botao {
  width: 100%; padding: 14px 20px;
  background: linear-gradient(180deg, var(--fundo-3), var(--fundo-2));
  border: 1px solid var(--linha); border-radius: 14px;
  color: var(--texto); font: inherit; font-size: 0.95rem; font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 0 rgba(0, 0, 0, .5);
  transition: transform .09s ease, box-shadow .09s ease;
}
.botao:active { transform: translateY(4px); box-shadow: 0 0 0 rgba(0, 0, 0, .5); }

/* ---------- escolha manual de região ---------- */
.cortina {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: rgba(6, 9, 14, .72);
  animation: surgir .22s ease;
}
.dialogo {
  width: 100%; max-width: 340px;
  background: var(--fundo-2); border: 1px solid var(--linha); border-radius: 20px;
  padding: 22px 20px; text-align: center;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
  animation: subir .28s cubic-bezier(.2,.85,.25,1);
}
.dialogo h2 { margin: 0 0 8px; font-size: 1.15rem; font-weight: 700; }
.dialogo .nota { margin: 0 0 16px; }
.seletor {
  width: 100%; padding: 12px; margin-bottom: 10px;
  background: var(--fundo); color: var(--texto);
  border: 1px solid var(--linha); border-radius: 12px;
  font: inherit; font-size: 0.9rem;
}
@keyframes surgir { from { opacity: 0; } to { opacity: 1; } }
@keyframes subir {
  from { opacity: 0; transform: translateY(18px) scale(.95); }
  to   { opacity: 1; transform: none; }
}

/* ---------- folha "sobre + apoio" ----------
   O aplicativo é gratuito e sem anúncios; o pedido de apoio vive aqui dentro,
   longe do caminho de responder, e nunca interrompe ninguém. */
/* A folha é mais alta do que a de escolher região: numa tela baixa ela tem de
   rolar por dentro, senão o botão "Fechar" fica fora do ecrã. */
.dialogo.sobre {
  max-width: 380px; text-align: left;
  max-height: calc(100vh - 48px); overflow-y: auto;
}
.dialogo.sobre h2 { text-align: center; margin-bottom: 2px; }
.sobre-subtitulo {
  margin: 0 0 10px; text-align: center; font-size: 0.78rem; color: var(--texto-2);
  letter-spacing: .06em; text-transform: uppercase;
}
.sobre-lema {
  margin: 0 0 14px; padding: 12px 14px;
  background: var(--fundo); border: 1px solid var(--linha); border-radius: 14px;
  font-size: 0.84rem; line-height: 1.55; color: var(--texto); text-align: center;
  text-wrap: balance;
}
.sobre h3 {
  margin: 16px 0 8px; font-size: 0.68rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.14em; color: var(--texto-2);
}
.sobre ul { margin: 0; padding-left: 18px; }
.sobre li { font-size: 0.8rem; line-height: 1.55; color: var(--texto-2); margin-bottom: 5px; }
.apoio { display: flex; flex-direction: column; gap: 8px; }
.apoio .botao { font-size: 0.9rem; padding: 12px 16px; }
.apoio .botao[disabled] { opacity: .45; cursor: default; box-shadow: none; }
.apoio .botao[disabled]:active { transform: none; }
.chave-pix {
  margin: 0; padding: 10px 12px;
  background: var(--fundo); border: 1px dashed var(--linha); border-radius: 10px;
  font-size: 0.78rem; color: var(--texto); word-break: break-all; text-align: center;
}

/* ================= Tela 2 — linguagem de game =================
   O mapa é o tabuleiro, o mostrador é o placar. As mesmas regras da Tela 1:
   alvos grandes, resposta imediata, e nada que esconda a incerteza. */

.barra-topo {
  display: flex; align-items: center; gap: 10px;
  padding: max(10px, env(safe-area-inset-top)) 12px 10px;
  border-bottom: 1px solid var(--linha);
  background: var(--fundo-2);
}
.icone-btn {
  /* 48 px: o mesmo que .escopos (40 do botão + 2×4 de recheio), para os dois
     lados da barra assentarem na mesma linha */
  width: 48px; height: 48px; flex: none;
  border-radius: 14px; border: 1px solid var(--linha);
  background: linear-gradient(180deg, var(--fundo-3), var(--fundo-2));
  color: var(--texto); font-size: 1.15rem; line-height: 1; cursor: pointer;
  box-shadow: 0 3px 0 rgba(0, 0, 0, .45);
  transition: transform .09s ease, box-shadow .09s ease, color .2s ease;
}
.icone-btn:active { transform: translateY(3px); box-shadow: 0 0 0 rgba(0, 0, 0, .45); }
.icone-btn:focus-visible { outline: 2px solid var(--surpresa); outline-offset: 2px; }
.icone-btn svg { display: block; width: 22px; height: 22px; margin: 0 auto; }

/* seletor de escala com um alvo que desliza por baixo do rótulo ativo */
.escopos {
  position: relative; flex: 1; display: flex; gap: 2px;
  background: var(--fundo); border: 1px solid var(--linha);
  border-radius: 14px; padding: 4px;
}
.escopo-alvo {
  position: absolute; top: 4px; bottom: 4px; left: 4px;
  border-radius: 11px; background: var(--fundo-3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), 0 2px 8px rgba(0, 0, 0, .35);
  transition: transform .3s cubic-bezier(.3,.85,.3,1), width .3s cubic-bezier(.3,.85,.3,1);
  pointer-events: none;
}
.escopo {
  position: relative; z-index: 1;
  flex: 1; border: none; background: none; color: var(--texto-2);
  font: inherit; font-size: 0.82rem; font-weight: 600;
  min-height: 40px; padding: 4px; border-radius: 11px; cursor: pointer;
  transition: color .2s ease;
}
.escopo.ativo { color: var(--texto); }
.escopo:focus-visible { outline: 2px solid var(--surpresa); outline-offset: -2px; }
/* Escala que a região não comporta. Fica visível de propósito: o botão
   desaparecer mudava a largura da barra conforme o país, e uma barra que muda
   de tamanho parece defeito. Desbotado diz "existe, mas não aqui".
   .55 e não .38: a .38 o rótulo dava 2,05:1 contra o fundo da barra e deixava
   de se ler — desativado tem de continuar legível, senão parece falha de
   desenho em vez de escolha. Medido, .55 dá 3,0:1, contra os ~7:1 dos irmãos
   ativos: lê-se, e nunca se confunde com um botão que responde. */
.escopo:disabled { opacity: .55; cursor: default; }

/* ---------- palco: mapa + painel ---------- */
.palco { flex: 1; display: flex; flex-direction: column; min-height: 0; }

.mapa-wrap {
  position: relative; flex: none;
  height: clamp(200px, 36vh, 380px);
  background: var(--oceano); touch-action: none;
  overflow: hidden;
}
#mapa { display: block; width: 100%; height: 100%; }
.mapa-vazio {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--texto-2); font-size: 0.85rem; pointer-events: none; text-align: center; padding: 24px;
}
.legenda {
  position: absolute; left: 10px; bottom: 10px; display: flex; flex-wrap: wrap; gap: 6px 10px;
  max-width: calc(100% - 70px); pointer-events: none;
}
.legenda i {
  display: inline-flex; align-items: center; gap: 5px;
  font-style: normal; font-size: 0.68rem; font-weight: 600; color: var(--texto-2);
  text-shadow: 0 1px 3px rgba(0, 0, 0, .8);
}
.legenda i::before {
  content: ""; width: 9px; height: 9px; border-radius: 3px; background: currentColor;
  box-shadow: 0 0 7px currentColor;
}
.icone-btn.reset { position: absolute; right: 10px; top: 10px; }

/* ---------- painel ---------- */
.painel {
  border-top: 1px solid var(--linha);
  background: var(--fundo-2);
  padding: 14px 16px max(14px, env(safe-area-inset-bottom));
  flex: 1; min-height: 0; overflow-y: auto;
}
.term-cabecalho { display: flex; align-items: center; gap: 10px; }
.term-titulo { font-size: 1.05rem; font-weight: 700; letter-spacing: -0.01em; }
.term-n { margin-right: auto; font-size: 0.72rem; color: var(--texto-2); font-variant-numeric: tabular-nums; }
.equil {
  display: flex; align-items: center; gap: 6px; flex: none;
  font-size: 0.74rem; color: var(--texto-2); cursor: pointer;
}
.equil input { accent-color: var(--surpresa); width: 16px; height: 16px; }

/* ---------- mostrador: arco, agulha e faixa de incerteza ---------- */
.mostrador { position: relative; width: 100%; max-width: 300px; margin: 6px auto 2px; }
#gauge { display: block; width: 100%; height: auto; overflow: visible; }

.gauge-trilho { fill: none; stroke: var(--fundo); stroke-width: 13; stroke-linecap: round; }
.gauge-escala { fill: none; stroke: url(#grad-eixo); stroke-width: 9; stroke-linecap: round; opacity: .9; }
.gauge-tique { stroke: var(--texto-2); stroke-width: 1.4; opacity: .45; stroke-linecap: round; }
.gauge-tique.zero { stroke: var(--texto); opacity: .75; stroke-width: 2; }

/* a faixa mostra quanto UM registro a mais moveria a agulha */
.gauge-faixa {
  fill: none; stroke: var(--texto); stroke-width: 11; stroke-linecap: butt;
  opacity: .2; transition: opacity .4s ease;
}

.gauge-agulha {
  /* view-box: sem isto o transform-origin resolve contra a caixa da própria
     agulha, e ela gira em torno de si mesma em vez do centro do mostrador */
  transform-box: view-box;
  transform-origin: 100px 100px;
  transition: transform .65s cubic-bezier(.34,1.25,.5,1);
}
.gauge-agulha line { stroke: var(--texto); stroke-width: 3.4; stroke-linecap: round; }
.gauge-agulha circle { fill: var(--texto); }
.gauge-eixo { fill: var(--fundo-3); stroke: var(--linha); stroke-width: 1.5; }

.mostrador-centro {
  position: absolute; left: 0; right: 0; bottom: 2%;
  display: flex; flex-direction: column; align-items: center; pointer-events: none;
}
.mostrador-valor {
  font-size: clamp(1.6rem, 8vw, 2.1rem); font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -0.03em;
  line-height: 1; color: var(--texto);
}
.mostrador-eixo {
  display: flex; justify-content: space-between; width: 100%;
  margin-top: 4px; font-size: 0.66rem; color: var(--texto-2);
}
.mostrador-eixo i { font-style: normal; }
/* Os polos nomeiam o que a emoção EXIGE, não se ela é boa ou má: à esquerda
   as que mandam fazer alguma coisa, à direita as que não mandam nada. O
   rótulo antigo ("angústia") era de valência e contradizia o próprio eixo. */

/* Entrada do painel quando uma região é tocada: mesma linguagem de game do
   resto — curta, com um exagero pequeno no início, e nada de espera. Casa com
   os 280 ms do carimbo em mapa.js; mexer num sem mexer no outro desirmana os
   dois lados do mesmo gesto. */
.termometro.assentando { animation: assentar .28s cubic-bezier(.2,.9,.3,1); }
@keyframes assentar {
  from { transform: scale(.975) translateY(7px); opacity: .5; }
  to   { transform: none; opacity: 1; }
}

/* A leitura em palavras do que a agulha mostra. Vazia quando não há frase a
   fazer — e vazia tem de ser invisível, senão sobra um buraco de uma linha
   por cima da composição. */
.leitura {
  margin: 10px 0 0; text-align: center;
  font-size: 0.86rem; line-height: 1.4; color: var(--texto);
  text-wrap: balance;
}
.leitura:empty { display: none; }

/* ---------- composição ---------- */
.composicao {
  display: flex; gap: 3px; height: 30px; margin: 14px 0 4px;
}
.composicao div {
  min-width: 0; border-radius: 6px;
  transition: flex-grow .55s cubic-bezier(.3,.9,.3,1);
}
.composicao span {
  display: block; font-size: 0.62rem; text-align: center; line-height: 30px;
  color: #0d1117; font-weight: 800; overflow: hidden; white-space: nowrap;
}
.composicao-vazia { background: var(--fundo); border-radius: 8px; }

/* ---------- ranking ---------- */
.ranking { list-style: none; margin: 12px 0 0; padding: 0; }
.ranking li { margin-bottom: 6px; }
.linha-ranking {
  width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 11px 10px; border: 1px solid transparent; border-radius: 12px;
  background: var(--fundo); color: var(--texto);
  font: inherit; font-size: 0.82rem; text-align: left; cursor: pointer;
  transition: transform .09s ease, border-color .2s ease, background .2s ease;
}
.linha-ranking:active { transform: translateY(2px); }
.linha-ranking:focus-visible { outline: 2px solid var(--surpresa); outline-offset: 2px; }
.ranking li.foco .linha-ranking { border-color: var(--surpresa); background: var(--fundo-3); }
.ranking .posicao {
  flex: none; width: 22px; height: 22px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  background: var(--fundo-3); color: var(--texto-2);
  font-size: 0.68rem; font-weight: 800; font-variant-numeric: tabular-nums;
}
.ranking li:nth-child(1) .posicao { background: var(--alegria); color: #0d1117; }
.ranking li:nth-child(2) .posicao { background: #9fb0c4; color: #0d1117; }
.ranking li:nth-child(3) .posicao { background: #b08155; color: #0d1117; }
.ranking .nome { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.ranking .mini {
  display: flex; gap: 2px; width: 88px; flex: none; height: 8px;
}
.ranking .mini div { min-width: 0; border-radius: 3px; transition: flex-grow .5s ease; }
.ranking .qtd { width: 36px; flex: none; text-align: right; color: var(--texto-2); font-variant-numeric: tabular-nums; }

.aviso {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  background: var(--fundo-3); border: 1px solid var(--linha); color: var(--texto);
  padding: 10px 16px; border-radius: 12px; font-size: 0.82rem;
  /* acima da cortina (70): a confirmação de "chave copiada" nasce com a folha
     "sobre" aberta e ficaria escondida por baixo dela */
  z-index: 80;
  max-width: 90vw; text-align: center;
}

/* Telas baixas: o botão continua grande, mas cabe.

   O corte era 700 px e estava errado — a .tela tem `overflow: hidden`, então
   o que não cabe não rola, some. Num 375x812 (iPhone X e companhia, altura
   muito comum) o rodapé passava do fim e o botão "Ver o mapa sem responder"
   ficava cortado, com o layout largo ainda em vigor. 880 apanha a família
   inteira de telemóveis em pé; acima disso há folga de sobra. */
@media (max-height: 880px) {
  .cartao { min-height: 58px; padding: 7px 6px; gap: 4px; border-radius: 15px; }
  .cartao svg { width: 36px; height: 36px; }
  .cartao span { font-size: 0.74rem; }
  .grade-emocoes { gap: 8px; padding: 8px 14px; grid-template-rows: repeat(5, minmax(58px, 1fr)); }
  .olho { margin: 0 0 6px; font-size: 0.6rem; }
  .cabecalho h1 { font-size: clamp(1.15rem, 5.4vw, 1.5rem); margin-bottom: 4px; }
  .sub { font-size: 0.8rem; }
  .cabecalho { padding-top: max(14px, env(safe-area-inset-top)); }
  /* o rodapé cede espaço aos botões, sem perder a frase sobre a coordenada */
  .selo { margin-bottom: 6px; padding: 6px 12px; }
  .rodape-emocao .nota { font-size: 0.72rem; margin: 4px 0; }
  .fantasma { margin-top: 0; padding: 10px 18px; }
}

/* Só nas telas mesmo baixas o lema cede o lugar: as dez opções cabem sem
   rolagem antes de qualquer frase, e a frase continua inteira na folha
   "sobre" e na tela do mapa. */
@media (max-height: 720px) {
  .lema { display: none; }
}

/* ---------------------------------------------------------------------------
   TELAS BAIXAS: o telemóvel deitado, e o iPhone pequeno em pé.
   ---------------------------------------------------------------------------
   A mesma régua de sempre — as dez opções têm de caber sem rolagem —, mas aqui
   o custo de falhar é maior do que viés: `.tela` tem `overflow: hidden`, então
   o que não cabe não rola, some. A opção deixa de ser menos escolhida e passa
   a ser IMPOSSÍVEL de escolher, e o instrumento perde uma emoção sem dizer.

   Medido no navegador, com o centro do último cartão testado por
   `elementFromPoint` para confirmar que estava mesmo fora de alcance:

     667×375  iPhone 8/SE2/SE3 deitado ....... última linha 126 px para lá do fim
     320×454  iPhone SE 1.ª ger. no Safari .... última linha  58 px para lá do fim

   O corte de 700 px de largura já resolvia o deitado dos telemóveis grandes
   (844×390 cabia, com 55 px de sobra) e deixava de fora justamente os de 667 e
   568 de largura. Por isso a decisão aqui é pela ALTURA, que é o que falta; a
   largura entra só para escolher a forma da grade. */
@media (max-height: 560px) and (min-width: 500px) {
  /* Havendo largura para cinco colunas, duas linhas resolvem sozinhas. */
  .grade-emocoes {
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: repeat(2, minmax(56px, 1fr));
    max-width: 900px; max-height: 260px;
    gap: 8px; padding: 6px 14px;
  }
  .cartao { min-height: 56px; padding: 6px 4px; gap: 3px; }
  .cartao svg { width: 32px; height: 32px; }
}

/* Sem largura para cinco colunas — o SE de 2016 em pé —, a grade continua 2×5
   e quem cede é o tamanho do cartão. 48 px ainda passa o mínimo de 44 pt que o
   iOS pede para alvo de toque, e cinco linhas mais baixas devolvem com folga
   os ~58 px que faltavam.

   O corte aqui é 520 e não 560 como no de cima, e a diferença foi medida: a
   grade em 2 colunas precisa de 512 px de altura, e a 553 (que é o SE2/SE3 e o
   iPhone 8 no Safari) ainda sobravam 56 px. Apertar a 560 encolhia a fonte e os
   espaços num aparelho que não precisava — este bloco só deve pegar onde o
   conteúdo não cabe mesmo. */
@media (max-height: 520px) and (max-width: 499px) {
  .grade-emocoes {
    grid-template-rows: repeat(5, minmax(48px, 1fr));
    gap: 6px; padding: 6px 12px;
  }
  .cartao { min-height: 48px; padding: 4px; gap: 2px; border-radius: 12px; }
  .cartao svg { width: 28px; height: 28px; }
  .cartao span { font-size: 0.68rem; }
  .cabecalho h1 { font-size: 1.05rem; margin-bottom: 2px; }
  .sub { font-size: 0.72rem; }
  .selo { margin-bottom: 4px; padding: 4px 10px; }
  .rodape-emocao .nota { font-size: 0.66rem; margin: 2px 0; }
}

@media (min-width: 700px) {
  /* cinco colunas × duas linhas = as dez exatas, sem célula fantasma a comer
     1fr da altura */
  .grade-emocoes {
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: repeat(2, minmax(104px, 1fr));
    max-width: 900px; max-height: 360px;
    gap: 14px;
  }
  .cartao { min-height: 104px; padding: 14px 8px 12px; gap: 9px; border-radius: 20px; }
  .cartao svg { width: 52px; height: 52px; }
  .cartao span { font-size: 0.86rem; }

  /* O palco é limitado em largura por causa da geometria do mapa: a escala
     mínima é largura/360 (senão o mundo aparece duplicado), então um mapa
     muito largo fica com escala alta e corta latitude. Uma coluna centrada
     de 880 px mostra o mundo inteiro em vez de uma faixa equatorial. */
  .palco { max-width: 880px; width: 100%; margin: 0 auto; }
  .mapa-wrap {
    height: clamp(300px, 46vh, 460px);
    border-left: 1px solid var(--linha); border-right: 1px solid var(--linha);
  }
  .painel {
    padding: 18px 24px;
    border-left: 1px solid var(--linha); border-right: 1px solid var(--linha);
  }
  .barra-topo { max-width: 880px; width: 100%; margin: 0 auto; border-bottom: none; }
  .mostrador { max-width: 340px; }
}

/* Movimento reduzido: a mesma informação, sem o espetáculo.
   As partículas e a onda de cor já se desligam sozinhas em efeitos.js. */
@media (prefers-reduced-motion: reduce) {
  .aura b { animation: none; }
  .cartao { animation: none; }
  .cartao svg { animation: none; }
  .cartao.escolhido { animation: none; transform: scale(1.05); border-color: currentColor; }
  .cartao.recusado { animation: none; }
  .selo .pino { animation: none; opacity: .8; }
  .cortina, .dialogo { animation: none; }
  .composicao div, .ranking .mini div { transition: none; }
  .gauge-agulha { transition: none; }
  .termometro.assentando { animation: none; }
  .escopo-alvo { transition: none; }
}

/* ================= Botão do Modo Constelação =================
   Vive dentro do painel, logo abaixo da barra de composição. Tem a mesma
   espessura dos outros botões do projeto (a "saia" escura que some ao premir),
   porque a linguagem de game não abre exceção para a funcionalidade nova. */
.botao-const {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; margin: 12px 0 4px;
  min-height: 52px; padding: 12px 16px;
  background: linear-gradient(180deg, var(--fundo-3), var(--fundo-2));
  border: 1px solid var(--linha); border-radius: 16px;
  color: var(--texto); font: inherit; font-weight: 600; font-size: 0.92rem;
  cursor: pointer;
  box-shadow: 0 5px 0 rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .05);
  transition: transform .09s cubic-bezier(.2,.7,.3,1), box-shadow .09s ease, border-color .2s ease;
  position: relative; overflow: hidden;
}
/* a cor dominante da região em foco atravessa o botão devagar: é a promessa do
   que está do outro lado, e é atualizada por JS na variável --cor-no */
.botao-const::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 160% at 15% 0%, var(--cor-no, var(--surpresa)), transparent 62%);
  opacity: 0.20; pointer-events: none;
  transition: opacity .3s ease, background .6s ease;
}
.botao-const:active { transform: translateY(5px); box-shadow: 0 0 0 rgba(0, 0, 0, .5); }
.botao-const:active::before { opacity: 0.34; }
.botao-const:focus-visible { outline: 2px solid var(--cor-no, var(--surpresa)); outline-offset: 2px; }
.botao-const svg { width: 22px; height: 22px; flex: none; color: var(--cor-no, var(--surpresa)); }
.botao-const span { position: relative; }

/* ================= A folha do Modo Constelação =================
   Cobre tudo. O fundo é o único lugar do projeto que não usa `--fundo`: é um
   degradê profundo de violeta para carvão, e existe para as estrelas terem
   contraste máximo. Um cinzento-azulado plano fazia os pontos de cor parecerem
   pintados na tela em vez de acesos por trás dela. */
body.const-ativa { overflow: hidden; }

.constelacao:focus { outline: none; }   /* recebe foco por código, não é um alvo visível */
.constelacao {
  position: fixed; inset: 0; z-index: 90;
  background:
    radial-gradient(120% 80% at 22% 8%, #1b1533 0%, transparent 60%),
    radial-gradient(110% 70% at 82% 92%, #101b33 0%, transparent 58%),
    linear-gradient(168deg, #0b0d1a 0%, #070910 55%, #0a0714 100%);
  animation: surgir .28s ease;
}

/* `touch-action: none` porque a pinça e o arrasto são nossos: sem isto o
   navegador leva os gestos para o zoom da página e a câmera nunca se mexe. */
.const-canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  touch-action: none; cursor: grab;
}
.const-canvas:active { cursor: grabbing; }

.const-barra {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: 12px;
  padding: max(12px, env(safe-area-inset-top)) 14px 20px;
  background: linear-gradient(180deg, rgba(7, 9, 16, .85), transparent);
  pointer-events: none;
}
.const-barra .icone-btn { pointer-events: auto; background: rgba(29, 37, 49, .72); }
.const-titulo {
  flex: 1; min-width: 0; font-weight: 700; font-size: 1.02rem;
  letter-spacing: .01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .8);
}

/* A escala em vigor. Fica logo abaixo do título, e é o que diz que a pinça
   mudou de continente para país sem o utilizador ter de adivinhar. */
.const-escala {
  position: absolute; top: max(52px, calc(env(safe-area-inset-top) + 40px)); left: 16px;
  margin: 0; padding: 4px 11px;
  font-size: 0.72rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--texto-2);
  background: rgba(13, 17, 23, .55); border: 1px solid rgba(148, 163, 184, .18);
  border-radius: 999px;
  pointer-events: none;
}

.const-dica {
  position: absolute; left: 0; right: 0; bottom: max(14px, env(safe-area-inset-bottom));
  margin: 0; padding: 0 24px; text-align: center;
  font-size: 0.76rem; line-height: 1.5; color: var(--texto-2);
  text-shadow: 0 1px 8px rgba(0, 0, 0, .8);
  pointer-events: none;
  transition: opacity .3s ease;
}
/* com o painel aberto a dica sai da frente, senão ficaria por baixo dele */
.constelacao.com-painel .const-dica { opacity: 0; }

/* ---------- painel de detalhe ----------
   Sobe de baixo ao tocar numa estrela. `translateY(101%)` e não 100%: a um
   pixel de folga a borda superior do painel não fica a assomar no fundo do
   ecrã em telas com arredondamento fracionário. */
.const-painel {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 16px 18px calc(16px + env(safe-area-inset-bottom));
  background: linear-gradient(180deg, rgba(17, 22, 34, .93), rgba(9, 12, 20, .97));
  border-top: 1px solid rgba(148, 163, 184, .18);
  box-shadow: 0 -14px 40px rgba(0, 0, 0, .55), 0 -1px 0 var(--cor-no, var(--surpresa));
  border-radius: 20px 20px 0 0;
  transform: translateY(101%);
  transition: transform .34s cubic-bezier(.2,.9,.25,1);
}
.const-painel.aberto { transform: translateY(0); }

.const-painel-topo {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px;
}
.const-nome {
  font-size: 1.06rem; font-weight: 700; letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.const-qtd {
  margin-left: auto; flex: none;
  font-size: 0.74rem; color: var(--texto-2); font-variant-numeric: tabular-nums;
}

.const-topo3 {
  list-style: none; margin: 10px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 8px 14px;
}
.const-topo3 li {
  display: flex; align-items: center; gap: 6px;
  font-size: 0.78rem; color: var(--texto-2);
}
.const-topo3 i { width: 9px; height: 9px; border-radius: 50%; flex: none; }

.const-nota {
  margin: 10px 0 0; font-size: 0.76rem; line-height: 1.5; color: var(--texto-2);
}

@media (min-width: 700px) {
  .const-painel { max-width: 560px; margin: 0 auto; border-radius: 20px 20px 0 0; }
  .const-dica { font-size: 0.8rem; }
}

/* Movimento reduzido: a mesma informação, sem o espetáculo. A deriva
   browniana e a pulsação já se desligam sozinhas em constelacao.js (o tempo
   congela em zero); aqui ficam as transições de CSS. */
@media (prefers-reduced-motion: reduce) {
  .constelacao { animation: none; }
  .const-painel { transition: none; }
  .botao-const::before { transition: none; }
}
