:root {
  /* Superficies e texto em cinza neutro (sem matiz), nao mais um preto/branco
     puxado pro verde da marca: cor so como acento (marca/foco) turvava o
     contraste do vermelho/azul de alta/queda, que E a informacao do site -
     ver rodada 1 da revisao de design. Contraste AA (4.5:1) calculado par a
     par contra --bg/--surface/--surface-2, nao estimado - qualquer troca
     aqui exige recalcular. */
  --bg: #f7f7f7;
  --surface: #ffffff;
  --surface-2: #eff0f0;
  --texto: #1a1a1a;
  --texto-fraco: #595959;
  --texto-suave: #6b6b6b;
  --borda: #e2e2e2;
  --linha: #c9c9c9;
  --marca: #0a7d3f;
  --foco: #0a7d3f;

  /* Par divergente: alta x queda. Vermelho/azul em vez de vermelho/verde -
     o par verde/vermelho reprova na separacao para daltonismo (deltaE 5.9);
     este passa com folga (21.4). O sinal +/- vai junto em todo numero. */
  --alta: #c0392b;
  --baixa: #1d6fb8;
  /* Mais escuro que um cinza medio "de catalogo": em #77837b (o valor
     anterior, ja neutro em L*) o texto .neutro caia pra 3.91:1 contra
     --surface-2, abaixo do minimo AA de 4.5:1. #676767 fecha em 4.95:1
     contra a superficie mais clara que ele encontra (--surface) e 4.34:1
     ja tinha sido descartado por ficar perto demais do limite. */
  --neutro: #676767;

  /* Hierarquia de elevacao: tres niveis em vez de uma sombra unica para todo
     cartao. "alta" so para o que e destaque/headline (kpi, mini dos
     destaques); "media" (--sombra, mantido pelo nome por compatibilidade)
     para cartoes informativos (cartao, procedencia); "baixa" para o que se
     repete muito e e rotina de consulta (as 17 tab-wrap de grupo). .viz
     continua sem sombra nenhuma - e so um link de navegacao. */
  --sombra-baixa: 0 1px 2px rgba(16,33,26,.03);
  --sombra: 0 1px 2px rgba(16,33,26,.04), 0 4px 14px rgba(16,33,26,.05);
  --sombra-alta: 0 2px 5px rgba(16,33,26,.06), 0 10px 24px rgba(16,33,26,.08);
  --raio: 14px;
  --raio-p: 10px;
  --alt-topo: 57px;
  /* IBM Plex Sans em vez de Inter: caráter institucional-técnico (desenhada
     pela IBM para interface e dados, não para marketing), algarismos
     tabulares nativos e acentuação latina completa - e não é a fonte mais
     estatisticamente comum em site gerado por IA. Só pesos 400-700: a
     familia nao tem corte 800, entao os usos de 800 (numero do KPI, selo da
     marca) desceram para 700. */
  --fonte: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Escala tipografica para o aglomerado de 11-14px que antes tinha sete
     valores soltos (11 / 11.5 / 12 / 12.5 / 13 / 13.5 / 14) sem sistema.
     Quatro degraus deliberados; usos fora desse aglomerado (15px pra cima)
     nao mudaram, nao faziam parte do problema. */
  --fs-2xs: 11px;
  --fs-xs: 12px;
  --fs-sm: 13px;
  --fs-base: 14px;

  /* ---------------- movimento ---------------- */
  /* Duracao/curva unicas para toda entrada e transicao de estado, dentro de
     150-300ms. --motion-y e o deslocamento vertical usado nas animacoes de
     entrada e nos hovers com "lift"; zerado inteiro no bloco de
     prefers-reduced-motion la embaixo, o que tambem cancela as @keyframes
     que dependem dele (a opacidade continua mudando, so o deslocamento some). */
  --dur-1: 180ms;
  --dur-2: 260ms;
  --ease-saida: cubic-bezier(0.16, 1, 0.3, 1);
  --motion-y: 4px;

  /* "light dark" e o estado SEM escolha explicita de tema: diz ao navegador
     que a pagina suporta os dois e deixa ele escolher o chrome de forms
     (select, barra de rolagem) pelo prefers-color-scheme do sistema - o
     mesmo criterio que os tokens de cor acima/abaixo usam. Sem isso a barra
     de rolagem e o <select> saem sempre desenhados no modo claro por cima
     da pagina, mesmo com o tema escuro ativo (visto: barra branca com
     setinhas no meio do fundo preto). Quando a pessoa escolhe um tema pelo
     botao (.tema no cabecalho, ver app.js), os blocos [data-tema] abaixo
     forcam "light" ou "dark" puro, inclusive contra o sistema. */
  color-scheme: light dark;
}

/* Tokens do tema escuro: precisam valer tanto por sistema (prefers-color-
   scheme, sem escolha explicita) quanto por escolha explicita no botao de
   tema - por isso o mesmo bloco de valores aparece duas vezes: uma dentro
   da media query (abaixo, so quando nao ha [data-tema] no <html>) e outra
   fora dela sob [data-tema="escuro"] (mais abaixo ainda, sempre que essa
   escolha existir, mesmo com o sistema claro). :not([data-tema]) exclui as
   duas escolhas explicitas daqui: sem isso, quem escolheu "claro" no botao
   mas usa o SO no escuro veria estes tokens brigarem por especificidade com
   os de :root. */
@media (prefers-color-scheme: dark) {
  :root:not([data-tema]) {
    --bg: #121212;
    --surface: #1c1c1c;
    --surface-2: #262626;
    --texto: #ececec;
    --texto-fraco: #adadad;
    --texto-suave: #949494;
    --borda: #303030;
    --linha: #454545;
    --marca: #35c46f;
    --foco: #35c46f;
    --alta: #ef5f52;
    --baixa: #4a9bd6;
    --neutro: #9a9a9a;
    --sombra-baixa: 0 1px 2px rgba(0,0,0,.22);
    --sombra: 0 1px 2px rgba(0,0,0,.3), 0 6px 18px rgba(0,0,0,.3);
    --sombra-alta: 0 2px 6px rgba(0,0,0,.35), 0 12px 28px rgba(0,0,0,.4);
    color-scheme: dark;
  }
}
:root[data-tema="escuro"] {
  --bg: #121212;
  --surface: #1c1c1c;
  --surface-2: #262626;
  --texto: #ececec;
  --texto-fraco: #adadad;
  --texto-suave: #949494;
  --borda: #303030;
  --linha: #454545;
  --marca: #35c46f;
  --foco: #35c46f;
  --alta: #ef5f52;
  --baixa: #4a9bd6;
  --neutro: #9a9a9a;
  --sombra-baixa: 0 1px 2px rgba(0,0,0,.22);
  --sombra: 0 1px 2px rgba(0,0,0,.3), 0 6px 18px rgba(0,0,0,.3);
  --sombra-alta: 0 2px 6px rgba(0,0,0,.35), 0 12px 28px rgba(0,0,0,.4);
  color-scheme: dark;
}
/* Tokens de cor ja sao os de :root (claro) por padrao - so falta forcar o
   color-scheme pra "light" puro, senao um sistema no escuro continuaria
   desenhando select/rolagem escuros por cima da pagina clara escolhida. */
:root[data-tema="claro"] {
  color-scheme: light;
}
@media (prefers-reduced-motion: reduce) {
  :root { --motion-y: 0px; }
  /* Zera toda animacao/transicao automatica ou continua; mantem apenas o
     retorno de opacidade e cor, que nao carregam risco vestibular. As
     regras individuais usam var(--motion-y) para o deslocamento, entao ja
     ficam sem movimento so com a variavel zerada acima - isto aqui cobre o
     que nao e so translateY: a animacao das barras do grafico ao carregar
     (movimento continuo de escala) e as durations, encurtadas a quase zero
     para quem pediu menos movimento. */
  .colunas .barras { animation: none !important; transform: none !important; }
  /* A interacao do grafico continua inteira (selecao, tooltip, teclado,
     tabela) - so a transicao anima e sai, o estado final e o mesmo. */
  .colunas .barras path, .grafico-tooltip, .tab tbody tr { transition: none !important; }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--texto);
  font-family: var(--fonte); line-height: 1.5; font-size: 16px;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--marca); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--foco); outline-offset: 2px; border-radius: 4px; }
h1, h2, h3 { letter-spacing: -.02em; }

.wrap { max-width: 1120px; margin: 0 auto; padding: 0 16px; }

.pular {
  position: absolute; left: -9999px; top: 8px; background: var(--surface);
  padding: 10px 14px; border-radius: var(--raio-p); border: 1px solid var(--borda); z-index: 40;
}
.pular:focus { left: 16px; }

/* ---------------- topo ---------------- */
.topo {
  background: var(--surface); border-bottom: 1px solid var(--borda);
  position: sticky; top: 0; z-index: 30;
}
.topo-in { display: flex; align-items: center; gap: 18px; padding: 10px 16px; flex-wrap: wrap; }
.marca { display: flex; align-items: center; gap: 10px; color: var(--texto); font-weight: 700; }
.marca:hover { text-decoration: none; }
.marca-icone { display: inline-grid; place-items: center; width: 28px; height: 28px; }
.marca-txt { font-size: 15px; }
.abas { display: flex; gap: 4px; margin-left: auto; }
.abas a {
  color: var(--texto-fraco); font-size: 14px; font-weight: 500;
  padding: 7px 14px; border-radius: 999px;
  transition: background-color var(--dur-1) ease-out, color var(--dur-1) ease-out;
}
.abas a:hover { text-decoration: none; background: var(--surface-2); color: var(--texto); }
.abas a.ativa { background: var(--surface-2); color: var(--texto); font-weight: 600; }
.topo-meta { font-size: var(--fs-xs); color: var(--texto-suave); }

/* Botao de tema (automatico/claro/escuro): 3 botoes num grupo so, nao um
   botao unico ciclando - aria-pressed por opcao e mais claro que ter que
   ouvir o rotulo mudar a cada clique, e a pessoa ve as 3 opcoes de cara.
   Fica discreto de proposito: mesmo tom de fundo que select/input (--surface-2),
   sem borda propria alem da do grupo. */
.tema {
  display: flex; gap: 2px; background: var(--surface-2); border: 1px solid var(--borda);
  border-radius: 999px; padding: 2px;
}
.tema-btn {
  display: inline-grid; place-items: center; width: 26px; height: 26px; padding: 0;
  border: none; background: transparent; color: var(--texto-suave); border-radius: 999px;
  cursor: pointer;
  transition: background-color var(--dur-1) ease-out, color var(--dur-1) ease-out;
}
.tema-btn:hover { color: var(--texto); }
/* A opcao ativa ganha fundo --surface (destaca sobre o --surface-2 do
   grupo) e a cor da marca - unico lugar no cabecalho, fora do link ativo
   das abas, onde o acento verde aparece. */
.tema-btn[aria-pressed="true"] { background: var(--surface); color: var(--marca); box-shadow: var(--sombra-baixa); }
.tema-btn svg { width: 15px; height: 15px; }

/* ---------------- hero ---------------- */
.hero { padding: 36px 0 26px; }
.hero-txt h1 { font-size: 32px; line-height: 1.15; margin: 0 0 10px; }
.unidade {
  display: inline-block; font-size: var(--fs-xs); font-weight: 600; color: var(--texto-fraco);
  background: var(--surface-2); border: 1px solid var(--borda); border-radius: 999px;
  padding: 4px 10px; margin: 0 0 12px;
}
.sub { color: var(--texto-fraco); margin: 0; max-width: 62ch; font-size: 15px; }
/* Rodada 2: substitui o selo "unidade" + o paragrafo .sub + o
   .procedencia-atalho que ficavam empilhados - os 3 diziam versoes do mesmo
   aviso ("isto e %, nao R$", de onde vem o dado) antes do primeiro numero.
   Uma frase so, mesmo peso do .sub que ela substitui. */
.aviso-unico { color: var(--texto-fraco); margin: 0 0 10px; max-width: 62ch; font-size: 15px; }
.aviso-unico strong { color: var(--texto); }
.aviso-unico a { color: var(--texto-fraco); text-decoration: underline; }
.resumo { font-size: 17px; font-weight: 600; color: var(--texto); margin: 0 0 10px; max-width: 62ch; }
/* Frase de sazonalidade (rodada 3): era a informacao mais interessante da
   pagina (padrao historico, ex.: "a maior queda para um mes de agosto desde
   o inicio da serie") no estilo mais apagado - caixinha cinza pequena, o
   mesmo peso de um aviso de rodape. Agora fica proxima do peso de .resumo
   (que e negrito 17px): 15px, peso 600, cor --texto (nao --texto-fraco) -
   mas sem virar alerta colorido, entao nada de --alta/--baixa/--marca aqui.
   O border-left neutro e o mesmo recurso ja usado em .defasado (var(--neutro))
   pra dar uma borda de destaque sem introduzir uma cor nova ao sistema. */
.sazonal {
  font-size: 15px; font-weight: 600; color: var(--texto); background: var(--surface-2);
  border-radius: var(--raio-p); padding: 12px 16px; margin: 0 0 10px; max-width: 62ch;
  border-left: 3px solid var(--neutro);
}

/* Legenda de cor: quem cai direto numa pagina de produto (busca, link
   compartilhado) nao passou pela pagina inicial e nao tem como saber que
   vermelho e alta e azul e queda so pelo grafico. O sinal +/- ja garante
   que nenhum numero DEPENDE da cor pra ser lido - isto aqui e so a chave,
   uma linha, nao repete em toda tabela. */
.legenda-cor {
  display: flex; align-items: center; flex-wrap: wrap; gap: 5px 16px;
  font-size: var(--fs-xs); color: var(--texto-suave); margin: 10px 0 0;
}
.legenda-cor .ponto {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px;
}
.legenda-cor .ponto.alta { background: var(--alta); }
.legenda-cor .ponto.baixa { background: var(--baixa); }

select, input[type=search] {
  font: inherit; font-size: var(--fs-base); color: var(--texto); background: var(--surface-2);
  border: 1px solid var(--borda); border-radius: var(--raio-p); padding: 9px 12px;
  transition: border-color var(--dur-1) ease-out;
}

.procedencia-atalho {
  font-size: var(--fs-xs); color: var(--texto-suave); margin: 0 0 20px;
}
.procedencia-atalho a { color: var(--texto-fraco); text-decoration: underline; }

/* ---------------- kpis ---------------- */
/* Rodada 2: eram 3 cards do mesmo tamanho, com numeros quase iguais
   (-0,43/-0,32/-0,34) que nao diziam qual e o principal. Agora e um card
   grande (alimentacao no domicilio, com o seletor de cidade) e uma coluna
   de 2 cards pequenos ao lado - peso visual ja diz qual e o numero em
   destaque, sem apagar nenhum dado. */
/* :not(.kpis-3) - produto.html usa "kpis kpis-3" para as 3 variacoes do
   proprio produto (grid de 3 iguais, layout diferente deste); sem a
   exclusao essa regra vazaria pra la e quebraria aquele grid. */
.kpis:not(.kpis-3) { display: flex; gap: 14px; margin: 0 0 24px; align-items: stretch; flex-wrap: wrap; }
.kpi-regiao { flex: 1 1 320px; }
.kpis-sec { display: flex; flex-direction: column; gap: 8px; flex: 1 1 220px; max-width: 280px; }
.kpi-sec {
  flex: 1; background: var(--surface); border: 1px solid var(--borda); border-radius: var(--raio-p);
  padding: 8px 12px; box-shadow: var(--sombra-baixa);
}
.kpi-sec-nome { font-size: var(--fs-2xs); color: var(--texto-suave); font-weight: 600; }
.kpi-sec-linha { display: flex; align-items: baseline; gap: 6px; font-size: var(--fs-sm); font-weight: 700; }
.kpi-sec-linha + .kpi-sec-linha { font-size: var(--fs-xs); font-weight: 600; margin-top: 1px; }
.kpi-sec-rot { font-size: var(--fs-2xs); font-weight: 400; color: var(--texto-suave); }
/* Base do .kpis.kpis-3 da pagina de produto (3 variacoes do produto, grid
   igual) - continua em grid, so o card composto do index (acima) mudou. */
.kpis.kpis-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin: 0 0 32px; }
.kpi {
  background: var(--surface); border: 1px solid var(--borda); border-radius: var(--raio);
  padding: 18px; box-shadow: var(--sombra-alta);
}
.kpi-nome { font-size: var(--fs-sm); color: var(--texto-fraco); font-weight: 600; }
/* Card de "Alimentação no domicílio": junta o indicador nacional com o
   seletor de região (antigo card separado .hero-num). A enfase usa
   --surface-2, o mesmo tom ja usado em pill/input/chip ativo no resto do
   site - nao uma borda colorida usada so aqui (isso lia como estado de erro
   de formulario esquecido, nao como parte do sistema). Nunca por tamanho de
   fonte maior que os outros KPIs. */
.kpi-regiao { background: var(--surface-2); }
.kpi-regiao .kpi-nome { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.kpi-regiao select {
  font: inherit; font-size: var(--fs-xs); font-weight: 600; color: var(--texto-fraco);
  background: var(--surface); border: 1px solid var(--borda); border-radius: 999px;
  padding: 3px 10px;
}
.kpi-val { font-size: 32px; font-weight: 700; letter-spacing: -.02em; margin-top: 6px; }
.kpi-rot { font-size: var(--fs-xs); color: var(--texto-suave); }
.kpi-linha {
  display: flex; gap: 18px; margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--borda); font-size: var(--fs-xs); color: var(--texto-fraco); flex-wrap: wrap;
}
.kpis-3 .kpi { text-align: center; }

/* Corpo do card em 2 colunas: os numeros (largura de conteudo, nunca
   esticam) e o grafico de mes a mes ocupando o resto - antes desta secao o
   card so tinha os numeros, que nao enchem a largura inteira (~2/3 da
   pagina em telas largas) e sobrava vao vazio a direita. min-width:0 nos
   dois filhos: sem isso um <svg width="100%"> dentro de um filho flex nao
   encolhe abaixo do seu tamanho intrinseco, e o grafico empurraria o card
   mais largo que o resto da pagina. */
.kpi-regiao-corpo { display: flex; gap: 20px; align-items: stretch; }
.kpi-regiao-numeros { flex: 0 0 auto; min-width: 0; }
.kpi-regiao-grafico {
  flex: 1 1 200px; min-width: 0; display: flex; flex-direction: column; justify-content: center;
}
.kpi-regiao-grafico-legenda {
  font-size: var(--fs-2xs); font-weight: 600; color: var(--texto-suave); margin: 0 0 4px;
}
.kpi-regiao-grafico-legenda.atualizado { animation: valor-atualiza var(--dur-2) var(--ease-saida); }
.kpi-regiao-graf { width: 100%; }

/* Troca de numero no card de regiao: retorno de estado, nao decoracao - o
   numero mudou porque a pessoa trocou de cidade no seletor, e a animacao
   confirma que a troca aconteceu. So toca opacity/transform (nunca layout),
   e so roda quando a classe e reaplicada via JS depois do textContent
   mudar (ver app.js); no carregamento inicial da pagina nada anima. */
@keyframes valor-atualiza {
  from { opacity: .35; transform: translateY(var(--motion-y)); }
  to   { opacity: 1;   transform: translateY(0); }
}
.kpi-regiao .kpi-val.atualizado,
.kpi-regiao .kpi-linha b.atualizado {
  animation: valor-atualiza var(--dur-2) var(--ease-saida);
}

/* ---------------- destaques ---------------- */
/* minmax(0,1fr) em vez de 1fr puro: sem isso, cada trilha do grid herda o
   max-content dos itens que caem nela (ex.: o nome "Feijao - carioca
   (rajado)" alarga so a coluna dele), as duas metades ficam com larguras
   diferentes e, como o sparkline e SVG de proporcao fixa a 100% de largura,
   a diferenca de largura virava diferenca de altura entre os cartoes. */
.destaques { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px; margin-bottom: 36px; }
.destaques h2 { font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: .06em; margin: 0 0 12px; }
.tit-alta { color: var(--alta); }
.tit-baixa { color: var(--baixa); }
.grid-mini { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.mini {
  background: var(--surface); border: 1px solid var(--borda); border-radius: 12px;
  padding: 12px 12px 10px; display: block; color: var(--texto); box-shadow: var(--sombra-alta);
  transition: border-color var(--dur-1) ease-out, transform var(--dur-1) var(--ease-saida),
              box-shadow var(--dur-1) ease-out;
}
.mini:hover, .mini:focus-visible {
  text-decoration: none; border-color: var(--linha);
  transform: translateY(calc(var(--motion-y) * -0.5));
}
.mini-topo { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.mini-nome { font-weight: 600; font-size: var(--fs-sm); }
/* Rodada 2: o numero grande e sempre de 12 meses (o rotulo "12 meses" ao
   lado dele diz isso explicitamente agora) - antes so o "mes X%" no rodape
   dizia um periodo, e o numero grande ficava sem nenhum, dando a entender
   errado que os dois eram do mesmo periodo (ex.: cebola aparecia como maior
   alta com +50,9% e, logo abaixo, "queda" no mes, sem explicar que eram
   janelas diferentes). */
.mini-metrica { display: flex; flex-direction: column; align-items: flex-end; gap: 0; flex: 0 0 auto; }
.mini-12m { font-weight: 700; font-size: var(--fs-base); white-space: nowrap; }
.mini-periodo { font-size: var(--fs-2xs); color: var(--texto-suave); white-space: nowrap; }
/* Duas linhas fixas sempre (subgrupo em cima, "no mes X%" embaixo), em vez
   de lado a lado com wrap condicional - com side-by-side, so o cartao com
   nome de subgrupo comprido (ex.: "Cereais, leguminosas e oleaginosas")
   quebrava pra 2 linhas, ficava mais alto que os vizinhos e desalinhava as
   fileiras entre a grade de altas e a de quedas (duas .grid-mini
   independentes, sem track de linha compartilhado). Com altura fixa por
   cartao, as fileiras alinham entre as duas grades. */
.mini-rod {
  display: flex; flex-direction: column; gap: 2px;
  font-size: var(--fs-2xs); color: var(--texto-suave);
}
/* Antes cortava com reticencias em uma linha ("Cereais, leguminosas e
   oleagin…") - agora quebra em ate 2 linhas, nome do subgrupo inteiro
   sempre legivel. line-clamp com altura minima de 2 linhas: reserva o
   mesmo espaco em todo cartao, mesmo quando o nome cabe em 1 linha so. */
.mini-sub {
  min-width: 0; display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; overflow: hidden;
  min-height: calc(var(--fs-2xs) * 1.35 * 2); line-height: 1.35;
}
.mini-rod > span + span { white-space: nowrap; }
.dest-nota {
  grid-column: 1 / -1; margin: 2px 0 0; font-size: var(--fs-xs); color: var(--texto-suave);
}

/* ---------------- graficos ---------------- */
.colunas { width: 100%; height: auto; display: block; margin: 8px 0 6px; }
.colunas .eixo { fill: var(--texto-suave); font-size: 10px; font-family: var(--fonte); }
.colunas .valor-ponta {
  fill: var(--texto-fraco); font-size: var(--fs-2xs); font-weight: 600; font-family: var(--fonte);
}
.graf { margin-top: 14px; position: relative; }
.graf .colunas { margin: 0; }

/* Grafico do card "Alimentacao no domicilio" (build_site.py::colunas_cartao)
   - classes proprias (eixo-cartao/cartao-sem-dado), nao .colunas .eixo:
   aquela foi calibrada pro viewBox de 760 da pagina de produto (ou os 168 do
   mini-grafico), com uma proporcao renderizada bem diferente da deste
   grafico. margin:0 (nao os 8px/6px de .colunas): aqui o espaco vertical ja
   e curto por design (ver colunas_cartao), a margem padrao so voltava a
   abrir vao dentro do card.
   Tamanho de fonte por FAIXA, nao um valor so: o container troca de ~1,57x
   o viewBox em telas largas para ~0,94x no celular (medido em 1280/390 via
   getBoundingClientRect - a mesma largura renderizada de sempre, so a
   altura do viewBox mudou), entao a MESMA unidade de fonte do SVG rende
   tamanhos bem diferentes nos dois casos. 7,3px aqui * ~1,57 e 12,2px no
   @media abaixo * ~0,94 mandam os dois pra ~11,5px renderizado - a faixa de
   11-12px pedida, medida por elemento (nao estimada). */
.kpi-regiao-graf .colunas { margin: 0; }
.eixo-cartao { fill: var(--texto-suave); font-size: 7.3px; font-family: var(--fonte); }
.cartao-sem-dado { fill: var(--texto-suave); font-size: 6.5px; font-family: var(--fonte); }

/* ---------------- grafico interativo (pagina de produto) ---------------- */
/* So existe no grafico grande: os rects sao a area de acerto real (passo
   inteiro, nao a barra estreita), touch-action:pan-y deixa a rolagem
   vertical da pagina passar direto por cima mesmo durante um arraste
   horizontal no grafico. */
.colunas .alvo { fill: transparent; pointer-events: all; touch-action: pan-y; }
.colunas:focus-visible { outline: 2px solid var(--foco); outline-offset: 3px; border-radius: 4px; }

/* fill-opacity, nao opacity: essas barras sao formas so-fill (sem stroke
   fora do estado .ativa), entao fill-opacity da o mesmo resultado visual e
   e a propriedade certa pra isso - nao e substituindo um "bug" de opacity,
   e so a escolha mais precisa pra um <path> que so tem preenchimento. */
.colunas .barras path { transition: fill-opacity var(--dur-1) ease-out; }
.colunas .barras path.ativa { stroke: var(--texto); stroke-width: 1.5; }
/* Atenuacao por CSS (:not), nao por loop em JS tocando estilo barra a
   barra - so uma classe muda por vez, no grupo e na barra ativa. */
.colunas .barras.tem-selecao path:not(.ativa) { fill-opacity: .4; }

.tab tbody tr.destacada { background: var(--surface-2); }

.grafico-tooltip {
  position: absolute; left: 0; top: 0; transform: translate(-50%, calc(-100% - 10px));
  background: var(--texto); color: var(--bg); box-shadow: var(--sombra-alta);
  padding: 6px 10px; border-radius: var(--raio-p);
  white-space: nowrap; pointer-events: none; z-index: 5;
  opacity: 0; transition: opacity var(--dur-1) ease-out;
}
.grafico-tooltip.visivel { opacity: 1; }
.grafico-tooltip .valor {
  display: block; font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.grafico-tooltip .mes { display: block; font-size: var(--fs-2xs); opacity: .75; margin-top: 1px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* As barras crescem uma vez a partir da linha do zero quando a pagina
   carrega - confirma "aqui esta o grafico" sem atrasar o numero, que fica
   em texto normal ao lado e nao depende da animacao pra aparecer. So
   transform (scaleY a partir do proprio y0, ver build_site.py::colunas),
   curta o bastante pra nao virar enfeite. Zerada inteira em
   prefers-reduced-motion (bloco no topo do arquivo). */
@keyframes crescer-barras {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}
.colunas .barras {
  animation: crescer-barras var(--dur-2) var(--ease-saida) both;
}

/* ---------------- lista / filtros ---------------- */
.lista { margin-bottom: 40px; }
.lista-cab h2 { font-size: 20px; margin: 0 0 6px; display: flex; align-items: center; gap: 10px; }
.contagem {
  font-size: var(--fs-xs); font-weight: 600; color: var(--texto-fraco);
  background: var(--surface-2); border: 1px solid var(--borda);
  border-radius: 999px; padding: 2px 9px; letter-spacing: 0;
}
.lista-cab .sub { margin-bottom: 14px; }

.barra {
  position: sticky; top: var(--alt-topo); z-index: 20;
  background: var(--bg); padding: 12px 0; margin-bottom: 8px;
  border-bottom: 1px solid var(--borda);
}
.barra-linha { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.barra-linha #busca, .barra-linha #buscaAtacado { flex: 1; min-width: 220px; max-width: 420px; }
.ordem { font-size: var(--fs-sm); color: var(--texto-fraco); display: flex; align-items: center; gap: 8px; }

/* Mensagem de "nada encontrado": entra com um leve fade quando o atributo
   hidden sai (a animacao roda sozinha sempre que o elemento volta a ser
   renderizado - nao precisa de JS). As 168 linhas da tabela continuam
   aparecendo/sumindo na hora, sem animacao - isto aqui e so o aviso final. */
@keyframes entrar-suave {
  from { opacity: 0; transform: translateY(var(--motion-y)); }
  to   { opacity: 1; transform: translateY(0); }
}
.sem-resultado {
  color: var(--texto-fraco); padding: 24px 2px;
  animation: entrar-suave var(--dur-1) ease-out;
}

.como-ler {
  font-size: var(--fs-sm); color: var(--texto-fraco); background: var(--surface-2);
  border: 1px solid var(--borda); border-radius: var(--raio-p);
  padding: 10px 14px; margin: 0 0 14px; max-width: 80ch;
}
.como-ler strong { color: var(--texto); }
.atacado-cab { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1000px) {
  .atacado-cab { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 32px; align-items: start; }
  .atacado-cab .como-ler { margin: 4px 0 0; }
}

/* Rodada 2: os 17 subgrupos eram 17 <table> soltas com header proprio (168
   linhas, 10-12 mil px de rolagem) - agora cada um e um <details> fechado
   por padrao, com so uma linha de resumo (nome, quantos produtos, mediana
   12m, maior movimento). <details>/<summary> funciona sem JS: sem
   JavaScript da pra abrir cada grupo clicando, so falta a busca abrir
   sozinha o grupo certo (ver app.js). */
.grupos-controle { display: flex; gap: 8px; margin: 2px 0 14px; }
.grupos-controle button {
  font: inherit; font-size: var(--fs-xs); color: var(--texto-fraco); cursor: pointer;
  background: var(--surface); border: 1px solid var(--borda); border-radius: 999px;
  padding: 5px 12px; transition: border-color var(--dur-1) ease-out, color var(--dur-1) ease-out;
}
.grupos-controle button:hover { border-color: var(--linha); color: var(--texto); }

.grupo {
  margin: 10px 0 0; scroll-margin-top: calc(var(--alt-topo) + 90px);
  background: var(--surface); border: 1px solid var(--borda); border-radius: var(--raio);
  box-shadow: var(--sombra-baixa); overflow: hidden;
}
.grupo-resumo {
  list-style: none; cursor: pointer; padding: 12px 16px;
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  font-size: 15px; transition: background-color var(--dur-1) ease-out;
}
.grupo-resumo::-webkit-details-marker { display: none; }
/* Seta customizada em vez do triangulo padrao do navegador (que varia muito
   de estilo entre eles) - mesmo visual em todo navegador, gira ao abrir. */
.grupo-resumo::before {
  content: ""; flex: 0 0 auto; width: 7px; height: 7px; align-self: center;
  border-right: 2px solid var(--texto-suave); border-bottom: 2px solid var(--texto-suave);
  transform: rotate(-45deg); transition: transform var(--dur-1) ease-out;
}
.grupo[open] .grupo-resumo::before { transform: rotate(45deg); }
.grupo-resumo:hover { background: var(--surface-2); }
.grupo-nome { font-weight: 600; }
.grupo-meta { font-size: var(--fs-xs); color: var(--texto-suave); margin-left: auto; }
.grupo-meta b { font-weight: 700; }
.grupo .tab-wrap { border: none; border-radius: 0; box-shadow: none; border-top: 1px solid var(--borda); }

/* ---------------- tabelas ---------------- */
.tab-wrap {
  overflow-x: auto; background: var(--surface); border: 1px solid var(--borda);
  border-radius: var(--raio); box-shadow: var(--sombra-baixa);
}
.tab { width: 100%; border-collapse: collapse; font-size: var(--fs-base); }
.tab th, .tab td { padding: 10px 14px; text-align: left; border-bottom: 1px solid var(--borda); }
.tab thead th {
  color: var(--texto-suave); font-size: var(--fs-2xs); font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; white-space: nowrap; background: var(--surface);
}
.tab thead th.num, .tab td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tab tbody tr:last-child td { border-bottom: none; }
.tab tbody tr { transition: background-color var(--dur-1) ease-out; }
.tab tbody tr:hover, .tab tbody tr:focus-within { background: var(--surface-2); }
/* "Como ler esta tabela" (templates/atacado.html) diz que nome sublinhado
   tem pagina propria - sem isto o link ficava so em negrito preto, sem cara
   nenhuma de link, e o texto descrevia algo que a tela nao mostrava. */
.td-nome a {
  font-weight: 600; color: var(--texto); text-decoration: underline;
  text-decoration-color: var(--texto-suave); text-underline-offset: 3px;
  transition: color var(--dur-1) ease-out, text-decoration-color var(--dur-1) ease-out;
}
.td-nome a:hover { color: var(--marca); text-decoration-color: var(--marca); }

/* .tab-lista: so a tabela de produtos do index (dentro de cada <details> de
   subgrupo) - NAO a do atacado, que continua com nome sublinhado e negrito
   (o "Como ler esta tabela" de atacado.html descreve exatamente esse
   visual). table-layout:fixed + a mesma largura de coluna nas 17 tabelas
   resolve o ziguezague: antes cada <table> tinha largura automatica
   propria, entao "No mes" comecava num x diferente em cada uma - com todo
   .grupo tendo a mesma largura de cartao e as colunas numericas com largura
   fixa igual, o texto alinha entre todas. */
.tab-lista { table-layout: fixed; }
.tab-lista th.num, .tab-lista td.num { width: 108px; }
/* Linha inteira clicavel sem perder o <a> real (funciona sem JS, abre em
   aba nova com Ctrl+clique): ::after no proprio link vira um retangulo
   invisivel com inset:0 - como a <tr> (nao o <td>) e o ancestral posicionado
   mais proximo (position:relative abaixo), o retangulo cobre a linha
   inteira, nao so a celula do nome. O destaque ao passar o mouse/focar
   (.tab tbody tr:hover / :focus-within, ja existia acima) continua por
   linha inteira, sem mudar. */
.tab-lista tbody tr { position: relative; }
.tab-lista .td-nome a {
  font-weight: 400; text-decoration: none; color: var(--texto);
}
.tab-lista .td-nome a:hover { color: var(--marca); text-decoration: none; }
.tab-lista .td-nome a::after { content: ""; position: absolute; inset: 0; }

.un {
  color: var(--texto-suave); font-size: var(--fs-2xs); background: var(--surface-2);
  border-radius: 5px; padding: 1px 6px; margin-left: 6px;
}
.faixa-mobile { display: none; }

/* Barra de faixa por linha (atacado.html, rodada 3): trilho na propria
   escala da linha (0%=minimo, 100%=maximo daquele produto - nunca
   comparavel entre linhas, ver comentario no template) com um traco na
   posicao do "comum" (--pct, inline por linha). Neutra de proposito - sem
   vermelho/azul/verde, so os tons de cinza ja usados no resto do site. */
.col-faixa { width: 96px; }
.faixa-bar {
  position: relative; display: inline-block; width: 84px; height: 14px;
  vertical-align: middle;
}
.faixa-trilha {
  position: absolute; left: 0; right: 0; top: 50%; height: 3px;
  transform: translateY(-50%); background: var(--linha); border-radius: 999px;
}
/* Bolinhas nas pontas (minimo/maximo): marcam onde a faixa comeca e termina,
   sem precisar de rotulo - os valores em R$ ja estao no texto ao lado
   (tabela no computador, .faixa-mobile no celular). */
.faixa-trilha::before, .faixa-trilha::after {
  content: ""; position: absolute; top: 50%; width: 4px; height: 4px;
  background: var(--linha); border-radius: 50%; transform: translateY(-50%);
}
.faixa-trilha::before { left: 0; }
.faixa-trilha::after { right: 0; }
.faixa-tick {
  position: absolute; top: 50%; left: var(--pct, 50%); width: 2px; height: 14px;
  background: var(--texto); transform: translate(-50%, -50%); border-radius: 1px;
}
/* No celular a barra entra na mesma linha discreta que ja mostra
   minimo/maximo/cobertura por texto (.faixa-mobile) - menor, sem as
   bolinhas de ponta (que a essa largura viram um borrao) e com quebra de
   linha proria acima dela pra nao espremer contra o texto. */
.faixa-mobile .faixa-bar { width: 56px; height: 12px; margin-left: 6px; }
.faixa-mobile .faixa-trilha::before, .faixa-mobile .faixa-trilha::after { display: none; }
.fraco { color: var(--texto-fraco); }
.destaque-num { font-weight: 700; }

.alta { color: var(--alta); }
.baixa { color: var(--baixa); }
.neutro { color: var(--neutro); }

/* ---------------- produto ---------------- */
.migalha { font-size: var(--fs-sm); color: var(--texto-suave); padding-top: 18px; display: flex; gap: 8px; }
.cartao {
  background: var(--surface); border: 1px solid var(--borda); border-radius: var(--raio);
  padding: 20px; box-shadow: var(--sombra); margin-bottom: 20px;
}
.cartao > h2 { font-size: 16px; margin: 0 0 4px; }
.cartao .tab-wrap { border: none; box-shadow: none; border-radius: 0; margin-top: 12px; }
.cartao .tab thead th { background: transparent; }
.nota-regiao { margin-top: 10px; }

/* Resumo curto do atacado (rodada 3): a resposta a "quanto custa" tinha que
   estar perto do topo, nao so no fim do bloco completo de atacado (grafico +
   13 linhas de tabela). Peso visual parecido com .kpi (mesma sombra-alta,
   numero grande), mas sem virar um 4o KPI - fica como cartao proprio logo
   abaixo dos KPIs, com o aviso de "nao e preco de gondola" junto do numero,
   nao separado la embaixo. */
.ceasa-flash {
  background: var(--surface); border: 1px solid var(--borda); border-radius: var(--raio);
  padding: 16px 20px; margin: 0 0 20px; box-shadow: var(--sombra-alta);
}
.ceasa-flash-cab {
  font-size: var(--fs-xs); font-weight: 600; color: var(--texto-suave);
  text-transform: uppercase; letter-spacing: .05em; margin: 0 0 6px;
}
.ceasa-flash-linha {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px;
  font-size: 22px; font-weight: 700; margin: 0;
}
.ceasa-flash-linha + .ceasa-flash-linha { margin-top: 2px; }
.ceasa-flash-variedade { font-size: var(--fs-sm); font-weight: 400; color: var(--texto-fraco); }
.ceasa-flash-meta { font-size: var(--fs-xs); font-weight: 400; color: var(--texto-suave); }
.ceasa-flash-aviso { margin: 10px 0 0; }

/* Grafico "Variacao mes a mes" e tabela "Historico mensal" lado a lado no
   computador (rodada 3): os dois sao ligados (passar o mouse numa coluna
   acende a linha da tabela e vice-versa, ver app.js) - empilhados, com o
   grafico bem acima da tabela, a linha acesa ficava fora da tela ao passar o
   mouse no grafico. Lado a lado os dois ficam visiveis juntos. So a partir de
   1000px: abaixo disso a coluna do grafico ficaria estreita demais para os
   13 rotulos de mes (a mesma faixa em que o eixo ja fica pequeno demais -
   ver o ajuste de fonte abaixo). Empilhado (1 coluna) e o padrao,
   inclusive no celular. */
.hist-par { display: grid; grid-template-columns: 1fr; gap: 20px; margin: 0 0 20px; }
.hist-par .cartao { margin-bottom: 0; }
@media (min-width: 1000px) {
  .hist-par { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  /* A tabela tem 13 linhas e o grafico bem menos altura: sem isto sobra um
     vao embaixo do grafico, e rolando a tabela ele sai da tela - e a linha
     acesa ao passar o mouse na tabela perde a coluna correspondente. */
  .hist-par .cartao-grafico { position: sticky; top: calc(var(--alt-topo) + 16px); }
  /* A coluna do grafico fica com ~metade da largura que ele tinha sozinho
     (medido: viewBox 760 renderiza a ~550px em vez de ~1040px a 1280px de
     tela) - o mesmo problema de rotulo pequeno que ja existia no celular,
     so que aqui. Reusa a mesma solucao: so os rotulos "eixo-chave" (a cada
     3 meses, ver build_site.py::colunas), com fonte maior so neles. */
  .hist-par .colunas .eixo { display: none; }
  .hist-par .colunas .eixo.eixo-chave { display: inline; font-size: 15px; }
  .hist-par .colunas .valor-ponta { font-size: 13px; }
}

/* "No atacado": o aviso de que o preco e da CEASA, nao da gondola, precisa
   chamar mais atencao que um .sub comum - por isso o mesmo tratamento visual
   que .como-ler ja usa (fundo --surface-2), nao so texto cinza. */
.aviso-ceasa {
  background: var(--surface-2); border: 1px solid var(--borda); border-radius: var(--raio-p);
  padding: 10px 14px; margin: 0 0 16px; max-width: 72ch; font-size: var(--fs-sm);
}
.aviso-ceasa strong { color: var(--texto); }
.atacado-item { margin-top: 4px; }
.atacado-item + .atacado-item {
  margin-top: 22px; padding-top: 20px; border-top: 1px solid var(--borda);
}
.atacado-variedade { font-size: 14px; margin: 0 0 6px; }
.atacado-resumo { margin: 0 0 4px; max-width: 68ch; }
.atacado-uf { margin: 0 0 10px; }
.graf-atacado { margin-top: 10px; }
/* width:100%/height:auto/display:block, mesma receita de .colunas: sem isso
   o <svg> so-viewBox (sem width/height no elemento) fica a mercê do
   tamanho-padrao do navegador em vez de escalar com o cartao. */
.linha-precos { width: 100%; height: auto; display: block; }
/* 9 unidades do viewBox (700 de largura) dao ~13,8px num cartao de 1046px -
   o mesmo tamanho renderizado do eixo de .colunas logo acima na pagina. Com
   11 o eixo saia do tamanho do texto do corpo, e eixo tem que ser recessivo. */
.linha-precos .eixo { fill: var(--texto-suave); font-size: 9px; font-family: var(--fonte); }
.linha-precos .valor-ponta {
  fill: var(--texto); font-size: var(--fs-2xs); font-weight: 700; font-family: var(--fonte);
  /* O rotulo fica junto do ultimo ponto e cai em cima da propria linha; o
     contorno na cor do cartao abre um vao atras do texto em vez de mover o
     rotulo para longe do ponto que ele nomeia. */
  paint-order: stroke; stroke: var(--surface); stroke-width: 4px; stroke-linejoin: round;
}
.intervalo-atacado { margin: 6px 0 0; }

/* "Variacao em cada ano" (build_site.py::colunas_anuais) - classes proprias
   (nao .colunas .eixo/.valor-ponta) de proposito: aquelas somem na maior
   parte no celular (@media max-width:700px abaixo), certo para 13 meses
   apertados mas errado aqui, onde so ha ~7 colunas e o rotulo/valor de
   CADA ano e o proprio conteudo do bloco - os dois tem que continuar
   visiveis em qualquer largura. */
.cartao-anos .graf { margin-top: 10px; }
.colunas-anuais .rotulo-ano {
  fill: var(--texto-suave); font-size: 11px; font-family: var(--fonte);
}
.colunas-anuais .valor-ano {
  fill: var(--texto-fraco); font-size: var(--fs-2xs); font-weight: 600; font-family: var(--fonte);
}

.tab-atacado-detalhe { margin-top: 12px; }
.tab-atacado-detalhe summary {
  cursor: pointer; font-size: var(--fs-sm); font-weight: 600; color: var(--texto-fraco);
}
.tab-atacado-detalhe summary:hover { color: var(--texto); }
.tab-atacado-detalhe .tab-wrap { margin-top: 10px; max-height: 320px; overflow-y: auto; }

.vizinhos { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; margin: 28px 0 40px; }
.viz {
  background: var(--surface); border: 1px solid var(--borda); border-radius: var(--raio-p);
  padding: 12px 14px; display: block; color: var(--texto);
  transition: border-color var(--dur-1) ease-out, transform var(--dur-1) var(--ease-saida);
}
.viz:hover, .viz:focus-visible {
  text-decoration: none; border-color: var(--linha);
  transform: translateY(calc(var(--motion-y) * -0.5));
}
.viz-rot { display: block; font-size: var(--fs-2xs); color: var(--texto-suave); }
.viz-nome { font-weight: 600; font-size: var(--fs-sm); }
.viz-prox { text-align: right; }
.viz-grupo { text-align: center; }

/* ---------------- avisos e rodape ---------------- */
.defasado {
  margin: 16px 0 0; padding: 12px 16px; font-size: var(--fs-sm); color: var(--texto-fraco);
  background: var(--surface); border: 1px solid var(--borda);
  border-left: 3px solid var(--neutro); border-radius: var(--raio-p);
}
.aviso {
  background: var(--surface); border: 1px solid var(--linha); border-left: 3px solid var(--neutro);
  border-radius: var(--raio); padding: 18px;
}
.aviso p { margin: 0 0 8px; }
.aviso p:last-child { margin-bottom: 0; }
code { background: var(--surface-2); padding: 2px 6px; border-radius: 6px; font-size: var(--fs-sm); }

.rodape {
  border-top: 1px solid var(--borda); background: var(--surface);
  margin-top: 24px; padding: 26px 0 44px;
}
.rodape p { color: var(--texto-fraco); font-size: var(--fs-sm); margin: 0 0 8px; max-width: 80ch; }
.fino { font-size: var(--fs-xs); color: var(--texto-suave); }

/* ---------------- procedencia dos dados ---------------- */
/* max-width no cartao inteiro, nao so no texto: sem isso, num monitor largo
   o cartao ficava com uma faixa em branco a direita do paragrafo (bordas e
   sombra do cartao esticadas ate 1120px so pra emoldurar vazio). */
.procedencia {
  margin: 40px 0 8px; padding: 20px 22px; background: var(--surface); max-width: 760px;
  border: 1px solid var(--borda); border-radius: var(--raio); box-shadow: var(--sombra);
}
.procedencia h2 { font-size: 16px; margin: 0 0 10px; }
.procedencia p { color: var(--texto-fraco); font-size: var(--fs-base); max-width: 70ch; margin: 0 0 10px; }
.procedencia p:last-child { margin-bottom: 0; }
.procedencia-prova {
  display: inline-block; background: var(--surface-2); border: 1px solid var(--borda);
  border-radius: var(--raio-p); padding: 12px 14px; font-weight: 600; color: var(--texto-fraco);
}
.procedencia-prova a { font-weight: 700; }

/* ---------------- responsivo ---------------- */
@media (max-width: 900px) {
  /* minmax(0, 1fr), nao so "1fr": mesmo motivo do comentario la em cima
     (.destaques) - sem o minimo zerado, o track de 1 coluna soh herdava
     como largura minima automatica o min-content dos filhos, e o grafico
     SVG do carrossel (rodada 2, ver .grid-mini abaixo) tem largura
     intrinseca grande o bastante pra empurrar a pagina inteira mais larga
     que a tela (medido: 840px de largura no card, viewport de 390px). */
  .destaques { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 700px) {
  .hero { padding: 24px 0 20px; }
  .hero-txt h1 { font-size: 25px; }
  /* Rodada 2: os 12 cartoes empilhados em 1 coluna viravam uma parede antes
     da lista de produtos (o motivo pelo qual a rodada 1 escondia os 4
     ultimos de cada lado). Agora e uma faixa horizontal com scroll-snap -
     nenhum cartao escondido, "arraste pra ver mais" fica implicito pelo
     proximo cartao cortado na borda (mesmo esmaecimento que os chips
     usavam) sem gastar altura vertical nenhuma. */
  .grid-mini {
    display: flex; grid-template-columns: none; overflow-x: auto; gap: 10px;
    scroll-snap-type: x mandatory; scrollbar-width: none; padding-bottom: 2px;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 22px), rgba(0, 0, 0, .5) 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 22px), rgba(0, 0, 0, .5) 100%);
  }
  .grid-mini::-webkit-scrollbar { display: none; }
  .grid-mini .mini { flex: 0 0 80%; scroll-snap-align: start; }
  /* Atacado: 5 colunas nao cabem em 390px sem rolagem lateral escondida
     (medido: Cobertura ficava a partir de x=361, fora da faixa visivel de
     358px). Minimo/Maximo/Cobertura viram uma linha junto do nome do
     produto em vez de sumirem da tela; Comum (o valor de destaque) continua
     como coluna. */
  .col-minmax, .col-cobertura, .col-faixa { display: none; }
  .faixa-mobile {
    display: flex; align-items: center; flex-wrap: wrap; gap: 2px 4px;
    font-size: var(--fs-2xs); color: var(--texto-suave); margin-top: 2px;
  }
  /* kpi-regiao ocupa a linha inteira, os 2 secundarios dividem a de baixo -
     empilhar os 3 (regiao + 2 secundarios) so uma embaixo da outra jogaria
     a busca (que ja esta logo depois) mais pra baixo sem necessidade. */
  .kpi-regiao { flex: 1 1 100%; }
  /* O card fica estreito demais pras 2 colunas lado a lado (numeros +
     grafico) - o grafico desce pra baixo dos numeros, largura inteira. */
  .kpi-regiao-corpo { flex-direction: column; }
  /* flex:1 1 200px (regra base, pra largura na tela larga) empilhada vira
     ALTURA minima de 200px - a base e o eixo principal do flex trocam de
     sentido junto com flex-direction. Sem isto o grafico ficava dentro de
     uma caixa de 200px de altura so pra ser centralizado nela (justify-
     content:center), abrindo um vao vazio embaixo dele so no celular. */
  .kpi-regiao-grafico { flex: 0 0 auto; width: 100%; }
  .kpis-sec { flex-direction: row; max-width: none; }
  .kpis-3 { grid-template-columns: repeat(3, 1fr); gap: 8px; }
  .kpis-3 .kpi { padding: 14px 8px; }
  .kpis-3 .kpi-val { font-size: 21px; }
  .topo-in { gap: 8px; }
  /* Rodada 2: eram ate 4 linhas (~165px) - marca sozinha, tema sozinho,
     abas, datas. 2 linhas agora: marca+tema dividem a 1a (o tema ja fazia
     isso), abas ficam sozinhas na 2a. As datas por fonte (item 5 da rodada
     1) saem do cabecalho no celular - o texto ja aparece na frase logo
     abaixo do titulo ("...do IPCA/IBGE em {{referencia}}") e no rodape;
     manter as duas linhas do cabecalho mais importava aqui do que repetir
     a data uma 3a vez. */
  .tema { order: 2; margin-left: auto; }
  .abas { order: 3; width: 100%; margin-left: 0; }
  .topo-meta { display: none; }
  /* No celular as abas quebram para uma 2a linha e o cabecalho fica mais alto
     que --alt-topo; em vez de perseguir essa altura (que ainda varia com o
     tamanho de fonte do usuario), tira o cabecalho do fluxo fixo para que a
     barra de busca, colada no topo da janela, nunca fique atras dele. */
  .topo { position: static; }
  .barra { top: 0; }
  .vizinhos { grid-template-columns: 1fr; }
  .viz-prox, .viz-grupo { text-align: left; }
  .tab th, .tab td { padding: 10px; }
  /* 108px por coluna numerica (valor de computador) sobrava pouco pro nome
     em 390px - 76px ainda cabe "+123,45%" sem quebrar (o maior valor real
     do site tem bem menos digitos que isso) e devolve espaco pro nome. */
  .tab-lista th.num, .tab-lista td.num { width: 76px; }
  /* No atacado (5 colunas) a tabela costuma ficar mais larga que a tela no
     celular; o esmaecimento na borda direita avisa que da pra rolar, no
     mesmo estilo ja usado nos chips de subgrupo. */
  .tab-wrap {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 20px), rgba(0, 0, 0, .55) 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 20px), rgba(0, 0, 0, .55) 100%);
  }
  /* Rotulo de mes do grafico grande: viewBox de 760 renderizado em ~316-358px
     no celular escala um font-size de 10 (unidade de viewBox) pra ~4px na
     tela - o font-size de elemento SVG escala junto com a geometria, nao e
     um px de CSS fixo independente do viewBox. Mostra so posicoes
     interiores (build_site.py garante que .eixo-chave nunca e a primeira
     nem a ultima) com fonte maior so pra essas - cabe sem sobrepor porque
     sobra 3x mais espaco entre elas, e cada uma fica centrada na propria
     coluna, sem truque de ancora. As pontas (ago/25 e ago/26) ficam sem
     rotulo no celular: o mes exato continua no balao (toque/arraste) e na
     tabela logo abaixo - nunca um rotulo fora do lugar. */
  .colunas .eixo { display: none; font-size: 22px; }
  .colunas .eixo.eixo-chave { display: inline; }
  /* Grafico do card do topo (colunas_cartao): no celular o container
     renderiza a ~0,94x o viewBox (bem mais perto de 1:1 que os ~1,57x da
     tela larga, onde o CSS acima ja usa uma unidade bem menor) - precisa da
     PROPRIA unidade de fonte pra continuar em ~11-12px renderizado (ver
     comentario junto de .eixo-cartao). */
  .eixo-cartao { font-size: 12.2px; }
  .cartao-sem-dado { font-size: 10.5px; }
  /* Mesma conta de escala do comentario acima (viewBox 760 ~0.45x no
     celular), mas aqui os rotulos NAO somem - "Variacao em cada ano" so
     tem ~7 colunas, cabe manter todas visiveis, so maiores. */
  .colunas-anuais .rotulo-ano { font-size: 20px; }
  .colunas-anuais .valor-ano { font-size: 20px; }
  /* Mesma escala de viewBox, mesmo problema: 11 unidades vira ~6px na tela.
     O valor da ultima coluna ja aparece grande no cartao "No mes" acima -
     tirar daqui no celular nao perde informacao, so a duplicata ilegivel. */
  .colunas .valor-ponta { display: none; }
  /* Mesmo defeito, grafico de linha do atacado: o cartao renderiza a ~316px
     no celular contra um viewBox de 700 (fator ~0.45x) - 11px de font-size
     vira ~5px na tela, medido. Diferente de .colunas, aqui NAO da pra so
     esconder e mostrar menos rotulos: ja emite so 2 no Y e 3 no X (poucos
     desde o desktop, nao 13 como o eixo de mes), entao os poucos que existem
     precisam crescer todos. 25px de viewBox * ~0.45 = ~11px renderizado -
     o minimo pedido; a margem esquerda do grafico (build_site.py::
     grafico_precos, "esq") ja reserva espaco pensando nesse tamanho maior. */
  .linha-precos .eixo { font-size: 25px; }
  /* O rotulo direto do ultimo ponto ("R$ 6,45") duplica o valor "comum" que
     ja aparece em negrito no paragrafo-resumo logo acima do grafico -
     mesma logica de .colunas .valor-ponta: no celular vira ilegivel (~5px)
     e esconder nao perde informacao nenhuma, so a copia pequena demais. */
  .linha-precos .valor-ponta { display: none; }
}
