/* O PADRÃO DO SISTEMA É NEUTRO, e desde 2026-08-23 ele não é mais a paleta da
   ParáBrasil. Fonte da verdade: `PALETA_NEUTRA`, em src/lib/paleta.ts, e
   `tests/estilos.test.ts` cobra que estes oito valores não divirjam dela.

   POR QUE ISTO É CINZA. Este arquivo é servido para o cliente de QUALQUER
   empresa. Enquanto o roxo da ParáBrasil morava aqui, uma rede recém-vendida que
   ainda não tivesse escolhido cores abria o QR dela e mostrava, ao cliente dela,
   a marca de outro cliente. Não era um detalhe de tema: era o produto entregando
   a identidade de um pagante para outro.

   A marca da ParáBrasil não sumiu — ela virou DADO da empresa 1
   (`scripts/carregar-marca.mjs`), e é `vestir()` em public/pesquisa.js que a
   aplica por cima destes tokens, com a marca da empresa daquela loja. Quem não
   tem marca cadastrada fica com o cinza, que é de ninguém.

   OS NOMES DOS TOKENS CONTINUAM OS DA PALETA ANTIGA, e é feio: `--cor-roxo` é
   um cinza. Eles ficaram porque são o CONTRATO com a coluna `empresa.cores` (os
   oito de `TOKENS` em src/lib/paleta.ts) e com a tela de marca; renomeá-los
   exigiria reescrever o JSON já gravado na linha de cada cliente. O que a tela
   de marca mostra ao dono não é o nome — é ONDE cada cor aparece.

   O amarelo NUNCA é cor de texto em fundo claro: o da ParáBrasil dá 1,97:1 sobre
   branco, e a regra vale para o token, seja qual for o tom que o cliente puser
   nele. */
:root {
  --cor-roxo-escuro: #2E2E2E;
  --cor-roxo-medio: #444444;
  --cor-roxo: #4A4A4A;
  --cor-verde: #575757;
  --cor-ocre: #8A8A8A;
  --cor-amarelo: #D6D6D6;
  --cor-creme: #F2F2F2;
  --cor-branco: #FFFFFF;

  --espaco: 1rem;
  --raio: 14px;

  /* O TEMPO DE UM AVANÇO DE TELA — um número só, para a barra e para o conteúdo.
     Quem explica a escolha é o bloco de `@keyframes tela-entra`, lá embaixo.
     Está aqui em cima porque `.progresso__barra` e `#tela > *` precisam do MESMO
     valor: duas durações diferentes para o mesmo acontecimento fazem a barra e a
     pergunta parecerem dois eventos, e não um. */
  --avanco-duracao: 240ms;
  --avanco-curva: ease;
}

@font-face {
  font-family: "Nunito";
  src: url("/fontes/nunito-400.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Nunito";
  src: url("/fontes/nunito-700.woff2") format("woff2");
  font-weight: 700;
  font-display: swap;
}
@font-face {
  font-family: "Bebas Neue";
  src: url("/fontes/bebas-neue.woff2") format("woff2");
  font-weight: 400;
  font-display: swap;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--cor-creme);
  color: var(--cor-roxo-escuro);
  font-family: "Nunito", system-ui, sans-serif;
  font-size: 1.0625rem;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
}

.moldura {
  max-width: 30rem;
  margin: 0 auto;
  padding: var(--espaco);
  /* svh não é suportado em toda WebView antiga; valor não suportado é descartado,
     não substituído — por isso o vh entra primeiro como piso e o svh o refina depois. */
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* `hidden` do HTML é só `display: none` da folha do NAVEGADOR, e qualquer
   seletor de classe ganha dele. `vestir()` esconde a <img> do logo quando a
   empresa não tem logo — e sem esta linha o `.cabecalho img { display: block }`
   logo abaixo desfazia isso em silêncio: a moldura vazia de 175x70 continuava
   desenhada no alto da pesquisa, parecendo imagem que não carregou. MEDIDO no
   navegador, com `img.hidden === true` e `display: block` ao mesmo tempo. */
[hidden] { display: none !important; }

.cabecalho { padding: 0.5rem 0 1rem; }
/* O logo entra como <img>, não como <svg> embutido. Um seletor só para `svg`
   não casa e o logo fica encostado à esquerda em tamanho de atributo. */
.cabecalho img,
.cabecalho svg { width: 11rem; height: auto; display: block; margin: 0 auto; }

.progresso {
  height: 8px;
  border-radius: 999px;
  background: var(--cor-roxo-escuro);
  overflow: hidden;
}
.progresso__barra {
  height: 100%;
  width: 0;
  background: var(--cor-amarelo);
  /* Os 240ms desta linha são anteriores à transição de tela e foram o PONTO DE
     PARTIDA dela: a barra já deslizava sozinha enquanto a pergunta trocava seca,
     e era a única coisa em movimento na página. O valor virou token para o
     conteúdo poder andar junto. Ver `@keyframes tela-entra`. */
  transition: width var(--avanco-duracao) var(--avanco-curva);
}

/* O RECIPIENTE DA AÇÃO DO DONO, e ele mora no cabeçalho por um motivo que não é
   de layout: `#tela` é `aria-live` e é arrancado por `replaceChildren` a cada
   pergunta, então um botão ali seria reanunciado ao leitor de tela em toda tela.
   Aqui ele é montado uma vez e a cada tela só o `hidden` troca, e quem o esconde
   é o `[hidden] { display: none !important }` lá em cima.

   PRECISÃO SOBRE O `!important`, porque a primeira versão desta frase estava
   errada e neste arquivo isso custa caro: quem ganhou `display` próprio foi o
   `<a>` FILHO (`.botao--dono`, com `display: flex`), não este recipiente — ele
   não declara `display` nenhum. Esconder o pai basta de qualquer jeito. O
   `!important` continua sendo o que segura a regra, mas pelo motivo geral do
   arquivo (o `hidden` do HTML é só a folha do navegador e perde de qualquer
   seletor de classe), e não por causa de um `display` que este seletor não tem. */
.cabecalho__acao { margin-top: 0.75rem; }

h1 {
  font-family: "Bebas Neue", "Nunito", sans-serif;
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: 0.02em;
  margin: 1.5rem 0 0.25rem;
}

.subtitulo { margin: 0 0 1.5rem; opacity: 0.85; }

/* O `minmax(0, 1fr)` NÃO É `1fr` COM ENFEITE — E O QUE ELE EVITA NÃO É O QUE EU
   ESCREVI AQUI PRIMEIRO. A primeira versão deste comentário dizia que ele
   segurava a rolagem horizontal; a mutação provou que não, e o que ele segura é
   outra coisa, pior de perceber.

   Item de grade tem TAMANHO MÍNIMO AUTOMÁTICO: por padrão a trilha não encolhe
   abaixo do `min-content` do que está dentro dela. Enquanto o botão só tinha um
   emoji (~33px), isso nunca pegou. Uma palavra é indivisível — não há onde
   quebrar "Normal" —, então o `min-content` de cada botão passa a ser a largura
   da palavra DELE, e as cinco palavras têm larguras diferentes.

   O que acontece com `repeat(5, 1fr)`, MEDIDO a 320px trocando "Amei" por
   "Sensacional": as colunas param de ser iguais. Elas saem em 43,6 / 43,6 / 49 /
   43,6 / 76,1 px — a coluna da palavra comprida rouba a largura das outras
   quatro, e o `1fr` distribui o que sobra. A página NÃO rola (a soma dos
   mínimos ainda cabe nos 288px), e é justamente por isso que o defeito é ruim:
   ele passa por todos os testes de rolagem e entrega uma régua de cinco degraus
   com degraus de tamanhos diferentes — cinco alvos de dedo desiguais, o maior
   sendo o da palavra mais comprida, que é enviesar a escala pelo tamanho da
   palavra.

   Com `minmax(0, 1fr)` o piso da trilha vira zero e as cinco colunas ficam
   presas em um quinto da largura, aconteça o que acontecer com o texto. Uma
   palavra que não caiba transborda o botão dela e é vista na hora — em vez de
   deformar a fila inteira em silêncio.

   COM AS CINCO PALAVRAS DE HOJE ESTA LINHA NÃO MUDA NADA, e isso está medido:
   a maior delas ("Normal", 45,0px) cabe nos 47,2px da coluna, então `1fr` e
   `minmax(0, 1fr)` dão exatamente o mesmo desenho. Ela é corrimão para a
   próxima pessoa que mexer nas palavras ou na fonte, e quem a segura no lugar é
   `tests/estilos.test.ts` — porque nenhum teste de navegador consegue derrubá-la
   sozinho enquanto as palavras couberem.

   E ELA NÃO É A GARANTIA DE QUE A PALAVRA CABE: essa é a escolha das palavras
   (ver `PALAVRAS_DA_ESCALA` em public/modelos.js, que traz as medições), cobrada
   palavra a palavra, no navegador, pelo teste que confere que nenhuma transborda
   o próprio botão. */
.carinhas {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.5rem;
}
.carinha {
  min-height: 72px;
  /* Coluna, e não a caixa de texto padrão do botão: o glifo em cima, a palavra
     embaixo, os dois centrados e os dois DENTRO do alvo do dedo. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  padding: 0.5rem 0;
  /* Sem calha lateral de propósito: a 320px sobram 47,2px de texto por coluna, e
     cada pixel de `padding` sairia da palavra. Quem afasta uma carinha da outra
     é o `gap` da grade.

     E NÃO HÁ `min-width: 0` NEM `overflow: hidden` AQUI. Os dois estiveram nesta
     regra e foram tirados por medição, não por gosto: os dois zeram o mesmo
     tamanho mínimo automático que o `minmax(0, 1fr)` da grade já zera, e trocar
     um pelo outro dá o MESMO desenho, com as mesmas cinco colunas iguais e o
     mesmo transbordo de 13px quando se põe "Sensacional" no lugar de "Amei".
     Eram as linhas mortas que esta folha já chama pelo nome duas vezes, no bloco
     do Instagram — alguém acreditaria que protegiam alguma coisa.

     O `overflow: hidden` tinha um efeito próprio, e é por ele que ele saiu: uma
     palavra grande demais sairia RECORTADA ("Sensacio…") em vez de transbordar à
     vista. Palavra que não cabe é defeito que não pode chegar à parede da loja;
     entre esconder e mostrar, esta obra mostra. O teste pega os dois casos
     (`scrollWidth` do botão acusa transbordo com `overflow` visível também —
     medido), então a escolha é sobre o que a pessoa VÊ se o teste falhar. */
  border: 2px solid var(--cor-roxo);
  border-radius: var(--raio);
  background: var(--cor-branco);
  color: var(--cor-roxo-escuro);
  /* `<button>` NÃO herda fonte do documento — a folha do navegador crava a do
     sistema. Sem esta linha a palavra sairia na fonte do sistema, mais larga que
     a Nunito, e as medições que escolheram as cinco palavras seriam sobre uma
     fonte que não é a que aparece: "Péssimo" mede 50,1px em Nunito 700 a 13px e
     53,5px na fonte que o botão usava. O emoji não muda — ele vem da fonte de
     emoji do sistema em qualquer caso. */
  font-family: inherit;
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
  transition: transform 120ms ease, background 120ms ease;
}
/* A PALAVRA NÃO TEM COR PRÓPRIA, E A AUSÊNCIA É O DESENHO.
   Ela herda `--cor-roxo-escuro` do botão, sobre `--cor-branco` solto e sobre
   `--cor-amarelo` quando escolhida — e esses são exatamente dois dos cinco pares
   que `PARES_DE_TEXTO` (src/lib/paleta.ts) mede em TODA paleta que um cliente
   salva. Ou seja: a legibilidade da palavra sai de graça, para qualquer marca,
   sem par novo para conferir.

   A tentação é concreta e tem nome: legenda embaixo de ícone quase sempre nasce
   "discreta", com um cinza próprio ou um `opacity: 0.8` (é o que `.subtitulo` e
   `.rodape-legal` fazem, dois blocos abaixo). Qualquer um dos dois tira a
   palavra do par medido — um cinza escolhido aqui escapa da peneira do servidor,
   e `opacity` derruba o contraste real sem mudar cor nenhuma, silenciosamente. É
   justamente esta palavra que não pode ficar discreta: ela é a legenda da
   decisão. `tests/estilos.test.ts` cobra a ausência das duas propriedades.

   O tamanho é 0.8125rem, que é o MENOR que esta folha já usava (`.rodape-legal`)
   — não é um degrau novo inventado para fazer a palavra caber. As palavras é que
   foram escolhidas para caber nele. */
.carinha__palavra {
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1.15;
}
.carinha[aria-pressed="true"] {
  background: var(--cor-amarelo);
  border-color: var(--cor-roxo-escuro);
  transform: scale(1.06);
}

.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chip {
  min-height: 44px;
  padding: 0.5rem 1rem;
  border: 2px solid var(--cor-roxo);
  border-radius: 999px;
  background: var(--cor-branco);
  color: var(--cor-roxo-escuro);
  font: inherit;
  cursor: pointer;
}
.chip[aria-pressed="true"] {
  background: var(--cor-amarelo);
  border-color: var(--cor-roxo-escuro);
  font-weight: 700;
}

.nps { display: grid; grid-template-columns: repeat(6, 1fr); gap: 0.4rem; }
.nps .chip { padding: 0.5rem 0; text-align: center; }

.campo {
  width: 100%;
  min-height: 44px;
  padding: 0.75rem;
  border: 2px solid var(--cor-roxo);
  border-radius: var(--raio);
  background: var(--cor-branco);
  color: var(--cor-roxo-escuro);
  font: inherit;
}
textarea.campo { min-height: 120px; resize: vertical; }

.consentimento {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  margin-top: 1rem;
  min-height: 44px;
}
.consentimento input { width: 24px; height: 24px; margin-top: 0.2rem; flex: none; }

/* O conteúdo da pergunta ocupa o espaço entre o cabeçalho e os botões e se
   centra nele. Sem isto, `.acoes` com `margin-top: auto` empurra os botões para
   o rodapé e o conteúdo fica encostado no topo, deixando um vazio no miolo em
   toda tela alta — a página parece inacabada.
   `justify-content: center` só centra quando sobra espaço; quando o conteúdo é
   maior que a área, o flex passa a alinhar pelo início e a página rola normal,
   sem cortar nada em cima. */
#tela {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 0;
  /* Centro ÓPTICO, não geométrico: o olho lê como centrado um ponto um pouco
     acima da metade. Sem este empurrão, uma tela alta com pouco conteúdo (as
     de nota) parece ter o texto caindo. */
  padding-bottom: 6vh;
}

/* A TELA NOVA CHEGA — SOBE OITO PIXELS E APARECE.
   ===========================================================================

   POR QUE EXISTE. `desenhar()` troca o conteúdo com `replaceChildren`, e a troca
   era instantânea. Isso é quase invisível justamente onde mais importa: as
   quatro telas de nota são a MESMA tela com outro `<h1>` — "E o produto?", "E o
   atendimento?", "E o ambiente?" —, com as mesmas cinco carinhas embaixo, na
   mesma posição. Trocada de uma vez, a pergunta seguinte parece a mesma
   pergunta, e o toque da pessoa parece ter falhado. Quem acha que o toque falhou
   toca de novo — que é exatamente o toque duplo que `ARMAR_APOS_MS` existe para
   matar, em public/pesquisa.js.

   A DURAÇÃO NÃO FOI ESCOLHIDA POR GOSTO. Ela é o encontro de dois números que
   já estavam no projeto:

     240ms é o que a barra de progresso no topo já levava para deslizar (a linha
     `transition` de `.progresso__barra`, acima). As duas coisas são disparadas
     pelo MESMO `desenhar()`, no mesmo quadro — com a mesma duração e a mesma
     curva elas começam e terminam juntas, e a pessoa vê UM movimento em dois
     lugares (a barra andando, a pergunta assentando), não dois avisos
     disputando atenção. Qualquer outro número transformaria a barra e o
     conteúdo em dois eventos separados.

     300ms é `ARMAR_APOS_MS`: toda tela nova IGNORA toque nos primeiros 300ms,
     porque o segundo toque de um toque duplo era hit-testado já na tela
     seguinte e carimbava nota em quem talvez nem estivesse na loja. Ou seja: a
     espera já existia, e era INVISÍVEL — parecia um toque que não pegou. O
     movimento cabe inteiro dentro dela, com 60ms de folga, e por isso não
     acrescenta espera nenhuma: ele só dá cara ao tempo morto que já se pagava.
     Uma transição mais longa que 300ms seria irritação nova, porque aí sim a
     pessoa estaria esperando a animação.

   Quem depender destes 240ms está avisado nos dois lados: mexer no
   `ARMAR_APOS_MS` de public/pesquisa.js sem mexer aqui deixa o movimento
   sobrando para fora da janela morta.

   POR QUE SÓ ENTRADA, e nada de cruzar com a tela que sai. Fazer a antiga sair
   exigiria manter os dois conteúdos no DOM ao mesmo tempo — e `#tela` é
   `aria-live="polite"`. Dois `<h1>` na região ao mesmo tempo é o leitor de tela
   anunciando a pergunta velha e a nova em sequência, que é justamente o que o
   fragmento único de `desenhar()` foi escrito para evitar. A tela antiga
   simplesmente acabou; a nova chega.

   POR QUE SOBE, e não desliza para o lado. Deslizar é o jeito clássico de fazer
   a página rolar na horizontal num celular de 320px, e a suíte proíbe isso nas
   duas larguras que medimos.

   E aqui há um número medido que vale guardar, porque ele contraria a intuição:
   um deslize LATERAL pequeno não vaza. Trocando este `translateY(0.5rem)` por
   `translateX(0.5rem)` a página continua sem rolar, nas duas larguras — o
   `padding: var(--espaco)` da `.moldura` são 16px de cada lado, e o conteúdo
   ainda cabe dentro deles. Quem vaza é o deslize MAIOR que a calha: com
   `translateX(1.5rem)` o documento vai a 328px num viewport de 320. Ou seja, o
   eixo X aqui é um precipício com corrimão curto, e a folga que existe é
   acidental — depende de um `padding` que não foi escolhido para isso.

   Subir 8px não escapa da caixa em eixo NENHUM: o `padding-bottom: 6vh` do
   `#tela` e as ações logo abaixo absorvem o deslocamento, então nem rolagem
   vertical nova aparece (`scrollHeight` medido em 727 num viewport de 727,
   quadro a quadro, do começo ao fim do movimento). É o eixo em que não há
   precipício.

   POR QUE NOS FILHOS, e não no `#tela`. `#tela` é o mesmo elemento a pesquisa
   inteira; uma animação nele só reiniciaria com o truque de tirar a classe,
   forçar reflow e repor. Os FILHOS são criados do zero a cada `desenhar()`,
   então a animação recomeça sozinha, sem uma linha de JavaScript. Eles sobem
   todos com a mesma duração e sem escalonamento, começando no mesmo quadro
   (entram numa mutação só), então o que se vê é um bloco só se movendo — é de
   propósito que não há `nth-child` aqui: conteúdo chegando em pedaços brigaria
   com o deslize único da barra.

   O BOTÃO DE AVANÇAR NÃO SE MEXE, e a ausência é o desenho: ele mora em
   `.acoes`, fora do `#tela`. O que muda de tela para tela é a pergunta; o botão
   é a mesma ação no mesmo lugar, e um alvo que dança embaixo do polegar de quem
   está com o copo na outra mão não ajuda ninguém.

   QUEM PEDIU MENOS MOVIMENTO NÃO VÊ NADA DISTO: o `@media
   (prefers-reduced-motion: reduce)` no fim do arquivo desliga `animation` em
   tudo com `!important`, e não há regra específica repetindo isso aqui de
   propósito — cópia que não muda nada é o que este arquivo já chama de linha
   morta, duas vezes, no bloco do Instagram. Que a regra genérica realmente pega
   ESTA animação não é dedução: está medido em `tests/e2e/transicao.spec.ts`, com
   a emulação ligada e o navegador confirmando zero evento de animação e nenhum
   quadro fora do lugar. */
@keyframes tela-entra {
  from {
    opacity: 0;
    transform: translateY(0.5rem);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
#tela > * {
  animation: tela-entra var(--avanco-duracao) var(--avanco-curva);
}

.acoes { margin-top: auto; padding-top: 1.5rem; display: flex; gap: 0.75rem; }

.botao {
  flex: 1;
  min-height: 52px;
  border: none;
  border-radius: var(--raio);
  background: var(--cor-roxo);
  color: var(--cor-branco);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.botao--fantasma {
  flex: 0 0 auto;
  padding: 0 1.25rem;
  background: transparent;
  color: var(--cor-roxo-escuro);
  border: 2px solid var(--cor-roxo);
}
/* O BOTÃO DE FALAR COM O DONO — tratamento de AÇÃO SECUNDÁRIA, e é o mesmo
   vocabulário do `.botao--fantasma` logo acima: fundo transparente, texto
   escuro, borda. Quem responde a pergunta continua sendo o botão primário da
   tela; este é a saída de quem teve um problema de verdade e não quer preencher
   dez telas.

   AS QUATRO PRIMEIRAS DECLARAÇÕES SÃO O QUE FAZ UM <a> VIRAR BARRA. Um <a> é
   inline: sem `display: flex` e `width: 100%` o `min-height` de 52px que
   `.botao` já dá não pega, e sobra uma pílula apertada em volta de duas linhas
   de texto. Está medido no parágrafo do `.botao--instagram`, logo abaixo, e é o
   mesmo fato — por isso as duas linhas do texto ganham `line-height` legível e
   `text-align: center` em vez de um `white-space` que as forçasse numa só.

   NÃO HÁ `min-height` AQUI, e a ausência é deliberada: o alvo de toque vem de
   `.botao`, e o elemento carrega as duas classes. Redeclarar 44px venceria por
   especificidade e faria deste o MENOR alvo da pesquisa.

   `flex: 0 0 auto` É CINTO, E NÃO CONSERTO. `.cabecalho` não declara `display` e
   é bloco, então filho de bloco ignora `flex-grow` hoje; o que fez o link do
   Instagram crescer mil pixels foi `#tela` ser flex em COLUNA, condição que o
   cabeçalho não reproduz. A linha fica para o dia em que alguém puser
   `display: flex` na `.cabecalho` — e, como apagá-la não move um pixel hoje, ela
   NÃO é cobrada em `tests/estilos.test.ts`.

   SEM GLIFO, por decisão. Isso também escapa do seletor de tipo `.cabecalho svg`
   lá em cima, que impõe 11rem de largura a todo <svg> do cabeçalho: um desenho
   aqui viraria um bloco de 176px centralizado em cima do texto.

   A cor sai SÓ de token. `--cor-roxo-escuro` sobre o `--cor-creme` do `body` é o
   par do `.botao--fantasma`, já medido em `PARES_DE_TEXTO` — nenhuma cor nova
   entra na pesquisa por causa deste botão. */
.botao--dono {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 0.625rem 1rem;
  text-align: center;
  line-height: 1.25;
  text-decoration: none;
  background: transparent;
  color: var(--cor-roxo-escuro);
  border: 2px solid var(--cor-roxo);
}
/* Este é um dos DOIS `.botao` que não moram dentro de `.acoes`: o link do
   Instagram fica no corpo da tela de agradecimento, e o `.botao--dono` logo
   acima fica no cabeçalho. (A frase dizia "o único" até o botão do dono chegar;
   um comentário errado é pior que comentário nenhum, e este arquivo já pagou
   por isso uma vez — ver o parágrafo do `flex: 1` abaixo.)

   O COMENTÁRIO QUE MORAVA AQUI DIZIA O CONTRÁRIO DO QUE ACONTECE, e foi por isso
   que o defeito chegou à parede da loja. Ele afirmava que "fora de `.acoes` o
   `flex: 1` não vale nada". Vale, e muito: `#tela` também é `display: flex`, só
   que em COLUNA — ali o `flex: 1` herdado de `.botao` não divide LARGURA com
   irmãos, ele manda este link CRESCER NA VERTICAL até engolir todo o espaço
   livre da tela. Em produção isso virou um retângulo de mais de mil pixels
   ocupando dois terços da tela de agradecimento, com o texto perdido no meio;
   está retratado em `capturas/05-agradecimento.png` do commit anterior a este.

   Um comentário errado é pior que comentário nenhum: quem passou por aqui leu
   "não vale nada" e não foi medir. Por isso o `flex` agora é DECLARADO, e não
   apenas herdado — e por isso este parágrafo é comprido.

   `min-height` não protege contra isso: ele é um PISO, e `flex-grow` cresce por
   cima dele à vontade. Quem segura a altura é o `flex: 0 0 auto`.

   O que o comentário antigo acertava, e continua valendo: um <a> é inline, então
   sem `display: flex` e `width: 100%` o `min-height` não pega e sobra uma pílula
   apertada em volta do texto, do lado de botões que são barras de 52px.

   NÃO HÁ `min-height` AQUI, e a ausência é deliberada. Ele estava — repetindo os
   52px que `.botao` já declara, e o elemento carrega as duas classes. A cópia
   foi MEDIDA e não fazia nada: apagá-la não mexeu num pixel (é o que este
   repositório chama de mutante equivalente; a altura só cede quando os DOIS
   `min-height` saem, e aí o botão cai para 49,5px). Pior que inútil, ela era uma
   armadilha: no dia em que o alvo de toque da pesquisa mudasse em `.botao`, este
   botão ficaria pregado nos 52 e passaria a destoar de todos os outros — que é
   exatamente o que `tests/e2e/agradecimento.spec.ts` proíbe, comparando a altura
   dele com a do `#botao-continuar` medido na tela anterior. */
.botao--instagram {
  /* A LINHA DO CONSERTO. Ver o parágrafo do `flex: 1` acima. */
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.625rem;
  width: 100%;
  padding: 0.75rem 1.25rem;
  margin-top: 1.5rem;
  text-decoration: none;
  /* A COR É A DA EMPRESA DAQUELA LOJA — nunca o degradê rosa do Instagram, por
     duas razões que doem igual. A primeira é a mesma que tirou o roxo da
     ParáBrasil do `:root` deste arquivo: o degradê é a identidade de OUTRA
     marca, cravada na última tela de um cliente pagante. A segunda é medível: os
     tons dele não passam por `validarPaleta`, e o contraste do texto deixaria de
     ser conferido justamente no único botão desta tela.

     `--cor-branco` sobre `--cor-roxo-escuro` é o PRIMEIRO par de `PARES_DE_TEXTO`
     lido ao contrário (o contraste WCAG é simétrico — está escrito lá), então
     toda paleta que o servidor aceita já garante os 4,5:1 aqui, seja de que rede
     for. Medido com `contraste()` de src/lib/cores.ts: 13,58:1 no padrão neutro,
     11,71:1 na ParáBrasil e 11,25:1 na Rede B da semente.

     Quem dá cara de Instagram é o GLIFO, e ele sai de graça em contraste porque
     é desenhado em `currentColor`. */
  background: var(--cor-roxo-escuro);
  color: var(--cor-branco);
}

/* O glifo tem tamanho SÓ AQUI, e não em atributo do <svg>: um lugar só decide.
   `flex: none` porque o irmão dele encolhe (ver o rótulo abaixo) — sem isto o
   glifo é o primeiro a ser espremido quando a arroba é comprida, e o desenho que
   identifica o Instagram é justamente o que não pode sumir. Largura e altura
   explícitas porque um <svg> sem dimensão não usa o `viewBox` como tamanho: ele
   cai no padrão de elemento substituído (300x150) e arrebenta a linha. */
.botao--instagram svg {
  flex: none;
  width: 22px;
  height: 22px;
}

/* ARROBA COMPRIDA: UMA LINHA SÓ, CORTADA COM RETICÊNCIAS NO FIM.
   ---------------------------------------------------------------------------
   O Instagram aceita até 30 caracteres de arroba; a da loja do Bonfim tem 14 e
   cabe, mas a decisão precisa valer para a rede seguinte. As três saídas
   possíveis e por que esta:

   QUEBRAR EM DUAS LINHAS faria o botão crescer em altura e reflow na última
   tela — e é o vizinho do defeito que este commit conserta. Pior: sem espaço
   para quebrar, uma arroba é UMA palavra só, então o navegador ou estoura a
   caixa (rolagem horizontal, que a suíte proíbe a 320px) ou parte a palavra no
   meio com `overflow-wrap`, e "@acaiparabrasil / bonfimcentro" lê como defeito.

   DIMINUIR A FONTE atacaria o alvo de leitura de quem está no balcão com o
   celular na mão, para salvar um texto que ninguém precisa DECORAR.

   CORTAR é o que sobra, e é honesto: as reticências dizem "tem mais". O botão é
   uma AÇÃO, não uma ficha de cadastro — quem toca vai parar no perfil, e a
   arroba inteira continua no `href`. Ela também não some para quem não enxerga:
   o nome acessível do link é o completo, montado em `telaFinal()` de
   public/pesquisa.js. O que é cortado é só o pixel.

   NÃO HÁ `min-width: 0` AQUI, e a ausência custou uma medição. A receita que se
   copia da internet manda pô-lo, porque item de flex nasce com `min-width: auto`
   e se recusa a encolher abaixo do próprio conteúdo — sem isso o
   `text-overflow` nunca chegaria a valer. Só que a regra do `min-width: auto`
   tem uma condição que a receita não conta: ela só vale para item com `overflow`
   VISÍVEL. Com o `overflow: hidden` logo abaixo, o mínimo automático já é zero,
   e a linha vira cópia morta. MEDIDO, não deduzido: apagando `min-width: 0` e
   deixando o resto, a arroba de 30 caracteres continua encolhendo e sendo
   cortada, com a mesma largura de antes; apagando `overflow: hidden` e deixando
   o `min-width: 0`, a tela passa a rolar na horizontal (384px num viewport de
   320px). Quem segura isto é o `overflow`, e é ele que não pode sair.

   As duas cópias mortas deste bloco — esta e o `min-height` lá em cima — foram
   encontradas MUTANDO. É o motivo de a suíte deste repositório exigir que toda
   asserção seja provada por mutação: uma linha que não muda nada é uma linha que
   o próximo leitor vai acreditar que protege alguma coisa. */
.botao--instagram__rotulo {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.aviso {
  margin-top: 0.5rem;
  padding-left: 0.75rem;
  border-left: 4px solid var(--cor-ocre);
  font-size: 0.9375rem;
  font-weight: 700;
}

.rodape-legal {
  margin-top: 1rem;
  font-size: 0.8125rem;
  opacity: 0.8;
}

:focus-visible {
  outline: 3px solid var(--cor-roxo-escuro);
  outline-offset: 2px;
}

.escondido { display: none !important; }

/* MENOS MOVIMENTO NÃO É ENFEITE: há quem sinta náusea com conteúdo que se mexe.
   O `animation: none` aqui é o que desliga a chegada de tela (`tela-entra`) e o
   `transition: none` é o que congela a barra de progresso — que continua
   marcando o avanço, só que num salto. O `!important` é o que faz esta regra
   genérica ganhar de `#tela > *`, que é bem mais específica. */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  .carinha[aria-pressed="true"] { transform: none; }
}
