/* =============================================================================
 * publico.css: a folha das páginas PÚBLICAS, renderizadas no servidor
 * (server/src/views/). Servida em /css/publico.css, depois de /css/tokens.css,
 * que é de onde vêm TODOS os var(--x) daqui (a fonte única de tokens; ver o
 * comentário no topo dele). Nenhum token de marca é declarado aqui: a guarda
 * web/test/padrao-visual.spec.ts recusa.
 *
 * Registro ALTO da §4.1 do padrão (corpo 16.5px, peso 400): é a superfície em
 * que o conteúdo é o que se julga. O painel (/org/) usa o registro baixo, na
 * folha dele.
 *
 * Só entra aqui regra que algum template de views/ cita, e a mesma guarda
 * cobra o contrário também: classe citada sem regra aqui (ou no tokens.css)
 * reprova. Regra sem quem a use é o terceiro defeito da §10 do padrão.
 * ========================================================================== */

/* ------------------------------------------------------------------- base */

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

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

/*
 * Coluna em flex: o rodapé institucional pousa no pé da janela mesmo quando a
 * tela tem três linhas de conteúdo (o estado vazio, o 404). Como bloco, ele
 * subiria e leria como parte do conteúdo.
 */
body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font-family: var(--ui);
  font-size: 16.5px;
  line-height: 1.62;
  font-weight: 400;
  background: var(--gelo);
  color: var(--tinta);
  -webkit-font-smoothing: antialiased;
}

/*
 * A tricolor, UMA vez por superfície (§1.2), 6px na página pública, com as
 * paradas duras de 34% e 67%. Pseudo-elemento do body, e não markup do layout:
 * assim nenhuma tela nova tem como repeti-la.
 */
body::before {
  content: '';
  flex: none;
  height: 6px;
  background: linear-gradient(90deg,
    var(--verde) 0 34%, var(--amarelo) 34% 67%, var(--laranja) 67% 100%);
}

/*
 * main.wrap, e não main: o .wrap abaixo zera o padding de cima, e um seletor só
 * de elemento perde para a classe. Com main sozinho, o h1 encostava no fio do
 * cabeçalho (visto na tela, não em teste).
 */
main.wrap {
  flex: 1;
  width: 100%;
  padding-top: 32px;
}

/* ------------------------------------------------------------- tipografia */

h1 {
  font-size: clamp(31px, 7.6vw, 50px);
  font-weight: 900;
  line-height: 1.04;
  letter-spacing: -.025em;
  margin: 0 0 14px;
}

/*
 * Título de campanha é texto livre de quem cadastra, e uma palavra sem espaço
 * (uma URL, "Natal#2026") estouraria a coluna em 320px e traria rolagem
 * horizontal. Quebrar dentro da palavra é feio; rolar é pior.
 */
h1, h3 {
  overflow-wrap: anywhere;
}

/* §4.3, literal: versalete em --meta com o traço de 34x4 acima, que é a
   citação da faixa do topo, não a faixa. */
h2 {
  position: relative; padding-top: 14px; margin: 38px 0 10px;
  font-size: 12px; font-weight: 900; letter-spacing: .2em;
  text-transform: uppercase; color: var(--meta);
}
h2::before {
  content: ''; position: absolute; left: 0; top: 0;
  width: 34px; height: 4px; border-radius: 2px;
  background: linear-gradient(90deg,
    var(--verde) 0 34%, var(--amarelo) 34% 67%, var(--laranja) 67% 100%);
}

h3 {
  font-size: 16.5px;
  font-weight: 900;
  letter-spacing: -.01em;
}

.lead {
  font-size: 17px;
  font-weight: 600;
  max-width: 34em;
  margin: 0;
}

a {
  color: var(--azul-cientec);
}
a:hover {
  color: var(--azul-escuro);
}

/* ----------------------------------------------------------------- layout */

/* §5, literal. */
.wrap { max-width: var(--medida); margin: 0 auto; padding: 0 20px 72px; }
@media (min-width: 600px) { .wrap { padding-left: 28px; padding-right: 28px; } }

/* ------------------------------------------------------------- cabeçalho */

/* Papel e fio (§7, estado normal). A cor cheia fica para o que muda decisão. */
.topo {
  background: var(--papel);
  border-bottom: 1px solid var(--linha);
}
.topo .wrap {
  padding-top: 10px;
  padding-bottom: 10px;
}
.marca {
  margin: 0;
}
/* O link inteiro é o alvo de toque: 75px de logo passam folgado dos 44px (§9). */
.marca a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border-radius: var(--r);
}
.marca img {
  display: block;
  width: 150px;
  height: auto;
}

/* ------------------------------------------------------ lista de campanhas */

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

/*
 * Cartão (§6). O cartão inteiro é o link. A borda esquerda carrega o estado
 * (§1.5): verde = arrecadação publicada. Cantos retos do lado da borda, para ela
 * não parecer descolada do cartão (§5, raio). overflow: hidden recorta a capa
 * nesses mesmos cantos.
 */
.campanha {
  display: block;
  overflow: hidden;
  background: var(--papel);
  border: 1px solid var(--linha);
  border-left: 6px solid var(--verde);
  border-radius: 0 16px 16px 0;
  text-decoration: none;
  color: inherit;
}
.campanha:hover {
  border-color: var(--azul-cientec);
  border-left-color: var(--verde);
  color: inherit;
}

/* Proporção da imagem de compartilhamento (1,91:1): a mesma arte que vai no
   og:image cabe aqui sem corte de texto. */
.campanha-capa {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1.91 / 1;
  object-fit: cover;
  background: var(--gelo);
}

.campanha-texto {
  padding: 16px 18px;
}

.campanha-titulo {
  margin: 0;
  font-size: 19px;
  line-height: 1.25;
  color: var(--tinta);
}
.campanha:hover .campanha-titulo {
  color: var(--azul-escuro);
}

.campanha-sub {
  margin: 4px 0 0;
  color: var(--meta);
}

/*
 * As anteriores (fase ENCERRADA): a borda vira fio (§7, concluído). A cor vem
 * da LISTA, e não de uma classe por cartão. Sem a opacidade .62 do §7: o texto
 * do cartão cairia abaixo do contraste AA, e a prestação de contas é justamente
 * o que se vem ler numa campanha encerrada.
 */
.campanhas-anteriores .campanha,
.campanhas-anteriores .campanha:hover {
  border-left-color: var(--linha-forte);
}

.campanha-fase {
  margin: 10px 0 0;
}
/* A pílula do cartão é um degrau menor que a da página (§4.1: 13.5 a 14px). */
.campanha-fase .pill {
  font-size: 13.5px;
  padding: 4px 12px;
}

.campanha .barra {
  height: 8px;
  margin: 12px 0 4px;
}

.campanha-valores {
  margin: 4px 0 0;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--meta);
  font-variant-numeric: tabular-nums;
}
.campanha-valores strong {
  color: var(--tinta);
  font-weight: 900;
}

/* ------------------------------------------------------ página da campanha */

/* A arte da campanha, na proporção da imagem de compartilhamento (1,91:1),
   com o raio de cartão. Decorativa: o h1 logo abaixo diz o que ela diria. */
.capa {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1.91 / 1;
  object-fit: cover;
  border-radius: 16px;
  background: var(--papel);
  margin: 0 0 20px;
}

.fase {
  margin: 14px 0 0;
}
/* Na confirmação do pagamento o lead vem DEPOIS da pílula, e sem margem encostava nela. */
.fase + .lead {
  margin-top: 14px;
}

/* Cada seção de baixo é alvo de atalho: o respiro em cima deixa o título à
   vista quando o fragmento rola a página até ela. */
.secao {
  scroll-margin-top: 12px;
}

/*
 * Os números (§6 do CLAUDE.md), num cartão de papel. Em coluna no celular,
 * lado a lado a partir de 600px (§5). Tudo tabular (§4.4): os valores são
 * comparados entre si.
 */
.numeros {
  display: grid;
  gap: 16px;
  margin: 22px 0 0;
  padding: 18px;
  background: var(--papel);
  border: 1px solid var(--linha);
  border-radius: 16px;
  font-variant-numeric: tabular-nums;
}
.numeros-bloco + .numeros-bloco {
  border-top: 1px solid var(--linha);
  padding-top: 16px;
}
@media (min-width: 600px) {
  .numeros {
    grid-template-columns: 3fr 2fr;
    gap: 24px;
    padding: 22px 24px;
  }
  .numeros-bloco + .numeros-bloco {
    border-top: 0;
    padding-top: 0;
    border-left: 1px solid var(--linha);
    padding-left: 24px;
  }
}

/* Rótulo versaletado (§4.1). */
.rotulo {
  margin: 0;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--meta);
}

.valor-grande {
  margin: 2px 0 0;
  font-size: clamp(30px, 8.4vw, 40px);
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: -.02em;
  color: var(--tinta);
}

.valor-medio {
  margin: 2px 0 0;
  font-size: 24px;
  font-weight: 900;
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tinta);
}

.numeros-meta {
  margin: 2px 0 0;
  font-size: 15px;
  font-weight: 700;
  color: var(--meta);
}

/*
 * A barra é um <progress> (ver partes.ts): o valor vai em atributo, sem style
 * inline. appearance: none desliga o desenho nativo; o trilho é o fio e o
 * preenchimento é a cor. Cada motor tem o seu pseudo-elemento, e as regras
 * ficam separadas porque um seletor desconhecido invalida a regra inteira.
 * Verde para o que entrou, laranja para o que saiu: duas cores da tricolor,
 * sem texto por cima (§3).
 */
.barra {
  display: block;
  width: 100%;
  height: 12px;
  margin: 12px 0 8px;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  -webkit-appearance: none;
  appearance: none;
  background: var(--linha);
  color: var(--verde);
}
.barra::-webkit-progress-bar {
  background: var(--linha);
  border-radius: 999px;
}
.barra::-webkit-progress-value {
  background: var(--verde);
  border-radius: 999px;
}
.barra::-moz-progress-bar {
  background: var(--verde);
  border-radius: 999px;
}
.barra-uso {
  color: var(--laranja);
}
.barra-uso::-webkit-progress-value {
  background: var(--laranja);
}
.barra-uso::-moz-progress-bar {
  background: var(--laranja);
}

.barra-legenda {
  margin: 0;
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.45;
  color: var(--meta);
}
.barra-legenda strong {
  color: var(--tinta);
  font-weight: 900;
}
/* Dois pontos de especificidade: .barra-legenda strong (um e um) pintaria de
   tinta o destaque se este seletor tivesse um só. */
.barra-legenda .meta-batida {
  color: var(--verde-tinta);
}

.numeros-contagem {
  margin: 10px 0 0;
  font-size: 14.5px;
  font-weight: 800;
  color: var(--tinta);
}

/* Atalhos para as seções: portas pequenas, 44px de alvo (§9). */
.atalhos {
  margin: 18px 0 0;
}
.atalhos ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.atalhos a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 16px;
  border: 2px solid var(--linha-forte);
  border-radius: 999px;
  background: var(--papel);
  color: var(--tinta);
  font-size: 14.5px;
  font-weight: 800;
  text-decoration: none;
}
.atalhos a:hover {
  border-color: var(--azul-cientec);
  color: var(--azul-escuro);
}

/* Texto escrito por uma pessoa preserva a quebra de linha (§4.4); a linha em
   branco já virou parágrafo (formato.ts). Medida de leitura (§5). */
.descricao p,
.faq-resposta p {
  white-space: pre-line;
  max-width: 68ch;
  margin: 0 0 12px;
}
.descricao p:last-child,
.faq-resposta p:last-child {
  margin-bottom: 0;
}

/*
 * Doadores: tabela de três colunas que cabe em 320px, com a hora embaixo da
 * data. Fio entre as linhas, sem zebra: a cor cheia fica para o que muda
 * decisão (§1.3). Os valores alinham à direita, tabulares.
 */
.doadores {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}
.doadores th {
  padding: 0 8px 6px;
  border-bottom: 2px solid var(--linha-forte);
  text-align: left;
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--meta);
}
.doadores td {
  padding: 9px 8px;
  border-bottom: 1px solid var(--linha);
  vertical-align: top;
}
.doadores th:first-child,
.doadores td:first-child {
  padding-left: 0;
}
.doadores th:last-child,
.doadores td:last-child {
  padding-right: 0;
}
.doadores .num {
  text-align: right;
  white-space: nowrap;
}
.doadores td.num {
  font-weight: 800;
}
.doador-iniciais {
  font-weight: 900;
  overflow-wrap: anywhere;
}
.hora {
  display: block;
  font-size: 13px;
  color: var(--meta);
}

/*
 * O aviso de doações novas, no topo da lista (campanha.js o mostra; sem JS ele
 * não existe). É informação, não alerta: a moldura da nota neutra (§6, papel,
 * fio e a borda verde), nunca o âmbar, que é para o que pede cuidado (§1.3).
 * O aviso inteiro é o link, com 44px de alvo (§9). A contagem vem em tinta e
 * peso 900, que é o que se lê primeiro; a ação, sublinhada, tem a cara de link
 * e a cor dele (o a:hover do topo da folha escurece no toque).
 */
.novas {
  margin: 0 0 14px;
}
.novas-link {
  display: block;
  min-height: 44px;
  padding: 10px 16px;
  background: var(--gelo);
  border: 1px solid var(--linha);
  border-left: 4px solid var(--verde);
  border-radius: 0 10px 10px 0;
  font-size: 15px;
  line-height: 1.45;
  font-weight: 800;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.novas-link:hover {
  border-color: var(--azul-cientec);
  border-left-color: var(--verde);
}
.novas-quantas {
  font-weight: 900;
  color: var(--tinta);
}
.novas-acao {
  text-decoration: underline;
}

/* Posição numa linha, os links embaixo: em 320px os três não cabem lado a lado.
   A "próxima" encosta à direita mesmo quando está sozinha (primeira página). */
.paginacao {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 16px 0 0;
}
.paginacao-posicao {
  flex-basis: 100%;
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--meta);
  font-variant-numeric: tabular-nums;
}
.paginacao-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 8px 18px;
  border: 2px solid var(--azul-cientec);
  border-radius: 999px;
  font-size: 15px;
  font-weight: 900;
  text-decoration: none;
}
.paginacao-link:hover {
  background: var(--azul-cientec);
  color: #fff;
}
.paginacao-proxima {
  margin-left: auto;
}

/* Gastos: o item e o subtotal em cima, a conta e a data embaixo. minmax(0, 1fr)
   deixa a descrição quebrar em vez de empurrar o subtotal para fora. */
.gastos {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 2px solid var(--linha-forte);
}
.gasto {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--linha);
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}
.gasto-item {
  font-weight: 800;
  overflow-wrap: anywhere;
}
.gasto-subtotal {
  font-weight: 900;
  text-align: right;
  white-space: nowrap;
}
.gasto-detalhe {
  grid-column: 1 / -1;
  margin-top: 2px;
  font-size: 13.5px;
  color: var(--meta);
}

/*
 * Perguntas frequentes: acordeão SEM JS, <details>/<summary> (§1.6). O círculo
 * de + e de menos é amarelo com a tinta da pílula (§3, contraste). summary no
 * registro alto (§4.1: 19px, peso 900).
 */
.faq {
  display: grid;
  gap: 10px;
}
.faq-item {
  background: var(--papel);
  border: 1px solid var(--linha);
  border-radius: 12px;
  padding: 0 16px;
}
.faq-item[open] {
  padding-bottom: 16px;
}
.faq-item > summary {
  position: relative;
  min-height: 44px;
  padding: 14px 46px 14px 0;
  list-style: none;
  cursor: pointer;
  font-size: 19px;
  font-weight: 900;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.faq-item > summary::-webkit-details-marker {
  display: none;
}
.faq-item > summary::after {
  content: '+';
  position: absolute;
  right: 0;
  top: 12px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--amarelo);
  color: var(--pilula-tinta);
  font-size: 23px;
  font-weight: 900;
  line-height: 1;
}
.faq-item[open] > summary::after {
  content: '\2212';
}

/* Links da campanha: cada um é um alvo de 44px (§9), com o domínio de destino
   ao lado do rótulo. O rótulo sem endereço válido vira texto, sem cara de link. */
.links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}
.link {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 8px;
  min-height: 44px;
  padding: 10px 14px;
  background: var(--papel);
  border: 1px solid var(--linha);
  border-radius: var(--r);
  font-weight: 800;
  text-decoration: none;
}
a.link:hover {
  border-color: var(--azul-cientec);
}
/* Sem endereço válido: o rótulo continua dizendo o que foi cadastrado, mas sem
   a caixa. Com a mesma caixa dos links, pareceria um botão que não faz nada. */
.link-texto {
  background: transparent;
  border-color: transparent;
  padding-left: 0;
  color: var(--tinta);
  font-weight: 700;
}
.link-rotulo {
  overflow-wrap: anywhere;
}
.link-dominio {
  font-size: 13px;
  font-weight: 700;
  color: var(--meta);
}

/* O convite a doar, logo abaixo dos números (só na fase ABERTA). */
.doar-convite {
  margin: 18px 0 0;
}

/* --------------------------------------------------------- fluxo de doação */

/*
 * O link de volta à campanha, no topo do formulário e da tela do PIX. Registro
 * de rótulo, e 44px de alvo (§9): é o caminho de saída de quem desistiu.
 */
.volta {
  margin: 0 0 6px;
}
.volta a {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  font-size: 14.5px;
  font-weight: 800;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.volta a:hover {
  text-decoration: underline;
}

.acoes {
  margin: 22px 0 0;
}

/* A ação secundária é link sem caixa, com o alvo de toque do §9. */
.acao-secundaria {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 800;
}

/*
 * Formulário: cada passo é um cartão de papel. O fieldset perde a moldura do
 * navegador (a borda do cartão faz esse papel) e o min-width: 0, sem o qual o
 * fieldset se recusa a encolher e estoura a coluna em 320px.
 */
.doar {
  margin: 8px 0 0;
}
.passo {
  min-width: 0;
  margin: 14px 0 0;
  padding: 16px;
  background: var(--papel);
  border: 1px solid var(--linha);
  border-radius: 16px;
}

/*
 * O título do passo, num <legend> ou num <p>. O legend flutua de propósito:
 * sem isso ele senta EM CIMA da borda do fieldset e a corta (é a regra de
 * desenho do legend), e o cartão sairia com um buraco no fio de cima. O
 * elemento seguinte limpa a flutuação.
 */
.passo-titulo {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  margin: 0 0 14px;
  padding: 0;
  font-size: 19px;
  font-weight: 900;
  line-height: 1.25;
  color: var(--tinta);
}
legend.passo-titulo {
  float: left;
}
.passo-titulo + * {
  clear: both;
}

/* O número do passo: o círculo amarelo com a tinta da pílula, como o + da FAQ (§3, contraste). */
.passo-numero {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--amarelo);
  color: var(--pilula-tinta);
  font-size: 15px;
  font-weight: 900;
}

.passo-texto {
  margin: 0 0 16px;
}

/*
 * Os valores sugeridos, em quantas colunas couberem com no mínimo 88px cada:
 * duas em 320px, três em 360px, mais na tela larga. Coluna FIXA não serve: o
 * valor é do cadastro, o rótulo não quebra (o Intl põe espaço não separável
 * depois do R$), e "R$ 2.500" ou "R$ 123,45" vazavam da caixa em 320px com
 * três colunas (visto na tela). "Outro valor" ocupa a linha inteira: é uma
 * escolha de outra natureza.
 */
.opcoes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 8px;
}
.opcao {
  position: relative;
  display: block;
}
.opcao-larga {
  grid-column: 1 / -1;
}

/*
 * O rádio de verdade fica por cima do rótulo, do mesmo tamanho e invisível:
 * recebe o toque, o foco e o teclado (setas trocam a opção), e o leitor de
 * tela o anuncia como rádio. Quem se vê é o rótulo ao lado, pelo seletor de
 * irmão, que todo navegador entende.
 */
.opcao-radio {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.opcao-rotulo {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 8px 6px;
  border: 2px solid var(--linha-forte);
  border-radius: var(--r);
  background: var(--papel);
  color: var(--tinta);
  font-size: 17px;
  font-weight: 900;
  line-height: 1.2;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.opcao:hover .opcao-rotulo {
  border-color: var(--azul-cientec);
}
/* Marcada: preenchimento cheio (§7, selecionado), azul com texto branco (§3). */
.opcao-radio:checked + .opcao-rotulo {
  background: var(--azul-cientec);
  border-color: var(--azul-cientec);
  color: #fff;
}
/* O foco é do rádio, que é invisível: o anel vai no rótulo (§9). */
.opcao-radio:focus-visible + .opcao-rotulo {
  outline: 3px solid var(--azul-cientec);
  outline-offset: 2px;
}

.outro-valor {
  margin: 14px 0 0;
}
/*
 * Com as opções na tela, o campo livre só aparece com "Outro valor" marcado:
 * sem isso, quem digita um valor e esquece de marcar a opção manda o valor
 * sugerido. Navegador sem :has() descarta a regra inteira e mostra o campo
 * sempre, e o formulário continua funcionando. Campanha sem valores sugeridos
 * não tem a opção, e o campo fica à vista.
 */
.passo-valor:has(.opcao-outro:not(:checked)) .outro-valor {
  display: none;
}

.campo-grupo {
  margin: 16px 0 0;
}
.campo-rotulo {
  display: block;
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 800;
  color: var(--tinta);
}
.campo-ajuda {
  margin: 0 0 6px;
  font-size: 14px;
  color: var(--meta);
}
/* Dado inválido: vermelho no texto e na borda (§1.3), nunca como fundo. */
.campo-erro {
  margin: 0 0 6px;
  font-size: 14.5px;
  font-weight: 800;
  color: var(--alerta);
}

/*
 * 17px, e nunca menos de 16px: abaixo disso o Safari do iPhone dá zoom na
 * página ao focar o campo, e a pessoa fica com o formulário cortado.
 */
.campo {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: 10px 14px;
  border: 2px solid var(--linha-forte);
  border-radius: var(--r);
  background: var(--papel);
  color: var(--tinta);
  font-family: inherit;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.3;
}
.campo::placeholder {
  color: var(--meta);
}
.campo[aria-invalid="true"] {
  border-color: var(--alerta);
}
.campo-cpf {
  max-width: 14em;
}

/* O "R$" dentro do campo, à esquerda; o campo abre espaço para ele. */
.moeda {
  position: relative;
  max-width: 14em;
}
.moeda-simbolo {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-weight: 900;
  color: var(--meta);
  pointer-events: none;
}
.campo-moeda {
  padding-left: 46px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

/* O resumo de erros no topo, com um link para cada campo (§9: 44px de alvo). */
.erro-resumo {
  margin: 0 0 8px;
}
.erro-resumo p {
  margin: 0;
}
/* A mensagem geral e o "confira" são dois parágrafos, e colados liam como um só (visto na tela). */
.erro-resumo p + p {
  margin-top: 8px;
}
.erro-resumo ul {
  margin: 4px 0 0;
  padding-left: 20px;
}
.erro-resumo a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: inherit;
}

/*
 * A tela do PIX. No celular, um bloco embaixo do outro, copia-e-cola primeiro;
 * a partir de 640px (§5), lado a lado, com o QR na coluna estreita.
 */
.pix-valor {
  margin: 10px 0 0;
  font-variant-numeric: tabular-nums;
}
.pix-prazo {
  margin: 6px 0 0;
  font-size: 15px;
  color: var(--meta);
  font-variant-numeric: tabular-nums;
}
.pix-prazo strong {
  color: var(--tinta);
  font-weight: 900;
}
.pix {
  display: grid;
  gap: 14px;
  margin: 20px 0 0;
}
@media (min-width: 640px) {
  .pix {
    grid-template-columns: minmax(0, 1fr) 260px;
    align-items: start;
  }
}
.pix-bloco {
  min-width: 0;
  padding: 16px;
  background: var(--papel);
  border: 1px solid var(--linha);
  border-radius: 16px;
}
/* O h2 do padrão tem 38px em cima, para separar seções da página; dentro do cartão, zero. */
.pix-bloco h2 {
  margin-top: 0;
}
.pix-passos {
  margin: 0 0 14px;
  padding-left: 22px;
}

/*
 * O copia-e-cola num campo somente-leitura que quebra em qualquer caractere
 * (o brcode não tem espaço). 16px pelo mesmo zoom do Safari que o .campo
 * evita, e fundo gelo para ler como "dado", e não como campo a preencher.
 */
.pix-codigo {
  display: block;
  width: 100%;
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 2px solid var(--linha-forte);
  border-radius: var(--r);
  background: var(--gelo);
  color: var(--tinta);
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  line-height: 1.45;
  word-break: break-all;
  resize: none;
  field-sizing: content;
}
.botao-copiar {
  margin: 0;
}
/* Copiar é uma ação NA página, e a seta do .cta diz "vai para outra". Dois
   pontos de especificidade, para vencer o .cta::after declarado mais abaixo. */
.cta.botao-copiar::after {
  content: none;
}
.copiar-avisos {
  margin: 10px 0 0;
}
.copiar-aviso {
  margin: 0;
  font-size: 14.5px;
  font-weight: 800;
  color: var(--verde-tinta);
}

/*
 * O QR: fundo de papel na zona de silêncio (a margem de 4 módulos que qr.ts
 * põe dentro do viewBox) e módulos na tinta, que é quase preta (contraste de
 * leitura de câmera). Largura limitada: acima disso o módulo não fica mais
 * legível, só a página mais comprida.
 */
.qr-figura {
  margin: 0;
}
.qr {
  display: block;
  width: 100%;
  max-width: 240px;
  height: auto;
  margin: 0 auto;
  background: var(--papel);
  color: var(--tinta);
}
.qr-figura figcaption {
  margin: 10px 0 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--meta);
}

/* ------------------------------------------------------------ componentes */

/*
 * Pílula de fase e de situação (§6 do padrão). Preenchimento colorido com a
 * tinta escura da pílula (§3: nunca branco sobre verde ou amarelo). O texto é
 * nosso e curto (formato.ts, textoDaFase; partes.ts, pilulaDaSituacao), por
 * isso o nowrap do padrão cabe em 320px.
 */
.pill {
  display: inline-block; border-radius: 999px; padding: 6px 15px;
  font-size: 14px; font-weight: 900; color: var(--pilula-tinta);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.pill-aberta { background: var(--verde); }
.pill-em-breve { background: var(--amarelo); }
.pill-encerrada { background: var(--linha); }
.pill-pendente { background: var(--amarelo); }
.pill-paga { background: var(--verde); }
.pill-inativa { background: var(--linha); }

/* Nota (§6), nos três graus, literais: neutra, aviso (âmbar) e recusa (vermelho). */
.note {
  font-size: 14.5px; line-height: 1.55; color: #3B5566;
  background: var(--gelo); border: 1px solid var(--linha);
  border-left: 4px solid var(--verde); border-radius: 0 10px 10px 0;
  padding: 12px 16px;
}
.note.warn {
  border-left-color: var(--ambar-borda); border-color: rgba(199,150,0,.4);
  background: rgba(255,215,94,.16); color: var(--ambar); font-weight: 700;
}
.note.bad {
  border-left-color: var(--alerta); border-color: rgba(164,41,26,.25);
  background: rgba(164,41,26,.07); color: #7C2417; font-weight: 700;
}

/*
 * Ação principal (§6). 48px de altura: alvo de toque da ação principal (§9).
 * font-family: inherit e não font: inherit, para quando a classe for posta
 * num <button>: o atalho apagaria o peso 900 e o tamanho definidos aqui.
 */
.cta {
  display: inline-flex; align-items: center; gap: 10px; min-height: 48px;
  background: var(--azul-cientec); color: #fff; text-decoration: none;
  border-radius: 999px; padding: 12px 24px; font-weight: 900; font-size: 16px;
  font-family: inherit;
}
.cta::after { content: '\2192'; font-size: 19px; line-height: 1; }  /* seta */
.cta:hover { background: var(--azul-escuro); color: #fff; }
/* Num <button>, a borda e o cursor do navegador saem. */
button.cta { border: 0; cursor: pointer; }
/*
 * O botão de enviar enquanto o PIX é gerado (doar.js o desabilita no envio).
 * Mesma cor, e não esmaecido: o rótulo "Gerando o PIX…" é para ser lido, e
 * branco sobre o azul com opacidade cai abaixo de 4,5:1 (4,87:1 inteiro). O
 * que muda é o que o botão diz, o cursor, e a seta, que sai porque o toque já
 * foi dado; o :hover não escurece o que não responde mais.
 */
button.cta:disabled { cursor: progress; background: var(--azul-cientec); }
button.cta:disabled::after { content: none; }
/* A ação principal em largura inteira no celular; do tamanho do texto a partir de 560px (§5). */
.cta-largo { width: 100%; justify-content: center; }
@media (min-width: 560px) { .cta-largo { width: auto; } }

/* ---------------------------------------------------------------- rodapé */

/*
 * §4.1: 13.5px / 1.75 em --meta. Fio em cima: é identificação, não conteúdo;
 * quem está doando não precisa ler o CNPJ, e quem precisa sabe onde procurar.
 */
.rodape {
  border-top: 1px solid var(--linha);
  background: var(--papel);
  color: var(--meta);
  font-size: 13.5px;
  line-height: 1.75;
  font-variant-numeric: tabular-nums;
}
.rodape .wrap {
  padding-top: 20px;
  padding-bottom: 28px;
}
.rodape p {
  margin: 0;
}
.rodape strong {
  color: var(--tinta);
  font-weight: 900;
}
/* "CNPJ" numa linha e o número na outra não se lê como um dado só. */
.cnpj {
  white-space: nowrap;
}

/*
 * Os contatos são links, e link precisa de 44px de alvo de toque (§9) mesmo
 * no texto miúdo do rodapé: numa linha corrida de 13.5px, e-mail, WhatsApp e
 * Instagram ficariam colados demais para o dedo.
 */
.contatos {
  list-style: none;
  margin: 4px 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  column-gap: 20px;
}
/*
 * O gap não é enfeite: dentro de flex, o espaço entre o rótulo e o número (um
 * nó de texto) é descartado, e sem gap sai "WhatsApp(11) 90000-0000" colado.
 * O HTML tem o espaço; é o layout que o come (visto na tela, não em teste).
 */
.contatos li {
  display: flex;
  align-items: center;
  gap: .3em;
  min-height: 44px;
}
.contatos a {
  display: inline-flex;
  align-items: center;
  gap: .3em;
  min-height: 44px;
  font-weight: 700;
}
.contato-rotulo {
  font-weight: 900;
}

/* Texto escrito por uma pessoa preserva a quebra de linha (§4.4): o registro
   em cartório vem em duas ou três linhas, e junto vira uma só ilegível. */
.texto-livre {
  white-space: pre-line;
}

/* ---------------------------------------------------------- acessibilidade */

/* §9: foco visível, nunca removido. O textarea entra na lista do padrão
   porque a tela do PIX tem um (o copia-e-cola). */
a:focus-visible, button:focus-visible, summary:focus-visible,
select:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--azul-cientec); outline-offset: 2px;
}

/*
 * hidden vence qualquer display de classe. A folha do navegador diz
 * [hidden] { display: none }, mas uma regra de autor ganha dela: o botão de
 * copiar é um .cta (inline-flex), chega do servidor com hidden, e sem esta
 * regra ele apareceria sem JS, um botão que não faz nada (§1.6). Os avisos do
 * botão dependem dela também.
 */
[hidden] { display: none !important; }

/* Texto só para leitor de tela: fora da vista, dentro da árvore de acessibilidade. */
.visualmente-oculto {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* §9: navegador sem <dialog> desenharia os filhos como texto solto. Rede de
   segurança da superfície inteira, e não regra de um componente: nenhuma tela
   usa <dialog> hoje (o fluxo de doação do M2 é feito de páginas). */
dialog:not([open]) { display: none; }

/* §9: movimento só com consentimento. O padrão é não animar. */
@media (prefers-reduced-motion: no-preference) {
  .cta,
  .campanha,
  .atalhos a,
  .paginacao-link,
  .link,
  .novas-link,
  .opcao-rotulo,
  .campo {
    transition: background-color .14s ease, border-color .14s ease, color .14s ease;
  }
}
