/* ==========================================================================
   Indicadores, dashboards e relatórios — GV Auditoria (Fase 6)

   Os gráficos são SVG puro (ver components/charts): esta folha só cuida do
   que o SVG não resolve sozinho — tipografia dos rótulos, legenda e o
   layout ao redor. Nenhuma cor aqui é literal fora dos tokens; onde a cor
   vem de dado (criticidade, classificação), ela chega pronta via prop.
   ========================================================================== */

/* --- gráficos genéricos ------------------------------------------------------ */
.sparkline { width: 100%; height: 2rem; display: block; }

.grafico-linha { display: flex; flex-direction: column; gap: var(--e-3); }
.grafico-linha__svg { width: 100%; height: auto; display: block; }

.grafico-barras__svg { width: 100%; height: auto; display: block; }

/* Gráficos desenhados 1:1 em pixels (LineChart `esticar` e BarChart
   horizontal se redesenham na caixa real), então estes tamanhos são os que
   aparecem na tela. Valores em Montserrat tabular — monospace fica só para
   IDs/códigos técnicos. */
.grafico__rotulo-eixo { font-size: 11px; fill: var(--texto-3); font-family: var(--fonte); font-variant-numeric: tabular-nums; }
.grafico__rotulo { font-size: 12px; fill: var(--texto-2); font-family: var(--fonte); }
.grafico__valor { font-size: 12px; font-weight: 600; fill: var(--texto); font-family: var(--fonte); font-variant-numeric: tabular-nums; }

.grafico__legenda {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3) var(--e-4);
}
.grafico__legenda--lista {
  flex-direction: column;
  gap: var(--e-2);
  list-style: none;
  padding: 0;
  margin: 0;
}
.grafico__legenda-item {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: 3px 0;
  font-size: var(--txt-sm);
  font-weight: 600;
}
.grafico__legenda-item .sub { font-weight: 400; }
.grafico__legenda-cor {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex: 0 0 auto;
}

.grafico-rosca {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--e-5);
}
/* Fluido em vez de tamanho fixo — não estoura a largura do cartão em telas
   pequenas (o cartão tem padding var(--e-5) de sobra, então 40vw já
   considera essa margem). */
.grafico-rosca__svg { width: min(12rem, 40vw); height: auto; aspect-ratio: 1; flex: 0 0 auto; }
.grafico-rosca__total {
  font-size: 22px;
  font-weight: 700;
  fill: var(--azul-900);
  font-family: var(--fonte);
}
.grafico-rosca__subtitulo {
  font-size: 11px;
  font-weight: 400;
  fill: var(--texto-2);
  font-family: var(--fonte);
  text-transform: uppercase;
  letter-spacing: .04em;
}
@media (max-width: 420px) {
  .grafico-rosca { flex-direction: column; }
}

/* --- estatística única (pages/dashboard/visualizacaoAdaptativa.js) -------------
   Quando um cartão de ranking/distribuição tem só 1 categoria real, vira uma
   linha de leitura direta em vez de um gráfico com uma barra sozinha ou um
   donut de 100% monocromático — mesmo peso tipográfico dos KPIs do topo
   (`.metrica`), porque um valor único É um KPI, só que dentro de um cartão
   de análise. */
.metrica-unica {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  /* `flex-start`, não `center`: um cartão baixo demais para o conteúdo
     inteiro (ícone+rótulo, valor, detalhe, barra) com `center` distribui o
     overflow pros dois lados — o topo do bloco vaza pra CIMA do próprio
     container e fica cortado pelo `overflow: hidden` do avô (achado real:
     "Ranking de lojas" com 1 loja só tinha o rótulo cortado ao meio, porque
     o `.metrica-unica__cabecalho` renderizava 15px ACIMA do topo medido de
     `.metrica-unica`). Mesma lição já aplicada ao donut denso mais acima
     neste arquivo — `flex-start` garante que, se ainda faltar espaço, o
     corte aconteça só embaixo. */
  justify-content: flex-start;
  height: 100%;
  min-height: 0;
}
.metrica-unica__cabecalho {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  color: var(--texto-2);
  min-width: 0;
}
.metrica-unica__icone { flex: 0 0 auto; color: var(--azul-500); }
/* Nome de loja longo ("código — nome completo") trunca em UMA linha com
   reticências, em vez de quebrar em 2+ linhas dentro de uma caixa curta
   demais para as duas — isso cortava a segunda linha na metade da altura
   (achado real: rótulo aparecia "cortado ao meio" no cartão de Ranking de
   lojas com só 1 loja no recorte). O nome completo continua acessível: o
   `title` no próprio elemento (ver `Metricas.js`/`visualizacaoAdaptativa.js`)
   cobre esse caso, mesmo padrão já usado nos KPIs. */
.metrica-unica__rotulo {
  font-size: var(--txt-sm);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* Valor + detalhe sempre na MESMA linha (ver `visualizacaoAdaptativa.js`):
   "81,3% · 2 auditoria(s) finalizada(s)" em vez de duas linhas empilhadas —
   a altura real disponível por cartão na grade sem scroll (medida de
   verdade em 1366/1440px) não sobra para 3-4 linhas de conteúdo, e o
   cartão sempre tem largura de sobra pra receber o detalhe ao lado (achado
   real: valor E detalhe inteiros cortados por `overflow: hidden` quando
   empilhados — "Evolução da conformidade"/"Conformidade por regional"
   perdiam o próprio dado principal). */
.metrica-unica__linha-valor {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--e-2);
  min-width: 0;
}
.metrica-unica__valor {
  font-size: var(--txt-2xl);
  font-weight: 700;
  color: var(--azul-900);
  letter-spacing: -0.01em;
}
.metrica-unica__linha-valor .sub {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.metrica-unica__trilho {
  height: 10px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}
.metrica-unica__barra { height: 100%; border-radius: 999px; }

/* Variante compacta (cartões de peso leve — ver `visualizacaoAdaptativa.js`):
   gap mínimo, valor um degrau menor (ainda bem maior que o rótulo/detalhe —
   continua sendo o elemento dominante do cartão) e sem a barra de
   progresso: ela é reforço visual do percentual que o `detalhe` já escreve
   por extenso, dispensável quando o espaço vertical é o recurso mais
   escasso do cartão (linha 4, 1366px). */
.metrica-unica--compacta { gap: 1px; }
.metrica-unica--compacta .metrica-unica__cabecalho { gap: 6px; }
.metrica-unica--compacta .metrica-unica__valor { font-size: var(--txt-lg); line-height: 1.1; }

/* --- pódio (ranking de lojas, top 3 — pages/dashboard/renderRegionalERanking.js) ---
   Três blocos, não três barras quase do mesmo tamanho: a pergunta que este
   cartão responde é "quem são as 3 lojas na frente", e a ordem 2º/1º/3º com
   o 1º mais alto e mais largo é a mesma leitura instantânea de um pódio
   físico — sem precisar de eixo, sem precisar comparar comprimento de barra. */
.podio {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: var(--e-3);
  list-style: none;
  margin: 0;
  padding: 0;
  height: 100%;
}
.podio__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-1);
  flex: 1 1 0;
  min-width: 0;
  padding: var(--e-4) var(--e-2) var(--e-3);
  border-radius: var(--raio-lg);
  background: var(--surface-2);
  text-align: center;
}
/* O 1º lugar é o único com destaque de cor — reserva o token de ação
   primária para quem de fato lidera, os outros dois ficam no neutro. Mais
   alto (`margin-top` negativo) e mais largo (`flex: 1.15`) fazem o mesmo
   trabalho que a base física de um pódio faria. */
.podio__item--1 {
  flex: 1.15 1 0;
  margin-top: calc(-1 * var(--e-4));
  background: var(--azul-100);
  border: 1px solid var(--azul-300);
}
.podio__item--2, .podio__item--3 { padding-top: var(--e-3); }
.podio__item[role='button'] { cursor: pointer; }
.podio__item[role='button']:hover { background: var(--surface); border-color: var(--linha-2); }
.podio__item--1[role='button']:hover { background: var(--azul-100); border-color: var(--azul-500); }
.podio__item[role='button']:focus-visible { outline: 2px solid var(--azul-500); outline-offset: 2px; }

.podio__posicao {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  font-size: var(--txt-sm);
  font-weight: 700;
  color: var(--neutro-0);
  background: var(--texto-3);
}
.podio__posicao--1 {
  width: 2.25rem;
  height: 2.25rem;
  font-size: var(--txt-md);
  background: var(--azul-900);
}
.podio__posicao--2 { background: var(--podio-prata); }
.podio__posicao--3 { background: var(--podio-bronze); }

.podio__valor {
  font-size: var(--txt-xl);
  font-weight: 700;
  color: var(--azul-900);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.podio__item--1 .podio__valor { font-size: var(--txt-2xl); }
.podio__nome {
  font-size: var(--txt-sm);
  font-weight: 600;
  color: var(--texto);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
}
.podio__codigo { font-size: var(--txt-xs); color: var(--texto-3); }

@media (max-width: 480px) {
  .podio { align-items: stretch; }
  .podio__item--1 { margin-top: 0; }
}

/* --- layout do painel executivo ------------------------------------------------ */
.filtros--largo {
  grid-template-columns: 1fr;
}
@media (min-width: 768px) {
  /* 11rem, não os 9rem de antes: "Todas as regionais"/"Todas as marcas"
     ficavam cortados dentro da própria caixa do select (achado real via
     captura de tela nos rankings, que usam esta variante mais densa). */
  .filtros--largo { grid-template-columns: repeat(auto-fit, minmax(12.5rem, 1fr)); }
}

/* Os 5 filtros do painel executivo (Período, Regional, Marca, UF, Loja)
   cabem numa linha só a partir de 1280px — `repeat(5, ...)` explícito, não
   `auto-fit`: `auto-fit` distribui o espaço entre QUANTAS colunas couberem
   e alarga cada uma até a largura sobrar, então o 5º campo ficava sempre a
   poucos pixels de não caber e quebrava pra uma segunda linha (achado
   real: cada campo com ~249px de largura, quando ~200px já bastava —
   sobrava exatamente o suficiente para inflar 4 campos e nunca abrir
   espaço pro 5º). A barra de filtros inteira passava de 248px de altura
   nesse caso, espremendo as 3 linhas de gráfico abaixo dela pra ~35-49px
   cada na grade sem scroll. */
@media (min-width: 1280px) {
  /* Período pesa mais que as outras 4 colunas: é dois inputs de data lado a
     lado (`campoIntervaloData.js`), não um select — precisa de mais largura
     mínima que "Todas as regionais" para não cortar "dd/mm/aaaa". */
  .dashboard-filtros { grid-template-columns: 1.3fr repeat(4, minmax(0, 1fr)); }
}

/* Densidade do painel executivo: label continua EM CIMA do campo (largura
   cheia por coluna é mais importante que economizar ~20px de altura — label
   ao lado do campo espremia "Todas as regionais"/"Buscar loja..." a ponto
   de truncar dentro do próprio select/input, achado real ao tentar a
   variante em linha). O que sobra pra cortar é só a ALTURA de cada peça:
   `--toque-min` (48px) é o alvo de toque da tela de contagem (RN de
   acessibilidade em tablet) — correto ali, generoso demais pra 5 campos
   clicados com mouse num painel executivo. Isso sozinho, empilhado com
   label+campo+Exportar, é o que deixava a barra de filtros com ~159px em
   1366px (achado real via `getBoundingClientRect()`), roubando altura das 3
   linhas de gráfico abaixo dela na grade sem scroll. Não mexe em
   `--toque-min` nem em `.campo`/`.rotulo` — outras telas continuam com o
   alvo de toque cheio. */
@media (min-width: 1280px) {
  .dashboard-filtros .campo-grupo,
  .dashboard-filtros > div > .campo-grupo {
    gap: 2px;
  }
  .dashboard-filtros .rotulo {
    font-size: var(--txt-xs);
  }
  .dashboard-filtros .campo,
  .dashboard-filtros .campo-intervalo {
    min-height: 34px;
  }
  .dashboard-filtros .campo-intervalo__input { padding: 0; }
}

/* --- campo de intervalo de datas (components/ui/campoIntervaloData.js) --------- */
.campo-intervalo {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  border: 1px solid var(--linha-2);
  border-radius: var(--raio);
  background: var(--surface);
  padding: 0 var(--e-2);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.campo-intervalo:focus-within {
  border-color: var(--azul-500);
  box-shadow: 0 0 0 3px var(--azul-100);
}
.campo-intervalo__input {
  border: none;
  background: transparent;
  padding: 0;
  /* `min-width` real, não 0: um `<input type="date">` nativo tem largura de
     conteúdo própria (dd/mm/aaaa + o ícone do seletor) que o navegador não
     encolhe de verdade — só CORTA visualmente quando o CSS aperta mais que
     isso, virando "dd/mm" sem o ano (achado real via screenshot em
     1366px). 118px é o piso onde "dd/mm/aaaa" completo continua visível
     com o ícone do calendário, medido de verdade no Chromium. */
  min-width: 118px;
  flex: 1 1 0;
}
.campo-intervalo__input:focus { outline: none; box-shadow: none; }
.campo-intervalo__separador { color: var(--texto-3); flex: 0 0 auto; }

/* --- largura cheia -------------------------------------------------------------
   `.shell__conteudo` (layout.css) trava em 80rem centralizado para toda tela
   do sistema — certo para tabela/formulário (linha de leitura confortável),
   errado para um painel executivo: numa janela de 1920px sobravam ~320px
   vazios de cada lado enquanto os gráficos ficavam pequenos por dentro dos
   1280px que restavam. `:has()` escopa a exceção só a esta página (já é o
   padrão do projeto, ver dados.css/central.css) — nenhuma outra tela muda. */
.shell__conteudo:has(.dashboard-pagina) {
  max-width: none;
  padding-left: var(--e-5);
  padding-right: var(--e-5);
}

/* Cabeçalho compacto (seção 4 do pedido): "Indicadores" + subtítulo não
   precisam da margem padrão de `--e-5` (24px) abaixo deles — num painel que
   já disputa cada pixel de altura contra a grade sem scroll, essa margem
   sozinha custava uma fração real de uma linha inteira de gráfico. */
.shell__conteudo:has(.dashboard-pagina) > .pagina-cabecalho { margin-bottom: var(--e-3); }

/* --- grade sem scroll (seção 25/44 do pedido) -----------------------------------
   No desktop (≥1280px), as 4 linhas (KPIs + 3 linhas de gráfico) precisam
   caber inteiras na viewport, sem rolagem vertical. A altura disponível é
   medida em JS (`DashboardPage#medirCabecalho`, via
   `--dashboard-cabecalho-h`) porque o cabeçalho+filtros pode quebrar em 2
   linhas num desktop mais estreito — um `calc()` com valor fixo travaria
   nesse caso. Abaixo de 1280px a página volta a rolar normalmente: o
   requisito de "uma tela só" é do desktop, não de qualquer largura. */
.dashboard-pagina { gap: var(--e-3); }

.dashboard-grade__linha {
  display: grid;
  gap: var(--e-3);
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 1024px) {
  /* Os dois gráficos de série temporal do painel (Evolução da conformidade
     e Evolução da divergência financeira) lado a lado, metade da largura
     cada — pedido pontual: antes a Evolução da conformidade ficava sozinha
     na linha, largura cheia, e a financeira dividia 1/3 de outra linha com
     Conformidade por regional/Ranking de lojas. */
  .dashboard-grade__linha--evolucao { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* `minmax(0, Nfr)`, não `Nfr` puro: uma faixa `fr` sem piso explícito
     ainda usa o min-content do cartão mais largo como piso mínimo — o mesmo
     estouro de `.dashboard-pagina` corrigido acima, um nível abaixo. */
  .dashboard-grade__linha--3col { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .dashboard-grade__linha--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1280px) {
  .dashboard-pagina {
    min-height: calc(100dvh - var(--header-h) - (2 * var(--e-6)) - var(--dashboard-cabecalho-h, 4rem));
    display: grid;
    /* Filtros e KPIs pedem só a própria altura de conteúdo (`auto`). Das
       duas linhas de gráfico que sobram, Evolução (série + tendência +
       tooltip, sozinha na própria linha) é a mais densa e ganha peso extra
       (1.3fr); as duas linhas de 3 cartões (roscas / regional-ranking-
       financeira) dividem o resto em partes iguais — mesma relevância
       editorial entre si, e pesos desiguais entre ELAS foi o que antes
       produzia cartões espremidos cortando o próprio conteúdo (achado real:
       "81,3%" cortado no Ranking de lojas, texto sobrepondo texto).
       `minmax(11rem, ...)`, não `Nfr` puro: o piso de 11rem é o que garante
       que um gráfico com legenda (donut + 3-6 itens) sempre tenha altura
       para respirar — sem ele, uma tela de 1366×768 (notebook comum, não
       caso extremo) divide o espaço que sobra do zero em linhas de ~90px
       cada, cortando texto de verdade (achado real, mesma classe do bug
       acima, só que por ALTURA DE VIEWPORT em vez de peso da linha: ambos
       produzem cartão espremido). Com o piso, a grade some com o "sem
       scroll" em telas baixas e a PÁGINA passa a rolar — melhor que cortar
       conteúdo, que é sempre pior que rolar duas telas. A MEDIÇÃO em JS
       (`--dashboard-cabecalho-h`) cobre só o cabeçalho da página (título +
       subtítulo) — filtros e KPIs já entram como linhas de grid próprias
       aqui, então não precisam ser medidos também. */
    grid-template-rows: auto auto minmax(13rem, 1.3fr) repeat(2, minmax(11rem, 1fr));
    grid-template-columns: minmax(0, 1fr);
  }

  /* `min-width: 0` em TODO filho direto: sem isso, uma faixa de grid usa o
     min-content do filho mais largo (aqui, os 6 campos de filtro antes de
     `auto-fit` reagrupar) como piso — e o piso vence o container, empurrando
     a faixa inteira para fora da tela (achado real via screenshot: UF e
     "Conformidade geral" cortados à direita em 1366px, sem barra de rolagem
     horizontal pra avisar, porque `overflow: hidden` só escondia o sintoma). */
  .dashboard-pagina > * { min-width: 0; }

  .dashboard-grade__linha { min-height: 0; min-width: 0; }
  .dashboard-grade__linha .cartao {
    min-height: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: var(--e-4);
  }
  .dashboard-grade__linha .cartao__titulo,
  .dashboard-grade__linha .cartao__cabecalho { margin-bottom: var(--e-3); font-size: var(--txt-md); }
  .dashboard-grade__linha .cartao__cabecalho .cartao__titulo { margin-bottom: 0; }

  /* `flex-wrap: wrap`: título ("Evolução da conformidade") + seletor de
     janela (5 botões) não cabem sempre na mesma linha num cartão de
     ~470px — sem isso os dois ficavam espremidos e o seletor cortava o
     último botão ("12 meses" virava "1", achado real via screenshot em
     1366px). Com wrap, o seletor desce pra própria linha quando precisa,
     em vez de cortar. */
  .dashboard-grade__linha .cartao__cabecalho { flex-wrap: wrap; row-gap: var(--e-2); }

  /* Filtros continuam numa barra compacta (linha 1 da grade), mas não
     precisam mais dos paddings/fontes na casa dos 11px — o full-bleed
     (acima) já devolveu a largura que faltava, então a barra de filtros
     cabe numa linha só sem precisar encolher o texto abaixo do confortável. */
  .dashboard-pagina > .filtros-barra { padding: var(--e-3) var(--e-4); }
  .dashboard-pagina > .filtros-barra .filtros { row-gap: var(--e-2); column-gap: var(--e-4); }
  .dashboard-kpis .metrica { padding: var(--e-3) var(--e-4); }

  /* Cartão com prévia + link (Ranking de lojas): o link nunca encolhe (é o
     caminho para a lista completa, precisa continuar clicável por inteiro).
     `grid` com uma linha `auto` (gráfico, o que ele pedir) e uma `auto`
     (botão) resolve o que o flex `1 1 auto` não resolvia de forma confiável
     aqui — a faixa do gráfico simplesmente colapsava para 0 quando o espaço
     sobrando era pequeno demais para o cálculo de `flex-basis` (achado real
     via medição: `getBoundingClientRect().height` do wrapper do gráfico
     voltava 0 mesmo com `flex: 1 1 auto; min-height: 0`). */
  .dashboard-grade__linha .cartao > .ranking-lojas-corpo {
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto;
    min-height: 0;
    height: 100%;
    gap: var(--e-2);
  }
  .dashboard-grade__linha .ranking-lojas-corpo > div:first-child { min-height: 0; overflow: hidden; }
  .dashboard-grade__linha .ranking-lojas-corpo > .cartao__nota {
    margin-top: 0;
    min-height: 0;
    padding: var(--e-2) var(--e-3);
  }

  /* Cada cartão de gráfico ocupa o resto da própria altura — o SVG (largura
     100%, altura automática pelo viewBox) e a legenda dividem esse espaço em
     vez de empurrar o cartão para além da grade. `flex-start`, não `center`:
     se o conteúdo ainda assim for alto demais, o corte de `overflow: hidden`
     precisa acontecer só embaixo — centralizado, ele cortaria os dois lados
     e o topo do gráfico apareceria vazando por cima do título do cartão
     (achado real via screenshot: legenda de donut flutuando acima do
     próprio título). */
  .dashboard-grade__linha .cartao > div:not(.cartao__cabecalho) {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    /* Container de tamanho: dá ao donut (via `cqh` abaixo) a altura REAL que
       sobrou neste cartão específico, em vez de uma estimativa por
       viewport — o mesmo cartão de "Distribuição de auditorias" tem folga
       bem diferente em 768px vs. 1080px de janela, e só o container mede
       isso de verdade. */
    container-type: size;
  }
  /* `width:100%; height:auto` (components.css) deriva a altura do SVG do
     `viewBox` só quando o item tem um `flex-basis` de conteúdo — sem isso
     um SVG sem texto/imagem (só formas vetoriais) tem altura de conteúdo
     0, e um `flex: 1 1 auto` (mesma regra do pai acima) pode preferir esse
     0 em vez de crescer. `flex: 1 1 0` força o SVG a crescer a partir de
     base zero, mesmo padrão já usado em `grafico-linha__svg`. Isto por si
     só não resolve o cartão ficar baixo demais em 1366px (esse é um
     problema de ALTURA DISPONÍVEL na linha, tratado no peso das linhas do
     grid acima) — só garante que o SVG usa TODA a altura que o cartão
     realmente tiver, em vez de menos ainda por colapsar a própria base. */
  .dashboard-grade__linha .grafico-barras__svg {
    flex: 1 1 0;
    min-height: 0;
    height: auto;
  }

  /* Donut na densidade "cockpit": ainda menor que o padrão solto (12rem),
     mas legível — rótulo/percentual continuam no floor mínimo confortável
     (seção 32 do pedido: "não usar fontes minúsculas para conseguir
     encaixar"), e o `cqh` (altura do CONTAINER, não da viewport) segue
     medindo o espaço real de cada cartão, que agora é maior por causa do
     full-bleed. */
  .dashboard-grade__linha .grafico-rosca {
    gap: var(--e-3);
    min-height: 0;
    min-width: 0;
    flex-wrap: nowrap;
    align-items: center;
    height: 100%;
  }
  .dashboard-grade__linha .grafico-rosca__svg {
    width: min(6.5rem, 90cqh);
    height: min(6.5rem, 90cqh);
    flex-shrink: 0;
  }
  .dashboard-grade__linha .grafico-rosca__total { font-size: 18px; }
  .dashboard-grade__linha .grafico-rosca__subtitulo { font-size: 10px; }
  .dashboard-grade__linha .grafico__legenda--lista {
    min-width: 0;
    max-height: 100%;
    overflow: hidden;
    gap: 4px;
  }
  .dashboard-grade__linha .grafico__legenda-item {
    padding: 1px 0;
    font-size: var(--txt-xs);
    line-height: 1.3;
  }
  .dashboard-grade__linha .grafico__legenda-cor { width: 9px; height: 9px; }

  /* Evolução da conformidade — só quando o gráfico de linha REALMENTE
     desenha (2+ pontos): o resumo em texto abaixo dele repete o que os
     KPIs do topo já mostram (conformidade atual, tendência), então cede
     lugar ao gráfico, que é a parte que os KPIs não substituem. Quando há
     menos de 2 pontos, o cartão nem chega a montar este resumo — usa
     `historicoInsuficiente()`/`metricaUnica()` em vez disso (ver
     `renderEvolucaoConformidade.js`), que não tem esta classe e por isso
     não é afetado por esta regra. O seletor de janela nunca quebra em 2
     linhas aqui (a densidade não tem altura de sobra para isso). */
  .dashboard-grade__linha .evolucao-conformidade__resumo { display: none; }
  .dashboard-grade__linha .evolucao-conformidade {
    min-height: 0;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
  }
  /* Estado "histórico insuficiente" (`metricaUnica()`) ou vazio: sem
     gráfico pra esticar, o bloco colava no topo do cartão e deixava um
     vão vazio grande embaixo (achado real: linha de evolução com 1.3fr de
     altura, ~250px de espaço morto sob um bloco de 2 linhas de texto).
     `justify-content: center` só entra quando o filho NÃO é o gráfico de
     linha de verdade — `.grafico-linha` continua ocupando a própria altura
     inteira via `flex: 1 1 auto` no SVG, como antes. Precisa MAIS que
     `justify-content` no pai: `.metrica-unica` tem `height: 100%` por
     padrão (para os outros cartões, onde ele É o conteúdo inteiro do
     cartão) — aqui ele é um bloco menor dentro de um cartão bem mais alto,
     então o stretch anulava o center do pai (não sobrava espaço pra
     centralizar porque o filho já preenchia tudo). `align-self: center`
     no filho substitui o stretch só neste contexto específico. */
  .dashboard-grade__linha .cartao > div.evolucao-conformidade:has(> .metrica-unica),
  .dashboard-grade__linha .cartao > div.evolucao-conformidade:has(> .estado-vazio-cartao) {
    justify-content: center;
  }
  .dashboard-grade__linha .evolucao-conformidade > .metrica-unica {
    height: auto;
    align-self: stretch;
  }
  .dashboard-grade__linha .segmentado { flex-wrap: nowrap; }
  .dashboard-grade__linha .segmentado__opcao { padding: 4px var(--e-2); min-height: 0; font-size: var(--txt-xs); }
  /* `grafico()` (`renderEvolucaoConformidade.js`) monta o `LineChart` dentro
     de um `<div>` ANÔNIMO (sem classe — só o alvo de `componente.mount()`),
     filho direto de `.evolucao-conformidade`. Sem esticar esse wrapper
     também, ele ficava `flex: 0 1 auto` (padrão) com altura = min-content
     do `.grafico-linha` dentro dele — e mesmo com `.grafico-linha` já
     esticado (regra abaixo), a altura REAL disponível (~170px) nunca
     chegava até lá: o wrapper anônimo vazava para a altura intrínseca do
     SVG (achado real: mesma causa raiz já corrigida para o mesmo padrão em
     `central-cockpit.css`, `.central-grafico__area > div`). */
  .dashboard-grade__linha .evolucao-conformidade > div {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }
  /* `.grafico-linha` é o wrapper ENTRE o card e o SVG (`LineChart.js`, modo
     interativo: `.grafico-linha.grafico-linha--interativo` > `.grafico-linha__area`
     > svg). Sem esticar este wrapper também, ele ficava `flex: 0 1 auto`
     (padrão do componente) com altura intrínseca do viewBox (~729px,
     derivada de um cálculo de aspect-ratio que não reflete a caixa real) —
     o SVG dentro dele tentava crescer para preencher ESSE wrapper inchado,
     não a altura real do card (~170px), e o conjunto vazava por baixo do
     `overflow: hidden` do card, cortando quase todo o gráfico visualmente
     (achado real: só uma faixa horizontal do meio do SVG aparecia, sem
     eixo X). Mesma causa raiz do `.grafico-linha__svg` abaixo, um nível
     acima na árvore. */
  .dashboard-grade__linha .grafico-linha { flex: 1 1 auto; min-height: 0; min-width: 0; }
  /* `display: flex` é o que falta aqui — sem ele, `flex: 1 1 auto` no SVG
     filho não tem efeito nenhum (só vale quando o PAI é flex container), e
     o navegador volta a derivar a altura do SVG pelo aspect-ratio do
     viewBox mesmo com `preserveAspectRatio="none"` no atributo (o
     `central-cockpit.css` já resolve assim para o mesmo componente,
     `.mk-central .grafico-linha__area`). */
  .dashboard-grade__linha .grafico-linha__area { display: flex; flex: 1 1 auto; min-height: 0; }
  .dashboard-grade__linha .grafico-linha__svg { flex: 1 1 auto; min-height: 0; }

  /* Empty state compacto (ver `renderEvolucaoConformidade.js` e
     `visualizacaoAdaptativa.js`): mensagem curta e enquadrada, nunca um
     parágrafo livre flutuando numa caixa vazia. O `line-clamp` continua
     como rede de segurança para qualquer texto inesperadamente longo, não
     como a estratégia principal de conter o conteúdo.
     `:not(.evolucao-conformidade__resumo)`: esse seletor é mais específico
     que `.evolucao-conformidade__resumo { display: none }` (linha acima) e
     vem depois na cascata — sem a exclusão, ele reativava o `<p>` escondido
     com `display: -webkit-box`, e o resumo (que deveria sumir, repete o que
     os KPIs já mostram) voltava a aparecer e estourar a altura do card
     (achado real: ao dividir esta linha em 2 colunas, o card ficou mais
     estreito e o texto, antes invisível por acidente de layout, passou a
     vazar por baixo do `overflow: hidden`). */
  .dashboard-grade__linha .cartao > div > p.texto-suave:not(.evolucao-conformidade__resumo) {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: var(--txt-sm);
  }

  .dashboard-previas { display: none; }
}

/* < 1280px: sem trava de altura — a página rola normalmente, e as linhas do
   grid viram colunas fluidas (auto-fit) em vez das proporções fixas do
   desktop grande. */
@media (max-width: 1279px) {
  .dashboard-grade__linha { grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); }
}

/* Mobile: só o essencial (KPIs + evolução + divergências) — o resto (motivos,
   distribuição de status, regional, ranking, financeira) fica reservado ao
   desktop e tablet, senão a tela vira 7 gráficos espremidos. */
@media (max-width: 767px) {
  .dashboard-grade__linha--3col > .cartao:nth-child(n + 2) { display: none; }
}

/* Os 6 KPIs do painel executivo cabem numa linha só a partir de 1024px —
   `.metricas` de base para em 4 colunas (pensada para os grupos de 4 da
   Central), aqui são 6 cartões mais estreitos. Sem `text-overflow:
   ellipsis` no rótulo/valor: com largura cheia (ver full-bleed acima) e
   moeda abreviada nos KPIs financeiros (`moedaCompacta()`, `renderKpis.js`),
   nenhum título ou valor precisa mais truncar — o pedido é explícito que
   nenhum KPI principal pode esconder o número atrás de reticências. */
@media (min-width: 1024px) {
  .dashboard-kpis { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
.dashboard-kpis > .metrica { min-width: 0; }
/* O pedido é explícito: nenhum título de KPI pode truncar com reticências
   (seção 9). Com 6 colunas reais e rótulos como "Acuracidade financeira"
   (186px de conteúdo, medido) ou "Divergência absoluta", a coluna de rótulo
   de um cartão de ~180px nunca vai caber isso numa linha só, mesmo depois
   do full-bleed — truncar era a única saída enquanto a regra insistia em
   uma linha. Deixar quebrar em até 2 linhas resolve sem esconder texto: o
   rótulo é secundário na hierarquia do cartão (o VALOR é o elemento
   principal, seção 11), então 2 linhas de rótulo custam ~14px de altura de
   cartão, previsível e uniforme — não é o mesmo problema que o valor
   quebrar linha (esse sim inflava a altura de forma imprevisível, ver nota
   em `.metrica__valor` abaixo). */
.dashboard-kpis .metrica__rotulo {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  line-height: 1.25;
}
.dashboard-kpis .metrica__cabecalho { align-items: flex-start; }
.dashboard-kpis .metrica__icone { margin-top: 2px; }
/* `white-space: nowrap`, não `overflow-wrap: break-word`: quebrar em 2
   linhas parecia mais seguro que truncar, mas o valor maior empurrava a
   ALTURA da linha inteira de KPIs, que por sua vez espremia as 3 linhas de
   gráfico abaixo dela na grade sem scroll (achado real: "R$ 5.616,80"
   quebrando em 2 linhas em 1366px reduziu cada linha de gráfico a ~34px).
   Com `moedaCompacta()` (`utils/format.js`) garantindo strings curtas para
   os KPIs financeiros, uma linha só sempre cabe — não é mais um
   truncamento escondendo o número, é o formato que já chega do tamanho
   certo. */
.dashboard-kpis .metrica__valor { white-space: nowrap; }

/* --- sinal de tendência (evolução de loja) ------------------------------------- */
.tendencia-selo {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-3);
  border-radius: var(--raio);
  font-weight: 600;
  font-size: var(--txt-sm);
  border: 1px solid currentColor;
}
.tendencia-selo--melhorando { color: var(--conforme); }
.tendencia-selo--piorando   { color: var(--falta); }
.tendencia-selo--estavel    { color: var(--texto-3); }

/* --- evolução da conformidade (veio da Central) --------------------------------
   O seletor de janela (7 dias … 12 meses) mudou de tela junto com o gráfico:
   a Central mostra o número, a análise da série é daqui. */
.evolucao-conformidade { min-height: 12rem; }

.segmentado {
  display: inline-flex;
  border: 1px solid var(--linha);
  border-radius: var(--raio-sm);
  overflow: hidden;
  background: var(--surface-2);
  flex-wrap: wrap;
}
.segmentado__opcao {
  border: none;
  background: transparent;
  padding: 6px var(--e-3);
  min-height: 34px;
  font: inherit;
  font-size: var(--txt-sm);
  color: var(--texto-2);
  cursor: pointer;
}
.segmentado__opcao + .segmentado__opcao { border-left: 1px solid var(--linha); }
.segmentado__opcao:hover { background: var(--azul-100); color: var(--texto); }
.segmentado__opcao[aria-pressed='true'] {
  background: var(--azul-900);
  color: var(--neutro-0);
  font-weight: 600;
}
.segmentado__opcao:focus-visible { outline: 2px solid var(--azul-500); outline-offset: -2px; }

@media (max-width: 640px) {
  .segmentado { width: 100%; }
  .segmentado__opcao { flex: 1 1 auto; }
}

/* --- interação dos gráficos --------------------------------------------------
   As classes abaixo pertencem aos COMPONENTES de gráfico, não a esta página —
   moram aqui porque é onde toda a folha de estilo de gráfico do projeto já
   estava quando a interação foi adicionada (Central de Auditoria). Manter as
   duas metades juntas vale mais que a pureza do nome do arquivo: separá-las
   criaria dois lugares para ajustar o mesmo desenho.
   -------------------------------------------------------------------------- */

/* Balão de leitura do gráfico de linha. Ancorado por porcentagem sobre a
   área do SVG e transladado conforme o lado, para não sair pela borda no
   primeiro e no último ponto. */
.grafico-linha__area { position: relative; }
.grafico-linha__svg:focus-visible { outline: 2px solid var(--azul-500); outline-offset: 2px; }

.grafico-tooltip {
  position: absolute;
  top: var(--e-2);
  z-index: 1;
  min-width: 9rem;
  max-width: min(16rem, 70vw);
  padding: var(--e-2) var(--e-3);
  background: var(--surface);
  border: 1px solid var(--linha-2);
  border-radius: var(--raio);
  box-shadow: var(--sombra-lg);
  font-size: var(--txt-xs);
  display: flex;
  flex-direction: column;
  gap: 3px;
  /* O balão segue o cursor: se ele próprio capturasse o ponteiro, entraria
     em laço de "entra no balão → sai do gráfico → some o balão". */
  pointer-events: none;
}
.grafico-tooltip[data-lado='direita']  { transform: translateX(var(--e-3)); }
.grafico-tooltip[data-lado='esquerda'] { transform: translateX(calc(-100% - var(--e-3))); }

.grafico-tooltip__titulo {
  font-size: var(--txt-xs);
  font-weight: 700;
  color: var(--texto);
  padding-bottom: 3px;
  border-bottom: 1px solid var(--linha);
  margin-bottom: 2px;
}
.grafico-tooltip__linha { display: flex; align-items: center; gap: var(--e-2); }
.grafico-tooltip__nome  { color: var(--texto-2); flex: 1 1 auto; min-width: 0; }
.grafico-tooltip__valor {
  font-family: var(--fonte);
  font-weight: 600;
  color: var(--texto);
  font-variant-numeric: tabular-nums;
}

/* Barra e fatia que levam a algum lugar. O realce é sutil de propósito: a
   informação continua sendo o tamanho da barra, não o efeito de hover. */
.grafico-barra--link { cursor: pointer; }
.grafico-barra--link:hover .grafico-barra__valor,
.grafico-barra--link:focus-visible .grafico-barra__valor { opacity: .82; }
.grafico-barra--link:hover .grafico-barra__trilho { fill: var(--azul-100); }
.grafico-barra--link:focus-visible {
  outline: 2px solid var(--azul-500);
  outline-offset: 1px;
  border-radius: var(--raio-sm);
}

.grafico-rosca__fatia--link { cursor: pointer; }
.grafico-rosca__fatia--link:hover { opacity: .85; }

.grafico__legenda-item--link {
  width: 100%;
  font: inherit;
  color: inherit;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--raio-sm);
  padding: 2px var(--e-2);
  cursor: pointer;
  min-height: 1.75rem;
}
.grafico__legenda-item--link:hover { background: var(--surface-2); border-color: var(--linha); }
.grafico__legenda-item--link:focus-visible { outline: 2px solid var(--azul-500); outline-offset: 1px; }

/* Ponteiro grosso demais para mirar uma faixa de 6px: no toque, o gráfico de
   linha ganha respiro vertical para o balão não cobrir o próprio dado. */
@media (max-width: 640px) {
  .grafico-tooltip { max-width: 60vw; }
}
