/**
 * Painel — as pecas do prototipo aprovado que nao existiam no codigo.
 * Especificacao: docs/design/sintese/dashboard.html
 * Racional: docs/design/DECISAO.md secoes 5 (linguagem), 7 (Fase 2), 8 (riscos)
 *
 * As pecas, na ordem em que aparecem na tela:
 *
 *   1. `.state` / `.state-card` — o cartao "Estado do monitoramento" ao lado da
 *                          faixa de KPIs. E o PRIMEIRO bloco do Painel.
 *   2. `.kpis` / `.kpi`  — a faixa de KPIs em mono, com delta e a barra medida
 *                          (calibracao 2: contra a faixa propria de 12 meses).
 *   3. `.series`         — a serie e a decomposicao lado a lado (2fr/1fr).
 *   4. `.decomp`         — "Para onde foram os N pontos": barras divergentes.
 *   5. `.coverage`       — Cobertura: quem publicou, sobre o que, em que formato.
 *   6. `.units`          — Unidades: composicao, NSS, faixa propria e desvio.
 *   7. `.events`         — Acontecimentos por repercussao: distribuicao por
 *                          tamanho, faixa-ponte do escopo e a lista ordenada
 *                          por publicacoes.
 *
 * A barra medida (`.measure`) tem o MESMO desenho nos KPIs e nas linhas de
 * unidade — trilho + faixa de referencia + mediana + marcador. Aprende-se uma
 * vez, le-se em dois contextos (DECISAO.md secao 5, "a barra medida").
 *
 * REGRA DE OURO DESTE ARQUIVO: nenhuma faixa e desenhada sem faixa vinda do
 * backend. A classe `.measure` so e emitida quando `linha-de-base` traz a faixa
 * daquele objeto; sem ela o lugar fica com o estado explicito `.measure-none`,
 * que diz o motivo (quantos meses faltam, ou que nao houve materia no mes de
 * referencia). O prototipo mostra "faixa historica 75,2-84,6%" porque e um
 * mockup; um numero desses sem lastro no endpoint seria invencao.
 *
 * A FAIXA DESENHADA E p10-p90, e nao minimo-maximo. E de p10-p90 que sai o
 * rotulo `acima`/`na_faixa`/`abaixo` no backend; desenhar minimo-maximo e
 * rotular por p10-p90 poria um marcador visivelmente dentro da barra com o
 * texto "abaixo" ao lado. Os extremos ficam no `title`.
 */

/* ============================================================================
   Rotulo condensado — o "lbl" do prototipo
   ========================================================================= */

.lbl {
  font-family: var(--font-primary);
  font-stretch: 78%;
  font-weight: var(--font-semibold);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-size: 10.5px;
  color: var(--ink-2);
}

.num,
.mono {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   0. #dashboard-content — a grade de sangria do Painel
   ========================================================================= */

/* Sem esta regra, `#dashboard-content` e um `div` comum (sem `display` proprio
   no CSS antigo — a pilha de secoes vinha do fluxo normal de bloco, cada uma
   com o proprio `margin-bottom`). A grade muda ISSO: 1fr | coluna do meio | 1fr,
   onde a coluna do meio e `min(--page-max, 100% - 2×gutter)` — main.css tem o
   racional completo. Sem `gap`: o espacamento entre secoes continua vindo so
   do `margin-bottom` de cada uma (`section` em main.css, `.state`/`.series` com
   override proprio aqui), exatamente como antes — declarar `gap` aqui somaria
   em cima disso. `.scope` (a unica `.sangria` desta aba) vira `grid-column:
   1 / -1` em main.css; todo o resto cai na coluna 2 pela mesma regra. */
#dashboard-content {
  display: grid;
  grid-template-columns: 1fr min(var(--page-max), calc(100% - 2 * var(--page-gutter))) 1fr;
}

/* ============================================================================
   1. Estado do monitoramento + faixa de KPIs
   ========================================================================= */

/* A grade do prototipo: cartao fixo a esquerda, KPIs ocupando o resto. O cartao
   nao e um KPI a mais — e a leitura do periodo em prosa, e por isso tem largura
   propria e nao entra na divisao por quatro. */
.state {
  display: grid;
  grid-template-columns: 340px minmax(0, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}

.state-card {
  background: var(--surface);
  border: 1px solid var(--rule);
  /* O fio da esquerda e o unico croma do chrome, e ele diz o estado. Neutro
     enquanto nao houver estado apurado — nao ha "cinza de atencao". */
  border-left: 3px solid var(--rule-2);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  min-width: 0;
}

.state-card-warn { border-left-color: var(--warn); }
.state-card-pos { border-left-color: var(--pos); }

/* A PALAVRA DE ESTADO EXPANDIDA — item 3.5 da auditoria visual 2026-08-17.
   DECISAO.md §5 promete "palavra de estado expandida ~118%" como dimensao de
   hierarquia; a especificacao (dashboard.html:147-150) e 30px, cor de
   atencao, font-stretch 118%. Medido: o elemento renderizava a 13px PRETA,
   no proprio prototipo E no produto de ontem, porque `.state-card p`
   (0-1-1: uma classe + um elemento) vence `.state-word` (0-1-0: uma classe)
   — a palavra e um `<p class="state-word">` (baseline.js `_estadoHtml`), e
   cai nas DUAS regras; a de maior especificidade ganha, na ordem que for.

   A correcao repete a tecnica que `.decomp-state p.decomp-state-word` ja usa
   umas cem linhas abaixo, no MESMO arquivo, para o MESMO problema: qualificar
   com o elemento para subir a especificidade a 0-2-1, acima de `.state-card
   p` (0-1-1). As duas variantes de cor (warn/pos) precisam da MESMA
   especificidade (0-2-1) e vem DEPOIS da regra base, para o empate se
   resolver por ordem de fonte a favor delas.

   Contraste verificado nos dois temas (formula WCAG 2.x, as mesmas contas do
   comentario de `.decomp-state-word` abaixo — --warn-ink e --pos-ink sao os
   MESMOS tokens, e a superficie e a MESMA --surface, herdada de `.state-card`):
     --warn-ink sobre --surface: 5,74:1 claro · 5,49:1 escuro (par ja medido)
     --pos-ink  sobre --surface: 5,73:1 claro · 5,44:1 escuro (medido agora)
   Os dois pares passam AA (>=4,5:1; texto de 30px so precisaria de 3:1) nos
   dois temas — nao houve necessidade de escurecer alem do que os tokens
   `-ink` ja fazem, porque `.insight-stamp` ja resolveu o mesmo problema com
   os MESMOS tokens (main.css, comentario de `.insight-stamp.atencao`). Nao
   inventei cor nova; reusei a que o resto da tela ja usa para "atencao" e
   "favoravel" em texto sobre superficie. */
.state-card p.state-word {
  font-family: var(--font-primary);
  font-stretch: 118%;
  font-weight: var(--font-bold);
  font-size: 30px;
  line-height: 1.05;
  letter-spacing: 0.015em;
  color: var(--ink);
  margin: 2px 0 var(--space-3);
  max-width: none;
}

.state-card-warn p.state-word { color: var(--warn-ink); }
.state-card-pos p.state-word { color: var(--pos-ink); }

.state-card p {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink);
  margin: 0 0 var(--space-2);
  max-width: 46ch;
}

.state-card p b {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
}

/* A oracao da decomposicao: mesma frase, um degrau abaixo na hierarquia. */
.state-card .state-sec {
  color: var(--ink-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--rule);
}

.state-card .state-meta {
  margin: var(--space-3) 0 0;
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ink-3);
}

/* "Como isto e calculado" — mitigacao registrada do risco 1 de DECISAO.md §8
   ("a frase de diagnostico pode errar com autoridade de maquina"): o metodo
   inteiro fica a um clique, com os numeros deste recorte. */
.state-how {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--act);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

/* ============================================================================
   2. Faixa de KPIs
   ========================================================================= */

/* Grade de celulas separadas por fio de 1px: o `gap: 1px` sobre fundo `--rule`
   desenha as divisorias sem uma borda por celula (que dobraria de espessura nos
   encontros). E o mesmo truque do prototipo. */
.kpis {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.kpis-4 {
  grid-template-columns: repeat(4, 1fr);
}

.kpi {
  background: var(--surface);
  padding: var(--space-4);
  min-width: 0;
}

/* `line-height` NAO e declarado aqui de proposito (item 1.13 da auditoria
   visual 2026-08-17, prescrito pelo worker de escala): a regra antiga
   fixava 1.1 (33,0px renderizado) contra os 43,5px do prototipo. Sem a
   declaracao, o elemento herda a razao do corpo (`main.css`, ~1.45 depois da
   mudanca de 16px para 13,5px) — 30px * 1.45 = 43,5px, o numero certo. */
.kpi .v {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
  font-size: 30px;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 5px 0 var(--space-3);
}

.kpi .v small {
  font-size: 15px;
  font-weight: var(--font-regular);
  color: var(--ink-2);
}

/* Numero de apoio (as citacoes ao lado das materias, por exemplo). Nunca e o
   numero grande, e nunca aparece sozinho. */
.kpi .sub {
  margin: 0 0 var(--space-2);
  font-size: 11.5px;
  color: var(--ink-2);
}

.kpi .sub b {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
  color: var(--ink);
}

/* --- A barra medida, calibracao 2: o valor contra a propria faixa --- */

/* `display: block` NAO e cosmetico. O elemento e um `<span>` (para poder ser
   filho de um botao, no caso da linha de unidade), e um inline ignora `height` e
   toma a largura do conteudo — que aqui e zero, porque os tres filhos sao
   absolutos. A barra colapsava num ponto de 8px. Nao aparecia antes porque
   nenhuma faixa chegava a ser desenhada. */
.measure {
  display: block;
  position: relative;
  width: 100%;
  height: 8px;
  background: var(--sunken);
  border-radius: 2px;
}

/* A faixa de referencia sobre o trilho.
   O FIO DE `--ink-3` NAO E ENFEITE. `--band` sobre `--sunken` mede 2,01:1 no
   claro e 2,00:1 no escuro — abaixo do piso de 3:1 que WCAG 1.4.11 exige de
   objeto grafico necessario para entender o conteudo, e esta faixa e o
   conteudo. O par de tokens nunca reprovou antes porque a faixa nunca chegou a
   ser desenhada (nao havia linha de base no payload); ao acende-la, a
   reprovacao passou a valer. O contorno resolve pela borda, sem mexer no token
   `--band`, que e de outro arquivo: `--ink-3` contra `--sunken` mede 4,68:1 no
   claro e 5,87:1 no escuro. Mesmo raciocinio de `.minibar.plain`, logo abaixo. */
.measure .mband {
  position: absolute;
  top: 0;
  bottom: 0;
  box-sizing: border-box;
  background: var(--band);
  border: 1px solid var(--ink-3);
  border-radius: 2px;
}

.measure .mmed {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 1px;
  background: var(--rule-2);
}

.measure .mdot {
  position: absolute;
  top: 50%;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  border: 1.5px solid var(--surface);
}

.mdot.ok { background: var(--pos); }
.mdot.bad { background: var(--neg); }
.mdot.warnc { background: var(--warn); }

/* O marcador NEUTRO. Existe porque o `rotulo` do backend e posicional e nao
   avaliativo: "acima da faixa" em volume de materias nao e boa nem ma noticia,
   e um ponto verde ali seria opiniao que o dado nao carrega. So os indicadores
   de sentimento (pct_positivo, nss) recebem `ok`/`bad`. */
.mdot.neutral { background: var(--ink); }

/* A LINHA QUE IMPEDE A LEITURA ERRADA DO CARTAO.
   O numero grande do KPI e o total do RECORTE; a barra mede o valor do MES DE
   REFERENCIA. Sao bases diferentes (um total de dezenove meses nao cabe numa
   distribuicao feita de meses), e sem esta linha a barra pareceria medir o
   numero grande. Ver Baseline.medida(). */
.kpi .mfoot {
  display: block;
  margin-top: 5px;
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  line-height: 1.5;
  color: var(--ink-2);
}

.kpi .mfoot b {
  font-weight: var(--font-semibold);
  color: var(--ink);
}

/* O rotulo em linha propria: a celula do KPI tem ~200px e "434 em jul/2026 ·
   acima da faixa" nunca cabe numa linha so — quebrando, o separador ficava
   pendurado no fim da primeira. */
.kpi .mfoot .tag {
  display: block;
  width: fit-content;
  margin-top: 3px;
  font-style: normal;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  background: var(--sunken);
  color: var(--ink-2);
}

.kpi .mfoot .tag.ok { background: var(--pos-soft); color: var(--pos-ink); }
.kpi .mfoot .tag.bad { background: var(--neg-soft); color: var(--neg-ink); }

/* Sem linha de base, ou sem medicao no mes: o lugar da barra fica ocupado pelo
   ESTADO, com o motivo no `title` — nunca por uma faixa estimada. */
.measure-none {
  display: block;
  font-size: 10.5px;
  line-height: 1.35;
  color: var(--ink-3);
  border-left: 2px solid var(--rule);
  padding-left: 7px;
}

/* --- O delta --- */

.kpi .d {
  margin-top: var(--space-3);
  display: inline-block;
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  background: var(--sunken);
  color: var(--ink-2);
}

.kpi .d.bad { background: var(--neg-soft); color: var(--neg-ink); }
.kpi .d.ok { background: var(--pos-soft); color: var(--pos-ink); }

/* Delta da comparacao escolhida pelo usuario: moldura na cor da escolha, para
   nao se confundir com o delta padrao (trimestre a trimestre). */
.kpi .d.cmp {
  background: transparent;
  border: 1px solid var(--act);
  color: var(--act);
}

.kpi .d + .d {
  margin-left: var(--space-2);
}

/* Sem dado de variacao: dizemos isso, em vez de mostrar 0,0%. */
.kpi .d.none {
  background: transparent;
  color: var(--ink-3);
  padding-left: 0;
}


/* --- A celula de PAR (Repercussao): dois numeros do MESMO peso --------------

   "Quanto repercutiu" nao tem um numero: tem dois, e eles medem alcance por
   caminhos diferentes — quantas vezes saiu (publicacoes) e em quantos lugares
   distintos (veiculos). Destacar um dos dois faria o olho ler exceção onde ha
   par, que e a regra que desfez o rotulo so na coluna do pico da serie.

   Por isso o par recebe o tratamento COMPLETO nos dois lados: cada numero tem a
   sua faixa medida e o seu delta, e os tres vivem DENTRO da mesma coluna. A
   barra pertence visivelmente ao numero que esta acima dela, e a pilha de 480px
   continua legivel sem regra nova — reparti-los em tres grades paralelas
   (numeros / faixas / deltas) alinhava no desktop e desmontava no celular, com
   as duas barras caindo juntas depois dos dois numeros. */

.kpi-pair .pair-nums {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
  margin: 5px 0 var(--space-3);
}

.kpi-pair .pn {
  min-width: 0;
}

/* A ordem DENTRO de cada metade e a mesma das outras tres celulas: valor,
   faixa medida, delta. */
.kpi-pair .pn .measure,
.kpi-pair .pn .measure-none {
  margin-top: var(--space-2);
}

.kpi-pair .pn-d {
  margin-top: var(--space-2);
}

/* O numero de apoio da celula (as citacoes) fica embaixo das DUAS metades,
   porque ele e do par e nao de um dos lados: pendura-lo em um deles diria que
   5.810 citacoes pertencem as publicacoes e nao aos veiculos. */
.kpi-pair .sub {
  margin: 0;
}

/* 22px, e nao os 30px de `.kpi .v`: sao dois numeros dividindo a largura de um.
   A hierarquia entre as celulas continua legivel porque as OUTRAS tres tem um
   numero grande cada — aqui o peso da celula esta na soma dos dois. */
.kpi-pair .pn > b {
  display: block;
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
  font-size: 22px;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.kpi-pair .pn > i {
  display: block;
  font-style: normal;
  font-size: 10.5px;
  color: var(--ink-3);
}

/* Dentro do par a coluna tem ~150px: o delta da comparacao NAO cabe ao lado do
   delta do trimestre. Empilha, em vez de estourar a celula — que e o que
   `margin-left` fazia aqui. */
.kpi-pair .pn-d .d {
  margin-top: 0;
  display: block;
  width: fit-content;
  max-width: 100%;
}

.kpi-pair .pn-d .d + .d {
  margin-left: 0;
  margin-top: 4px;
}

/* "acima da faixa" quebrava em "acima da / faixa" na coluna de ~150px, e a
   frase partida ao meio deixava a celula do par mais alta que as outras tres —
   que numa grade de altura compartilhada estica as quatro. Ela cabe em uma
   linha; o que faltava era autorizacao. */
.kpi-pair .pn .mfoot .tag {
  white-space: nowrap;
}

/* ============================================================================
   7. Acontecimentos por repercussao
   ============================================================================

   O painel que a tela nao conseguia produzir: sem agrupamento por evento, cada
   materia de um release e um acontecimento a parte e "ordenar por quanto
   repercutiu" nao significa nada.

   A grade e a mesma familia de `.units` — cabecalho de grade, linhas de altura
   fixa, numeros em mono a direita, composicao em `.minibar`. E de proposito: as
   duas tabelas do Painel se leem do mesmo jeito, e a peca e aprendida uma vez.

   A DIFERENCA que importa: as linhas NAO sao botoes e nao tem realce de hover.
   Nao existe filtro por acontecimento no vocabulario de escopo, e um realce de
   linha prometeria um clique que nao leva a lugar nenhum. `.units .u-row` tem
   hover porque clicar nela FAZ alguma coisa. */

.events .ev-head,
.events .ev-row {
  display: grid;
  grid-template-columns:
    minmax(200px, 1.5fr) 76px 68px minmax(96px, 0.9fr) 62px;
  gap: var(--space-3);
  align-items: center;
  padding: 8px var(--space-4);
}

.events .ev-head {
  border-bottom: 1px solid var(--rule-2);
}

.events .ev-head .r {
  text-align: right;
}

.events .ev-row {
  border-bottom: 1px solid var(--rule);
}

.events .ev-row:last-of-type {
  border-bottom: none;
}

/* Uma linha, com reticencias: o titulo inteiro vive no `title` do elemento, e a
   coluna existe para comparar magnitudes, nao para ler manchete. Quebrar em
   duas linhas faria as alturas variarem com o comprimento do titulo e a coluna
   de numeros perderia o alinhamento que a torna comparavel. */
.events .ev-title {
  font-size: 12.5px;
  font-weight: var(--font-semibold);
  color: var(--ink);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.events .ev-num,
.events .ev-nss {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--ink);
  text-align: right;
}

.events .ev-nss {
  font-weight: var(--font-semibold);
}

.events .ev-comp {
  min-width: 0;
}

/* --- A distribuicao por tamanho ---

   RAMPA NEUTRA (`--tile-*`), nunca `--pos`/`--neu`/`--neg`. Isto e MAGNITUDE:
   quantos acontecimentos repercutiram pouco e quantos repercutiram muito.
   Pintar "6 ou mais" de vermelho afirmaria que repercutir e ma noticia, que e
   opiniao que o dado nao carrega — a mesma regra que faz o marcador de volume
   da barra medida ser neutro. */
.events .dist {
  padding: var(--space-4);
  border-bottom: 1px solid var(--rule);
}

.events .dist-bar {
  display: flex;
  height: 10px;
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: var(--space-3);
}

.events .dist-bar i {
  display: block;
  height: 100%;
}

.events .dist-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  font-size: 11.5px;
  color: var(--ink-2);
}

.events .dist-legend .sw {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-sm);
  margin-right: 5px;
  vertical-align: -1px;
}

.events .dist-legend b {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
  color: var(--ink);
}

/* `--tile-1` e claro demais para sustentar 3:1 contra `--surface` sozinho, e a
   barra e objeto grafico necessario para entender o conteudo (WCAG 1.4.11). O
   contorno em `--ink-3` resolve pela borda, sem mexer no token — mesmo
   raciocinio de `.measure .mband` e de `.minibar.plain`. Os tres segmentos
   recebem o contorno, nao so o claro: ou todos os elementos de um conjunto
   recebem um tratamento, ou nenhum. */
.events .dist-bar i,
.events .dist-legend .sw {
  box-sizing: border-box;
  border: 1px solid var(--ink-3);
}

.events .t1 { background: var(--tile-1); }
.events .t2 { background: var(--tile-2); }
.events .t4 { background: var(--tile-4); }

/* --- A faixa-ponte ---

   Quanto das publicacoes destes acontecimentos ficou FORA do escopo. Mesmo
   recurso do painel geografico, e pela mesma razao: o painel conta o que esta
   no escopo e DIZ o que nao esta, em vez de deixar a diferenca invisivel. */
.events .ev-bridge {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--rule);
  background: var(--sunken);
  font-size: 11.5px;
  color: var(--ink-2);
}

.events .ev-bridge b {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
  color: var(--ink);
}

.events .ev-foot {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--rule);
  font-size: 11.5px;
  color: var(--ink-3);
  text-align: center;
}

.events .ev-foot button {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--act);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.events .ev-foot-note {
  display: block;
  margin-top: 3px;
}

.events .ev-empty {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  font-size: 12.5px;
  color: var(--ink-3);
}

/* ============================================================================
   3. Serie + decomposicao lado a lado
   ========================================================================= */

.series {
  display: grid;
  grid-template-columns: 2fr minmax(0, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  align-items: start;
}

/* `.panel` traz `margin-bottom` para o empilhamento normal; dentro da grade o
   espacamento e do `gap`, e a margem so desalinharia o pe dos dois paineis. */
.series > .panel {
  margin-bottom: 0;
}

/* ============================================================================
   4. Decomposicao — "para onde foram os N pontos"
   ========================================================================= */

.decomp-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.decomp .toggle {
  display: inline-flex;
  border: 1px solid var(--rule-2);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.decomp .toggle button {
  padding: 4px 11px;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: var(--font-semibold);
  color: var(--ink-2);
  background: transparent;
  border: none;
  cursor: pointer;
}

.decomp .toggle button:hover {
  background: var(--sunken);
}

.decomp .toggle button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--surface);
}

.decomp-unit {
  font-size: 10.5px;
  color: var(--ink-3);
}

/* Uma linha por grupo. O eixo do meio e o zero: contribuicao negativa cresce
   para a esquerda, positiva para a direita, na MESMA escala — inclusive a linha
   residual. Duas escalas fariam barras de tamanho igual valerem numeros
   diferentes. */
.drow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 132px 58px;
  gap: var(--space-3);
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid var(--rule);
}

.dlist .drow:last-child {
  border-bottom: none;
}

.drow .dl {
  font-size: 12.5px;
  color: var(--ink);
  min-width: 0;
}

.drow .dl small {
  display: block;
  margin-top: 1px;
  font-size: 10px;
  line-height: 1.3;
  color: var(--ink-3);
}

.dbar {
  position: relative;
  height: 9px;
}

.dbar .dz {
  position: absolute;
  top: -3px;
  bottom: -3px;
  left: 50%;
  width: 1px;
  background: var(--rule-2);
}

.dbar i {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 2px;
  min-width: 1px;
}

.dbar .neg-b { background: var(--neg); }
.dbar .pos-b { background: var(--pos); }

.drow .dv {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  color: var(--ink);
  text-align: right;
}

.drow .dv.up { color: var(--pos-ink); }
.drow .dv.down { color: var(--neg-ink); }

/* A LINHA "(sem tema)". Ela sai da lista ordenada de proposito: por magnitude
   seria a primeira, e leria como "o maior tema" — sendo a AUSENCIA de tema.
   Esconde-la faria a soma nao fechar na tela, e o fechamento e o que torna esta
   contabilidade conferivel a olho. Entao: abaixo de um fio grosso, com a
   contagem que a produz escrita ao lado. */
.dlist-resid {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--rule-2);
}

.drow.resid .dl {
  color: var(--ink-2);
  font-style: italic;
}

.decomp-sum {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--rule-2);
  font-size: 11.5px;
  color: var(--ink-2);
}

/* "a soma fecha": a verificacao da contabilidade, na tela, sem sair dela. */
.decomp-check {
  color: var(--ink-3);
}

.decomp-sum .tot {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
  font-size: 14px;
  white-space: nowrap;
}

.decomp-sum .tot.up { color: var(--pos-ink); }
.decomp-sum .tot.down { color: var(--neg-ink); }

.decomp-caption,
.decomp-hint {
  margin: var(--space-3) 0 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--ink-3);
}

/* A ressalva que vale para a lista inteira vem ANTES dela, uma vez, em vez de
   repetida sob cada uma das nove linhas. */
.decomp-hint-top {
  margin: 0 0 var(--space-2);
  color: var(--ink-2);
}

/* --- O estado `nao_decomponivel` --- */

/* Quando a parte nao atribuida e maior que a variacao inteira, o painel NAO
   mostra lista. Uma lista ranqueada com ressalva por cima continua sendo uma
   lista, e e a lista que a pessoa le. O lugar dela recebe o estado, o motivo, os
   dois numeros de cobertura que o produzem e o caminho de saida — mesma regra de
   `.measure-none` para a faixa. */
.decomp-state {
  border-left: 3px solid var(--warn);
  padding-left: var(--space-3);
}

.decomp-state p {
  margin: 0 0 var(--space-2);
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink);
}

/* Depois de `.decomp-state p`, e com a mesma especificidade — a palavra do
   estado E um `<p>`, e escrita antes ela perdia a cor para a regra geral e
   saia em `--ink`. Medido: 5,74:1 no claro, 5,49:1 no escuro. */
.decomp-state p.decomp-state-word {
  font-family: var(--font-primary);
  font-stretch: 100%;
  font-weight: var(--font-bold);
  font-size: 15px;
  letter-spacing: 0.01em;
  color: var(--warn-ink);
  margin: 0 0 var(--space-2);
}

.decomp-state p b {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-semibold);
}

.covlbl {
  font-family: var(--font-primary);
  font-stretch: 78%;
  font-weight: var(--font-semibold);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  font-size: 10px;
  color: var(--ink-2) !important;
  margin: var(--space-3) 0 var(--space-2) !important;
}

.cover {
  margin-bottom: var(--space-3);
}

.covrow {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(48px, 0.9fr) 84px;
  gap: var(--space-2);
  align-items: center;
  padding: 4px 0;
}

.covj {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Barra de cobertura: objeto grafico necessario para entender o conteudo, entao
   `--ink-2` sobre `--sunken` (6,04:1 no claro, 7,80:1 no escuro) e nao um cinza
   de fio. Nao usa `--pos`/`--neg`: cobertura de classificacao nao tem valencia
   de sentimento, e pinta-la com a paleta do tom sugeriria que tem. */
.covbar {
  position: relative;
  height: 7px;
  background: var(--sunken);
  border-radius: 1px;
  overflow: hidden;
}

.covbar i {
  display: block;
  height: 100%;
  background: var(--ink-2);
  border-radius: 1px;
}

.covn {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  color: var(--ink);
  text-align: right;
}

.covn small {
  display: block;
  font-size: 9.5px;
  color: var(--ink-3);
}

/* Comparacao indisponivel: o motivo, e nada de numero. */
.decomp-none {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-2);
  border-left: 2px solid var(--rule-2);
  padding-left: var(--space-3);
}

/* ============================================================================
   5. Cobertura
   ========================================================================= */

.coverage {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--rule);
}

.cov-col {
  background: var(--surface);
  padding: var(--space-4);
  min-width: 0;
}

.cov-col h3 {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-family: var(--font-primary);
  font-stretch: 78%;
  font-weight: var(--font-semibold);
  font-size: 10.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-2);
  margin-bottom: var(--space-3);
}

.cov-col h3 .cnt {
  margin-left: auto;
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-regular);
  font-size: 9.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-3);
  white-space: nowrap;
}

/* Linha de cobertura. E um botao: clicar aplica o recorte no escopo unico, do
   mesmo jeito que o mosaico geografico e o trilho de facetas. */
.crow {
  display: grid;
  grid-template-columns: minmax(88px, 132px) minmax(0, 1fr) 52px;
  gap: var(--space-3);
  align-items: center;
  width: 100%;
  padding: 4px 2px;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.crow:hover {
  background: var(--sunken);
}

.crow.on {
  background: var(--act-soft);
  box-shadow: inset 2px 0 0 var(--act);
}

.crow .cl {
  font-size: 12px;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.crow .cv {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  color: var(--ink);
  text-align: right;
}

.crow .ctrack {
  min-width: 0;
}

/* A barra de magnitude E a barra de composicao: "quem publica mais" e "quem
   publica mal" na mesma tinta e no mesmo espaco (DECISAO.md secao 5).

   `gap: 2px` nao e estetica: os pares do trio de sentimento ficam entre 1,35 e
   2,4 de contraste entre si, que DECISAO.md secao 4 assume explicitamente como
   troca — e a mitigacao registrada la e "folgas de 2 px" mais rotulo escrito.
   Com 1px a folga nao sustenta a separacao sob CVD. */
.minibar {
  display: flex;
  gap: 2px;
  height: 7px;
}

.minibar i {
  display: block;
  height: 100%;
  border-radius: 1px;
}

.minibar .p { background: var(--pos); }
.minibar .n { background: var(--neu); }
.minibar .g { background: var(--neg); }

/* Sem decomposicao por sentimento disponivel para esta dimensao: traco unico e
   NEUTRO. Um traco cinza diz "so sei o tamanho"; tres segmentos inventados
   diriam "sei o tom", que e falso.

   `--ink-3`, nao `--rule-2`: uma barra e objeto grafico necessario para entender
   o conteudo, e o piso de WCAG 1.4.11 e 3:1. `--rule-2` media 1,84:1 — servia de
   fio, nao de dado. `--ink-3` fica em 4,5+, bem acima do piso, e e visivelmente
   mais escuro que `--neu` (o cinza do sentimento NEUTRO), o que impede confundir
   "nao sei o tom" com "o tom e neutro". */
.minibar.plain {
  background: var(--ink-3);
  border-radius: 1px;
  min-width: 3px;
}

.minibar.plain i { display: none; }

.cov-note {
  margin: var(--space-3) 0 0;
  font-size: 10.5px;
  line-height: 1.4;
  color: var(--ink-3);
}

.cov-legend {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--rule);
  font-size: 11px;
  color: var(--ink-2);
}

.cov-legend .sw {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: var(--radius-sm);
  margin-right: 5px;
}

.cov-legend .sw.p { background: var(--pos); }
.cov-legend .sw.n { background: var(--neu); }
.cov-legend .sw.g { background: var(--neg); }
.cov-legend .sw.plain { background: var(--ink-3); }

/* ============================================================================
   6. Unidades
   ========================================================================= */

.units .u-head,
.units .u-row {
  display: grid;
  grid-template-columns:
    minmax(150px, 1.3fr) 62px minmax(96px, 0.8fr) 52px minmax(110px, 1fr) 74px;
  gap: var(--space-3);
  align-items: center;
  padding: 8px var(--space-4);
}

.units .u-head {
  border-bottom: 1px solid var(--rule-2);
}

.units .u-head .r {
  text-align: right;
}

.units .u-row {
  border-bottom: 1px solid var(--rule);
  width: 100%;
  background: transparent;
  border-left: none;
  border-right: none;
  border-top: none;
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.units .u-row:last-of-type {
  border-bottom: none;
}

.units .u-row:hover {
  background: var(--sunken);
}

.units .u-row.on {
  background: var(--act-soft);
  box-shadow: inset 3px 0 0 var(--act);
}

.units .un {
  font-size: 12.5px;
  font-weight: var(--font-semibold);
  color: var(--ink);
  min-width: 0;
}

.units .un small {
  display: block;
  margin-top: 1px;
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-weight: var(--font-regular);
  font-size: 9.5px;
  color: var(--ink-3);
}

.units .um,
.units .unss {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--ink);
  text-align: right;
}

.units .unss {
  font-weight: var(--font-semibold);
}

.units .ucomp {
  min-width: 0;
}

.units-foot {
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--rule);
  font-size: 11.5px;
  color: var(--ink-3);
  text-align: center;
}

.units-foot button {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--act);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

/* A coluna "posicao na faixa propria". Quando a unidade nao tem faixa, o lugar
   fica com `.measure-none` (estado + motivo no title), nunca com faixa
   estimada. `.u-band-pending` sobrevive para o caso de `Baseline` nao ter
   carregado — sem modulo nao ha nem estado a declarar. */
.units .u-band-pending {
  font-size: 10.5px;
  color: var(--ink-3);
}

.units .u-measure {
  min-width: 0;
}

/* Dentro da linha a barra nao leva o rodape "434 em jul/2026": a coluna Desvio,
   ao lado, ja e o numero, e o cabecalho ja carrega a data. */
.units .u-measure .measure-none {
  border-left-width: 2px;
  padding-left: 6px;
  font-size: 10px;
}

/* --- A coluna Desvio --- */

/* O numero e a distancia ate a borda VIOLADA da propria faixa (p10 ou p90), e
   zero quando dentro — e por ele que a tabela ordena. `flat` para "na faixa" e
   `none` para os estados sem numero: um "0,000" ali seria indistinguivel de uma
   medida de fato nula. */
.u-dev {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  text-align: right;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  justify-self: end;
  white-space: nowrap;
}

.u-dev.bad { background: var(--neg-soft); color: var(--neg-ink); }
.u-dev.ok { background: var(--pos-soft); color: var(--pos-ink); }
.u-dev.flat { background: var(--sunken); color: var(--ink-2); }
.u-dev.none { background: transparent; color: var(--ink-3); padding-right: 0; }

/* AMOSTRA FINA. `MINIMO_MESES` do backend conta MESES, nao materias: uma
   unidade com tres materias no mes atinge as seis observacoes, ganha faixa, e o
   desvio dela e ruido — na base real uma unidade de 3 materias liderou esta
   ordenacao. A linha nao some (isso esconderia dado real): ela desce na ordem e
   recebe esta marca, com a contagem do mes no `title`. Forma, e nao so cor. */
.u-dev .fina-mark {
  font-style: normal;
  margin-left: 4px;
  font-size: 9px;
  vertical-align: 1px;
}

.u-dev.fina {
  outline: 1px dashed var(--rule-2);
  outline-offset: -1px;
}

/* ============================================================================
   Sinais (os insights promovidos) — carimbo com forma, nunca so cor
   ========================================================================= */

.insight-stamp .shp {
  font-size: 8px;
  line-height: 1;
  margin-right: 4px;
}

/* --- Itens 1.2 e 1.3 da auditoria visual 2026-08-17 ---

   `.insight-item`/`.insights-grid` moram em main.css (outro dono nesta
   rodada) e nao podem ser editados ali; as regras abaixo sao overrides que
   vencem por vir DEPOIS no cascade (index.html carrega main.css e
   components.css antes de panel.css) com a MESMA especificidade — o mesmo
   recurso que este arquivo ja usa para `.card`/`.panel` (comentario no
   cabecalho de main.css: "os vizinhos mudaram; ele acompanha sem uma linha
   de HTML alterada"). Nao toquei main.css.

   1.2 — o cartao vinha com `background: var(--gray-50)` neutro na regra
   base, mas as tres variantes (`.positive/.warning/.negative`) pintavam o
   FUNDO inteiro com a cor da severidade (`--success-light`/`--warning-light`
   etc.) e usavam `border-left: 4px` + `border-radius: var(--radius-md)`
   (4px). O protótipo pinta só um fio de 3px sobre superfície neutra, raio
   7px — "se algo está colorido, algo aconteceu": quando o cartão inteiro é
   cor, o carimbo (`.insight-stamp`) para de gritar. */
.insight-item {
  background: var(--surface);
  border-left-width: 3px;
  border-radius: var(--radius-lg);
}

.insight-item.positive,
.insight-item.negative,
.insight-item.warning {
  background: var(--surface);
}

.insight-item.positive { border-left-color: var(--pos); }
.insight-item.warning,
.insight-item.negative { border-left-color: var(--warn); }

/* 1.3 — grade de 3 colunas (o protótipo: `repeat(3, 1fr)`), nao coluna
   unica. Sem isto um cartao mede ~1.198x155 (uma faixa) em vez de 377x269 —
   a comparacao lado a lado entre sinais, que e o ponto de ordena-los por
   severidade, desaparece. Os desdobramentos (2 colunas, depois 1) seguem o
   mesmo ponto de corte de `.coverage`, o painel irmao mais proximo em
   proposito (tres colunas de leitura rapida). */
.insights-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-4);
}

@media (max-width: 1000px) {
  .insights-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 768px) {
  .insights-grid { grid-template-columns: minmax(0, 1fr); }
}

/* 1.5 — o CTA do cartao ("Ver as N materias →") e um LINK, nao um botao com
   borda: `link sem borda, caixa alta, font-stretch:85%, letter-spacing:.04em,
   cor --act` (especificacao do prototipo, `.sig .go`). A NAVEGACAO em si
   (Scope.set + troca de aba) ja existia em main.js antes desta rodada —
   `setupInsightCards()` — e continua a mesma; o que estava errado era so a
   FORMA. Verificado clicando: leva ao Analitico com o filtro aplicado. */
.insight-action {
  margin-left: auto;
  background: none;
  border: none;
  padding: 0;
  border-radius: 0;
  font-family: var(--font-primary);
  font-stretch: 85%;
  font-weight: var(--font-bold);
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--act);
  cursor: pointer;
  transition: none;
  white-space: nowrap;
}

.insight-action:hover {
  background: none;
  color: var(--act);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============================================================================
   Barra de contexto do sinal (item 1.6) — Analitico
   ========================================================================= */

/* O que esta barra E e o que NAO E: ver a nota longa em analitico.js
   `mountPanel()`. Em resumo — mostra o FATO que motivou a navegacao
   (`insight.text`, ja calculado, ja exibido no Painel) e um jeito de desfazer
   o recorte que ele aplicou. NAO afirma idade de sinal nem NSS por objeto:
   esses dados nao existem (Fase 4, DECISAO.md §7). */
.ctx-bar {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--ink-3);
  border-radius: var(--radius-lg);
}

.ctx-bar.ctx-warn { border-left-color: var(--warn); }
.ctx-bar.ctx-pos { border-left-color: var(--pos); }

.ctx-stamp {
  flex-shrink: 0;
  font-family: var(--font-primary);
  font-stretch: 78%;
  font-weight: var(--font-semibold);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
}

.ctx-bar.ctx-warn .ctx-stamp { color: var(--warn-ink); }
.ctx-bar.ctx-pos .ctx-stamp { color: var(--pos-ink); }

.ctx-fact {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12.5px;
  color: var(--ink);
}

.ctx-clear {
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 11.5px;
  color: var(--act);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  white-space: nowrap;
}

/* ============================================================================
   Segundo grafico de "Sentimento no tempo" (item 1.9) —
   "% positivo ao mes contra a faixa historica"
   ========================================================================= */

.sb-divide {
  border-top: 1px solid var(--rule);
  margin: var(--space-4) calc(-1 * var(--space-4)) var(--space-4);
}

.sb-wrap { min-width: 0; }

.sb-legend {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  align-items: baseline;
  margin-bottom: var(--space-2);
  font-size: 11px;
  color: var(--ink-2);
}

.sb-sw {
  display: inline-block;
  margin-right: 5px;
  vertical-align: middle;
}

.sb-sw-band {
  width: 13px;
  height: 8px;
  border-radius: 2px;
  background: var(--band);
}

.sb-sw-line {
  width: 14px;
  height: 2px;
}

.sb-svg {
  display: block;
  width: 100%;
  height: auto;
}

.sb-svg .sb-ylab,
.sb-svg .sb-mlab {
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 9.5px;
  fill: var(--ink-3);
}

.sb-svg .sb-grid { stroke: var(--rule); stroke-width: 1; stroke-dasharray: 1 3; }
.sb-svg .sb-axis { stroke: var(--rule); stroke-width: 1; }

.sb-caption {
  margin: var(--space-2) 0 0;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-3);
}

.sb-caption b {
  font-family: var(--font-numbers);
  font-weight: var(--font-semibold);
  color: var(--ink);
}

/* ============================================================================
   Colofão (item 1.8) — a promessa de emissão, nao um rodape de copyright
   ========================================================================= */

/* DECISAO.md §1: "a ordem das secoes do Painel E a ordem do relatorio
   emitido — promessa registrada no colofao do mockup". O rodape anterior
   ("© 2026 ISAC... Desenvolvido com ♥ por WeDo", Archivo 16px sobre
   --surface-2) nao exibia a frase — e a frase tinha parado de ser
   verdadeira, porque a ordem mudou (item 1.1). As duas coisas voltam juntas:
   a ordem (index.html) e o texto (aqui). Forma do prototipo `.colophon`:
   mono, sem fundo proprio, fio superior fino, sem moldura de cartao. */
.colophon {
  max-width: 1216px;
  margin: var(--space-8) auto 0;
  padding: var(--space-4) var(--space-4) var(--space-8);
  border-top: 1px solid var(--rule-2);
}

.colophon .container {
  max-width: none;
  padding: 0;
  margin: 0;
}

.colophon p {
  margin: 0 0 var(--space-1);
  font-family: var(--font-numbers);
  font-variant-numeric: tabular-nums;
  font-size: 10.5px;
  line-height: 1.8;
  color: var(--ink-3);
}

.colophon p:last-child { margin-bottom: 0; }

.colophon a,
.colophon-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--act);
  text-decoration: none;
  cursor: pointer;
}

.colophon a:hover,
.colophon-link:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ============================================================================
   Responsivo
   ========================================================================= */

@media (max-width: 1120px) {
  /* O cartao de estado empilha antes dos KPIs: em 340px fixos ele espremeria as
     quatro celulas abaixo do que o numero de 30px aguenta. */
  .state {
    grid-template-columns: minmax(0, 1fr);
  }

  .series {
    grid-template-columns: minmax(0, 1fr);
  }

  /* A tabela de unidades perde a coluna de composicao antes de perder a de
     desvio: a composicao ja esta escrita na linha de apoio de cada unidade
     ("112 pos · 30 neu · 8 neg"), o desvio nao esta em lugar nenhum. */
  .units .u-head,
  .units .u-row {
    grid-template-columns: minmax(140px, 1.4fr) 58px 52px minmax(104px, 1fr) 72px;
  }

  .units .ucomp {
    display: none;
  }

  .units .u-head .lbl:nth-child(3) {
    display: none;
  }
}

@media (max-width: 1000px) {
  .coverage {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 768px) {
  .kpis,
  .kpis-4 {
    grid-template-columns: repeat(2, 1fr);
  }

  .state-word {
    font-size: 26px;
  }

  .drow {
    grid-template-columns: minmax(0, 1fr) 92px 52px;
  }

  .kpi .v {
    font-size: 24px;
  }

  .coverage {
    grid-template-columns: minmax(0, 1fr);
  }

  /* O par de Repercussao NAO empilha aqui, e a razao e medida: a 768px a
     faixa de KPIs ja esta em 2 colunas, entao a celula tem ~328px e cada metade
     do par fica com ~158px — a mesma largura que ela tem no desktop a 1440px,
     onde cabe. Empilhar antes da hora custava 182px de altura e empurrava as
     Sinalizacoes de y=1.260 para y=1.442, desfazendo no celular a posicao que a
     auditoria de 2026-08-17 conquistou. A quebra do par mora em 480px. */

  /* A tabela de acontecimentos vira ficha, pela mesma regra da de unidades:
     sem rolagem horizontal, cada linha se descreve. */
  .events .ev-head {
    display: none;
  }

  .events .ev-row {
    grid-template-columns: minmax(0, 1fr) 62px;
    grid-template-areas:
      "tit tit"
      "pub nss"
      "vei comp";
    row-gap: 4px;
    align-items: center;
  }

  .events .ev-title {
    grid-area: tit;
    white-space: normal;
    overflow: visible;
  }

  .events .ev-pub { grid-area: pub; text-align: left; }
  .events .ev-vei { grid-area: vei; text-align: left; }
  .events .ev-nss { grid-area: nss; }
  .events .ev-comp { grid-area: comp; align-self: center; }

  /* O numero perde a coluna, entao ganha o substantivo — mesma solucao de
     `.units .um::after`. Os DOIS numeros recebem, nao so um. */
  .events .ev-pub::after { content: " publicações"; }
  .events .ev-vei::after { content: " veículos"; }
  .events .ev-nss::before { content: "NSS "; }

  .events .ev-num::after,
  .events .ev-nss::before {
    font-family: var(--font-primary);
    font-size: 10.5px;
    font-weight: var(--font-regular);
    color: var(--ink-3);
  }

  /* A tabela de unidades vira ficha: o cabecalho de grade sai e cada linha se
     descreve. Sem rolagem horizontal — a tabela nao e responsiva por scroll. */
  .units .u-head {
    display: none;
  }

  .units .u-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "un   dev"
      "unss band"
      "um   band";
    row-gap: var(--space-2);
  }

  .units .un { grid-area: un; }
  .units .unss { grid-area: unss; text-align: left; }
  .units .um { grid-area: um; text-align: left; }
  .units .u-dev { grid-area: dev; align-self: start; }
  .units .u-measure,
  .units .u-band-pending { grid-area: band; align-self: center; justify-self: stretch; }

  /* Na ficha o NSS perde a coluna e ganha o substantivo, pela mesma razao que a
     contagem de materias ganha o dela. */
  .units .unss::before {
    content: "NSS ";
    font-family: var(--font-primary);
    font-size: 10.5px;
    font-weight: var(--font-regular);
    color: var(--ink-3);
  }

  /* O numero perde a coluna, entao ganha o substantivo: "137" solto numa ficha
     nao diz de que. */
  .units .um::after {
    content: " matérias";
    font-family: var(--font-primary);
    font-size: 10.5px;
    color: var(--ink-3);
  }
}

@media (max-width: 480px) {
  /* Aqui, sim, o par empilha: a celula cai para ~139px e duas metades de 63px
     nao sustentam um numero de quatro digitos em 22px, muito menos a barra
     medida embaixo dele. Empilhado, cada metade fica com a largura inteira da
     celula. O custo em altura e real e esta registrado no relatorio desta
     rodada — e o preco de mostrar duas medidas onde antes havia duas celulas. */
  .kpi-pair .pair-nums {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
  }

  /* Empilhadas, as duas metades precisam de uma divisa: sem ela a faixa da
     primeira encosta no numero da segunda e parece medi-lo. */
  .kpi-pair .pair-nums .pn + .pn {
    padding-top: var(--space-3);
    border-top: 1px solid var(--rule);
  }

  /* `.kpis, .kpis-4 { grid-template-columns: minmax(0,1fr) }` REMOVIDO aqui
     (item 1.18 da auditoria visual 2026-08-17, prescrito pelo worker de
     escala). A quebra de 768px (abaixo, `repeat(2, 1fr)`) ja cobre ate
     390px; esta segunda quebra a desfazia e devolvia os KPIs a 1 coluna,
     custando +439px de altura no mobile — e o prototipo nao tem esta
     segunda quebra. */

  .crow {
    grid-template-columns: minmax(0, 1fr) 48px;
    grid-template-areas:
      "cl cv"
      "bar bar";
    row-gap: 4px;
  }

  .crow .cl { grid-area: cl; }
  .crow .cv { grid-area: cv; }
  .crow .ctrack { grid-area: bar; }
}
