/* ============================================================================
   nex-ui.css: camada de interface compartilhada do sistema NexDrones.

   Duas coisas moram aqui, e só duas:

   1. A TIPOGRAFIA OFICIAL da marca, servida pelo próprio sistema. Geist nos
      títulos e números, Google Sans Flex no corpo, exatamente como manda o
      design-guide. As duas são variáveis (um arquivo cobre 100 a 900) e foram
      recortadas pro alfabeto latino: 32 KB e 50 KB, contra 168 KB e 4,1 MB dos
      TTF originais em marca/fontes/. Isso importa porque o vendedor abre no
      celular, muitas vezes em 4G de fazenda.

   2. A CAMADA DE DATAVIZ no desenho do bklit UI: card com cabeçalho e valor
      grande, grade tracejada só na horizontal, área com gradiente que some,
      linha de 2px com ponta arredondada, tooltip flutuante e legenda com
      bolinha. O bklit é React sobre shadcn e Recharts, e este sistema é HTML
      puro sem build, então o que veio foi a gramática visual, reescrita em
      SVG e CSS. Zero dependência nova, zero passo de build.

   NADA de cor nova entra aqui. Todo valor sai dos tokens que index.html e
   dashboards.html já declaram (--acao, --superficie, --borda, --cinza...),
   então o tema escuro continua funcionando sozinho e a identidade não muda.
   ========================================================================= */

/* ------------------------------------------------------------------ fontes */
@font-face {
  font-family: "Geist";
  src: url("/fontes/Geist.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  /* swap, não block: o texto aparece na hora com a fonte do sistema e troca
     quando a oficial chega. Em conexão ruim, ler tarde é pior que ler feio. */
  font-display: swap;
}
@font-face {
  font-family: "Google Sans Flex";
  src: url("/fontes/GoogleSansFlex.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --fonte-titulo: "Geist", ui-sans-serif, system-ui, sans-serif;
  --fonte-corpo: "Google Sans Flex", "Geist", Inter, ui-sans-serif, system-ui,
    -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Profundidade. O design-guide diz que o site aposta em contraste de fundo,
     não em sombra, então a sombra aqui é quase invisível de propósito, só o
     bastante pro card descolar do fundo cinza como acontece no shadcn. */
  --sombra-1: 0 1px 2px rgba(17, 24, 39, .05);
  --sombra-2: 0 1px 3px rgba(17, 24, 39, .07), 0 1px 2px rgba(17, 24, 39, .04);
  --sombra-flutua: 0 8px 24px rgba(17, 24, 39, .12), 0 2px 6px rgba(17, 24, 39, .06);
}
/* No escuro, sombra preta não aparece sobre fundo preto: quem dá profundidade
   é a borda. Zerar a sombra evita aquele halo sujo em volta do card. */
:root[data-tema="escuro"] {
  --sombra-1: none;
  --sombra-2: none;
  --sombra-flutua: 0 8px 28px rgba(0, 0, 0, .55);
}

/* Tipografia aplicada. O seletor é o mesmo que os arquivos já usam, mas como
   este CSS entra ANTES do <style> inline de cada página, a linha de
   font-family de lá foi trocada pra apontar pras variáveis daqui. */
body { font-family: var(--fonte-corpo); }

h1, h2, h3, h4,
.valor-hero, .valor, .num-esteira, .ranking-pos,
.cartao-titulo, .cartao-valor {
  font-family: var(--fonte-titulo);
  letter-spacing: -0.011em;
}

/* Número em fonte de largura fixa: sem isso a coluna dança quando o valor
   troca de 9 pra 10, e em tabela de performance isso cansa a leitura. */
.valor, .valor-hero, .num-esteira, .cartao-valor,
td.num, th.num, .mes-valor, .ranking-pontos {
  font-variant-numeric: tabular-nums;
}

/* ==================================================== número na horizontal
   Regra do Vini (2026-08-05): número e valor em reais NUNCA quebram em duas
   linhas, em nenhuma tela. "R$ 215.988" partido no meio do card não é só
   feio: o olho lê "R$" e "215.988" como duas informações separadas, e o
   card de resumo existe justamente pra ser lido de relance.

   nowrap sozinho resolveria a quebra e criaria outra: o número vaza pra fora
   do card em vez de descer. Quem impede isso é o degrau de tamanho por
   comprimento (data-tam), aplicado no JS que monta o card, onde o número de
   caracteres é conhecido. Ver a função `metrica` em index.html e
   dashboards.html.

   Regra de fim de linha, quando entrar valor novo em algum canto: se o texto
   é um número, uma moeda, uma porcentagem ou uma contagem, ele entra nesta
   lista. Não existe exceção "esse é curto, deixa quebrar". */
.metrica .valor, .valor-hero, .num-esteira, .cartao-valor,
.g-valor, .ranking-pos, .ranking-pontos, .mes-valor, .mes-rotulo,
td.num, th.num, .conta-score li b, .anel b,
.carteira-topo .conta, .etapa-esteira .tx-esteira,
.tag, .taxa, .etq {
  white-space: nowrap;
}

/* O degrau. O card do resumo tem largura fixa pela grade, então o que sobra
   pro número é largura de card menos o padding. Cada faixa foi medida pra
   caber nessa sobra com a fonte da marca, inclusive no celular, onde a grade
   cai pra duas colunas e o card fica com a mesma largura de sempre. */
.metrica .valor[data-tam="medio"] { font-size: 21px; }
.metrica .valor[data-tam="longo"] { font-size: 18px; }
.metrica .valor[data-tam="enorme"] { font-size: 15.5px; }

/* A grade densa (seis números numa linha só, no marketing) começa menor e
   cai pra quatro colunas em tela média, que é o caso mais apertado do
   sistema inteiro. O degrau dela desce mais rápido por causa disso. */
.grade.densa .metrica .valor[data-tam="medio"] { font-size: 16px; }
.grade.densa .metrica .valor[data-tam="longo"] { font-size: 13.5px; }
.grade.densa .metrica .valor[data-tam="enorme"] { font-size: 11.5px; }

/* O número herói da diretoria ocupa a largura inteira do bloco, então só
   encolhe quando o valor passa da casa dos milhões. */
.valor-hero[data-tam="longo"] { font-size: 33px; }
.valor-hero[data-tam="enorme"] { font-size: 27px; }

/* ============================================================ card do bklit
   O card do bklit tem quatro faixas fixas: título curto, descrição, corpo
   (o gráfico) e rodapé com a leitura. Manter essa ordem é o que faz um
   painel com oito gráficos parecer um sistema só, e não oito telas. */
.g-card {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--r-2xl, 16px);
  box-shadow: var(--sombra-1);
  padding: 18px;
  margin-bottom: 12px;
}
.g-cab { margin-bottom: 14px; }
.g-titulo {
  font-family: var(--fonte-titulo);
  font-size: 14px; font-weight: 600; color: var(--texto);
  margin: 0; letter-spacing: -0.01em;
}
.g-desc { font-size: 12.5px; color: var(--cinza); margin: 3px 0 0; }
.g-valor {
  font-family: var(--fonte-titulo);
  font-size: 30px; font-weight: 600; color: var(--texto);
  line-height: 1.12; margin: 10px 0 0; font-variant-numeric: tabular-nums;
}
.g-rodape {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--borda);
  font-size: 12.5px; color: var(--cinza);
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}

/* Selo de variação. Verde e vermelho aqui são estado, não identidade. É
   exatamente o uso que o design-guide libera pras cores de apoio. */
.g-delta {
  font-size: 12px; font-weight: 600; padding: 2px 9px; border-radius: 999px;
  white-space: nowrap; display: inline-flex; align-items: center; gap: 4px;
}
.g-delta.sobe { background: var(--ok-fundo); color: var(--ok-texto); border: 1px solid var(--ok-borda); }
.g-delta.desce { background: var(--erro-fundo); color: var(--erro-texto); border: 1px solid var(--erro-borda); }
.g-delta.neutra { background: var(--fundo); color: var(--cinza); border: 1px solid var(--borda); }

/* ------------------------------------------------------------- área do svg */
.g-svg { display: block; width: 100%; height: auto; overflow: visible; }

/* Grade: só horizontal e tracejada. Linha vertical em série temporal curta
   vira ruído e briga com a própria linha do dado. */
.g-grade line {
  stroke: var(--borda); stroke-width: 1; stroke-dasharray: 3 3;
  shape-rendering: crispEdges;
}
/* O eixo não tem linha de base: o rótulo já ancora a leitura, e a régua
   sólida engrossa a tela sem informar nada. */
.g-eixo text { fill: var(--cinza); font-size: 10.5px; font-family: var(--fonte-corpo); }
.g-eixo .g-y { text-anchor: end; }
.g-eixo .g-x { text-anchor: middle; }

.g-linha { fill: none; stroke: var(--acao-forte); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.g-area { stroke: none; }
.g-ponto { fill: var(--superficie); stroke: var(--acao-forte); stroke-width: 2; }

/* Barra com topo arredondado e base reta: o bklit usa isso pra barra apoiada
   no eixo não parecer flutuando.

   pointer-events: none porque no SVG a barra é pintada POR CIMA do alvo de
   mouse (ver a ordem em graficos.js). Sem isso ela roubaria o ponteiro no
   meio da coluna, e o realce piscaria toda vez que o cursor passasse por cima
   da própria barra. */
.g-barra { fill: var(--acao); pointer-events: none; }
.g-barra.parcial { opacity: .5; }
.g-barra-trilho { fill: var(--fundo); }

/* Alvo de mouse invisível cobrindo a coluna inteira: acertar uma barra de
   6px de largura com o dedo é impossível, e o dedo é o caso principal.

   O `+` é obrigatório aqui, não é preferência de estilo: com `~` (irmão
   geral), apontar uma coluna acendia ela E TODAS as seguintes, porque a regra
   pegava todo .g-realce posterior no mesmo SVG. */
.g-alvo { fill: transparent; cursor: pointer; }
.g-alvo:hover + .g-realce, .g-alvo:focus + .g-realce { opacity: 1; }
.g-realce { fill: var(--acao-suave); opacity: 0; transition: opacity .12s; pointer-events: none; }

/* --------------------------------------------------------------- tooltip */
.g-tip {
  position: fixed; z-index: 60; pointer-events: none;
  background: var(--superficie); border: 1px solid var(--borda);
  border-radius: 8px; box-shadow: var(--sombra-flutua);
  padding: 8px 10px; font-size: 12px; color: var(--texto);
  min-width: 120px; opacity: 0; transform: translateY(3px);
  transition: opacity .12s, transform .12s;
}
.g-tip[data-aberto="1"] { opacity: 1; transform: translateY(0); }
.g-tip .t-rot { color: var(--cinza); font-size: 11px; margin-bottom: 4px; }
.g-tip .t-linha { display: flex; align-items: center; gap: 7px; justify-content: space-between; }
.g-tip .t-nome { display: flex; align-items: center; gap: 6px; color: var(--cinza); }
.g-tip .t-val { font-family: var(--fonte-titulo); font-weight: 600; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------- legenda */
.g-legenda { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 12px; font-size: 12px; color: var(--cinza); }
.g-legenda span { display: inline-flex; align-items: center; gap: 6px; }
.g-bola { width: 8px; height: 8px; border-radius: 50%; background: var(--acao-forte); flex: none; }

/* ----------------------------------------------------------- ring / gauge
   O ring do bklit é um arco de ponta arredondada por cima de um trilho da
   mesma espessura, com o número no centro. Vale pra taxa: o vazio do anel
   comunica "quanto falta" muito mais rápido que um número solto. */
.g-ring { display: block; }
.g-ring .trilho { fill: none; stroke: var(--fundo); stroke-width: 9; }
.g-ring .arco { fill: none; stroke: var(--acao); stroke-width: 9; stroke-linecap: round; transform: rotate(-90deg); transform-origin: 50% 50%; }
.g-ring .arco.bom { stroke: var(--ok); }
.g-ring .arco.ruim { stroke: var(--erro); }
.g-ring-centro { text-anchor: middle; font-family: var(--fonte-titulo); font-weight: 600; fill: var(--texto); font-variant-numeric: tabular-nums; }
.g-ring-rot { text-anchor: middle; fill: var(--cinza); font-size: 10px; font-family: var(--fonte-corpo); }

/* Fila de anéis: uma taxa por anel, lado a lado, rolando no celular. */
.g-aneis { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 10px; }
.g-anel-item { text-align: center; }
.g-anel-item .rot { font-size: 12px; color: var(--cinza); margin-top: 2px; }

/* --------------------------------------------------------------- sparkline
   Linha miúda dentro do quadradinho de número. Sozinho, o número diz onde
   está; com a sparkline junto, diz pra onde vai. */
.g-spark { display: block; width: 100%; height: 26px; margin-top: 8px; overflow: visible; }
.g-spark .l { fill: none; stroke: var(--acao-forte); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.g-spark .p { fill: var(--acao-forte); }

/* ============================================================ polimento geral
   Ajustes finos que alinham os componentes que já existiam ao mesmo desenho.
   Nenhum muda cor, fonte ou hierarquia: mexem em sombra, espaço e transição. */
.card, .metrica, .hero { box-shadow: var(--sombra-1); }
.card, .metrica, .hero, .g-card { transition: box-shadow .16s ease, border-color .16s ease, transform .16s ease; }

/* Card clicável reage; card de leitura fica quieto. */
a.card:hover, .card.clicavel:hover { box-shadow: var(--sombra-2); border-color: var(--acao-forte); }

/* Barra do funil: trilho arredondado com preenchimento que cresce, no lugar
   do corte reto. A transição é a mesma curva do bklit (saída suave). */
.preenche { transition: width .6s cubic-bezier(.22, 1, .36, 1); }

/* Cabeçalho de tabela grudado no topo ao rolar: em tabela de performance com
   15 linhas, perder o nome da coluna é perder a tabela. */
.rolagem table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--superficie);
  box-shadow: inset 0 -1px 0 var(--borda);
}
tbody tr { transition: background .12s; }
tbody tr:hover { background: var(--fundo); }

/* Entrada dos blocos. Quem tem "reduzir movimento" ligado no sistema recebe
   tudo já no lugar (a regra está no fim do arquivo. */
.entra { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .entra { opacity: 1 !important; transform: none !important; }
  .preenche, .card, .metrica, .hero, .g-card, .g-tip { transition: none !important; }
}
