
/* ------------------------------------------------------------------ fontes */

/* Subconjunto "latin" apenas. Ver o cabecalho do arquivo: os outros oito
   arquivos do pacote cobrem vietnamita, cirilico e latin-ext, que este site
   nao escreve. */

@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 200 700;
  font-display: swap;
  src: url('/assets/fontes/Newsreader-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 700;
  font-stretch: 100%;
  font-display: swap;
  src: url('/assets/fontes/Archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fontes/IBM-Plex-Mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

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

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

:root {
  color-scheme: dark;

  /* --- a escala de vinho ------------------------------------------------ */
  /* O 500 e o token da marca (o mesmo de src/marca/index.ts). O 600 existe
     porque o 500 reprova em contraste como SUPERFICIE de botao; o 300 existe
     porque o 500 tambem reprova como TEXTO sobre o fundo escuro. Mesma matiz,
     tres degraus, cada um no seu lugar. */
  --vinho-300: oklch(0.76 0.11 25);
  --vinho-500: oklch(0.58 0.14 20);
  --vinho-600: oklch(0.50 0.15 22);
  --vinho-900: oklch(0.26 0.05 20);

  /* --- neutros quentes -------------------------------------------------- */
  /* Matiz 30–80, nunca cinza puro: a adega nao e um painel de administracao. */
  --papel: oklch(0.19 0.014 30);
  /* Chao mais fundo que --papel, so no app: o vidro precisa de algo escuro
     ATRAS para o desfoque ter o que desfocar. No site nao e usado.
     (Sem crase neste comentario: ele vive DENTRO de um template literal, e
     uma crase aqui encerra a string e derruba o arquivo inteiro.) */
  --papel-fundo: oklch(0.155 0.012 30);
  /* Palha: o segundo acento, para DADO (nota, safra, posição). Existe para o
     número não competir com o vinho, que é a cor de ação. */
  --palha: oklch(0.82 0.07 75);
  --palha-fundo: oklch(0.33 0.04 75);
  /* O alvo minimo de toque (Apple HIG). Estava escrito 44px a mao em cinco
     lugares; o app acrescentaria mais oito. Um numero, um nome. */
  --toque: 44px;
  --papel-alto: oklch(0.235 0.016 30);
  --tinta: oklch(0.95 0.012 80);
  --tinta-fraca: oklch(0.74 0.014 60);
  --tinta-fraquissima: oklch(0.60 0.014 50);
  --linha: oklch(0.30 0.016 30);
  --linha-forte: oklch(0.42 0.020 30);

  /* --- os nomes que as paginas ja usam ---------------------------------- */
  /* Estes quatro sao a interface publica do arquivo: as sete paginas que ja
     existem leem "--acento" e "--fundo-caixa", e nao podem saber que a escala
     acima passou a existir. */
  --acento: var(--vinho-600);
  --acento-texto: oklch(0.97 0.01 80);
  --fundo: var(--papel);
  --fundo-caixa: var(--papel-alto);

  /* Aviso. Deliberadamente NAO e da matiz da marca: e o unico lugar onde cor
     carrega informacao, e ela precisa continuar legivel se a identidade mudar. */
  --alerta-fundo: oklch(0.26 0.03 80);
  --alerta-linha: oklch(0.40 0.06 85);
  --alerta-tinta: oklch(0.85 0.09 85);

  --erro: oklch(0.72 0.16 25);

  --sucesso: oklch(0.75 0.11 150);

  /* --- tipografia ------------------------------------------------------- */
  --fonte-titulo: 'Newsreader', Georgia, 'Times New Roman', serif;
  --fonte-corpo: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --fonte-dado: 'IBM Plex Mono', ui-monospace, 'SFMono-Regular', Menlo, monospace;

  /* A escala inteira, e nao meia escala: ter --texto-miudo com nome e o h1 como
     numero solto seria a pior das tres opcoes, porque quem le nao sabe se o
     numero solto e desvio ou e o valor certo que ninguem nomeou.
     ⚠️ --texto-corpo, --texto-h1 e --texto-h2 SAO REDEFINIDOS nas media queries
     la embaixo. E de proposito: o token responde "qual o tamanho aqui", e a
     alternativa (regra sobrescrevendo regra) espalha a resposta em tres lugares. */
  /* ESCALA CONTINUA, e nao degraus — 2026-08-27.
     ---------------------------------------------------------------------------
     Ela terminava em 64em: acima de 1024px nada crescia, e no monitor externo do
     Brenno o texto ficava do tamanho de um notebook. A primeira correcao foi por
     media query, e ele pediu o certo em seguida: que o aumento seja PROPORCIONAL
     aos pixels, e nao um salto quando a janela cruza uma largura.

     A forma e a mesma de --goteira, logo abaixo: clamp(minimo, base + vw, teto).

     ⚠️ O MINIMO DE CADA UM E O VALOR QUE O CELULAR JA TINHA. Ele disse que no
     celular estava perfeito, entao a coluna estreita nao pode mudar um pixel — e
     nao muda: abaixo de ~768px todos os clamps estao presos no minimo.

     ⚠️ E a base fica em REM, nunca vw sozinho. Font-size so em vw ignora o zoom e
     a preferencia de fonte do navegador; com a parte em rem, as duas continuam
     valendo e o vw so acrescenta. */
  --texto-corpo: clamp(1.0625rem, 0.9375rem + 0.26vw, 1.25rem);
  --texto-chamada: clamp(1.1875rem, 1.021rem + 0.35vw, 1.4375rem);
  --texto-miudo: clamp(0.9375rem, 0.854rem + 0.17vw, 1.0625rem);
  --texto-h1: clamp(2.125rem, 1.708rem + 1.91vw, 4rem);
  --texto-h2: clamp(1.5rem, 1.417rem + 0.69vw, 2.25rem);
  --texto-h3: clamp(1.125rem, 1.042rem + 0.17vw, 1.25rem);
  --altura-corpo: 1.6;

  /* O rotulo tipografico (a "sobrancelha") e o dado: mono, caixa alta, espacado. */
  --rastro-sobrancelha: 0.14em;
  --rastro-dado: 0.06em;

  --raio: 10px;
  --raio-g: 16px;
  /* Os tres raios do app. O do vidro e o da barra sao maiores que os do site de
     proposito: superficie flutuante com raio de cartao parece cartao colado. */
  --raio-vidro: 1.375rem;
  --raio-barra: 1.625rem;
  --raio-pilula: 999px;
  /* ⚠️ A LARGURA CRESCE JUNTO com a letra: corpo maior em coluna fixa encurta a
     linha e faz o texto quebrar mais — o remedio viraria outro sintoma.
     --medida sobe pouco de proposito: ela e a MEDIDA DE LEITURA, e linha longa
     demais cansa. O limite confortavel nao muda porque o monitor e maior. */
  --medida: clamp(34rem, 32.67rem + 2.78vw, 36rem);   /* largura de leitura confortavel */
  --largura: clamp(60rem, 50.67rem + 19.44vw, 74rem); /* largura maxima do conteudo largo */
  --coluna-app: 27rem;    /* a coluna do app: o mockup tinha 390px fixos, aqui e limite */

  /* --- o vidro do app ---------------------------------------------------- */
  /* ⚠️ Os tres sao uma ESCADA de translucidez sobre branco (0.055 < 0.08 <
     0.09), e o nome diz o uso TIPICO, nao o unico: --vidro-linha tambem e o
     fundo da vaga do mapa, e --vidro-forte tambem e borda. Quem trocar um pelo
     outro procurando o nome certo vai mudar a cor sem querer. */
  --vidro-fundo: oklch(1 0 0 / 0.055);
  --vidro-linha: oklch(1 0 0 / 0.08);
  --vidro-forte: oklch(1 0 0 / 0.09);

  --sombra: 0 1px 2px oklch(0 0 0 / 0.30), 0 8px 24px oklch(0 0 0 / 0.22);
  --sombra-vidro: 0 8px 24px oklch(0.08 0.01 30 / 0.35), inset 0 1px 0 oklch(1 0 0 / 0.05);
  --sombra-barra: 0 14px 34px oklch(0.07 0.01 30 / 0.55);
  --sombra-acao: 0 8px 20px oklch(0.40 0.14 20 / 0.40);
  --desfoque-vidro: blur(18px);
  --desfoque-barra: blur(22px);

  /* Movimento: so transicao curta de cor. Nada de bounce, nada de entrada.

     ⚠️ `ease` em `--transicao` esta CERTO e nao e descuido: a regua da skill
     `animate` reserva a curva embutida exatamente para hover e mudanca de cor,
     que e o unico uso dele aqui. O que `ease` nao serve e para coisa ANDANDO na
     tela — deslocamento e rotacao —, e e por isso que existe a curva abaixo.

     --ease-in-out e o valor exato da skill (nao aproxime; a tabela dela recusa
     `cubic-bezier(0.4, 0, 0.2, 1)` justamente por ser o que "parece familiar").
     Ela mora aqui como TOKEN, e nao solta na regra, porque valor de movimento e
     do design system: entra no `estilo.ts` e volta para o `tonti-design`. */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --transicao: 120ms ease;
  --transicao-seta: 140ms var(--ease-in-out);

  /* --- o que so a marca desenha ------------------------------------------ */
  /* As duas luzes de fundo do app (vinho no alto a direita, palha embaixo a
     esquerda), o unico gradiente de superficie da UI, e a listra que diz
     "falta foto do rotulo". Sao da marca, e nao da escala: por isso o prefixo. */
  --tonti-luz-vinho: radial-gradient(circle, oklch(0.55 0.19 20 / 0.40) 0%, oklch(0.55 0.19 20 / 0) 66%);
  --tonti-luz-palha: radial-gradient(circle, oklch(0.68 0.11 70 / 0.18) 0%, oklch(0.68 0.11 70 / 0) 70%);
  --tonti-gradiente-foto: linear-gradient(160deg, oklch(0.58 0.17 22) 0%, oklch(0.42 0.14 20) 100%);
  --tonti-listra-selo: repeating-linear-gradient(135deg, oklch(0.30 0.02 28) 0 5px, oklch(0.25 0.016 28) 5px 10px);
}

html {
  /* Sem isto o iPhone infla o texto em paisagem. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--fundo);
  color: var(--tinta);
  font-family: var(--fonte-corpo);
  font-size: var(--texto-corpo);
  line-height: var(--altura-corpo);
  /* A rolagem e sempre vertical. Se algum dia aparecer horizontal, e defeito —
     e melhor cortar do que deixar a pagina "tremer" de lado no celular. */
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  /* Sem isto o navegador do celular SEGURA o toque esperando um segundo toque
     (o gesto de dar zoom), e todo botao do site responde com atraso visivel.
     O zoom por PINCA continua funcionando — o que sai e so o duplo-toque, que
     nao e como ninguem da zoom de proposito. */
  touch-action: manipulation;
  /* O padrao do Android e um retangulo cinza que pisca por cima do botao, com a
     forma da CAIXA e nao a do raio. Zerado aqui porque o estado de toque quem
     desenha e o :hover/:active da marca. */
  -webkit-tap-highlight-color: transparent;
}

/* Respeita quem desligou animacao no sistema. Duas linhas, e para algumas
   pessoas e a diferenca entre usar e passar mal. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}

/* ---------------------------------------------------------------- estrutura */

.pagina { max-width: var(--largura); margin: 0 auto; padding: 0 1.25rem; }
.prosa  { max-width: var(--medida); }

/* ---------------------------------------------------------------------------
   AS TRES PAGINAS DE DOCUMENTO — ajuda, termos e privacidade
   ---------------------------------------------------------------------------

   ⚠️ ELAS TINHAM TRES TRATAMENTOS DIFERENTES, e so aparecia olhando as fotos
   lado a lado (2026-08-22):

     /termos e /privacidade   <section> + .prosa  -> respiro no topo, medida de
                              34rem, e a coluna encostada na ESQUERDA de um
                              container de 60rem centrado. Em 1440px isso le como
                              pagina inacabada.
     /ajuda                   .pagina estreita    -> SEM <section>, entao sem
                              respiro nenhum: o titulo encostava no cabecalho. E
                              a classe estreita nao existe nesta folha — ela e
                              fantasma: sem regra, sem efeito. Por isso a ajuda
                              saia com 60rem e sem medida de leitura.

   As tres passaram a section.documento, e a medida vai ao CENTRO. A
   medida de leitura FICA: linha longa demais cansa, e estes sao os textos mais
   longos do site. O que muda e onde a coluna se apoia. */
.documento .prosa { margin-inline: auto; }

.topo {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: 1.25rem 0; border-bottom: 1px solid var(--linha);
}

/* O lugar do logo. Deixou de ser "vazio de propriedade" em 2026-08-05. */
/* ⚠️ MAIOR desde 2026-08-21, a pedido do Brenho: "aumente a logo e o nome
   Tonti". Era 1,25rem com imagem de 32x24; foi para 1,6rem com 44x33.

   A proporcao da imagem NAO mudou (4:3 nos dois), e isso importa: o SVG da
   marca tem traco fino, e esticar so um dos lados o deformaria de um jeito que
   a tela mostra e o codigo nao acusa. */
.marca {
  display: inline-flex; align-items: center; gap: 0.75rem;
  font-family: var(--fonte-titulo);
  /* Continua, como a escala do texto. Ver o :root. */
  font-weight: 600; font-size: clamp(1.6rem, 1.3rem + 0.625vw, 2.05rem); letter-spacing: -0.01em;
  color: var(--tinta); text-decoration: none;
}
.marca img {
  /* Altura e largura no CSS **e** no HTML: sem as duas o cabecalho pula quando
     a imagem chega, e o pulo acontece justamente na primeira visita.

     O border-radius de 7px que ficava aqui saiu em 2026-08-05 junto com o PNG:
     ele arredondava o quadrado do icone. O vetor nao tem quadrado, e uma imagem
     de fundo transparente com canto arredondado corta o proprio traco.
     (Sem crase neste comentario: ele vive DENTRO de um template literal.) */
  width: 44px; height: 33px; display: block;
}
.marca span { color: var(--tinta-fraquissima); font-weight: 400; font-size: var(--texto-miudo); font-family: var(--fonte-corpo); }

.rodape {
  margin-top: 4rem; padding: 2rem 0 3rem;
  border-top: 1px solid var(--linha);
  color: var(--tinta-fraca); font-size: var(--texto-miudo);
}
.rodape a { color: var(--tinta-fraca); }
.rodape ul { list-style: none; margin: 0 0 1rem; padding: 0; display: flex; flex-wrap: wrap; gap: 0.5rem 1.25rem; }

section { padding: 2.5rem 0; }
section + section { border-top: 1px solid var(--linha); }

h1, h2, h3 {
  font-family: var(--fonte-titulo);
  font-weight: 500;
  /* Titulo de duas linhas quebrando com uma palavra sozinha embaixo e o defeito
     tipografico mais visivel que existe, e some com uma declaracao. */
  text-wrap: balance;
}
h1 { font-size: var(--texto-h1); line-height: 1.12; letter-spacing: -0.02em; margin: 0 0 0.75rem; }
h2 { font-size: var(--texto-h2); line-height: 1.25; letter-spacing: -0.01em; margin: 0 0 0.75rem; }
h3 { font-size: var(--texto-h3); line-height: 1.3; margin: 0 0 0.375rem; font-weight: 600; }
p  { margin: 0 0 1rem; }
p:last-child { margin-bottom: 0; }

.chamada { font-size: var(--texto-chamada); line-height: 1.55; color: var(--tinta-fraca); text-wrap: pretty; }
.miudo   { font-size: var(--texto-miudo); color: var(--tinta-fraca); }
.fraco   { color: var(--tinta-fraca); }

a { color: var(--vinho-300); text-decoration: underline; text-underline-offset: 0.15em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

/* Foco visivel em tudo. Quem navega por teclado precisa saber onde esta, e o
   contorno padrao do navegador desaparece em cima do nosso fundo.
   ⚠️ O contorno usa o vinho CLARO, nao o "--acento": o acento e escuro e sumiria
   contra o fundo escuro — que e exatamente o caso que este seletor existe para
   evitar. */
:focus-visible { outline: 2px solid var(--vinho-300); outline-offset: 2px; border-radius: 4px; }

/* -------------------------------------------------------------------- botao */

.botao {
  display: inline-flex; align-items: center; justify-content: center;
  /* O alvo de toque. Nao e estetica: e o minimo para o dedo acertar. O valor
     mora no token --toque, uma vez so — ver o :root. */
  min-height: var(--toque);
  padding: 0.6875rem 1.375rem;
  border: 1px solid var(--acento); border-radius: var(--raio);
  background: var(--acento); color: var(--acento-texto);
  font-family: var(--fonte-corpo); font-weight: 600; font-size: clamp(1rem, 0.917rem + 0.17vw, 1.125rem);
  letter-spacing: 0.005em;
  text-decoration: none; cursor: pointer;
  transition: background-color var(--transicao), border-color var(--transicao);
  /* Sem isto, um botao com texto longo estoura a largura no celular. */
  max-width: 100%; text-align: center;
}
.botao:hover { background: var(--vinho-500); border-color: var(--vinho-500); }
.botao[disabled], .botao[aria-disabled="true"] { opacity: 0.4; cursor: not-allowed; }
.botao[disabled]:hover, .botao[aria-disabled="true"]:hover { background: var(--acento); border-color: var(--acento); }

.botao-fantasma { background: transparent; color: var(--tinta); border-color: var(--linha-forte); }
.botao-fantasma:hover { background: var(--papel-alto); border-color: var(--tinta-fraquissima); }

.botao-largo { width: 100%; }

/* -------------------------------------------------------------------- caixa */

.caixa {
  border: 1px solid var(--linha); border-radius: var(--raio-g);
  padding: 1.375rem; background: var(--fundo-caixa);
  /* Filho de grid sem isto nao encolhe: e a causa numero um de rolagem
     horizontal no celular. */
  min-width: 0;
}

.aviso {
  border: 1px solid var(--alerta-linha); background: var(--alerta-fundo);
  color: var(--alerta-tinta); border-radius: var(--raio);
  padding: 1rem 1.125rem; margin: 0 0 1.5rem; font-size: var(--texto-miudo);
}
/* FILHO DIRETO, e o seletor mais importante deste arquivo depois do font-size dos
   campos. A versao anterior era ".aviso strong", que pega TODO strong de dentro do
   aviso — inclusive um "<strong>atendimento</strong>" no meio de uma frase. O
   resultado era a palavra virando linha propria e a frase continuando com ":"
   orfao comecando a linha seguinte. Nao aparece em teste nenhum; aparece na foto. */
.aviso > strong { display: block; margin-bottom: 0.25rem; }
.aviso p:last-child { margin-bottom: 0; }
.aviso a { color: var(--alerta-tinta); }

/* --------------------------------------------------------------------- grid */

.grade { display: grid; gap: 1rem; }

/* Empilha no celular, lado a lado quando couber. "auto-fit" com "minmax" faz
   isso sem media query e sem numero magico de breakpoint — o layout responde a
   largura disponivel, nao a um modelo de aparelho. */
.grade-2 { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.grade-3 { grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
.grade > * { min-width: 0; }

/* -------------------------------------------------------------------- planos */

.plano { display: flex; flex-direction: column; gap: 0.875rem; }
.plano h3 { margin: 0; }
/* Preco na familia de dado, com algarismo de largura fixa: numero de dinheiro
   em coluna que "dança" entre um plano e outro le como erro de alinhamento. */
.plano .preco {
  font-family: var(--fonte-dado); font-variant-numeric: tabular-nums;
  font-size: 1.75rem; font-weight: 400; letter-spacing: -0.03em; line-height: 1.1;
  color: var(--tinta);
}
.plano .preco small { display: block; margin-top: 0.25rem; font-family: var(--fonte-corpo); font-size: 0.875rem; font-weight: 400; color: var(--tinta-fraca); letter-spacing: 0; }
.plano .preco-a-definir { font-family: var(--fonte-corpo); font-size: var(--texto-h3); font-weight: 600; color: var(--alerta-tinta); letter-spacing: 0; }
.plano ul { margin: 0; padding-left: 1.125rem; font-size: var(--texto-miudo); color: var(--tinta-fraca); }
.plano li { margin-bottom: 0.375rem; }
.plano li::marker { color: var(--vinho-500); }
.plano .botao { margin-top: auto; }

/* ------------------------------------------------------------------- passos */

.passos { list-style: none; counter-reset: p; margin: 0; padding: 0; display: grid; gap: 1.125rem; }
.passos li { counter-increment: p; display: grid; grid-template-columns: 1.75rem 1fr; gap: 0.875rem; align-items: start; }
.passos li::before {
  content: counter(p);
  width: 1.75rem; height: 1.75rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--acento); color: var(--acento-texto);
  font-family: var(--fonte-dado); font-size: 0.8125rem; font-weight: 400;
}
.passos strong { display: block; }
.passos p { margin: 0.125rem 0 0; color: var(--tinta-fraca); font-size: var(--texto-miudo); }

/* ---------------------------------------------------------------- formulario */

/* A margem de cima nao e enfeite. O paragrafo acima do formulario e o ultimo filho
   do bloco de texto, e ".prosa p:last-child { margin-bottom: 0 }" apaga a margem
   dele — o primeiro rotulo do formulario encostava na linha de cima. Visivel na
   foto de celular, invisivel em qualquer teste. */
form { max-width: var(--medida); margin-top: 1.75rem; }
.campo { margin-bottom: 1.25rem; }
.campo > label { display: block; font-weight: 600; font-size: var(--texto-miudo); margin-bottom: 0.375rem; }
.campo .ajuda { display: block; color: var(--tinta-fraca); font-size: 0.875rem; margin-bottom: 0.375rem; }

input[type="text"], input[type="email"], input[type="tel"], select {
  width: 100%;
  min-height: var(--toque);
  padding: 0.625rem 0.75rem;
  border: 1px solid var(--linha-forte); border-radius: var(--raio);
  background: var(--papel-alto); color: var(--tinta);
  font-family: inherit;
  /* 16px E O MINIMO. Abaixo disso o Safari do iPhone da zoom na pagina ao focar
     o campo e nao volta mais — o cadastro fica cortado pela metade. */
  font-size: max(1rem, 16px);
  line-height: 1.4;
}
input::placeholder { color: var(--tinta-fraquissima); }
input:focus { border-color: var(--vinho-300); }
input[aria-invalid="true"] { border-color: var(--erro); border-width: 2px; }

/* Data de nascimento em tres campos.
   O ano recebe o dobro da largura: com todos iguais, "1985" fica apertado e a
   pessoa acha que nao cabe. Em "fr" e nao em px, porque em 320px o conjunto
   ainda precisa caber com folga.

   ⚠️ A classe do ano era usada no HTML e NUNCA existiu neste arquivo — classe
   morta desde sempre. O ano so ficava largo porque era o TERCEIRO filho e o
   grid dava "2fr" a terceira coluna: o layout dependia da ordem da marcacao.
   Quatro colunas iguais com o ano ocupando duas da o mesmo resultado
   (25/25/50) e para de estreitar o ano em silencio se alguem reordenar. */
fieldset.data { border: 0; margin: 0; padding: 0; min-width: 0; }
fieldset.data legend { padding: 0; font-weight: 600; font-size: var(--texto-miudo); margin-bottom: 0.375rem; }
.data-campos { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.625rem; }
.data-campos > span { min-width: 0; }
.data-campos .data-ano { grid-column: span 2; }
.data-campos label { display: block; font-weight: 400; font-size: 0.8125rem; color: var(--tinta-fraca); margin-bottom: 0.25rem; }

/* Campo numerico em fonte de dado: dia, mes e ano sao numeros, e a largura fixa
   do algarismo evita o campo "respirar" enquanto se digita. */
.data-campos input { font-family: var(--fonte-dado); font-variant-numeric: tabular-nums; }

/* Caixa de marcar: o alvo e o TEXTO junto, nao so o quadradinho de 13px. */
.marcar { display: grid; grid-template-columns: 1.5rem 1fr; gap: 0.75rem; align-items: start; min-height: var(--toque); padding: 0.375rem 0; cursor: pointer; }
.marcar input[type="checkbox"] { width: 1.375rem; height: 1.375rem; margin: 0.125rem 0 0; accent-color: var(--vinho-500); }
.marcar span { font-size: var(--texto-miudo); line-height: 1.5; }

.erro { color: var(--erro); font-size: 0.875rem; margin: 0.375rem 0 0; font-weight: 500; }

.resumo-erros { border: 2px solid var(--erro); border-radius: var(--raio); padding: 1rem 1.125rem; margin-bottom: 1.5rem; background: oklch(0.24 0.04 25); }
.resumo-erros h2 { color: var(--erro); font-size: 1rem; margin-bottom: 0.5rem; font-family: var(--fonte-corpo); font-weight: 600; }
.resumo-erros ul { margin: 0; padding-left: 1.25rem; font-size: var(--texto-miudo); }
.resumo-erros a { color: var(--erro); }

/* ------------------------------------------------------------------ recibo */

.recibo { display: grid; gap: 0.625rem; margin: 0; }
.recibo div { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; border-bottom: 1px solid var(--linha); padding-bottom: 0.5rem; }
.recibo dt { color: var(--tinta-fraca); font-size: var(--texto-miudo); }
.recibo dd { margin: 0; font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }

/* ----------------------------------------------------------------- perguntas */

details { border-bottom: 1px solid var(--linha); padding: 0.875rem 0; }
details summary {
  cursor: pointer; font-weight: 600; min-height: var(--toque);
  display: flex; align-items: center; gap: 0.5rem;
  position: relative; padding-right: 2rem;
}
details p { margin: 0.625rem 0 0; color: var(--tinta-fraca); }

/* ⚠️ AS PERGUNTAS NAO PARECIAM CLICAVEIS, E O DEFEITO ERA UMA LINHA DE CSS.
   "display: flex" no <summary> apaga o ::marker em Chrome e Safari. O triangulo
   sumia, e as seis perguntas do fim da pagina viravam titulos em negrito sem
   nada indicando que abrem. Nenhum teste pega: o HTML esta correto, o
   comportamento funciona, so nao ha convite para clicar.

   A seta e desenhada aqui em vez de devolvida ao ::marker porque marker nao
   aceita rotacao — e girar ao abrir e o que diz que a coisa e um acordeao. */
details summary::-webkit-details-marker { display: none; }
details summary::after {
  content: ""; position: absolute; right: 0.375rem; top: 50%;
  width: 0.5rem; height: 0.5rem;
  border-right: 2px solid var(--vinho-300); border-bottom: 2px solid var(--vinho-300);
  transform: translateY(-70%) rotate(45deg);
  transition: transform var(--transicao-seta);
}
details[open] summary::after { transform: translateY(-25%) rotate(-135deg); }

/* --------------------------------------------------------------------- capa */

/* Daqui para baixo e o que a landing usa e mais nenhuma pagina — a abertura do
   design entregue. Fica separado de proposito: se um dia a capa mudar, nada
   aqui embaixo e lido pelas outras sete paginas. */

/* Rotulo curto acima do titulo. Em fonte de dado e caixa alta porque ele nao e
   frase — e etiqueta, e precisa ler como etiqueta sem virar titulo menor. */
.sobrancelha {
  font-family: var(--fonte-dado); font-size: 0.75rem;
  text-transform: uppercase; letter-spacing: var(--rastro-sobrancelha);
  color: var(--vinho-300); margin: 0 0 1rem;
  display: flex; align-items: center; gap: 0.625rem;
}
.sobrancelha::before { content: ""; width: 1.75rem; height: 1px; background: var(--vinho-500); flex: none; }

.capa { padding: 3rem 0 3.5rem; }
.capa h1 { font-size: clamp(2.375rem, 7vw, 3.75rem); letter-spacing: -0.03em; line-height: 1.05; }
.capa .chamada { font-size: 1.25rem; max-width: 32rem; }
.acoes { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }
/* ⚠️ A grade e uma classe PROPRIA e nao ".capa .pagina". O conteudo ja nasce
   dentro de <main class="pagina">, entao um seletor pedindo ".pagina" DENTRO da
   capa nunca casaria — a capa vira duas colunas em lugar nenhum e o sintoma e
   "no desktop ficou tudo empilhado". */
.capa-grade { display: grid; gap: 2.5rem; }

/* A conversa de exemplo. E a coisa mais honesta que a capa pode mostrar: o
   produto E uma conversa de WhatsApp, entao a capa mostra uma. */
.conversa {
  display: grid; gap: 0.625rem; margin: 0;
  padding: 1.25rem; border: 1px solid var(--linha); border-radius: var(--raio-g);
  background: var(--papel-alto); box-shadow: var(--sombra);
}
.bolha {
  /* ⚠️ 'min-width: 0' porque o item de grid tem 'min-width: auto' por padrao, e
     'auto' e o tamanho MINIMO DO CONTEUDO — uma foto de 680px levanta a coluna
     inteira com ela. Ver '.foto-anexo'. */
  min-width: 0;
  margin: 0; padding: 0.6875rem 0.9375rem;
  border-radius: var(--raio-g) var(--raio-g) var(--raio-g) 4px;
  background: var(--papel); border: 1px solid var(--linha);
  font-size: var(--texto-miudo); line-height: 1.5;
  max-width: 88%; justify-self: start;
}
.bolha-cliente {
  border-radius: var(--raio-g) var(--raio-g) 4px var(--raio-g);
  background: var(--vinho-900); border-color: var(--vinho-600);
  justify-self: end;
}

/* O ANEXO DE FOTO, nas duas conversas de exemplo.

   🔴 A JUSTIFICATIVA DE UM BLOCO INTEIRO ESTAVA VENCIDA — corrigido em 05/09/2026.

   Havia aqui uma etiqueta de TEXTO ("FOTO DA GONDOLA") no lugar da imagem, e o
   motivo escrito era: "o CSP e default-src none e nao ha de onde carregar
   imagem". Isso foi verdade e deixou de ser — "img-src self data:" esta na BASE
   da politica desde que as fontes e o logo passaram a ser servidos. A restricao
   real nunca foi a CSP: e a lista FECHADA de ARQUIVOS em rotas.ts, e nela se
   acrescenta um arquivo.

   ⚠️ Fica escrito porque o comentario me convenceu por meio dia. Motivo tecnico
   que envelhece continua parecendo motivo tecnico, e ninguem reconfere o que ja
   esta explicado.

   ⚠️ E a etiqueta saiu de vez, a pedido. Quem ouve a pagina nao perde nada: o
   "alt" da imagem diz o que ela mostra, e e o lugar certo para essa frase. */
.foto-anexo {
  display: block; width: 100%;
  /* ⚠️ 'max-width' JUNTO do 'width', e nao redundante: '.conversa' e um grid, e
     um item de grid e dimensionado pelo CONTEUDO. Sem isto a coluna inteira
     cresce ate a largura intrinseca da foto (680px) e o bloco estoura a borda no
     iPad — medido por 'fotografar-site', que acusou 'img.foto-anexo ate 1144px'. */
  max-width: 100%;
  /* 🔴 'height: auto' NAO E REDUNDANTE, e custou uma volta em 05/09/2026.
     Os atributos width/height do <img> entram como DICA DE APRESENTACAO e viram
     'height: 1004px' na folha do navegador. O 'width: 100%' de autor ganha do
     lado da largura, mas sem declarar a altura a dica sobrevive — e a foto saiu
     com mil pixels de altura, dominando a bolha. Os atributos ficam (eles evitam
     o pulo do layout enquanto a imagem carrega); quem manda na altura e o
     'aspect-ratio'. */
  height: auto;
  /* ⚠️ RETRATO, e nao 4:3: e uma foto de celular numa conversa. Recorte deitado
     numa foto tirada em pe joga fora justamente o que ela mostra — a estante
     subindo, a pagina inteira da carta. */
  aspect-ratio: 4 / 5; object-fit: cover;
  border-radius: calc(var(--raio-g) - 6px);
  border: 1px solid var(--linha);
}
.bolha-cliente .foto-anexo { border-color: var(--vinho-600); }
/* ---------------------------------------------------------------------------
   A BOLHA DA FICHA TECNICA — entrou em 05/09/2026
   ---------------------------------------------------------------------------

   ⚠️ Ela e MUITO mais alta que as outras: a ficha real que o Brenno mandou tem
   quinze campos, e truncar tiraria justamente o que a diferencia (o «Por que» e
   o «Voce provavelmente da», que sao as duas ultimas linhas).

   Entao ela ganha tres coisas que as bolhas de conversa nao tem:

   🔴 max-width MAIOR (98% contra 88%). Com 88% a ficha quebrava quase toda
   linha em duas, e uma lista de campos com quebra no meio de cada valor deixa
   de ler como ficha e passa a ler como paragrafo.

   ⚠️ Entrelinha MENOR (1.35 contra 1.5). Numa lista de rotulo+valor a entrelinha
   de paragrafo separa demais, e os campos param de parecer um conjunto.

   ⚠️ E font-variant-numeric: tabular-nums, porque metade dos valores e numero
   (12 a 12,5%, 13 a 15 graus, 8,5 a 9,5) e digito que «dança» numa coluna e o
   defeito que a fonte de dado ja resolve em todo o resto do sistema. */
.bolha-ficha {
  max-width: 98%;
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}

/* O selo do veredito («✅ ALINHADO»), na cor de quem aprova.

   ⚠️ Ele nao e um emoji solto: o emoji vem do texto e o selo e a moldura, para
   o veredito ler como CARIMBO e nao como enfeite de frase. */
.selo-ficha {
  display: inline-block;
  margin-top: 0.25rem;
  padding: 0.125rem 0.5rem;
  border: 1px solid var(--vinho-600);
  border-radius: 999px;
  font: 600 0.6875rem/1.4 var(--fonte-dado);
  letter-spacing: 0.08em;
  color: var(--vinho-300);
}


/* ---------------------------------------------------------------------------
   A CHEGADA DAS BOLHAS — a unica animacao de entrada do sistema (ADR-0030)
   ---------------------------------------------------------------------------

   O desenho original da capa pedia entrada por rolagem e ela foi RECUSADA em
   21/08 por um motivo tecnico correto na epoca: era IntersectionObserver, e
   IntersectionObserver e script. A CSP e default-src 'none' e nao ha uma tag
   <script> no site (ver o cabecalho de servidor.ts).

   🔴 O QUE MUDOU: `animation-timeline` faz animacao disparada por ROLAGEM em CSS
   puro — sem observador, sem script, sem encostar na CSP. A recusa de agosto nao
   valia mais, e o Brenno destravou a excecao em 25/08.

   POR QUE AQUI, E SO AQUI. O produto E uma conversa. Um transcrito parado le
   como captura de tela; bolha chegando em sequencia le como alguem respondendo.
   Na regua da skill `animate` o proposito tem nome — *explanation* — e a
   frequencia permite: a capa e vista uma vez por visitante. Nenhuma outra peca
   do site tem esse argumento, e a secao Movimento do `tonti-design` lista as
   cinco condicoes que esta regra cumpre e a proxima teria de cumprir.

   ⚠️ SO `translateY`, NUNCA OPACIDADE. E a regra do proprio desenho original:
   *"conteudo jamais fica invisivel"*. Com opacidade, um navegador sem suporte —
   ou um `@supports` que falhe — deixaria o texto SUMIDO. Movendo so o eixo Y, o
   pior caso e o texto no lugar, parado, que e a aparencia de antes de hoje.

   ⚠️ A LINHA DO TEMPO E DO CONTEINER, e nao de cada bolha. Com `view()` em cada
   uma, o escalonamento viria da geometria — e num monitor alto as quatro entram
   juntas, sem sequencia nenhuma. Uma linha do tempo so, com faixas
   deslocadas por bolha, garante a ordem em qualquer altura de tela. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* A CHEGADA POR ROLAGEM — v3, 05/09/2026.
       ---------------------------------------------------------------------

       🔴 A TERCEIRA VERSAO EM UM DIA, E CADA TROCA FOI DELE OLHANDO.

       v1 (25/08) rolagem, so translateY. v2 (05/09) TEMPO com opacidade, a
       pedido: "as mensagens aparecendo iguais as mensagens de whatsapp". v3
       volta para rolagem, tambem a pedido: "quero que o efeito da conversa do
       WhatsApp seja por scroll e nao tempo".

       ⚠️ E ELA NAO E A v1 DE VOLTA. O que a v2 acrescentou fica: as bolhas
       APARECEM (opacidade), e nao apenas deslizam. O pedido de aparecer nunca
       foi revogado — o que mudou foi o GATILHO. Juntas, as duas versoes viram o
       que cada uma tinha de certo: a mensagem surge, e surge quando a pessoa
       chega nela.

       🔴 POR QUE ROLAGEM E MELHOR AQUI, e vale escrito porque eu defendi o
       contrario de manha: por tempo, a sequencia comeca no "load" e termina em
       ~4s. Quem rola ate a conversa depois disso encontra tudo ja parado, e o
       efeito simplesmente nao existe para essa pessoa — que e a maioria, porque
       a conversa esta a mil pixels do topo. Por rolagem, ela acontece QUANDO a
       pessoa chega, sempre.

       ---------------------------------------------------------------------
       ⚠️ A OPACIDADE CONTINUA SO DENTRO DO @keyframes
       ---------------------------------------------------------------------

       A garantia de 25/08 ("conteudo jamais fica invisivel") vale igual: o zero
       mora no @keyframes e nunca na regra base. Sem suporte a "animation-timeline"
       o @supports nao casa, animacao nenhuma se aplica, e a conversa aparece
       inteira e parada — que e a aparencia de antes de tudo isto.

       ---------------------------------------------------------------------
       🔴 SEIS FAIXAS, E A v1 SO TINHA QUATRO
       ---------------------------------------------------------------------

       A primeira conversa tem SEIS bolhas desde que a ficha tecnica entrou, e a
       v1 declarava faixa para quatro. As duas ultimas caiam na faixa PADRAO
       ("cover 0% cover 100%"), ou seja, atravessavam a rolagem inteira em vez de
       chegarem na vez delas — defeito silencioso, porque tudo continuava
       aparecendo, so que no ritmo errado.

       ⚠️ A LINHA DO TEMPO E DO CONTEINER, e nao de cada bolha. Com "view()" em
       cada uma, o escalonamento viria da geometria, e num monitor alto as seis
       entrariam juntas. Uma linha do tempo so, com faixas deslocadas, garante a
       ordem em qualquer altura de tela. */
    .conversa { view-timeline-name: --entrada-da-conversa; view-timeline-axis: block; }
    /* ⚠️ LONGHANDS, e nao o atalho "animation". O atalho REDEFINE a duracao para
       "0s", e numa linha do tempo de rolagem a duracao tem de ser "auto" — quem
       manda no progresso e a faixa, nao o relogio. Com "0s" a animacao termina
       antes de comecar e a bolha nunca se move: o efeito nao aparece, sem erro
       nenhum no console. */
    .conversa dd,
    .conversa dt {
      animation-name: chegada-da-bolha;
      animation-duration: auto;
      animation-timing-function: ease-out;
      animation-fill-mode: both;
      animation-timeline: --entrada-da-conversa;
    }
    /* O passo de 6% e o escalonamento: curto o bastante para nao virar espera,
       longo o bastante para a ordem ser legivel. E o nome de quem falou anda
       junto da bolha dele, senao ele aparece antes da mensagem. */
    .conversa dd:nth-of-type(1), .conversa dt:nth-of-type(1) { animation-range: cover 20% cover 28%; }
    .conversa dd:nth-of-type(2), .conversa dt:nth-of-type(2) { animation-range: cover 26% cover 34%; }
    .conversa dd:nth-of-type(3), .conversa dt:nth-of-type(3) { animation-range: cover 32% cover 40%; }
    .conversa dd:nth-of-type(4), .conversa dt:nth-of-type(4) { animation-range: cover 38% cover 46%; }
    .conversa dd:nth-of-type(5), .conversa dt:nth-of-type(5) { animation-range: cover 44% cover 52%; }
    .conversa dd:nth-of-type(6), .conversa dt:nth-of-type(6) { animation-range: cover 50% cover 58%; }

    /* ------------------------------------------------------------------
       CADA CONVERSA TEM A SUA ROLAGEM — v4, 05/09/2026
       ------------------------------------------------------------------

       Pedido dele: "cada conversa deve ter a animacao separada de acordo com o
       scroll da pagina".

       🔴 DUAS COISAS ERAM VERDADE AO MESMO TEMPO, e so uma delas era defeito.

       O GATILHO ja era separado: "view-timeline-name" cria uma linha do tempo no
       proprio elemento, e cada bolha procura a mais PROXIMA subindo pelos
       ancestrais — ou seja, as bolhas da segunda conversa ja liam a rolagem da
       segunda. Isso nao precisava de conserto.

       ⚠️ O QUE ESTAVA ERRADO ERAM AS FAIXAS. Elas foram calibradas na primeira
       conversa, que tem SEIS bolhas e e alta (a ficha tecnica sozinha ocupa meia
       tela). A segunda tem TRES e e curta: com o mesmo passo de 6%, as tres
       chegavam entre 20% e 40% do percurso dela — e num elemento curto esse
       trecho passa quase de uma vez, entao as tres apareciam praticamente
       juntas. O efeito existia e nao se via.

       🔴 E O NOME PROPRIO E DELIBERADO, mesmo sem ser exigido. Duas conversas
       declarando "--entrada-da-conversa" funciona hoje porque a busca e pelo
       ancestral mais proximo; um nome por conversa tira a pergunta da mesa e faz
       a separacao ficar ESCRITA em vez de deduzida.

       ⚠️ Passo de 15% aqui contra 6% la, e a diferenca e a altura do elemento:
       numa conversa curta, uma faixa estreita e um piscar. */
    .faixa-conversa-espelhada .conversa {
      view-timeline-name: --entrada-da-segunda;
    }
    .faixa-conversa-espelhada .conversa dd,
    .faixa-conversa-espelhada .conversa dt {
      animation-timeline: --entrada-da-segunda;
    }
    .faixa-conversa-espelhada .conversa dd:nth-of-type(1),
    .faixa-conversa-espelhada .conversa dt:nth-of-type(1) { animation-range: cover 15% cover 33%; }
    .faixa-conversa-espelhada .conversa dd:nth-of-type(2),
    .faixa-conversa-espelhada .conversa dt:nth-of-type(2) { animation-range: cover 30% cover 48%; }
    .faixa-conversa-espelhada .conversa dd:nth-of-type(3),
    .faixa-conversa-espelhada .conversa dt:nth-of-type(3) { animation-range: cover 45% cover 63%; }
  }
}
@keyframes chegada-da-bolha {
  /* ⚠️ 12px, e o numero tem historia: 8px na v1 sumiam diluidos na rolagem, 14px
     era o ajuste para isso, e 10px foi o da versao por TEMPO (onde o movimento
     acontece em 420ms de relogio e 14 viravam salto). De volta a rolagem, 12 e o
     meio termo — visivel sem virar chamariz. */
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}
/* Quem falou vai no HTML com a classe ".so-leitor": a bolha se distingue por
   cor e por lado, e nenhuma das duas coisas existe para quem ouve a pagina.
   Nao usar "font-size: 0" para esconder — em alguns leitores o texto some junto,
   que e o oposto do que se quer aqui. */

/* ------------------------------------------------------- telas maiores */

/* 48rem ~ 768px: e onde o iPad em retrato comeca. Daqui para cima ha espaco
   para o texto respirar; abaixo, cada pixel de largura conta. */
@media (min-width: 48em) {
  /* ⚠️ A ESCALA SAIU DAQUI — 2026-08-27. Estes tres tokens eram redefinidos aqui
     e na de 64em; agora eles sao continuos no :root, e redefini-los voltaria a
     criar o degrau que a mudanca existe para tirar. O que fica nestas media
     queries e LAYOUT (respiro, colunas), que muda de forma e nao de tamanho. */
  section { padding: 3.25rem 0; }
  .pagina { padding: 0 2rem; }
  .capa { padding: 4.5rem 0 4rem; }
}

@media (min-width: 64em) {
  section { padding: 4rem 0; }
  /* A capa vira duas colunas: o argumento a esquerda, a conversa a direita.
     ⚠️ A coluna da esquerda leva 1.25fr, e nao metade. Com as colunas quase
     iguais o titulo quebrava em CINCO linhas — 3,75rem de serifada num espaco de
     30rem. Titulo de capa em cinco linhas nao le como titulo, le como paragrafo
     grande. O teto do tamanho tambem cai aqui: o clamp de 7vw serve para a
     coluna unica do celular, nao para meia largura de desktop. */
  .capa-grade { grid-template-columns: 1.25fr 0.95fr; gap: 3.5rem; align-items: center; }
}



/* ------------------------------------------------- a capa editorial (home) */

/*
   O desenho "Site do Tino v2" (claude.ai/design, projeto Site Wine, 2026-08-21).
   Capa de viewport inteiro, divisorias TRACEJADAS em vez de caixas, e a conversa
   promovida a peca central em vez de ilustracao ao lado do titulo.

   ⚠️ TRES COISAS DO DESENHO NAO VIERAM, E CADA UMA TEM MOTIVO:

   1. O fundo animado em WebGL. O desenho traz um <canvas> com shader de liquido
      que reage ao ponteiro. Aqui o CSP e "default-src 'none'" e NAO existe uma
      tag <script> no site inteiro (ver o cabecalho de servidor.ts). O proprio
      desenho ja declara o que fazer sem WebGL — um radial-gradient — e e ele que
      esta abaixo, escrito em TOKEN e nao nos tres hex crus do arquivo original.
   2. A entrada por rolagem (IntersectionObserver). Tambem e script. Nao custa
      nada: o desenho move so translateY e nunca opacidade, "conteudo jamais fica
      invisivel" nas palavras dele. Sem o script, o estado final e o estado.
   3. O "Entrar" no cabecalho. Nao ha login neste produto — e o proprio texto do
      desenho diz "sem senha, sem login", tres secoes abaixo do proprio botao.

   O resto do desenho e inteiro, e sem inventar token: todas as cores, fontes,
   raios e sombras daqui ja existiam no :root acima.
*/

/* A goteira lateral. Um valor, tres dezenas de usos — no desenho ele estava
   escrito a mao em cada secao, e uma capa com margem diferente por secao le
   como pagina desalinhada. */
:root { --goteira: clamp(1.25rem, 4.5vw, 4rem); }

/* O <main> da home nao tem largura maxima: quem limita e cada faixa. */
main.cheia { max-width: none; margin: 0; padding: 0; }

/* O fundo. Mesma posicao, mesmo inset e mesmo z-index do <canvas> do desenho —
   negativo pinta ACIMA do fundo do body e ABAIXO do conteudo, que e exatamente
   onde o canvas ficava. */
.fundo-liquido {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  /* ⚠️ LARGURA E ALTURA EXPLICITAS, E NAO SO O inset: 0.
     <canvas> e elemento SUBSTITUIDO: com largura automatica ele cai no tamanho
     intrinseco (300x150) em vez de esticar pelo inset, como faria uma <div>.
     O sintoma foi um selo de 300x150 no canto superior esquerdo com o fundo
     dentro dele, e o resto da tela na cor lisa do body — sem erro nenhum.
     Medido: a area limpa do heroi dava #1A1210 (o --fundo) e ZERO variacao
     entre pixels vizinhos, quando o shader poe ruido em todos.
     Usa 100% e nao 100vw: para elemento fixo o bloco recipiente e a area
     visivel SEM a barra de rolagem, e 100vw a inclui — o que poria o canvas
     alguns pixels alem da borda e faria a trava de transbordo acusar. */
  display: block; width: 100%; height: 100%;
  background:
    radial-gradient(120% 90% at 70% 10%,
      var(--vinho-900) 0%,
      color-mix(in oklab, var(--vinho-900) 45%, var(--papel-fundo)) 45%,
      var(--papel-fundo) 100%);
}

/* O cabecalho FLUTUA sobre a capa em vez de empurra-la: a capa e de viewport
   inteiro, e um topo em fluxo comeria a altura que ela existe para ter. */
/* O topo acompanha a rolagem, e o botao de assinar nao some mais na dobra.
   -----------------------------------------------------------------------------
   Ele era absolute: existia sobre a capa e ia embora na primeira rolagem, entao
   quem lia os seis passos e se convencia no meio da pagina tinha de voltar ao
   topo para achar a acao. A referencia que o Brenno trouxe (decade.com) mantem o
   CTA visivel o tempo todo, e e a diferenca de maior efeito por menor risco.

   ⚠️ fixed e nao sticky, de proposito: sticky OCUPA espaco no fluxo e
   empurraria a capa de 100vh para baixo, mudando a geometria da dobra. fixed
   flutua, e a capa continua exatamente como estava.

   ⚠️ Sem script: o CSP e default-src 'none', entao nao existe "adicionar
   classe ao rolar". Por isso o fundo e translucido SEMPRE — sobre a capa escura
   ele quase nao aparece, e sobre o conteudo ele separa. Uma borda permanente
   ficaria mal sobre a capa e por isso nao entra.

   ⚠️ E o backdrop-filter tem cor de fundo por baixo: onde ele nao for
   suportado, o que sobra e a faixa translucida, que ja resolve. */
.topo-capa {
  position: fixed; top: 0; left: 0; right: 0; z-index: 5;
  display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; padding: clamp(1.4rem, 1.067rem + 0.69vw, 1.9rem) var(--goteira);
  background: color-mix(in oklch, var(--papel-fundo) 78%, transparent);
  backdrop-filter: blur(10px);
}

/* O topo flutua sobre o conteudo, entao a ancora precisa parar ABAIXO dele.
   Sem isto, a ancora #planos levaria o titulo da secao para debaixo da barra. */
:where(section[id]) { scroll-margin-top: 5.5rem; }
.topo-capa nav { display: flex; gap: 1.6rem; align-items: center; }

/* Os links de secao so aparecem quando ha coluna larga. No celular eles
   competiriam com o botao de assinar, que e a unica acao que importa ali. */
.navlink {
  display: none;
  /* 0,72rem sao 11,5px: tamanho de enfeite discreto no notebook, ilegivel numa
     tela de 27 polegadas — que e usada de mais longe. Cresce com a tela. */
  font: 500 clamp(0.72rem, 0.598rem + 0.25vw, 0.9rem)/1 var(--fonte-dado); letter-spacing: 0.16em;
  color: var(--tinta-fraca); text-decoration: none;
}
.navlink:hover { color: var(--tinta); text-decoration: underline; text-underline-offset: 0.3em; }

/* O texto vertical na borda. Enfeite honesto: aria-hidden, e some no celular. */
.vertical { display: none; }

.capa-cheia {
  min-height: 100svh; position: relative;
  display: flex; flex-direction: column; justify-content: center;
  padding: 7rem var(--goteira) 5rem;
}
.capa-cheia h1 {
  font-size: clamp(2.75rem, 7.5vw, 5.25rem); line-height: 1.02;
  font-weight: 500; letter-spacing: -0.01em;
  max-width: 18ch; margin: 1.25rem 0 0; text-wrap: balance;
}
.capa-cheia .aviso { margin-top: 2rem; max-width: 42rem; }
.capa-acoes { display: flex; gap: 0.75rem; flex-wrap: wrap; margin-top: 2rem; }

/* O trilho de baixo da capa: duas frases curtas nas pontas. */
.capa-trilho {
  position: absolute; left: var(--goteira); right: var(--goteira); bottom: 1.4rem;
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font: 500 0.625rem/1.4 var(--fonte-dado); letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--tinta-fraca); margin: 0;
}

/* A faixa e a unidade de secao desta pagina. A divisoria e TRACEJADA e nao
   solida de proposito: ela separa sem fechar caixa, que e a diferenca entre
   pagina editorial e painel de administracao. */
.faixa {
  border-top: 1px dashed var(--linha);
  padding: clamp(4.5rem, 14vh, 8rem) var(--goteira);
}
.faixa > h2 {
  font-size: clamp(1.75rem, 3vw, 2.5625rem); line-height: 1.05;
  font-weight: 500; margin: 1rem 0 2.5rem; text-wrap: balance;
}
.faixa-dupla, .faixa-conversa { display: grid; gap: 2rem; }
.faixa-dupla > div > h2 { margin: 1rem 0 0; }
.faixa-conversa { min-height: 100svh; align-content: center; gap: 2.5rem; }
.faixa-conversa > div > h2 { margin: 1rem 0 0; }
.faixa-conversa .chamada { margin: 0; }

/* As tres coisas que ele faz, em linhas numeradas em vez de tres cartoes.
   O numero e dado, entao vai na fonte de dado e com tabular-nums — ele fica
   numa coluna, e coluna de numero que "dança" e o defeito que a fonte resolve. */
/* ⚠️ SEM PARAGRAFO DE EXPLICACAO desde 2026-08-21, a pedido do Brenho: "deixe os
   topicos bem evidentes". O que sobrou em cada linha e o numero e o titulo.

   Com a explicacao, a linha era um bloco de leitura e o titulo servia de
   cabecalho. Sem ela, o TITULO e a linha — e mante-lo no tamanho de subtitulo
   deixaria a secao com cara de indice inacabado. Por isso ele cresce aqui, e a
   linha ganha ar.

   O numero e o titulo passam a dividir a MESMA linha em tela larga: seis titulos
   grandes empilhados um a um esticariam a secao sem acrescentar nada. */
.linha-num {
  display: grid; gap: 0.35rem 1rem;
  grid-template-columns: auto 1fr; align-items: baseline;
  border-top: 1px dashed var(--linha); padding-block: 1.5rem;
}
/* 🔴 O PARAGRAFO ATRAVESSA AS DUAS COLUNAS NO CELULAR — 05/09/2026.
   ---------------------------------------------------------------------------

   A linha tem TRES filhos (.num, h3, p) e a grade do celular tem DUAS
   colunas (auto 1fr). Sem esta regra o <p> cai na coluna 1, e a coluna 1 e
   auto: ela passa a ser dimensionada pelo item mais largo, que e o paragrafo
   inteiro. O titulo, espremido no 1fr do que sobra, quebrava uma ou duas
   palavras por linha e descia empilhado.

   ⚠️ O BRENNO VIU ISSO NO TELEFONE, e nenhuma ferramenta daqui tinha visto:
   npm run fotografar-site mede TRANSBORDO, e nada transbordava — o texto so
   quebrava mal, dentro dos limites. E a mesma cegueira da goteira de 03/09, em
   que a folha inteira perdia a margem lateral e o relatorio dizia «nenhum
   elemento passa da borda direita». Transbordo nao e a unica forma de errar.

   ⚠️ Na media query de 64em a grade vira TRES colunas e cada filho tem a sua,
   entao la o grid-column volta a auto. Sem esse par, consertar o celular
   quebraria o desktop. */
.linha-num > p { grid-column: 1 / -1; }
.linha-num:last-child { border-bottom: 1px dashed var(--linha); }
.linha-num h3, .linha-num p { margin: 0; }
.linha-num h3 { font-size: clamp(1.15rem, 1rem + 0.9vw, 1.6rem); line-height: 1.15; }
.num {
  font: 500 0.875rem/1 var(--fonte-dado);
  font-variant-numeric: tabular-nums; color: var(--palha);
}

/* O plano deixa de ser cartao e vira linha. O preco continua saindo de
   blocoDePlanos — esta folha nao sabe quanto custa nada, e e assim que a regra
   3.6 continua valendo depois de uma troca de layout. */
.plano-linha {
  display: grid; gap: 1.25rem;
  border-top: 1px dashed var(--linha); padding-block: 2.25rem;
  align-items: center;
}
.plano-linha:last-of-type { border-bottom: 1px dashed var(--linha); }
.plano-linha h3 { margin: 0 0 0.35rem; }
.plano-linha .preco {
  margin: 0; font: 500 clamp(2rem, 4vw, 3.25rem)/1 var(--fonte-dado);
  font-variant-numeric: tabular-nums; color: var(--palha);
}
.plano-linha .preco small {
  display: block; margin-top: 0.25rem;
  font-family: var(--fonte-corpo); font-size: 0.875rem; font-weight: 400;
  letter-spacing: 0; color: var(--tinta-fraca);
}
/* ⚠️ A CELULA DO PRECO, e ela existe para a grade contar TRES.
   O anual tem duas linhas (o mensal equivalente e o total do ano) e o mensal tem
   uma. Sem este bloco, o segundo paragrafo do anual virava uma quarta celula e
   empurrava o botao para baixo — as duas linhas de plano saiam assimetricas. */
.preco-bloco { display: grid; gap: 0.35rem; }

.plano-linha .preco-a-definir {
  font-family: var(--fonte-corpo); font-size: var(--texto-h3);
  font-weight: 600; color: var(--alerta-tinta); letter-spacing: 0;
}
/* ⚠️ AQUI HAVIA `:hover { border-color: var(--vinho-500) }` nas duas, e saiu.
   `.linha-num` e `.plano-linha` sao <div> — nao sao link nem botao. Acender a
   borda no hover promete um clique que nao existe, e no caso do plano isso
   acontecia em cima do caminho de conversao: a linha do plano acendia inteira
   enquanto o unico alvo clicavel era o botao "Assinar o mensal" dentro dela.
   Quem passa o mouse na linha, clica na linha, e nada acontece.
   Se um dia a linha do plano DEVER ser clicavel, o conserto e o markup virar
   link — nao a borda voltar a fingir. Ver ADR-0029. */

/* O brilho que atravessa o botao no hover. Puro CSS: um pseudo-elemento que
   anda de -100% a 100%. "isolation" prende o z-index negativo dentro do botao,
   senao ele cai atras da secao inteira e some.

   ⚠️ O PSEUDO-ELEMENTO SO EXISTE ONDE HA PONTEIRO FINO. No celular, um toque
   dispara :hover falso: o brilho atravessa o botao sozinho depois de o dedo
   sair, e o estado fica grudado ate alguem tocar em outra coisa. Movimento no
   hover sem este gate e defeito em tela de toque, nao preferencia.

   240ms e nao 420ms: acima de 300ms um efeito de UI le como lentidao, e a
   secao "Movimento" do `tonti-design` pede "discreto e curto". E a curva e
   --ease-in-out porque isto e coisa ANDANDO na tela; `ease` fica para cor. */
.botao { position: relative; overflow: hidden; isolation: isolate; }
@media (hover: hover) and (pointer: fine) {
  .botao::after {
    content: ""; position: absolute; inset: 0; z-index: -1;
    background: linear-gradient(90deg, transparent,
      color-mix(in oklab, var(--vinho-300) 26%, transparent), transparent);
    transform: translateX(-100%); transition: transform 240ms var(--ease-in-out);
  }
  .botao:hover::after { transform: translateX(100%); }
}

details summary { transition: color var(--transicao); }
details summary:hover { color: var(--vinho-300); }

@media (min-width: 64em) {
  .navlink { display: inline; }
  .vertical {
    display: block; position: fixed; right: 1.1rem; top: 50%;
    transform: translateY(-50%); writing-mode: vertical-rl;
    font: 500 0.625rem/1 var(--fonte-dado); letter-spacing: 0.24em;
    text-transform: uppercase; color: var(--tinta-fraca);
    opacity: 0.7; pointer-events: none; z-index: 3; margin: 0;
  }
  /* ⚠️ "start" e nao "end", apesar de o desenho pedir "end".
     La a faixa dupla emparelhava um titulo curto com um paragrafo curto, e
     alinhar por baixo lia como pe de pagina de revista. Aqui a coluna da
     direita e alta (duas linhas numeradas), e por baixo o titulo da secao
     terminava ABAIXO do proprio conteudo: quem le encontra dois itens sem
     saber ainda do que a secao trata. */
  .faixa-dupla { grid-template-columns: 1.1fr 0.9fr; align-items: start; gap: 3rem; }
  .faixa-conversa { grid-template-columns: 1fr minmax(340px, 1.15fr) 1fr; align-items: center; gap: 3rem; }
  .faixa-conversa .chamada { align-self: end; }

  /* A SEGUNDA conversa (a carta do restaurante) espelha a primeira: conversa a
     ESQUERDA, texto a direita. Duas faixas de viewport inteiro seguidas com o
     mesmo eixo leem como a mesma secao rolando duas vezes; invertido, a virada
     e o proprio aviso de que mudou de assunto.

     ⚠️ DUAS colunas aqui, e nao as tres da primeira. Espelhar as tres poria a
     `.chamada` — o paragrafo mais miudo da faixa — na PRIMEIRA coluna, e o olho
     bate nela antes do titulo. Com duas, o titulo e a chamada empilham na mesma
     coluna da direita e a ordem de leitura continua sendo titulo -> conversa ->
     chamada.

     ⚠️ A `.chamada` volta para `align-self: start`: a regra logo acima a cola no
     rodape da faixa, o que serve quando ela tem uma coluna so para si. Aqui ela
     mora debaixo do titulo e precisa ficar colada NELE. Mesma especificidade das
     duas regras — quem ganha e a ordem, entao esta tem de vir depois. */
  /* ⚠️ 2fr na coluna do texto, e nao 1fr. Com 1fr a conversa levava 1.15 de 2.15
     (53%) contra 1.15 de 3.15 (37%) na primeira faixa: o MESMO cartao saia com
     dois tamanhos, uma secao abaixo da outra, e lia como dois componentes. Com
     2fr a PROPORCAO passa a ser a mesma — 1.15/3.15 nas duas. Sobra uma diferenca
     de um vao: a faixa espelhada tem duas colunas, logo um gap em vez de dois, e
     o cartao fica ~17px mais largo em 1440. Nao se ve. Medido na foto de 1440px
     de `npm run fotografar-site`.

     E o texto ganha teto de medida: sobrando 63% da faixa, o titulo esticaria
     para ~900px de linha, que nao se le. */
  .faixa-conversa-espelhada { grid-template-columns: minmax(340px, 1.15fr) 2fr; }
  .faixa-conversa-espelhada > div,
  .faixa-conversa-espelhada > .chamada { max-width: 30rem; }
  .faixa-conversa-espelhada > div { grid-column: 2; grid-row: 1; }
  .faixa-conversa-espelhada > .conversa { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
  .faixa-conversa-espelhada > .chamada { grid-column: 2; grid-row: 2; align-self: start; }
  .linha-num { grid-template-columns: 5ch 1fr 1.25fr; gap: 2rem; align-items: baseline; }
  /* ⚠️ Desfaz o 1 / -1 do celular: aqui ha uma coluna por filho. */
  .linha-num > p { grid-column: auto; }
  .plano-linha { grid-template-columns: 1.25fr auto auto; gap: 2.5rem; }
}

/* Quem desligou animacao no sistema perde o brilho do botao. O bloco global la
   em cima ja zera duracao; este desliga o EFEITO, que e o que incomoda mesmo
   em 0.01ms.

   🔴 E ELE SOME, em vez de ter o transform zerado. A diferenca nao e estetica:
   o REPOUSO de `.botao::after` e `translateX(-100%)`, e e so isso que mantem o
   gradiente fora do botao. A regra antiga dizia `transform: none !important`
   para quatro seletores de uma vez — e dos quatro, apenas este tinha transform
   de base. O efeito era o pseudo-elemento voltar para `inset: 0`, ou seja,
   estacionar EM CIMA do botao: toda pagina do site passava a ter uma faixa de
   luz parada no meio de cada botao, permanentemente, e SO para quem usa
   movimento reduzido — que e justamente quem nunca ia ver aquilo se mover.
   Ninguem enxerga isso sem ligar a preferencia no sistema. Achado ao rodar a
   skill `review-animations` (ADR-0029).

   ⚠️ Zerar `transform` num elemento cujo estado de repouso E um transform
   inverte o que a regra queria: nao desliga o movimento, entrega o fim dele. */
@media (prefers-reduced-motion: reduce) {
  .botao::after { display: none !important; }
}

/* --------------------------------------------------------------- impressao */

/* Alguem vai imprimir os termos.
   ⚠️ Nao basta esconder o topo e clarear o body: com tema escuro, a .caixa e o
   .aviso levam fundo proprio, e "fundo proprio" numa impressora e um retangulo
   de tinta escura cobrindo o texto — ou pagina em branco, se o navegador estiver
   com "imprimir cores de fundo" desligado. Entao aqui todo fundo cai. */
@media print {
  .topo, .topo-capa, .rodape, .botao, .conversa, .fundo-liquido, .vertical, .capa-trilho { display: none; }
  body { font-size: 11pt; color: #000; background: #fff; }
  h1, h2, h3, p, li, dt, dd, summary { color: #000; }
  .caixa, .aviso, .resumo-erros, .capa, .capa-cheia {
    background: #fff; border-color: #999; box-shadow: none; color: #000;
  }
  a { color: #000; }
  section + section { border-color: #999; }
}

/* O link de pular. Ele existe para TODO MUNDO, e nao so para leitor de tela:
   quem navega por teclado tambem atravessa o topo a cada pagina.

   Por isso ele nao usa .so-leitor — sai do esconderijo quando recebe foco, e
   precisa APARECER, com fundo proprio. Um link de pular invisivel ate no foco e
   o modo de falha classico deste padrao: parece implementado e nao serve. */
.pular {
  position: absolute; left: 0.5rem; top: -100%; z-index: 10;
  padding: 0.6875rem 1.375rem; border-radius: var(--raio);
  background: var(--acento); color: var(--acento-texto);
  text-decoration: none; font-weight: 600;
}
.pular:focus-visible { top: 0.5rem; }

/* Acessibilidade: o texto que so o leitor de tela precisa. */
.so-leitor {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ------------------------------------------------------------- utilitarias */

/* Estas cinco existem para que NENHUMA pagina precise de "style="..."" no HTML.
   Nao e purismo: com atributo de estilo inline, o CSP precisa de
   "style-src-attr 'unsafe-inline'", e ai a protecao contra injecao de estilo
   deixa de valer no site inteiro — por causa de uma margem. Ver servidor.ts. */
.estreito       { max-width: var(--medida); }
.medio          { max-width: 44rem; }
.espaco-acima   { margin-top: 1.5rem; }
.espaco-acima-p { margin-top: 1rem; }
.espaco-volta   { margin: 1.75rem 0; }

/* ----------------------------------------------------------------- a casca */

/* `100dvh` e nao `100vh`: no celular, `vh` inclui a barra de endereco que
   some ao rolar — a tela "cresce" ~60px no primeiro gesto e a barra de baixo
   pula. `dvh` acompanha. O `100vh` fica de reserva: navegador que nao
   entende `dvh` ignora a segunda linha e fica com a primeira. */
.app {
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--papel-fundo);
  display: flex;
  flex-direction: column;
  position: relative;
  overflow-x: hidden;
}
.app-coluna {
  width: 100%; max-width: var(--coluna-app); margin-inline: auto;
  flex: 1; display: flex; flex-direction: column; min-height: 0;
}

/* As duas luzes de fundo. `pointer-events: none` porque decoracao que
   intercepta o toque e um botao que nao funciona sem motivo aparente. */
.app::before, .app::after {
  content: ""; position: fixed; border-radius: 50%; pointer-events: none; z-index: 0;
}
.app::before {
  width: 29rem; height: 29rem; right: -9rem; top: -7rem;
  background: var(--tonti-luz-vinho);
}
.app::after {
  width: 25rem; height: 25rem; left: -10rem; bottom: -4rem;
  background: var(--tonti-luz-palha);
}

.app-rolagem {
  position: relative; z-index: 1;
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; gap: 0.75rem;
  padding: 0.5rem 1.125rem 0;
  /* O respiro do fim da lista: a barra + o que o aparelho reserva embaixo (a
     barrinha do iPhone). Sem isto o ultimo vinho fica atras da barra e ninguem
     descobre que ele esta ali. */
  padding-bottom: calc(7.5rem + env(safe-area-inset-bottom, 0px));
}

/* ----------------------------------------------------------------- o vidro */

/* Uma classe so, para tudo que flutua. O `backdrop-filter` degrada sozinho:
   navegador que nao suporta mostra a superficie translucida sem o desfoque, e
   continua legivel porque o contraste vem da cor, nao do blur. */
.vidro {
  background: var(--vidro-fundo);
  border: 1px solid var(--vidro-linha);
  border-radius: var(--raio-vidro);
  backdrop-filter: var(--desfoque-vidro);
  box-shadow: var(--sombra-vidro);
}

/* -------------------------------------------------------------- cabecalho */

.app-topo {
  position: relative; z-index: 1;
  display: flex; align-items: center; gap: 0.75rem;
  padding: calc(0.75rem + env(safe-area-inset-top, 0px)) 1.375rem 0.25rem;
  max-width: var(--coluna-app); margin-inline: auto; width: 100%;
}
.app-topo img { width: 2.25rem; height: 2.25rem; border-radius: 0.7rem; flex: none; }
.app-saudacao { flex: 1; display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; }
.app-saudacao span { font-size: 0.85rem; color: var(--tinta-fraca); }
.app-saudacao strong {
  font-family: var(--fonte-titulo); font-weight: 400; font-size: 1.2rem;
  color: var(--tinta); letter-spacing: -0.005em;
}
.app-sino {
  width: 2.25rem; height: 2.25rem; flex: none; border-radius: 0.8rem;
  display: flex; align-items: center; justify-content: center;
  color: var(--tinta); position: relative; text-decoration: none;
}
.app-sino:hover { text-decoration: none; }
.app-sino[data-novidade]::after {
  content: ""; position: absolute; top: 0.45rem; right: 0.5rem;
  width: 0.4rem; height: 0.4rem; border-radius: 50%; background: var(--vinho-500);
}

/* ------------------------------------------------------ rotulo tipografico */

.dado {
  font-family: var(--fonte-dado); font-size: 0.7rem;
  letter-spacing: var(--rastro-dado); font-variant-numeric: tabular-nums;
  color: var(--tinta-fraquissima);
}
.sobrancelha-app {
  font-family: var(--fonte-dado); font-size: 0.69rem; font-weight: 500;
  letter-spacing: var(--rastro-sobrancelha); text-transform: uppercase; color: var(--tinta-fraca);
}

/* -------------------------------------------------------- sugestao do Tonti */

.sugestao {
  padding: 0.875rem; display: flex; flex-direction: column; gap: 0.625rem;
  background: linear-gradient(155deg, oklch(0.42 0.13 20 / 0.42) 0%, oklch(1 0 0 / 0.05) 62%);
}
.sugestao-cabeca { display: flex; align-items: center; gap: 0.5rem; }
.sugestao-cabeca .sobrancelha-app { color: oklch(0.86 0.06 45); }
.sugestao-cabeca .dado { margin-left: auto; }
.sugestao-corpo { display: flex; gap: 0.875rem; align-items: center; }
.sugestao-corpo > div { flex: 1; display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.sugestao-titulo {
  font-family: var(--fonte-titulo); font-weight: 400; font-size: 1.3rem;
  line-height: 1.15; margin: 0; color: var(--tinta); text-wrap: balance;
}
.sugestao-origem { font-size: 0.78rem; color: var(--tinta-fraca); }
.sugestao-porque { font-size: 0.85rem; color: oklch(0.90 0.014 60); text-wrap: pretty; margin: 0; }
.sugestao-acoes { display: flex; gap: 0.5rem; }

/* A moldura do rotulo. Enquanto nao ha foto, a listra diagonal DIZ que falta
   foto — um retangulo cinza liso pareceria foto que carregou errado. */
.selo {
  border-radius: 0.75rem; flex: none;
  background: var(--tonti-listra-selo);
  display: flex; align-items: flex-end; justify-content: center; overflow: hidden;
}
.selo span {
  font-family: var(--fonte-dado); font-size: 0.44rem;
  color: var(--tinta-fraquissima); padding-bottom: 0.375rem;
}
.selo img { width: 100%; height: 100%; object-fit: cover; }
.selo-sugestao { width: 3.5rem; height: 4.375rem; }
.selo-garrafa  { height: 3.625rem; }

/* ------------------------------------------------------------------ fichas */

.ficha { display: flex; gap: 0.375rem; align-items: center; padding-top: 0.2rem; flex-wrap: wrap; }
.ficha .dado { color: var(--palha); }
.vaga-nome {
  font-family: var(--fonte-dado); font-size: 0.7rem; letter-spacing: var(--rastro-dado);
  color: var(--palha); background: var(--vidro-forte);
  border-radius: var(--raio-pilula); padding: 0.2rem 0.55rem;
}

/* ----------------------------------------------------------- botoes do app */

.botao-app {
  flex: 1; display: inline-flex; align-items: center; justify-content: center;
  gap: 0.45rem; min-height: var(--toque); border-radius: 1rem; padding-inline: 0.75rem;
  font-family: var(--fonte-corpo); font-weight: 600; font-size: 0.85rem;
  color: var(--acento-texto); background: var(--vinho-600);
  text-decoration: none; border: 0; cursor: pointer; text-align: center;
  box-shadow: var(--sombra-acao);
}
.botao-app:hover { background: var(--vinho-500); color: var(--acento-texto); text-decoration: none; }
.botao-app-quadrado {
  width: var(--toque); min-height: var(--toque); flex: none; border-radius: 1rem;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--tinta); text-decoration: none;
}
.botao-app-quadrado:hover { text-decoration: none; }

/* ----------------------------------------------------------------- filtros */

/* Rolam na horizontal com o dedo. As duas regras de barra somem com o
   indicador de rolagem; o `margin-inline` negativo sangra ate a borda da
   tela, para o ultimo filtro nao parecer o ultimo que existe. */
.filtros {
  display: flex; gap: 0.5rem; overflow-x: auto; scrollbar-width: none;
  margin-inline: -1.125rem; padding: 0 1.125rem 0.125rem;
}
.filtros::-webkit-scrollbar, .trilho::-webkit-scrollbar { display: none; }
.filtro {
  font-family: var(--fonte-corpo); font-weight: 500; font-size: 0.78rem;
  padding: 0.5rem 0.875rem; border-radius: var(--raio-pilula); white-space: nowrap; flex: none;
  border: 1px solid var(--vidro-forte); color: var(--tinta-fraca);
  background: oklch(1 0 0 / 0.03); text-decoration: none;
}
.filtro:hover { color: var(--tinta); text-decoration: none; }
.filtro[aria-current="true"] {
  background: var(--vinho-600); border-color: transparent;
  color: var(--acento-texto); font-weight: 600;
}

/* -------------------------------------------------------------- dois blocos */

.dupla { display: grid; grid-template-columns: 1.15fr 1fr; gap: 0.625rem; align-items: start; }
.pilha { display: flex; flex-direction: column; gap: 0.625rem; }

/* ----------------------------------------------------------- mapa da adega */

.mapa { padding: 0.75rem; display: flex; flex-direction: column; gap: 0.5rem; }
.mapa-grade { display: grid; gap: 0.3rem; }
/* A largura da grade vem por CLASSE, e nao por style="grid-template-columns".
   O CSP proibe atributo de estilo, entao o numero de colunas vira nome.

   🔴 NAO HA FALLBACK. Esta lista e o contrato inteiro: `mapa-de-9` nao existe,
   e `.mapa-grade` e `display: grid` SEM `grid-template-columns` — uma classe
   fora de 4..8 nao "cai na de 8", ela deixa a grade sem colunas definidas e o
   navegador empilha tudo em UMA. O comentario que estava aqui afirmava o
   contrario, e foi por isso que o defeito viveu escondido.

   Quem garante a faixa e o TypeScript: `COLUNAS_MAX_DO_MAPA` em
   `src/web/paginas-adega.ts`. Acrescentar `.mapa-de-9` aqui sem subir o teto la
   nao serve para nada, e subir o teto la sem acrescentar a regra aqui quebra a
   tela — ha teste que falha se os dois lados divergirem. */
.mapa-de-4 { grid-template-columns: repeat(4, 1fr); }
.mapa-de-5 { grid-template-columns: repeat(5, 1fr); }
.mapa-de-6 { grid-template-columns: repeat(6, 1fr); }
.mapa-de-7 { grid-template-columns: repeat(7, 1fr); }
.mapa-de-8 { grid-template-columns: repeat(8, 1fr); }
.vaga {
  border-radius: 0.375rem; min-height: 1.625rem;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--fonte-dado); font-size: 0.56rem; letter-spacing: 0.04em;
  color: var(--tinta-fraca); background: var(--vidro-linha); text-decoration: none;
}
.vaga:hover { color: var(--tinta); text-decoration: none; }
.vaga-vazia  { background: none; border: 1px dashed oklch(1 0 0 / 0.12); }
.vaga-hoje   { background: var(--vinho-600); color: var(--acento-texto); }
.vaga-janela { background: var(--palha-fundo); color: var(--palha); }
.vaga-guarda { background: var(--vinho-900); border: 1px solid var(--vinho-500); color: var(--vinho-300); }

/* ----------------------------------------------------------------- numeros */

.numero { padding: 0.75rem; display: flex; flex-direction: column; gap: 0.2rem; }
.numero strong {
  font-family: var(--fonte-titulo); font-weight: 400; line-height: 1.05;
  font-size: 1.6rem; color: var(--tinta); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.numero strong .dado { font-size: 0.75rem; }
.numero-sobe { color: var(--sucesso); }

/* ------------------------------------------------------ trilho de garrafas */

.trilho-cabeca { display: flex; align-items: center; gap: 0.5rem; padding-inline: 0.25rem; }
.trilho-cabeca .dado { margin-left: auto; color: var(--sucesso); }
.trilho {
  display: flex; gap: 0.75rem; overflow-x: auto; scrollbar-width: none;
  margin-inline: -1.125rem; padding: 0 1.125rem 0.125rem;
}
.garrafa {
  width: 9.375rem; flex: none; padding: 0.625rem;
  display: flex; flex-direction: column; gap: 0.375rem; text-decoration: none;
}
.garrafa:hover { text-decoration: none; }
.garrafa strong {
  font-family: var(--fonte-titulo); font-weight: 400; font-size: 0.95rem;
  color: var(--tinta); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --------------------------------------------------------- barra debaixo */

/* A tarja que protege a leitura. Sem ela, o texto que rola por tras da barra
   translucida fica ilegivel por dois segundos a cada rolagem. */
.app-tarja {
  position: fixed; left: 0; right: 0; bottom: 0; height: 8rem;
  pointer-events: none; z-index: 2;
  background: linear-gradient(to top,
    oklch(0.155 0.012 30 / 0.92) 0%, oklch(0.155 0.012 30 / 0) 100%);
}
.barra {
  position: fixed; z-index: 3;
  left: 50%; transform: translateX(-50%);
  width: calc(100% - 2.25rem); max-width: 24.75rem;
  bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  min-height: 4.25rem; border-radius: var(--raio-barra);
  display: flex; align-items: center; justify-content: space-around;
  background: oklch(0.20 0.016 28 / 0.86);
  border: 1px solid var(--vidro-forte);
  backdrop-filter: var(--desfoque-barra);
  box-shadow: var(--sombra-barra);
}
.barra a {
  display: flex; flex-direction: column; align-items: center; gap: 0.2rem;
  min-width: 3.625rem; min-height: var(--toque); justify-content: center;
  color: var(--tinta-fraca); text-decoration: none;
}
.barra a:hover { color: var(--tinta); text-decoration: none; }
.barra a[aria-current="page"] { color: var(--vinho-300); }
.barra a span { font-family: var(--fonte-dado); font-size: 0.56rem; letter-spacing: 0.03em; }

/* O botao da foto sobe acima da barra porque e a acao principal do app:
   fotografar o rotulo e o jeito mais rapido de por vinho na adega. */
.foto {
  width: 3.75rem; height: 3.75rem; border-radius: var(--raio-vidro); flex: none;
  margin-top: -1.75rem;
  display: flex; align-items: center; justify-content: center;
  color: var(--acento-texto); text-decoration: none;
  background: var(--tonti-gradiente-foto);
  box-shadow: 0 12px 28px oklch(0.45 0.16 20 / 0.45), inset 0 1px 0 oklch(1 0 0 / 0.22);
}
.foto:hover { text-decoration: none; }

/* ------------------------------------------------------------------ icones */

.icone { width: 1.25rem; height: 1.25rem; flex: none; display: block; }
.icone-g { width: 1.6rem; height: 1.6rem; }
.icone-p { width: 0.95rem; height: 0.95rem; }

/* ------------------------------------------------------------------ vazio */

.vazio { padding: 1.5rem 1.25rem; display: flex; flex-direction: column; gap: 0.75rem; text-align: center; }
.vazio h2 { font-family: var(--fonte-titulo); font-weight: 400; font-size: 1.25rem; margin: 0; color: var(--tinta); }
.vazio p { margin: 0; color: var(--tinta-fraca); font-size: 0.9rem; text-wrap: pretty; }

/* ------------------------------------------------ a tela de UMA garrafa */

/* O caminho de volta. Discreto de proposito: ele nao compete com o nome da
   garrafa, que e o assunto da tela. */
.voltar { color: var(--tinta-fraca); text-decoration: none; }
.voltar:hover { color: var(--tinta); }

/* A frase que a pessoa disse, entre aspas. Em serifada porque e CITACAO — o
   resto do app e sem serifa, e a diferenca marca de quem e a voz. */
.fala-do-cliente {
  font-family: var(--fonte-titulo); font-size: 1.05rem; line-height: 1.45;
  color: var(--tinta); margin: 0.5rem 0 0; text-wrap: pretty;
}

.espaco-curto { margin: 0.5rem 0 0; }

/* ------------------------------------------------- a busca na adega */

.busca-adega {
  display: flex; align-items: flex-end; gap: 0.5rem; flex-wrap: wrap;
  margin: 0.75rem 0 0.25rem;
}
.busca-adega label {
  font-size: 0.72rem; letter-spacing: var(--rastro-sobrancelha);
  text-transform: uppercase; color: var(--tinta-fraca);
  display: block; width: 100%;
}
/* Cresce e ocupa o que sobrar; o min-width zero deixa encolher no celular em vez
   de empurrar o botao para fora. */
.busca-adega input[type="search"] {
  flex: 1 1 8rem; min-width: 0;
  font-family: var(--fonte-corpo); font-size: max(1rem, 16px);
  min-height: var(--toque); padding: 0 0.75rem;
  background: var(--papel-alto); color: var(--tinta);
  border: 1px solid var(--linha-forte); border-radius: var(--raio);
}
.busca-adega input[type="search"]::placeholder { color: var(--tinta-fraquissima); }
.busca-achou { margin: 0 0 0.5rem; display: flex; gap: 0.75rem; flex-wrap: wrap; align-items: baseline; }

/* ---------------------------------------------- o relatorio da adega */

/* Quatro numeros em grade. O par auto-fit + minmax responde a largura real:
   no celular estreito viram duas colunas, e no iPad quatro, sem media query e
   sem escolher um modelo de aparelho. */
.resumo {
  display: grid; gap: 0.75rem; margin-top: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr));
}
.resumo-item { display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; }
.resumo-item strong {
  font-family: var(--fonte-dado); font-size: 1.6rem; line-height: 1.05;
  color: var(--tinta); font-variant-numeric: tabular-nums;
}

/* O campo de data. Some no papel junto com o resto dos controles. */
.dia-escolhido {
  display: flex; align-items: flex-end; gap: 0.5rem; flex-wrap: wrap;
  margin-top: 0.75rem;
}
.dia-escolhido label {
  font-size: 0.72rem; letter-spacing: var(--rastro-sobrancelha);
  text-transform: uppercase; color: var(--tinta-fraca);
  display: block; width: 100%;
}
/* ⚠️ 16px no minimo: abaixo disso o Safari do iPhone da zoom na pagina inteira
   ao focar o campo, e nao volta. Mesma regra dos campos do site. */
.dia-escolhido input[type="date"] {
  font-family: var(--fonte-dado); font-size: max(1rem, 16px);
  min-height: var(--toque); padding: 0 0.625rem;
  background: var(--papel-alto); color: var(--tinta);
  border: 1px solid var(--linha-forte); border-radius: var(--raio);
  /* Sem isto o iOS desenha o campo com fundo claro e o texto some. */
  color-scheme: dark;
}

/* -------------------------------------- o aviso depois de uma escrita */

/* Barra de cor na borda de inicio, e nao fundo colorido: o desfecho precisa se
   distinguir do resto sem virar alarme, e fundo vermelho num app escuro le como
   ERRO mesmo quando a frase diz "registrado". */
.aviso { border-inline-start: 3px solid var(--vinho-600); }

/* ------------------------------------------ o registro de «bebi esta garrafa» */

.registro { display: flex; flex-wrap: wrap; gap: 0.5rem 0.75rem; margin: 0.75rem 0 0; }
/* A nota e curta e o comentario cresce: base de flex diferente nos dois faz os
   dois caberem lado a lado no iPad e empilharem no celular, sem media query. */
.campo-app { display: flex; flex-direction: column; gap: 0.25rem; flex: 0 1 6rem; min-width: 0; }
.campo-app.largo { flex: 1 1 12rem; }
.campo-app label {
  font-size: 0.72rem; letter-spacing: var(--rastro-sobrancelha);
  text-transform: uppercase; color: var(--tinta-fraca);
}
/* ⚠️ 16px no minimo: abaixo disso o Safari do iPhone da zoom na pagina inteira
   ao focar o campo, e nao volta. Mesma regra dos outros campos. */
.campo-app input {
  width: 100%; box-sizing: border-box;
  font-family: var(--fonte-corpo); font-size: max(1rem, 16px);
  min-height: var(--toque); padding: 0 0.75rem;
  background: var(--papel-alto); color: var(--tinta);
  border: 1px solid var(--linha-forte); border-radius: var(--raio);
  /* Sem isto o iOS desenha o campo com fundo claro e o texto some. */
  color-scheme: dark;
}
.campo-app input::placeholder { color: var(--tinta-fraquissima); }
.registro-acao { flex: 1 1 100%; display: flex; margin: 0.25rem 0 0; }

@media (prefers-reduced-motion: reduce) {
  .app *, .barra * { transition: none; animation: none; }
}
