/* ==========================================================================
   NewGas Portal — Sistema de design
   ==========================================================================

   Portal B2B (SaaS/CRM) para gestão de contratos de gás natural, operado por
   equipe interna e por clientes externos sobre a MESMA base de telas.

   Esta folha implementa o guia de marca NewGas
   (docs/especificacao-saas-frontend-com-guia-de-marca.md). O guia é dependência
   funcional do produto, não material de marketing: as cores oficiais, a
   tipografia Urbanist e a área de segurança do logotipo entram aqui como
   token e são travadas por teste em `portal/tests_marca.py`.

   As quatro decisões que governam o resto:

   1. A MARCA É A PALETA. Etano (#224964) é a ação; Metano (#1E2F39) é a
      estrutura e o texto; Propano (#5BC8BA) é a confirmação. Nenhum azul
      genérico sobrevive nesta folha.
   2. SUPERFÍCIE PLANA. Separação por linha de 1px e por cor de fundo, não por
      sombra. Sombra fica reservada ao que de fato flutua (popover, gaveta) —
      assim ela volta a significar "isto está por cima".
   3. DENSIDADE DE OPERAÇÃO. Linha de tabela em 40px, célula 13px. Quem concilia
      uma carteira de centenas de unidades precisa ver 25 linhas sem rolar, não
      12 linhas confortáveis.
   4. COR COM SIGNIFICADO. Verde/âmbar/vermelho são estado, nunca decoração, e
      estado nunca é comunicado só por cor (§4.3 do guia, WCAG 1.4.1).

   VALOR OFICIAL x VALOR LEGÍVEL — a regra que explica as rampas abaixo.
   Três cores oficiais reprovam como texto sobre branco: Propano (2,02:1),
   Laranja (2,57:1) e Amarelo (1,41:1); o próprio Cinza oficial dá 3,90:1. O
   guia manda usar as cores E validar contraste (§4.4), então a folha separa os
   dois papéis: o valor oficial serve de PREENCHIMENTO (selo, barra, gráfico
   sobre fundo claro) e um derivado do MESMO MATIZ, mais escuro, serve de
   TEXTO. Nenhum matiz é inventado; nenhum contraste fica abaixo de 4,5:1.
   `tests_marca` recalcula todos os pares e falha se algum descer.

   Toda cor entra como token neste bloco :root — nenhuma regra abaixo carrega
   um literal. É o que permite o tema escuro existir sem uma segunda folha e é
   travado por teste (PaletaTests.test_nenhum_hex_fora_do_root).
   -------------------------------------------------------------------------- */

:root {
  color-scheme: light;

  /* --- Cores oficiais da marca (guia §4.1) ------------------------------
     Os nove valores do guia, literalmente. Não se ajusta nada aqui por gosto:
     é contra estes hexadecimais que `tests_marca.CoresOficiaisTests` compara.
     Toda a rampa abaixo é derivada deles. */
  --color-methane:  #1e2f39;
  --color-ethane:   #224964;
  --color-propane:  #5bc8ba;
  --color-black:    #000000;
  --color-gray:     #808184;
  --color-white:    #ffffff;
  --color-orange:   #eb8a09;
  --color-iris:     #6666e8;
  --color-yellow:   #e5de51;

  /* --- Rampa da marca ---------------------------------------------------
     Ancorada nos dois valores oficiais: 600 É Etano e 900 É Metano. Os demais
     degraus são o mesmo matiz (~204°) em outra luminosidade — a rampa existe
     para haver hover, borda e fundo suave sem sair da marca. */
  --brand-50:   #eff6fa;
  --brand-100:  #d9e8f2;
  --brand-200:  #b5d1e3;
  --brand-300:  #84b0cd;
  --brand-400:  #4585b0;
  --brand-500:  #2d6286;
  --brand-600:  #224964;
  --brand-700:  #1a3b51;
  --brand-800:  #1a2f3d;
  --brand-900:  #1e2f39;

  /* --- Neutros (a base da tela) -----------------------------------------
     Matizados no azul do Metano (204°), não em cinza puro: cinza neutro ao
     lado de Etano puxa para o verde. O Cinza oficial (#808184) vive em
     --color-gray e é usado onde o guia pede cinza de marca; para TEXTO entra
     --ink-600, porque o oficial dá 3,90:1 sobre branco e reprova (§4.4). */
  --ink-0:      #ffffff;
  --ink-25:     #fcfdfd;
  --ink-50:     #f5f8f9;
  --ink-100:    #ecf0f3;
  --ink-150:    #e0e7eb;
  --ink-200:    #d1dae0;
  --ink-300:    #aebcc6;
  --ink-400:    #8497a4;
  --ink-500:    #637683;
  --ink-600:    #4b5f6c;
  --ink-700:    #384b57;
  --ink-800:    #273945;
  --ink-900:    #1e2f39;
  --ink-950:    #131f26;

  /* --- Estado -----------------------------------------------------------
     Propano/Laranja/Amarelo/Íris entram no degrau em que o guia os define
     (400 ou 500) e ganham degraus escuros para uso como texto. */
  --propano-50:   #ecf9f7;
  --propano-100:  #c9ede8;
  --propano-300:  #8cd9cf;
  --propano-400:  #5bc8ba;
  --propano-500:  #33a394;
  --propano-600:  #218376;
  --propano-700:  #18675d;

  --laranja-50:   #fef4e7;
  --laranja-100:  #fbdfbc;
  --laranja-500:  #eb8a09;
  --laranja-600:  #ba6d08;
  --laranja-700:  #915608;

  --amarelo-50:   #fbfae4;
  --amarelo-100:  #f5f2bc;
  --amarelo-400:  #e5de51;
  --amarelo-700:  #716114;

  --iris-50:      #ededfc;
  --iris-100:     #d3d3f8;
  --iris-500:     #6666e8;
  --iris-600:     #3e3ecc;
  --iris-700:     #3131a5;

  /* Erro não existe na paleta principal do guia: é cor FUNCIONAL, aplicada com
     moderação para não competir com a identidade (§4.2). */
  --rubro-50:     #fceded;
  --rubro-100:    #f7d4d4;
  --rubro-500:    #c74343;
  --rubro-600:    #a83232;
  --rubro-700:    #7f2424;

  /* --- Papéis semânticos ------------------------------------------------
     É o que as regras de componente usam. Trocar a marca é trocar a rampa
     acima; nenhum papel muda de nome. */
  --fundo:          var(--ink-50);
  --superficie:     var(--ink-0);
  --superficie-2:   var(--ink-25);
  --superficie-3:   var(--ink-100);
  --linha:          var(--ink-150);
  --linha-forte:    var(--ink-200);
  --texto:          var(--ink-900);
  --texto-2:        var(--ink-600);
  --texto-3:        var(--ink-500);
  --texto-inverso:  var(--ink-0);
  --acao:           var(--brand-600);
  --acao-hover:     var(--brand-700);
  --acao-suave:     var(--brand-50);
  --acao-borda:     var(--brand-200);
  --foco:           var(--brand-500);

  /* 700 e não 600: o selo pinta --ok sobre --ok-suave, e o 600 dava 4,26:1
     nesse par. Sobre branco o 700 dá 6,50:1 — passa nos dois usos. */
  --ok:             var(--propano-700);
  --ok-suave:       var(--propano-50);
  --warn:           var(--laranja-700);
  --warn-suave:     var(--laranja-50);
  --alert:          var(--rubro-600);
  --alert-suave:    var(--rubro-50);
  --info:           var(--brand-500);
  --info-suave:     var(--brand-50);
  --destaque:       var(--iris-600);
  --destaque-suave: var(--iris-50);
  --atencao:        var(--amarelo-700);
  --atencao-suave:  var(--amarelo-50);

  /* Camada da barra lateral: Metano nos dois temas. Ela é moldura, não
     conteúdo — o contraste permanente separa "onde estou" de "o que estou
     lendo" sem precisar de sombra nem de borda grossa. É também a aplicação
     que o guia recomenda para a marca branca (§3.5). */
  --rail-fundo:     var(--ink-950);
  --rail-fundo-2:   var(--ink-900);
  --rail-texto:     var(--ink-300);
  --rail-texto-2:   var(--ink-400);
  --rail-ativo:     var(--ink-0);
  --rail-linha:     var(--ink-800);

  /* --- Camada de dados (gráficos e setores) -----------------------------
     Nomes consumidos como string por charts.js e metrics.SECTOR_COLORS —
     renomear quebra gráfico e distribuição por setor. Os VALORES passaram a
     honrar o guia: --propano é teal e --etano é azul, que é o que os nomes
     sempre disseram. Ambos entram no degrau legível sobre fundo claro
     (WCAG 1.4.11 pede 3:1 para objeto gráfico). */
  --propano:        var(--propano-600);
  --propano-deep:   var(--propano-700);
  --etano:          var(--brand-600);
  --iris:           var(--iris-600);
  --laranja:        var(--laranja-600);
  --accent:         var(--propano-500);
  --accent-deep:    var(--propano-600);
  --prog:           var(--brand-400);
  /* Série neutra dos gráficos. Precisa ser PAPEL e não primitivo: como
     `var(--ink-700)` ela não acompanhava o tema e sumia no escuro (1,81:1). */
  --serie-neutra:   var(--ink-700);
  --chart-prog:     var(--ink-400);
  --chart-grid:     var(--ink-150);
  --chart-text:     var(--ink-500);
  --chart-area:     rgba(34, 73, 100, .10);

  /* --- Transparências (não dá para aplicar alfa a um var() em rgba) ------
     Os canais são Metano (30 47 57) e Etano (34 73 100) — as sombras e o véu
     puxam para o azul da marca em vez de para um cinza neutro. */
  --sombra-1:       rgba(30, 47, 57, .06);
  --sombra-2:       rgba(30, 47, 57, .10);
  --sombra-3:       rgba(30, 47, 57, .16);
  --veu:            rgba(19, 31, 38, .52);
  --foco-halo:      rgba(34, 73, 100, .28);
  --marca-halo:     rgba(34, 73, 100, .14);

  /* --- Tipografia (guia §5) ---------------------------------------------
     Urbanist é a família da marca. O fallback não é decorativo: se a fonte não
     carrega, a tela precisa continuar legível (§5.4) — daí a pilha de sistema
     logo atrás. O mono existe só para dado tabular (CNPJ, código, número de
     contrato), onde alinhamento de dígito vale mais que personalidade. */
  --fonte: "Urbanist", ui-sans-serif, system-ui, -apple-system,
           "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --fonte-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo,
                Consolas, monospace;
  --font-family-brand: var(--fonte);

  /* Pesos do guia §5.2. Black só em título de destaque; Light nunca em texto
     pequeno — as duas proibições estão em §5.4 e valem na revisão. */
  --font-weight-light:   300;
  --font-weight-regular: 400;
  --font-weight-bold:    700;
  --font-weight-black:   900;

  /* Escala de tamanho. Os --t-* são a escala canônica da folha (densa, em
     px lógicos); os --font-size-* são os nomes do guia §5.3 apontando para
     ela, para a especificação continuar verificável sem criar uma segunda
     escala que possa divergir. */
  --t-11: .6875rem;
  --t-12: .75rem;
  --t-13: .8125rem;
  --t-14: .875rem;
  --t-16: 1rem;
  --t-18: 1.125rem;
  --t-22: 1.375rem;
  --t-28: 1.75rem;
  --t-34: 2.125rem;
  --font-size-xs:  var(--t-12);
  --font-size-sm:  var(--t-14);
  --font-size-md:  var(--t-16);
  --font-size-lg:  var(--t-18);
  --font-size-xl:  var(--t-22);
  --font-size-2xl: var(--t-28);
  --font-size-3xl: var(--t-34);

  --line-height-tight:   1.2;
  --line-height-normal:  1.5;
  --line-height-relaxed: 1.7;

  /* --- Geometria da marca (guia §3.4) -----------------------------------
     ÁREA DE SEGURANÇA. O guia define a reserva como a área da letra "e" no
     tamanho original do logotipo. O valor NÃO é estimado a olho: foi medido no
     arquivo oficial em uso (static/img/logo-newgas.png, 1024x259), segmentando
     os seis glifos de "newgas" pelo canal alfa. O "e" é o 2º glifo e mede
     143x150px, com a linha de base em y=180.

       altura do "e" ÷ altura do logotipo aparado = 150 ÷ 206 = 0,728

     A reserva é proporcional porque acompanha a escala: definida como razão,
     ela continua correta em qualquer tamanho de renderização, que é o que o
     guia quer dizer com "no tamanho original". Remeça quando o SVG oficial
     entrar — o procedimento está em static/img/brand/README.md. */
  --brand-e-ratio-logo:   .728;

  /* Alturas de renderização por contexto. O trilho exibe o logotipo SEM
     tagline: a 26px o lockup inteiro reduzia a tagline embutida a ~4px, o que
     §3.3 proíbe ("não utilizar versões que comprometam a leitura"). A tagline
     voltou para onde há espaço — login e páginas institucionais (§3.1) — e
     como texto vivo, então escala e é lida por leitor de tela. */
  --brand-h-rail:   28px;
  --brand-h-auth:   48px;
  --brand-h-mini:   26px;
  --brand-logo-clearance: calc(var(--brand-h-rail) * var(--brand-e-ratio-logo));

  /* --- Espaço (escala densa, dial de densidade 8/10) -------------------- */
  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 20px;
  --e-6: 24px;
  --e-7: 32px;
  --e-8: 40px;

  /* --- Forma ------------------------------------------------------------ */
  /* Raio único de 6px em controle, cartão, campo, selo e linha — a medida do
     padrão de referência (django-unfold: `--radius-default: 6px`). Antes eram
     três raios (8/12/16) aplicados sem regra, e o mesmo tipo de elemento
     aparecia com cantos diferentes em telas diferentes.
     `--r-2` sobrou só para superfície grande (gaveta, modal), onde 6px lê como
     canto vivo; `--r-3` foi aposentado e aponta para `--r-2`. */
  --r-1: 6px;
  --r-2: 10px;
  --r-3: var(--r-2);
  --r-full: 999px;

  /* --- Ponte para o vocabulário shadcn/ui + Radix ------------------------
     shadcn/ui e Radix Themes são bibliotecas React; o portal é Django com
     template e CSS próprios, então o que se adota deles é o que atravessa a
     stack: os *nomes* de token e a semântica de foco/estado.

     Os aliases abaixo não introduzem valor novo — apontam para a escala
     NewGas já aprovada pelo guia de marca. Servem para que um componente
     portado de shadcn (card, dialog, select, tabela) caia no lugar sem
     reescrever a folha, e para que `--ring` signifique a mesma coisa aqui e
     lá. Trocar a marca continua sendo trocar a rampa, não estes aliases. */
  --radius: var(--r-1);          /* shadcn: --radius */
  --radius-sm: 6px;
  --radius-lg: var(--r-2);
  --radius-full: var(--r-full);
  --ring: var(--foco);           /* shadcn: --ring / Radix: focus ring */
  --ring-offset: 2px;
  --ring-width: 2px;

  /* --- Estrutura -------------------------------------------------------- */
  --rail-w: 252px;
  --rail-w-min: 72px;
  --topo-h: 60px;
  --linha-tabela: 42px;
  --largura-max: 1680px;

  /* --- Movimento (dial 3/10: micro-interação, nada coreografado) -------- */
  --rapido: 120ms;
  --normal: 170ms;
  --curva: cubic-bezier(.2, .6, .3, 1);
}

/* Tema escuro. Só os PAPÉIS mudam de valor — nenhuma regra de componente é
   reescrita, que é a razão de os papéis existirem.

   As superfícies são Metano rebaixado (matiz 203°), não cinza-azulado
   genérico: no escuro a marca aparece como AMBIENTE, já que o logotipo passa a
   ser a variante branca sobre ela. Os acentos sobem de degrau — sobre fundo
   escuro quem precisa clarear é o texto, então Propano volta ao valor oficial
   (#5BC8BA, 10,11:1 aqui) e Etano cede lugar ao 300. */
.theme-dark {
  color-scheme: dark;

  --fundo:          #0d161b;
  --superficie:     #152128;
  --superficie-2:   #1c2931;
  --superficie-3:   #24333d;
  --linha:          #30404b;
  --linha-forte:    #3f535f;
  --texto:          #e9eef2;
  --texto-2:        #b1bfc9;
  --texto-3:        #90a1ad;
  --texto-inverso:  var(--ink-950);
  --acao:           var(--brand-300);
  --acao-hover:     var(--brand-200);
  --acao-suave:     #182c39;
  --acao-borda:     #325267;
  --foco:           var(--brand-300);

  --ok:             var(--propano-300);
  --ok-suave:       #142e2b;
  --warn:           #f3a949;
  --warn-suave:     #362612;
  --alert:          #e87373;
  --alert-suave:    #391818;
  --info:           var(--brand-300);
  --info-suave:     #182c39;
  --destaque:       #9696ee;
  --destaque-suave: #1c1c40;
  --atencao:        var(--amarelo-400);
  --atencao-suave:  #2e2b14;

  --rail-fundo:     #0a1115;
  --rail-fundo-2:   #111b22;
  --rail-texto:     #a5b5c0;
  --rail-texto-2:   #738896;
  --rail-ativo:     #f2f7fa;
  --rail-linha:     #22313a;

  /* No escuro o Propano oficial finalmente cabe como traço de gráfico:
     10,11:1 sobre a superfície. */
  --propano:        var(--propano-400);
  --propano-deep:   var(--propano-300);
  --etano:          var(--brand-300);
  --iris:           #9696ee;
  --laranja:        #f3a949;
  --accent:         var(--propano-400);
  --accent-deep:    var(--propano-300);
  --prog:           var(--brand-300);
  --serie-neutra:   var(--ink-300);
  --chart-prog:     var(--ink-500);
  --chart-grid:     #30404b;
  --chart-text:     #90a1ad;
  --chart-area:     rgba(91, 200, 186, .14);

  --sombra-1:       rgba(0, 0, 0, .32);
  --sombra-2:       rgba(0, 0, 0, .44);
  --sombra-3:       rgba(0, 0, 0, .58);
  --veu:            rgba(0, 0, 0, .62);
  --foco-halo:      rgba(132, 176, 205, .36);
  --marca-halo:     rgba(91, 200, 186, .20);
}

/* ==========================================================================
   1. Base
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--fundo);
  color: var(--texto);
  font-family: var(--fonte);
  font-size: var(--t-14);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0; font-weight: 700; letter-spacing: -.015em; line-height: 1.25; }
h1 { font-size: var(--t-22); }
h2 { font-size: var(--t-18); }
h3 { font-size: var(--t-14); }
p  { margin: 0 0 var(--e-3); }
p:last-child { margin-bottom: 0; }

a { color: var(--acao); text-decoration: none; }
a:hover { text-decoration: underline; }

img { max-width: 100%; height: auto; }

hr { border: 0; border-top: 1px solid var(--linha); margin: var(--e-5) 0; }

/* Foco visível e uniforme. Nunca removido: é a única pista de "onde estou"
   para quem navega por teclado. */
:focus-visible {
  outline: var(--ring-width) solid var(--ring);
  outline-offset: var(--ring-offset);
  border-radius: var(--radius);
}

/* Padrão Radix: o container que recebe o foco por delegação (`tabindex="-1"`
   em painel de aba, linha de tabela rolável, item de menu) desenha o mesmo
   anel do foco real. Sem isto, mover o foco por script deixava o usuário de
   teclado sem pista nenhuma de onde caiu. */
[data-foco-delegado]:focus-within {
  outline: var(--ring-width) solid var(--ring);
  outline-offset: var(--ring-offset);
  border-radius: var(--radius);
}

/* Padrão Radix/shadcn de estado desabilitado: um só lugar decide como um
   controle inerte se apresenta, em vez de cada componente repetir opacidade e
   cursor. */
[data-disabled],
[aria-disabled="true"] {
  opacity: .55;
  cursor: not-allowed;
  pointer-events: none;
}

::selection { background: var(--marca-halo); }

/* Barras de rolagem discretas — a tela tem muitas áreas roláveis (tabela,
   árvore de escopo, gaveta) e a barra padrão do sistema domina cada uma. */
* { scrollbar-width: thin; scrollbar-color: var(--linha-forte) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--linha-forte);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--r-full);
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--ink-400); background-clip: content-box; }

/* ==========================================================================
   2. Utilitários
   ========================================================================== */

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

.muted  { color: var(--texto-2); }
.mono   { font-family: var(--fonte-mono); font-size: .95em; }
.nowrap { white-space: nowrap; }
.num    { text-align: right; }
.tabular { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.spacer { flex: 1 1 auto; }
.full   { grid-column: 1 / -1; }
.stack  > * + * { margin-top: var(--e-4); }
.code {
  font-family: var(--fonte-mono);
  font-size: var(--t-12);
  background: var(--superficie-3);
  border: 1px solid var(--linha);
  border-radius: var(--r-1);
  padding: 1px var(--e-1);
}

/* ==========================================================================
   2b. Marca — logotipo, símbolo e lockup
   --------------------------------------------------------------------------
   Implementa o guia §3 (uso do logotipo) e §3.4 (área de segurança). Toda
   ocorrência da marca no portal passa pela tag `{% ngmarca %}`, que emite esta
   estrutura — não há `<img>` de logotipo solto em template nenhum.

   ÁREA DE SEGURANÇA. O guia define a reserva como a área da letra "e" no
   tamanho original. A razão foi MEDIDA no arquivo (150px de "e" sobre 206px de
   logotipo = 0,728) e vive em `--brand-e-ratio-logo`. Aqui ela vira padding
   proporcional à altura renderizada: a reserva continua correta em qualquer
   escala, que é o que "no tamanho original" quer dizer. Por isso os containers
   da marca (trilho, login, rodapé) não aplicam padding próprio ao redor dela —
   somariam à reserva e desalinhariam a marca do resto da coluna.

   PROPORÇÃO. Só a ALTURA é fixada; a largura é `auto`. É o que impede o
   esticamento que §3.6 proíbe — e é também por isso que `.marca__img` não pode
   receber `width` em px, `transform`, `filter`, `border` ou `rotate` em
   nenhuma regra desta folha. `tests_marca.ProibicoesDoGuiaTests` varre a folha
   atrás dessas propriedades e falha se alguma aparecer.
   ========================================================================== */

.marca {
  /* Reserva medida do arquivo oficial. Fica exposta como custom property para
     um container conseguir descontá-la do próprio espaçamento. */
  --marca-clearance: calc(var(--marca-h) * var(--brand-e-ratio-logo));
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--marca-h) * .16);
  padding: var(--marca-clearance);
  max-width: 100%;
  min-width: 0;
}

/* Proporção travada: altura definida, largura livre. Nunca o contrário. */
.marca__img {
  height: var(--marca-h);
  width: auto;
  max-width: 100%;
  display: block;
  /* A marca é arte final: nada de suavização inventada ao reduzir. */
  object-fit: contain;
}

/* Tagline como TEXTO, não como pixel embutido (§3.1).
   O piso de tamanho não é estética: a tagline embutida no PNG legado ficava com
   ~4px de altura no trilho, e §3.3 proíbe versão que comprometa a leitura. Com
   `max()` ela nunca desce de 12px, por menor que fique o logotipo. */
.marca__tagline {
  font-family: var(--fonte);
  font-weight: var(--font-weight-regular);
  font-size: max(var(--t-12), calc(var(--marca-h) * .2));
  line-height: var(--line-height-tight);
  color: var(--marca-tagline-cor, currentColor);
}

/* Variante por CONTRASTE DO FUNDO (§3.5), não por gosto. A tag escolhe o
   arquivo; aqui fica só a cor da tagline, que é texto e acompanha o tema. */
.marca--escuro { color: var(--ink-0); --marca-tagline-cor: var(--color-propane); }
.marca--claro  { color: var(--color-methane); --marca-tagline-cor: var(--brand-600); }

/* O símbolo é quadrado e só existe para espaço compacto (§3.3): favicon,
   avatar, trilho recolhido. Nunca substitui o logotipo onde há largura. */
.marca--simbolo { --marca-clearance: calc(var(--marca-h) * var(--brand-e-ratio-logo) * .5); }

/* Marca dentro de um link não deve ganhar sublinhado no hover. */
a:hover .marca__img, a:hover .marca__tagline { text-decoration: none; }

/* ==========================================================================
   3. Estrutura da aplicação
   --------------------------------------------------------------------------
   Grade de duas colunas: trilho fixo + coluna de conteúdo. O trilho é
   `position: fixed` e a coluna recebe a margem correspondente — assim a
   listagem rola sem arrastar o menu junto, que é o comportamento esperado de
   quem passa o dia comparando linha com filtro.
   ========================================================================== */

.app { min-height: 100vh; }

/* --- Trilho de navegação -------------------------------------------------- */
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 40;
  width: var(--rail-w);
  display: flex;
  flex-direction: column;
  gap: var(--e-5);
  padding: var(--e-5) var(--e-3) var(--e-4);
  background: var(--rail-fundo);
  border-right: 1px solid var(--rail-linha);
  /* Filete de Propano: a marca entra como moldura, sem competir com o item ativo. */
  box-shadow: inset 3px 0 0 var(--propano-400);
  overflow-y: auto;
  overscroll-behavior: contain;
  transition: width var(--normal) var(--curva);
}

.sidebar__logo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-2);
  /* Sem padding ao redor da marca: a área de segurança já vem DENTRO de
     `.marca` (§3.4) e somar os dois desalinharia a marca da coluna de itens.
     Resta só o respiro à direita, do botão de recolher. */
  padding: 0 var(--e-2) 0 0;
  border-bottom: 1px solid var(--rail-linha);
}

.sidebar__brand { display: flex; align-items: center; min-width: 0; }
.sidebar__brand:hover { text-decoration: none; }

/* O trilho recolhido troca o logotipo pelo símbolo — o uso que §3.3 reserva à
   versão reduzida ("navegação compacta"). Antes era um quadrado azul com a
   letra "N", que não é a marca. */
.brand-full { display: block; min-width: 0; }
.brand-mini { display: none; }

.sidebar__toggle {
  margin-left: auto;
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border: 1px solid var(--rail-linha);
  border-radius: var(--r-1);
  background: transparent;
  color: var(--rail-texto-2);
  cursor: pointer;
  transition: color var(--rapido) var(--curva), border-color var(--rapido) var(--curva);
}
.sidebar__toggle:hover { color: var(--rail-ativo); border-color: var(--rail-texto-2); }
.sidebar__toggle .ic { transform: rotate(180deg); transition: transform var(--normal) var(--curva); }
.nav-collapsed .sidebar__toggle .ic { transform: rotate(0deg); }

.sidebar__section-label {
  padding: 0 var(--e-2);
  margin-bottom: var(--e-2);
  color: var(--rail-texto-2);
  font-size: var(--t-12);
  font-weight: 600;
}

/* Grupo sem rótulo: a home. Ela não pertence a categoria nenhuma — é o
   destino, não um assunto — e um rótulo de seção só para ela ("Início") seria
   uma linha de texto para um item. A margem menor a cola ao logotipo, que é o
   outro caminho para a mesma tela. */
.sidebar__grupo--solto { margin-bottom: var(--e-4); }

.sidebar__nav { display: flex; flex-direction: column; gap: 2px; }

.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: 10px var(--e-3);
  border-radius: var(--r-2);
  color: var(--rail-texto);
  font-size: var(--t-13);
  font-weight: 500;
  white-space: nowrap;
  transition: background var(--rapido) var(--curva), color var(--rapido) var(--curva);
}
.nav-item:hover { background: var(--rail-fundo-2); color: var(--rail-ativo); text-decoration: none; }
.nav-item .ic { flex: none; opacity: .85; }

/* O item corrente é marcado por três sinais ao mesmo tempo (fundo, cor e a
   barra à esquerda) porque cor sozinha não chega a quem não a distingue. */
.nav-item.active {
  background: var(--rail-fundo-2);
  color: var(--rail-ativo);
  font-weight: 600;
}
.nav-item.active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 18px;
  border-radius: 0 var(--r-1) var(--r-1) 0;
  background: var(--propano-400);
}
.nav-item.active .ic { opacity: 1; color: var(--propano-400); }

.sidebar__footer {
  margin-top: auto;
  padding: var(--e-3) var(--e-2) 0;
  border-top: 1px solid var(--rail-linha);
  color: var(--rail-texto-2);
  font-size: var(--t-11);
  line-height: 1.6;
}

/* Trilho recolhido: só ícones. O rótulo sai do fluxo mas continua no DOM para
   o leitor de tela. */
.nav-collapsed .sidebar { width: var(--rail-w-min); }
.nav-collapsed .sidebar__logo { padding-inline: 0; justify-content: center; flex-wrap: wrap; gap: var(--e-2); }
.nav-collapsed .brand-full { display: none; }
.nav-collapsed .brand-mini { display: block; }
.nav-collapsed .sidebar__toggle { margin: 0; }
.nav-collapsed .sidebar__section-label { text-align: center; padding: 0; font-size: 0; height: 1px; overflow: hidden; }
.nav-collapsed .nav-item { justify-content: center; padding-inline: 0; }
.nav-collapsed .nav-item .lbl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
.nav-collapsed .nav-item.active::before { left: 0; }
.nav-collapsed .sidebar__footer { display: none; }

/* --- Coluna de conteúdo --------------------------------------------------- */
.main {
  margin-left: var(--rail-w);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  transition: margin-left var(--normal) var(--curva);
}
.nav-collapsed .main { margin-left: var(--rail-w-min); }

.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: var(--e-3);
  height: var(--topo-h);
  padding: 0 var(--e-6);
  background: var(--superficie);
  border-bottom: 1px solid var(--linha);
}

.topbar__menu {
  display: none;
  align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border: 1px solid var(--linha);
  border-radius: var(--r-1);
  background: var(--superficie);
  color: var(--texto-2);
  cursor: pointer;
}

.topbar__crumbs {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  min-width: 0;
  font-size: var(--t-13);
  color: var(--texto-3);
}
.topbar__crumbs b { color: var(--texto); font-weight: 600; }
.topbar__crumbs a { color: var(--texto-3); }
.topbar__crumbs a:hover { color: var(--acao); }
.crumb-parent { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 22ch; }
.crumb-sep { display: inline-flex; color: var(--ink-300); }

.topbar__spacer { flex: 1 1 auto; }

.topbar__user-info { text-align: right; line-height: 1.25; }
.topbar__user-info .name { font-size: var(--t-13); font-weight: 600; }
.topbar__user-info .role { font-size: var(--t-11); color: var(--texto-3); }

.avatar {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: var(--r-full);
  background: var(--acao-suave);
  color: var(--acao);
  border: 1px solid var(--acao-borda);
  font-size: var(--t-11);
  font-weight: 700;
}

/* --- Atalho de teclado para o conteúdo ------------------------------------ */
.pular {
  position: absolute;
  left: var(--e-3);
  top: var(--e-3);
  z-index: 100;
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-1);
  background: var(--acao);
  color: var(--texto-inverso);
  font-size: var(--t-13);
  font-weight: 600;
  transform: translateY(-200%);
  transition: transform var(--normal) var(--curva);
}
.pular:focus { transform: none; text-decoration: none; }

.content:focus { outline: none; }

/* --- Menu da conta --------------------------------------------------------
   <details> nativo: abre e fecha por conta própria, é operável por teclado e
   não precisa de handler inline (que a CSP com nonce bloquearia). */
.usermenu { position: relative; }
.usermenu__btn {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-1) var(--e-2) var(--e-1) var(--e-1);
  border: 1px solid transparent;
  border-radius: var(--r-full);
  cursor: pointer;
  list-style: none;
  transition: background var(--rapido) var(--curva), border-color var(--rapido) var(--curva);
}
.usermenu__btn::-webkit-details-marker { display: none; }
.usermenu__btn:hover { background: var(--superficie-3); border-color: var(--linha); }
.usermenu[open] .usermenu__btn { background: var(--superficie-3); border-color: var(--linha-forte); }
.usermenu__btn .ic { color: var(--texto-3); transform: rotate(90deg); }
.usermenu .topbar__user-info { display: flex; flex-direction: column; }

.usermenu__painel {
  position: absolute;
  z-index: 50;
  top: calc(100% + var(--e-2));
  right: 0;
  width: 264px;
  background: var(--superficie);
  border: 1px solid var(--linha-forte);
  border-radius: var(--r-2);
  box-shadow: 0 14px 36px var(--sombra-2), 0 2px 6px var(--sombra-1);
  overflow: hidden;
}
.usermenu__cabecalho { padding: var(--e-3); border-bottom: 1px solid var(--linha); }
.usermenu__nome { font-size: var(--t-13); font-weight: 700; }
.usermenu__meta {
  font-size: var(--t-11);
  color: var(--texto-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.usermenu__papel { display: flex; flex-wrap: wrap; gap: var(--e-1); margin-top: var(--e-2); }
.usermenu__acoes { padding: var(--e-1); }
.usermenu__acoes form { margin: 0; }
.usermenu__item {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  width: 100%;
  padding: var(--e-2);
  border: 0;
  border-radius: var(--r-1);
  background: transparent;
  color: var(--texto);
  font-family: inherit;
  font-size: var(--t-13);
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}
.usermenu__item:hover { background: var(--superficie-3); text-decoration: none; }
.usermenu__item .ic { color: var(--texto-3); flex: none; }
.usermenu__rot { flex: 1 1 auto; }
.usermenu__estado {
  font-size: var(--t-11);
  font-weight: 600;
  color: var(--texto-3);
  border: 1px solid var(--linha);
  border-radius: var(--r-full);
  padding: 0 var(--e-2);
}
.usermenu__item--sair { color: var(--alert); }
.usermenu__item--sair .ic { color: var(--alert); }
.usermenu__item--sair:hover { background: var(--alert-suave); }

.sidebar__grupo { min-width: 0; }
.sidebar__versao { color: var(--rail-texto); font-weight: 600; }

.content {
  flex: 1 1 auto;
  width: 100%;
  max-width: var(--largura-max);
  margin-inline: auto;
  padding: var(--e-6) var(--e-6) var(--e-7);
  display: flex;
  flex-direction: column;
  gap: var(--e-5);
}

.nav-backdrop { display: none; }

/* ==========================================================================
   4. Cabeçalho de página
   ========================================================================== */

.page-head {
  display: flex;
  align-items: flex-start;
  gap: var(--e-4);
  flex-wrap: wrap;
}
.page-head__kicker {
  margin: 0 0 var(--e-1);
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--acao);
}
.page-head h1 { font-size: var(--t-28); font-weight: 900; letter-spacing: -.03em; }
.page-head .sub {
  margin-top: var(--e-1);
  color: var(--texto-2);
  font-size: var(--t-14);
  max-width: 82ch;
  line-height: 1.5;
}
.page-head .actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--e-2);
  flex-wrap: wrap;
}

.secao {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
  margin-top: var(--e-2);
}

/* ==========================================================================
   5. Botões
   --------------------------------------------------------------------------
   Três pesos e nada mais: `accent` (a ação principal da tela, uma por tela),
   padrão (ação secundária) e `ghost` (ação de linha/terciária). `danger` é
   variação de destino, não um quarto peso.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  height: 36px;
  padding: 0 var(--e-3);
  border: 1px solid var(--linha-forte);
  border-radius: var(--r-1);
  background: var(--superficie);
  color: var(--texto);
  font-family: inherit;
  font-size: var(--t-13);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--rapido) var(--curva),
              border-color var(--rapido) var(--curva),
              color var(--rapido) var(--curva);
}
.btn:hover { background: var(--superficie-3); text-decoration: none; }
.btn:active { transform: translateY(.5px); }
.btn .ic { flex: none; }

.btn.accent {
  background: var(--acao);
  border-color: var(--acao);
  color: var(--texto-inverso);
}
.btn.accent:hover { background: var(--acao-hover); border-color: var(--acao-hover); }

.btn.ghost {
  background: transparent;
  border-color: transparent;
  color: var(--texto-2);
  font-weight: 500;
}
.btn.ghost:hover { background: var(--superficie-3); color: var(--texto); }

.btn.danger {
  background: var(--alert);
  border-color: var(--alert);
  color: var(--ink-0);
}
.btn.danger:hover { filter: brightness(.94); }

.btn.sm { height: 30px; padding: 0 var(--e-2); font-size: var(--t-12); }
.btn.icon { width: 36px; padding: 0; }
.btn.sm.icon { width: 30px; }

.btn.is-disabled, .btn[disabled] {
  opacity: .45;
  pointer-events: none;
  cursor: default;
}

/* Estado de envio: o rótulo troca no texto (não só no ícone) para o leitor de
   tela ouvir que o envio começou. */
.btn.is-enviando { opacity: .7; pointer-events: none; }

.form-inline { display: inline-flex; }

/* ==========================================================================
   6. Selos de estado (pill)
   --------------------------------------------------------------------------
   Fundo suave + texto na cor do estado + ponto opcional. Nunca só cor: o
   rótulo textual sempre acompanha, porque a coluna "Ativo" precisa ser legível
   por quem não distingue verde de vermelho.
   ========================================================================== */

/* Raio do sistema, não cápsula: o selo totalmente arredondado era o terceiro
   raio da mesma tela (controle 6, cartão 10, cápsula 999). O padrão de
   referência usa o mesmo `rounded-default` em cartão, botão e selo. O ponto
   de estado continua redondo — é um ponto. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  padding: 2px var(--e-2);
  border-radius: var(--r-1);
  border: 1px solid var(--linha);
  background: var(--superficie-3);
  color: var(--texto-2);
  font-size: var(--t-11);
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}
.pill .dot {
  width: 5px; height: 5px;
  border-radius: var(--r-full);
  background: currentColor;
  flex: none;
}
.pill.ok      { background: var(--ok-suave);    color: var(--ok);    border-color: transparent; }
.pill.alert   { background: var(--alert-suave); color: var(--alert); border-color: transparent; }
.pill.warn    { background: var(--warn-suave);  color: var(--warn);  border-color: transparent; }
.pill.info    { background: var(--info-suave);  color: var(--info);  border-color: transparent; }
.pill.brand   { background: var(--acao-suave);  color: var(--acao);  border-color: transparent; }
.pill.neutro  { background: var(--superficie-3); color: var(--texto-2); border-color: transparent; }
.pill.outline { background: transparent; border-color: var(--linha-forte); color: var(--texto-2);
                font-family: var(--fonte-mono); font-size: var(--t-11); }
.pill.danger  { background: var(--alert-suave); color: var(--alert); border-color: transparent; }
/* Íris e Amarelo fecham o mapeamento de status do guia (§7.6): "destaque
   analítico" e "alerta não destrutivo". O Amarelo oficial (#E5DE51) só entra
   como FUNDO — sobre branco ele dá 1,41:1 e o guia proíbe texto branco sobre
   ele (§4.4); o texto do selo é o degrau escuro do mesmo matiz.

   Os dois existem sem status que os peça hoje: são o mapeamento do guia
   escrito por inteiro, para que o dia em que um status precisar deles não
   invente uma cor. `FolhaDeEstiloTests.SELOS_DO_GUIA` os declara — sem isso a
   trava de regra órfã os apagaria. */
.pill.destaque { background: var(--destaque-suave); color: var(--destaque); border-color: transparent; }
.pill.atencao  { background: var(--atencao-suave);  color: var(--atencao);  border-color: transparent; }

.pill-cloud { display: inline-flex; flex-wrap: wrap; gap: var(--e-1); }

.contagem {
  display: inline-flex;
  align-items: center; justify-content: center;
  min-width: 18px; height: 18px;
  padding: 0 5px;
  border-radius: var(--r-full);
  background: var(--acao);
  color: var(--texto-inverso);
  font-size: var(--t-11);
  font-weight: 700;
}

/* ==========================================================================
   7. Cartão
   ========================================================================== */

.card {
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  padding: var(--e-4);
}
.card.tight { padding: 0; overflow: hidden; }
.card.tight > .card__head { padding: var(--e-3) var(--e-4); }
.card--estreito { max-width: 780px; }

.card__head {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-bottom: var(--e-3);
  min-height: 26px;
}
.card.tight > .card__head { margin-bottom: 0; border-bottom: 1px solid var(--linha); }
.card__head h3 {
  font-size: var(--t-13);
  font-weight: 700;
  letter-spacing: -.005em;
}
.card__head .meta,
.card__head .btn,
.card__head .export-btn,
.card__head .legend { margin-left: auto; }
.card__head .meta { color: var(--texto-3); font-size: var(--t-12); }

.box {
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  padding: var(--e-3);
  background: var(--superficie-2);
}

/* --- Grades --------------------------------------------------------------- */
.grid { display: grid; gap: var(--e-3); }
.cols-2  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cols-12-8 { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); align-items: start; }
.grid--secao { gap: var(--e-4); }

/* ==========================================================================
   8. Faixa de resumo
   --------------------------------------------------------------------------
   `.resumo` é a faixa fina que abre uma listagem: quatro números em uma linha
   de 64px. O número nunca é gigante — o que se lê primeiro é o rótulo, e um
   número de 34px já domina a linha sem empurrar a tabela para fora da tela.

   O cartão de KPI (`.kpi`) que dividia esta seção saiu: onde ele era usado
   para enfileirar números soltos, a tela passou a usar tabela ou a faixa de
   resumo. Um número por moldura era a anatomia que enchia Pendências de sete
   cartões em três colunas para dizer o que cabe em ~300px de tabela.
   ========================================================================== */

.resumo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0;
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  overflow: hidden;
}
.resumo__item {
  padding: var(--e-4) var(--e-4);
  border-right: 1px solid var(--linha);
  min-width: 0;
}
.resumo__item:last-child { border-right: 0; }
.resumo__label {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
}
.resumo__valor {
  margin-top: 2px;
  font-size: var(--t-22);
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.resumo__sub {
  margin-top: 1px;
  font-size: var(--t-11);
  color: var(--texto-3);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ==========================================================================
   8b. Estágios da medição (QDC → QDS → QDP → QDR)
   --------------------------------------------------------------------------
   Quatro cartões idênticos lado a lado convidavam à soma — e somar os quatro
   conta o mesmo metro cúbico até quatro vezes, que foi exatamente o erro do
   KPI "volume total do dia". Aqui eles são desenhados como o que são: quatro
   ESTÁGIOS do mesmo gás, ligados por seta, numa sequência que não se totaliza.
   ========================================================================== */

.estagios {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  overflow: hidden;
}
.estagio {
  position: relative;
  padding: var(--e-4) var(--e-4);
  border-right: 1px solid var(--linha);
  min-width: 0;
}
.estagio:last-child { border-right: 0; }
/* A seta entre os estágios: desenhada na própria borda, sem elemento extra. */
.estagio + .estagio::before {
  content: "";
  position: absolute;
  left: -5px;
  top: 50%;
  width: 8px; height: 8px;
  margin-top: -4px;
  border-top: 1px solid var(--linha-forte);
  border-right: 1px solid var(--linha-forte);
  transform: rotate(45deg);
  background: var(--superficie);
}
.estagio__sigla {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  font-size: var(--t-11);
  font-weight: 800;
  color: var(--acao);
}
.estagio__nome { font-size: var(--t-12); color: var(--texto-3); }
.estagio__valor {
  margin-top: var(--e-1);
  font-size: var(--t-22);
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  gap: var(--e-1);
}
.estagio__valor .unit { font-size: var(--t-11); font-weight: 600; color: var(--texto-3); letter-spacing: 0; }
.estagio__glosa { font-size: var(--t-11); color: var(--texto-3); }
/* O realizado é o que se compara com o contrato: é o único destacado. */
.estagio--realizado { background: var(--acao-suave); }
/* A seta é desenhada sobre a borda e leva o fundo da célula que ela aponta:
   com o branco fixo, ela abria um entalhe claro na célula destacada. */
.estagio--realizado::before { background: var(--acao-suave); }
.estagio--realizado .estagio__valor { color: var(--acao); }

@media (max-width: 980px) {
  .estagios { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .estagio:nth-child(2n) { border-right: 0; }
  .estagio:nth-child(-n+2) { border-bottom: 1px solid var(--linha); }
  .estagio:nth-child(3)::before { display: none; }
}
@media (max-width: 520px) {
  .estagios { grid-template-columns: minmax(0, 1fr); }
  .estagio { border-right: 0; border-bottom: 1px solid var(--linha); }
  .estagio::before { display: none; }
}

/* ==========================================================================
   8c. Repartição da QDC contratada
   --------------------------------------------------------------------------
   Três cartões iguais (total, cativo, livre) não diziam que os dois últimos
   REPARTEM o primeiro — liam-se como três medidas independentes. A relação
   entre as partes fica no desenho: uma barra só, dividida na proporção.

   Os números vivem na faixa de resumo do painel (`.resumo`), com o mesmo
   quadradinho de legenda (`.sw`) que pinta cada parte da barra — por isso a
   moldura própria que a barra tinha (`.qdc-bloco`) saiu.
   ========================================================================== */

.qdc-split__barra {
  display: flex;
  height: 16px;
  border-radius: var(--r-full);
  overflow: hidden;
  background: var(--superficie-3);
}
.qdc-split__parte { height: 100%; }
.qdc-split__parte--cativo { background: var(--etano); }
.qdc-split__parte--livre { background: var(--propano); }

/* ==========================================================================
   9. Tabelas
   --------------------------------------------------------------------------
   O componente mais usado do portal. Regras que valem para todas:
   cabeçalho grudado no topo ao rolar, linha de 40px, número em tabular-nums e
   alinhado à direita, e uma coluna de identidade que absorve as colunas
   secundárias quando a tela encolhe (ver .cel-extra).
   ========================================================================== */

.table-wrap {
  width: 100%;
  overflow: auto;
  max-height: 72vh;
}
.table-wrap:focus-visible { outline-offset: -2px; }

.table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--t-13);
}

/* Cabeçalho: fundo próprio, uma linha, 13px em peso 600 e CAIXA NORMAL.
   A versão anterior era 11px em caixa alta com `letter-spacing` — o mesmo
   tratamento que os rótulos de seção e de KPI usavam, então três hierarquias
   diferentes disputavam a mesma atenção na mesma tela. O padrão de referência
   não usa `uppercase` em componente nenhum. */
/* Fundo do cabeçalho: `--superficie-3`, não `--superficie-2`.
   `--superficie-2` (#fcfdfd) fica 1,2% acima do branco da linha — invisível na
   tela — e era EXATAMENTE o mesmo tom do hover de linha: o cabeçalho lia como
   mais um registro em negrito, e passar o mouse numa linha a fazia parecer o
   cabeçalho. A borda inferior mais forte fecha o bloco. */
.table thead th {
  position: relative;
  text-align: left;
  padding: var(--e-2) var(--e-3);
  background: var(--superficie-3);
  border-bottom: 1px solid var(--linha-forte);
  color: var(--texto-2);
  font-size: var(--t-13);
  font-weight: 600;
  white-space: nowrap;
}
.table-wrap.sticky thead th { position: sticky; top: 0; z-index: 2; }

/* 6px no vertical (o `py-1.5` do padrão de referência), não 8: com a célula de
   identidade em dois níveis, 8px punha a linha em 53px — acima do teto de 48
   que a densidade exige. */
.table tbody td {
  padding: 6px var(--e-3);
  border-bottom: 1px solid var(--linha);
  vertical-align: middle;
}
.table tbody tr:last-child td { border-bottom: 0; }
/* `height` numa <tr> vale como ALTURA MÍNIMA: é assim que se fixa a densidade
   da linha. `min-height` na <td> não é honrado de forma confiável. */
.table tbody tr { height: var(--linha-tabela); transition: background var(--rapido) var(--curva); }
.table.compacta tbody tr { height: auto; }
/* Mais claro que o cabeçalho, de propósito: os dois tons não podem coincidir,
   senão a linha sob o cursor vira uma segunda faixa de cabeçalho. */
.table tbody tr:hover { background: var(--superficie-2); }

/* Coluna de atributo curto (UF, setor, combustível, ambiente) não quebra: uma
   célula em duas linhas devolve à linha toda a altura que a densidade de M1
   acabou de tirar — "Alimentos e Bebidas" sozinho empurrava a linha de 48 para
   75px. Passa de reticência quando não couber; o valor inteiro fica no title. */
.table td.atributo {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 22ch;
}

/* Segundo nível dentro de uma célula: o qualificador do valor principal.
   Mesmo papel da meta da célula de identidade, para a tabela ter UM jeito de
   dizer "isto explica a linha de cima" — antes cada coluna inventava o seu
   (`sub-line`, mini-barra, selo empilhado). */
.cel-sub {
  display: block;
  font-size: var(--t-12);
  line-height: 1.35;
  color: var(--texto-3);
  font-weight: 400;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cel-sub--alerta { color: var(--warn); }

.table th.num, .table td.num { text-align: right; }
.table td.num { font-variant-numeric: tabular-nums; }
.table td.muted { color: var(--texto-2); }
.table tfoot td {
  padding: var(--e-2) var(--e-3);
  border-top: 1px solid var(--linha-forte);
  background: var(--superficie-2);
  font-weight: 700;
}

.table .col-ident { min-width: 240px; }
.table .col-marca { width: 34px; padding-right: 0; }
.table .col-situacao { width: 92px; }
.table .col-acoes { width: 1%; white-space: nowrap; }

/* Ações de linha: aparecem em foco/hover, mas nunca somem para o teclado nem
   para o toque — em tela sem ponteiro ficam visíveis o tempo todo. */
.acoes-linha { display: inline-flex; gap: 2px; opacity: .55; transition: opacity var(--rapido) var(--curva); }
tr:hover .acoes-linha, .acoes-linha:focus-within { opacity: 1; }
@media (hover: none) { .acoes-linha { opacity: 1; } }

/* Tabela compacta: usada dentro de cartão de detalhe, onde a linha não precisa
   de área de clique. */
.table.compacta tbody td { padding: 5px var(--e-2); }
.table.compacta thead th { padding: var(--e-1) var(--e-2); }

/* Célula-extra: o que as colunas ocultas diziam, reagrupado dentro da célula
   de identidade quando a tela é estreita. O par é exclusivo por CSS, então o
   leitor de tela nunca ouve o mesmo dado duas vezes. */
.cel-extra { display: none; }
.cel-extra__par { display: inline-flex; gap: var(--e-1); align-items: baseline; }
.cel-extra__rot { color: var(--texto-3); font-size: var(--t-12); }

/* --- Célula de identidade (dois níveis) ---------------------------------- */
/* Nome em cima, tudo o que qualifica o nome numa linha de meta embaixo. O
   monograma de 28px e a linha de grupo em caixa alta saíram: somados, faziam a
   linha da listagem passar de 100px (o padrão de referência fixa 45px) sem
   acrescentar informação — as iniciais eram derivadas do texto ao lado. */
.ident { min-width: 0; }
.ident.is-continuacao { opacity: .55; }

.ident__nome {
  display: block;
  font-weight: 600;
  font-size: var(--t-13);
  line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 46ch;
}

/* Meta: uma linha só, sem quebra. Com `flex-wrap` a célula voltava a crescer em
   altura no primeiro nome longo — que é justamente o caso comum. */
.ident__meta {
  display: flex;
  align-items: baseline;
  gap: var(--e-2);
  min-width: 0;
  line-height: 1.35;
  font-size: var(--t-12);
  color: var(--texto-3);
  white-space: nowrap;
  overflow: hidden;
}
.ident__meta > * { overflow: hidden; text-overflow: ellipsis; }
/* Separador entre as partes da meta, desenhado e não digitado: some junto com
   a parte que ele separaria quando ela não existe. */
.ident__meta > * + *::before {
  content: "·";
  margin-right: var(--e-2);
  color: var(--linha-forte);
}
.ident__grupo { max-width: 26ch; flex: 0 1 auto; }
.ident__grupo--vazio { font-style: italic; color: var(--ink-400); }
.ident__unidade { max-width: 26ch; flex: 0 1 auto; }
.ident__cnpj, .ident__sigla { font-family: var(--fonte-mono); flex: none; }

/* ==========================================================================
   9b. Painel de trabalho (o padrão de toda listagem)
   --------------------------------------------------------------------------
   A tela antiga empilhava cartões independentes: um para o resumo, um para os
   filtros, um para a tabela, e a paginação solta no fim. Quatro molduras para
   uma coisa só — a listagem — e o olho tinha de remontar o conjunto a cada
   tela.

   Aqui a listagem é UM objeto: barra de ferramentas, faixa de números, filtros,
   tabela e rodapé dentro da mesma superfície, separados por linha. É o mesmo
   arranjo em Clientes, Agentes, Impostos, Consumo e Contratos, então quem
   aprendeu uma tela aprendeu as cinco.
   ========================================================================== */

.painel {
  display: flex;
  flex-direction: column;
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  overflow: hidden;
}

.painel__topo {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-2) var(--e-3);
  border-bottom: 1px solid var(--linha);
  background: var(--superficie-2);
  flex-wrap: wrap;
}
.painel__topo .topbar__search { flex: 1 1 220px; }
.painel__acoes { margin-left: auto; display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }

/* Faixa de filtros: um <details> de largura inteira logo abaixo da barra de
   ferramentas. Não é popover de propósito — a filtragem é automática e cada
   mudança recarrega a página; um painel flutuante reapareceria por cima da
   tabela a cada recarga. Aberto quando há filtro aplicado (o servidor decide),
   recolhido quando não há: recorte guardado que não se anuncia é armadilha. */
.painel__filtros { border-bottom: 1px solid var(--linha); }
.painel__filtros[open] { background: var(--superficie-2); }

.painel__filtro-bar {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-2) var(--e-3);
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-2);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.painel__filtro-bar::-webkit-details-marker { display: none; }
.painel__filtro-bar:hover { color: var(--texto); background: var(--superficie-3); }
.painel__filtro-bar .ic:first-child { color: var(--texto-3); }
/* A seta gira: é o único sinal de que a faixa abre. */
.painel__filtro-bar .painel__seta { margin-left: var(--e-1); transition: transform var(--normal) var(--curva); }
.painel__filtros[open] > .painel__filtro-bar .painel__seta { transform: rotate(90deg); }
.painel__filtro-bar.is-ativo { color: var(--acao); }

.painel__campos { border-top: 1px solid var(--linha); }
.painel__campos .filters-bar { padding: var(--e-3); }

/* Rótulo de contexto na barra de ferramentas: usado onde a seleção da tela
   (o tipo de imposto, a medição do gráfico) precisa ser dita em texto. */
.painel__contexto { display: flex; align-items: baseline; gap: var(--e-2); min-width: 0; }
.painel__contexto-rot { font-size: var(--t-13); font-weight: 700; }
.painel__contexto-meta { font-size: var(--t-12); color: var(--texto-3); }

.painel .resumo { border: 0; border-radius: 0; border-bottom: 1px solid var(--linha); }
.painel .tabs { padding: 0 var(--e-3); background: var(--superficie-2); }
.painel__rodape {
  border-top: 1px solid var(--linha);
  background: var(--superficie-2);
  padding: 0 var(--e-3);
}
.painel__rodape .pagination { padding: var(--e-2) 0; }
.painel__vazio { padding: 0; }
.painel__corpo { padding: var(--e-4); }
/* Painel usado só como barra (o filtro do Portfólio): sem tabela, sem rodapé. */
.painel--barra { background: var(--superficie-2); }
.painel--barra .filters-bar { padding: var(--e-3); }

/* ==========================================================================
   10. Vazio, nota, mensagem
   ========================================================================== */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-1);
  padding: var(--e-7) var(--e-4);
  text-align: center;
  color: var(--texto-2);
}
.empty .ic { color: var(--ink-300); margin-bottom: var(--e-2); }
.empty h3 { font-size: var(--t-14); color: var(--texto); }
.empty p { font-size: var(--t-13); margin: 0; max-width: 46ch; }

.vazio { color: var(--texto-3); font-size: var(--t-13); padding: var(--e-3); }

/* Nota explicativa: onde a tela precisa dizer por que um número é o que é.
   Barra à esquerda em vez de fundo colorido — não compete com os selos de
   estado, que são os únicos elementos coloridos por significado. */
.nota {
  border-left: 3px solid var(--acao-borda);
  background: var(--superficie-2);
  border-radius: 0 var(--r-1) var(--r-1) 0;
  padding: var(--e-2) var(--e-3);
  color: var(--texto-2);
  font-size: var(--t-12);
  line-height: 1.6;
}
.nota b { color: var(--texto); }
/* Variante de atenção: usada onde a nota descreve algo a corrigir, não algo a
   entender. Continua sendo nota (barra + fundo suave), não um alerta modal. */
.nota--atencao { border-left-color: var(--warn); background: var(--warn-suave); color: var(--warn); }
.nota--atencao b { color: inherit; }

.messages { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-2); }
.messages li {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  padding: var(--e-2) var(--e-3);
  border: 1px solid var(--linha);
  border-left-width: 3px;
  border-radius: var(--r-1);
  background: var(--superficie);
  font-size: var(--t-13);
}
.messages li::before { content: "●"; font-size: 9px; line-height: 1.7; }
.messages li.success { border-left-color: var(--ok);    color: var(--ok);    background: var(--ok-suave); }
.messages li.error   { border-left-color: var(--alert); color: var(--alert); background: var(--alert-suave); }
.messages li.warning { border-left-color: var(--warn);  color: var(--warn);  background: var(--warn-suave); }
/* Resumo de erros de formulário: focável, com link para cada campo recusado.
   Não substitui o erro por campo — responde "por que nada foi salvo" sem
   obrigar a varrer o formulário inteiro. */
.erro-resumo {
  border: 1px solid var(--alert);
  border-left-width: 3px;
  border-radius: var(--r-2);
  background: var(--alert-suave);
  padding: var(--e-3) var(--e-4);
}
.erro-resumo:focus { outline: 2px solid var(--alert); outline-offset: 2px; }
.erro-resumo h2 {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  font-size: var(--t-14);
  color: var(--alert);
}
.erro-resumo ul { margin: var(--e-2) 0 0; padding-left: var(--e-5); font-size: var(--t-13); }
.erro-resumo li { margin-bottom: var(--e-1); }
.erro-resumo a { color: var(--alert); font-weight: 600; text-decoration: underline; }

/* Painel de apoio ao lado de um formulário: explica a decisão que o campo
   pede, no lugar onde ela é tomada. */
.ajuda { display: flex; flex-direction: column; gap: var(--e-3); }
.ajuda__titulo {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
}
.ajuda__item { display: flex; flex-direction: column; gap: var(--e-1); align-items: flex-start; }
.ajuda__item p { font-size: var(--t-12); color: var(--texto-2); line-height: 1.55; margin: 0; }

.messages li.info,
.messages li.debug   { border-left-color: var(--info);  color: var(--info);  background: var(--info-suave); }

/* ==========================================================================
   11. Formulários
   --------------------------------------------------------------------------
   Rótulo sempre visível acima do campo (nunca placeholder no lugar de
   rótulo), ajuda abaixo, erro colado ao campo. A altura de 34px é a mesma dos
   botões: numa barra de filtros os dois convivem na mesma linha.
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--e-1); min-width: 0; }
.field > label {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-2);
}

input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=search], input[type=tel], input[type=url],
input:not([type]), select, textarea {
  width: 100%;
  height: 36px;
  padding: 0 var(--e-3);
  border: 1px solid var(--linha-forte);
  border-radius: var(--r-1);
  background: var(--superficie);
  color: var(--texto);
  font-family: inherit;
  font-size: var(--t-13);
  transition: border-color var(--rapido) var(--curva), box-shadow var(--rapido) var(--curva);
}
textarea { height: auto; min-height: 78px; padding: var(--e-2); line-height: 1.5; resize: vertical; }

select {
  appearance: none;
  padding-right: var(--e-6);
  /* Seta desenhada em CSS: um SVG de fundo teria de vir por data-URI com cor
     fixa e não acompanharia o tema escuro. */
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 15px center, right 10px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--foco);
  box-shadow: 0 0 0 3px var(--foco-halo);
}
input::placeholder, textarea::placeholder { color: var(--texto-3); }
input[disabled], select[disabled], textarea[disabled] {
  background: var(--superficie-3);
  color: var(--texto-3);
  cursor: not-allowed;
}
input[type=checkbox], input[type=radio] {
  width: 15px; height: 15px;
  accent-color: var(--acao);
  cursor: pointer;
  flex: none;
}

.field .help { font-size: var(--t-11); color: var(--texto-3); line-height: 1.45; }
.field .err, .error, .auth-field-err {
  font-size: var(--t-11);
  font-weight: 600;
  color: var(--alert);
}
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--alert); }
.field.has-error > label { color: var(--alert); }

.check { display: flex; align-items: center; gap: var(--e-2); font-size: var(--t-13); cursor: pointer; }
.check span { font-weight: 500; }
.check-list { display: flex; flex-direction: column; gap: var(--e-2); }
/* Grupo de caixas em linha.
   O `flex` daqui não alcançava as caixas: o widget do Django embrulha as
   opções num <div> próprio, que era o único filho — o grupo ficava numa coluna
   de seis linhas para rótulos de uma palavra ("GLP", "OC"). O `display:
   contents` dissolve esse embrulho e devolve as opções ao fluxo do flex. */
.checks-inline { display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-4); }
.checks-inline > div { display: contents; }

.campo-curto { max-width: 150px; }

/* Controle na barra de ferramentas da listagem: acompanha o próprio conteúdo.
   Preso em `campo-curto` (150px), o seletor de ordenação cortava o rótulo; o
   teto impede que ele empurre a exportação para fora da linha. */
.painel__acoes select { width: auto; max-width: 220px; }

/* Grupo de caixas de seleção dentro de um campo.
   O <fieldset> chegava com a borda e o entalhe de <legend> do navegador: uma
   moldura arredondada com o título cortando a linha, anatomia que não existe em
   nenhum outro campo do formulário. Agora ele se parece com os vizinhos — o
   <legend> vira um rótulo comum e o grupo, uma lista. */
fieldset.field {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;   /* <fieldset> ignora o encolhimento do grid sem isto */
}
fieldset.field > legend {
  padding: 0;
  margin-bottom: var(--e-2);
  font-size: var(--t-13);
  font-weight: 500;
  color: var(--texto-2);
}

/* Bloco de campos de um formulário longo: um cartão por assunto, com título
   que serve de ponto de referência ao rolar (o formulário de contrato tem 40+
   campos).

   O reset é só para <fieldset>, que chega com borda, margem e padding do
   navegador. Aplicado a `.form-section` em geral ele também zerava o `.card`
   das seções — que são `<div class="card form-section">` — e o formulário
   inteiro perdia moldura e respiro: os títulos encostavam no conteúdo da seção
   anterior e nada agrupava nada. */
fieldset.form-section { border: 0; margin: 0; padding: 0; }
.form-section + .form-section { margin-top: var(--e-4); }
.form-section > legend,
.form-section > h3 {
  padding: 0 0 var(--e-3);
  margin: 0 0 var(--e-4);
  width: 100%;
  border-bottom: 1px solid var(--linha);
  /* Mesmo papel do título de cartão (15px, semibold, tinta forte): é o título
     do bloco, não uma legenda de campo. Em 12px na escala apagada ele pesava
     menos que os próprios rótulos dos campos abaixo. */
  font-size: var(--t-14);
  font-weight: 600;
  color: var(--texto);
}
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--e-3) var(--e-4);
}
.form-grid--1 { grid-template-columns: minmax(0, 1fr); }
.field--grupo { grid-column: 1 / -1; }

.form-actions {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding-top: var(--e-4);
  margin-top: var(--e-2);
  border-top: 1px solid var(--linha);
}
.form-actions .spacer { flex: 1 1 auto; }

/* Barra de ações grudada no rodapé da janela. No formulário de contrato, com
   os quatro formsets abertos, "Salvar" ficava a várias telas de rolagem. */
.form-actions--fixa {
  position: sticky;
  bottom: 0;
  z-index: 10;
  margin-top: var(--e-3);
  padding: var(--e-3) var(--e-4);
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  box-shadow: 0 -4px 16px var(--sombra-1);
}

/* Ação destrutiva secundária: fica em texto, longe da ação principal, e só
   ganha o vermelho no hover — vermelho permanente ao lado de "Salvar" faz o
   olho tratá-lo como parte do par. */
.acao-destrutiva { color: var(--texto-2); }
.acao-destrutiva:hover { background: var(--alert-suave); color: var(--alert); }

/* O interruptor que muda o formulário inteiro (o "Cliente?" do agente) abre a
   tela sozinho, em vez de ser o primeiro de vinte campos iguais. */
.interruptor { background: var(--superficie-2); }
.interruptor .form-grid { gap: var(--e-4); }

/* Confirmação de exclusão. */
.confirmar { text-align: center; }
.confirmar__icone {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 48px; height: 48px;
  border-radius: var(--r-full);
  background: var(--alert-suave);
  color: var(--alert);
  margin-bottom: var(--e-3);
}
.confirmar__icone--ok { background: var(--ok-suave); color: var(--ok); }
.confirmar__titulo { font-size: var(--t-18); margin-bottom: var(--e-2); }
.confirmar__texto { color: var(--texto-2); font-size: var(--t-13); max-width: 52ch; margin-inline: auto; }
.confirmar .form-actions { justify-content: center; }

/* Formset (linhas repetíveis: moléculas, transportes, faixas de penalidade) */
/* `hidden` precisa vencer o display dos componentes: `.field` é flex, e um
   flex container com [hidden] continuaria na tela. */
[hidden] { display: none !important; }

.formset { }
.formset__head {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-3) var(--e-4);
  cursor: pointer;
  list-style: none;
  background: var(--superficie-2);
  border-bottom: 1px solid transparent;
}
.formset__head::-webkit-details-marker { display: none; }
.formset__head:hover { background: var(--superficie-3); }
.formset[open] > .formset__head { border-bottom-color: var(--linha); }
.formset__head .ic:first-child { color: var(--texto-3); transition: transform var(--normal) var(--curva); }
.formset[open] > .formset__head .ic:first-child { transform: rotate(90deg); }
.formset__titulo { font-size: var(--t-13); font-weight: 700; }
.formset__contagem { font-size: var(--t-12); color: var(--texto-3); margin-left: auto; }
.formset__corpo { padding: var(--e-4); display: flex; flex-direction: column; gap: var(--e-3); }
.formset-rows { display: flex; flex-direction: column; gap: var(--e-2); }
.formset-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: var(--e-2) var(--e-3);
  padding: var(--e-3);
  border: 1px solid var(--linha);
  border-radius: var(--r-1);
  background: var(--superficie-2);
}
.formset-row .del { align-self: end; }
.add-row { align-self: flex-start; }

/* ==========================================================================
   12. Abas
   ========================================================================== */

.tabs {
  display: flex;
  gap: var(--e-1);
  border-bottom: 1px solid var(--linha);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
  position: relative;
  padding: 12px var(--e-4);
  color: var(--texto-2);
  font-size: var(--t-13);
  font-weight: 600;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--rapido) var(--curva), border-color var(--rapido) var(--curva);
}
.tabs a:hover { color: var(--texto); text-decoration: none; }
.tabs a.active { color: var(--acao); border-bottom-color: var(--acao); }
/* Contagem dentro da aba: número neutro, para não competir com o rótulo. */
.tabs__n {
  display: inline-block;
  margin-left: var(--e-1);
  padding: 0 5px;
  border-radius: var(--r-full);
  background: var(--superficie-3);
  color: var(--texto-3);
  font-size: var(--t-11);
  font-variant-numeric: tabular-nums;
}
.tabs a.active .tabs__n { background: var(--acao-suave); color: var(--acao); }
.tabs__vazio { padding: var(--e-2) var(--e-3); font-size: var(--t-12); color: var(--texto-3); }
.tabs.sm a { padding: var(--e-1) var(--e-2); font-size: var(--t-12); }

/* ==========================================================================
   13. Barra de filtros
   --------------------------------------------------------------------------
   Com JavaScript a filtragem é automática e o botão "Filtrar" some (.is-auto),
   dando lugar ao indicador de quantos filtros estão ativos. Sem JavaScript o
   botão continua lá — a barra é um <form method="get"> comum.
   ========================================================================== */


.filters-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--e-2) var(--e-3);
  padding: var(--e-3) var(--e-4);
}
.filters-bar .field--inline { flex: 0 1 auto; min-width: 130px; }
.filters-bar .field--inline > label {
  font-size: var(--t-12);
  color: var(--texto-3);
}
/* `is-auto`/`is-loading` ficam no <form> (que envolve busca e faixa de
   filtros), não na linha de campos — daí os seletores serem descendentes. */
.is-loading { opacity: .6; pointer-events: none; }
.is-auto .filters-bar__submit { display: none; }

/* Rodapé da faixa: ocupa a linha inteira, separado dos campos. O botão
   "Aplicar" só existe sem JavaScript; com script quem informa o estado é o
   contador ao lado. */
.filters-bar__rodape {
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding-top: var(--e-3);
  margin-top: var(--e-1);
  border-top: 1px solid var(--linha);
}
.filters-bar__status {
  display: none;
  align-items: center;
  gap: var(--e-1);
  font-size: var(--t-12);
  color: var(--texto-3);
}
.is-auto .filters-bar__status { display: inline-flex; }
.filters-bar__status.ativo { color: var(--acao); font-weight: 600; }
.filters-bar__limpar { margin-left: auto; }

/* Campo de busca com ícone. Nasceu na topbar (daí o nome) e é o mesmo em toda
   barra de filtros e na árvore de escopo. */
.topbar__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 240px;
  min-width: 200px;
  max-width: 380px;
}
.topbar__search .ic {
  position: absolute;
  left: var(--e-2);
  color: var(--texto-3);
  pointer-events: none;
}
.topbar__search input { padding-left: calc(var(--e-6) + 2px); }

/* ==========================================================================
   14. Seletor de escopo (Grupo Econômico › Unidade)
   ========================================================================== */

.escopo { display: flex; flex-direction: column; gap: var(--e-2); }

.escopo__pop { position: relative; }

.escopo__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  height: 36px;
  padding: 0 var(--e-3);
  border: 1px solid var(--linha-forte);
  border-radius: var(--r-1);
  background: var(--superficie);
  font-size: var(--t-13);
  cursor: pointer;
  list-style: none;
  width: fit-content;
  max-width: 100%;
}
.escopo__btn::-webkit-details-marker { display: none; }
.escopo__btn:hover { border-color: var(--acao-borda); }
.escopo__btn.is-ativo { border-color: var(--acao); background: var(--acao-suave); color: var(--acao); }
.escopo__btn-rot { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.escopo__btn-meta { color: var(--texto-3); font-size: var(--t-11); white-space: nowrap; }
.escopo__btn .ic:last-child { transform: rotate(90deg); transition: transform var(--normal) var(--curva); }
.escopo__pop[open] .escopo__btn .ic:last-child { transform: rotate(-90deg); }

.escopo__painel {
  position: absolute;
  z-index: 25;
  top: calc(100% + var(--e-1));
  left: 0;
  width: min(520px, calc(100vw - var(--e-6)));
  background: var(--superficie);
  border: 1px solid var(--linha-forte);
  border-radius: var(--r-2);
  box-shadow: 0 12px 32px var(--sombra-2), 0 2px 6px var(--sombra-1);
  overflow: hidden;
}
.escopo__topo {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-3);
  border-bottom: 1px solid var(--linha);
}
.escopo__busca { flex: 1 1 auto; max-width: none; }
/* Sem JavaScript a busca não filtra nada: só aparece quando o script assume. */
.escopo__busca { display: none; }
.js-pronto .escopo__busca { display: flex; }
.escopo__contagem { font-size: var(--t-11); color: var(--texto-3); white-space: nowrap; }

.escopo__arvore { max-height: 320px; overflow-y: auto; padding: var(--e-2); }
.escopo__grupo { border-bottom: 1px solid var(--linha); padding-bottom: var(--e-1); margin-bottom: var(--e-1); }
.escopo__grupo:last-child { border-bottom: 0; }

.escopo__linha {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-1) var(--e-2);
  border-radius: var(--r-1);
  cursor: pointer;
  font-size: var(--t-13);
}
.escopo__linha:hover { background: var(--superficie-3); }
.escopo__linha--grupo { font-weight: 600; }
.escopo__linha--unidade { padding-left: var(--e-6); font-weight: 400; }
.escopo__rot { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.escopo__sub { color: var(--texto-3); font-size: var(--t-11); }
.escopo__uf {
  margin-left: auto;
  font-family: var(--fonte-mono);
  font-size: var(--t-11);
  color: var(--texto-3);
}
.escopo__n {
  margin-left: auto;
  font-size: var(--t-11);
  color: var(--texto-3);
  font-variant-numeric: tabular-nums;
}
.escopo__unidades > summary {
  padding: var(--e-1) var(--e-2) var(--e-1) var(--e-6);
  font-size: var(--t-11);
  color: var(--texto-3);
  cursor: pointer;
}
.escopo__unidades > summary:hover { color: var(--acao); }
.escopo__grupo--avulso .escopo__linha--grupo { color: var(--texto-3); font-style: italic; }

.escopo__acoes {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-3);
  border-top: 1px solid var(--linha);
  background: var(--superficie-2);
}

.escopo__chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-2); }
.escopo__chips-rot {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
}
.escopo__chip { font-size: var(--t-11); }
.escopo__limpar { font-size: var(--t-12); font-weight: 600; text-decoration: underline; }

/* ==========================================================================
   15. Paginação
   ========================================================================== */

.pagination {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-2) var(--e-1);
  font-size: var(--t-12);
}
.pagination__info { color: var(--texto-3); font-variant-numeric: tabular-nums; }
.pagination__nav { display: flex; align-items: center; gap: var(--e-1); margin-left: auto; flex-wrap: wrap; }
.pagination__numeros { display: flex; align-items: center; gap: 2px; }
.pagination__num {
  display: inline-flex;
  align-items: center; justify-content: center;
  min-width: 28px; height: 28px;
  padding: 0 var(--e-1);
  border-radius: var(--r-1);
  color: var(--texto-2);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.pagination__num:hover { background: var(--superficie-3); text-decoration: none; }
.pagination__num.is-atual { background: var(--acao); color: var(--texto-inverso); }
.pagination__reticencias { padding: 0 var(--e-1); color: var(--texto-3); }
.pagination__salto { display: flex; align-items: center; gap: var(--e-2); }
.pagination__salto label { color: var(--texto-3); }
.pagination__salto input { width: 68px; height: 28px; }
.pagination__de { color: var(--texto-3); }

/* ==========================================================================
   16. Gráficos e barras
   ========================================================================== */

.chart-host { width: 100%; min-height: 260px; }
/* O ECharts dimensiona o próprio <svg> (largura e altura em px). O
   `height: auto` da versão SVG-artesanal achatava o gráfico para 0 antes do
   primeiro resize. */
.chart-canvas { width: 100%; }
.chart-host svg { display: block; max-width: 100%; }
.chart-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 200px;
  color: var(--texto-3);
  font-size: var(--t-13);
}

.legend { display: flex; flex-wrap: wrap; gap: var(--e-3); font-size: var(--t-12); color: var(--texto-2); }
.legend span { display: inline-flex; align-items: center; gap: var(--e-1); }
.sw { width: 10px; height: 10px; border-radius: 3px; background: var(--chart-prog); display: inline-block; }
.sw--propano { background: var(--propano); }
.sw--accent  { background: var(--accent-deep); }
.sw--alert   { background: var(--alert); }
.sw--ok      { background: var(--ok); }

/* Estados do calendário de calor (§11.2). Cada amostra vem acompanhada do
   rótulo por extenso na legenda: a cor sozinha não carrega o status. */
.sw--st-dentro  { background: var(--ok); }
.sw--st-atencao { background: var(--atencao); }
.sw--st-fora    { background: var(--alert); }
.sw--st-sem     { background: var(--chart-grid); }

.bar-list { display: flex; flex-direction: column; gap: var(--e-4); }
.bar-row { display: flex; flex-direction: column; gap: var(--e-1); }
.bar-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--e-2);
  font-size: var(--t-13);
}
.bar-top span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-track {
  height: 10px;
  border-radius: var(--r-full);
  background: var(--superficie-3);
  overflow: hidden;
}
.bar-fill { height: 100%; border-radius: var(--r-full); background: var(--propano); }
.bar-fill--outros { background: var(--ink-300); }

/* Rank: a QDC da linha como barra relativa à maior da lista. O número continua
   sendo o dado; a barra só mostra a concentração. */
.rank {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
  min-width: 7rem;
}
.rank__n { font-variant-numeric: tabular-nums; font-weight: 700; }
.rank__track {
  display: block;
  width: 96px;
  height: 6px;
  border-radius: var(--r-full);
  background: var(--superficie-3);
  overflow: hidden;
}
.rank__fill {
  display: block;
  height: 100%;
  border-radius: var(--r-full);
  background: var(--propano);
}
/* ==========================================================================
   17. Ficha do contrato e vigências de QDC
   ========================================================================== */

.kv { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--e-2); }
.kv--grade { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: var(--e-3) var(--e-4); }
.kv > div { min-width: 0; }
.kv dt {
  display: block;
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
}
.kv dd {
  display: block;
  margin: 1px 0 0;
  font-size: var(--t-13);
  font-weight: 500;
  overflow-wrap: anywhere;
}
.kv dd.tabular, .kv .tabular { font-variant-numeric: tabular-nums; }
.kv .sub-line { font-size: var(--t-11); color: var(--texto-3); }


/* "herdado": o valor não é próprio da vigência, veio do cabeçalho do contrato.
   É a diferença entre "o aditivo manteve" e "o aditivo não falou nada". */
.origem {
  display: inline-block;
  margin-left: var(--e-1);
  font-size: var(--t-11);
  font-style: normal;
  color: var(--texto-3);
  border: 1px solid var(--linha);
  border-radius: var(--r-full);
  padding: 0 var(--e-1);
}

.dossies { display: flex; flex-direction: column; gap: var(--e-4); }
/* Dentro do painel de listagem os dossiês precisam de respiro próprio: sem
   ele, a borda do dossiê encostava na borda do painel e virava linha dupla. */
.painel > .dossies { padding: var(--e-4); }
.painel > .dossies > .empty { padding: var(--e-6) var(--e-4); }
.dossie {
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  background: var(--superficie);
  overflow: hidden;
}
.dossie__head {
  display: flex;
  align-items: flex-start;
  gap: var(--e-3);
  padding: var(--e-3) var(--e-4);
  border-bottom: 1px solid var(--linha);
  background: var(--superficie-2);
  flex-wrap: wrap;
}
.dossie__ident { min-width: 0; flex: 1 1 260px; }
.dossie__numero { font-family: var(--fonte-mono); font-size: var(--t-12); color: var(--texto-3); }
.dossie__contrato { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.dossie__qdc { text-align: right; }
.dossie__qdc-valor {
  font-size: var(--t-18);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.dossie__rotulo {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
}
.dossie__acoes { display: flex; align-items: center; gap: var(--e-1); }
.dossie__cabecalho { padding: var(--e-3) var(--e-4); border-bottom: 1px solid var(--linha); }
.dossie__linha { padding: var(--e-3) var(--e-4); border-bottom: 1px solid var(--linha); }
.dossie__linha:last-child { border-bottom: 0; }
.dossie__vigencias { display: flex; flex-direction: column; }

/* Linha do tempo das vigências: cada faixa é uma janela de QDC, a largura é
   proporcional à duração. A largura vem inline (é dado), a cor vem de token. */
.vig-timeline {
  display: flex;
  gap: 2px;
  height: 8px;
  border-radius: var(--r-full);
  overflow: hidden;
  background: var(--superficie-3);
}
.vig-timeline__faixa { height: 100%; background: var(--propano); opacity: .45; }
.vig-timeline__faixa.vigente, .vig-timeline__faixa.ativa { opacity: 1; }
.vig-timeline__faixa.encerrada { background: var(--ink-300); }
.vig-timeline__faixa.programada { background: var(--prog); opacity: .6; }

.vig { border-top: 1px solid var(--linha); }
.vig:first-child { border-top: 0; }
.vig__sum {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-2) var(--e-4);
  cursor: pointer;
  list-style: none;
  flex-wrap: wrap;
}
.vig__sum::-webkit-details-marker { display: none; }
.vig__sum:hover { background: var(--superficie-2); }
.vig__ordem {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 22px; height: 22px;
  border-radius: var(--r-full);
  background: var(--superficie-3);
  border: 1px solid var(--linha);
  font-size: var(--t-11);
  font-weight: 700;
  color: var(--texto-2);
  flex: none;
}
.vig__titulo { display: flex; flex-direction: column; min-width: 0; }
.vig__nome { font-size: var(--t-13); font-weight: 600; }
.vig__periodo { font-size: var(--t-11); color: var(--texto-3); font-variant-numeric: tabular-nums; }
.vig__qdc { margin-left: auto; text-align: right; }
.vig__qdc-rot { font-size: var(--t-12); color: var(--texto-3); }
.vig__qdc-valor { font-size: var(--t-14); font-weight: 700; font-variant-numeric: tabular-nums; }
.vig__body { padding: 0 var(--e-4) var(--e-4); }
.delta { font-size: var(--t-11); font-weight: 600; }
.delta.ok { color: var(--ok); }
.delta.alert { color: var(--alert); }

/* Listagem agrupada por grupo econômico, com seleção em massa. */
.grupo-bloco { border-bottom: 2px solid var(--linha-forte); }
.grupo-cab-celula { background: var(--superficie-3); padding: var(--e-3) var(--e-3) !important; }
.grupo-cab { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.grupo-cab__marca { display: inline-flex; align-items: center; }
.grupo-cab__nome { font-weight: 700; font-size: var(--t-12); }
.grupo-cab--avulso .grupo-cab__nome { color: var(--texto-3); font-style: italic; }
.grupo-cab__meta {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-left: auto;
  color: var(--texto-3);
  font-size: var(--t-11);
  font-weight: 500;
  flex-wrap: wrap;
}
.grupo-cab__qdc { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--texto); }

/* Controle segmentado: alternância entre dois modos de leitura da mesma lista.
   São links (o estado fica na URL) para a escolha sobreviver ao "voltar" e
   poder ser salva nos favoritos junto com o recorte. */
.segmentado {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--linha-forte);
  border-radius: var(--r-1);
  background: var(--superficie-3);
  gap: 2px;
}
.segmentado a {
  padding: var(--e-1) var(--e-3);
  border-radius: calc(var(--r-1) - 1px);
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-2);
}
.segmentado a:hover { color: var(--texto); text-decoration: none; }
.segmentado a.is-atual { background: var(--superficie); color: var(--acao); box-shadow: 0 1px 2px var(--sombra-1); }

.vig--vigente > .vig__sum { background: var(--acao-suave); }
.vig--vigente .vig__ordem { background: var(--acao); border-color: var(--acao); color: var(--texto-inverso); }
.vig--encerrada > .vig__sum .vig__nome { color: var(--texto-2); }
.delta--sobe { color: var(--ok); }
.delta--desce { color: var(--alert); }

/* Lista de instruções ao lado de um formulário de carga. */
.lista-ajuda { margin: 0; padding-left: var(--e-4); font-size: var(--t-12); color: var(--texto-2); line-height: 1.6; }
.lista-ajuda li { margin-bottom: var(--e-2); }
.lista-ajuda b { color: var(--texto); }

/* Linha recusada na pré-visualização: fundo suave + a pill de erro na célula
   de situação. Cor sozinha não diria o quê — o motivo vai escrito. */
tr.is-erro td { background: var(--alert-suave); }
.export-grupo { display: flex; flex-wrap: wrap; gap: var(--e-4); margin-bottom: var(--e-3); }

/* Item da faixa de resumo que é atalho: o resto da faixa é leitura, então ele
   precisa dizer que é clicável. */
a.resumo__item { color: inherit; transition: background var(--rapido) var(--curva); }
a.resumo__item:hover { background: var(--acao-suave); text-decoration: none; }
.resumo__item--acao .resumo__sub { color: var(--acao); font-weight: 600; display: inline-flex; align-items: center; gap: 2px; }

.dossie__periodo { font-size: var(--t-11); color: var(--texto-3); margin-top: var(--e-1); }
.dossie__atalhos { display: flex; flex-wrap: wrap; gap: var(--e-1); margin-top: var(--e-3); }
.dossie__timeline { padding: var(--e-3) var(--e-4) 0; }
.dossie__contrato { margin-top: var(--e-2); font-size: var(--t-12); }
.dossie__linha { padding: 0; border: 0; font-size: var(--t-11); color: var(--texto-3); margin-top: var(--e-1); }
.vig__body .vazio { padding: var(--e-3); }
.vig__sum .painel__seta { color: var(--texto-3); transition: transform var(--normal) var(--curva); }
.vig[open] > .vig__sum .painel__seta { transform: rotate(90deg); }

/* Barra de seleção: só aparece com algo marcado (o script põe .is-ativa). Sem
   JavaScript ela fica visível o tempo todo, que é o estado seguro. */
.selecao-bar {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-2) var(--e-4);
  border-bottom: 1px solid var(--acao-borda);
  background: var(--acao-suave);
  color: var(--acao);
  font-size: var(--t-12);
  font-weight: 600;
  flex-wrap: wrap;
}
.js-pronto .selecao-bar { display: none; }
.js-pronto .selecao-bar.is-ativa { display: flex; }
.selecao-bar__n { font-variant-numeric: tabular-nums; }
.lista-selecao { display: flex; align-items: center; gap: var(--e-2); }

.mais-filtros { border-top: 1px dashed var(--linha-forte); padding-top: var(--e-2); width: 100%; }
.mais-filtros > summary { font-size: var(--t-12); font-weight: 600; color: var(--texto-2); cursor: pointer; }
.mais-filtros__campos {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--e-2) var(--e-3);
  padding-top: var(--e-3);
}

/* Matriz de permissões: a coluna da área fica grudada à esquerda ao rolar,
   porque a leitura é por linha ("o que este perfil pode fazer em Contratos") e
   sem ela a área sai da tela justo quando se marca a última coluna. */
.matriz th.num, .matriz td { text-align: center; }
.matriz__area {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--superficie);
  text-align: left !important;
  font-weight: 600;
  min-width: 180px;
}
.table thead th.matriz__area { background: var(--superficie-2); z-index: 3; }
.matriz tbody tr:hover .matriz__area { background: var(--superficie-2); }
.matriz__cel { padding: 0 !important; }
/* O rótulo cobre a célula inteira: alvo de toque de verdade, não a caixa de 15px. */
.matriz__marca {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  cursor: pointer;
}
.matriz__marca:hover { background: var(--acao-suave); }
.matriz__na { color: var(--ink-300); }

/* ==========================================================================
   17b. Página de registro (ficha do contrato e do cliente)
   --------------------------------------------------------------------------
   A ficha era uma pilha vertical de oito cartões: para chegar aos documentos
   de um contrato com três aditivos, rolavam-se ~4000px sem nenhum mapa do que
   vinha pela frente. Aqui ela é uma página de registro: um trilho fixo à
   esquerda com os fatos-chave e o índice das seções, e o conteúdo à direita.
   ========================================================================== */

.registro {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: var(--e-4);
  align-items: start;
}
.registro__rail {
  position: sticky;
  top: calc(var(--topo-h) + var(--e-4));
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  min-width: 0;
}
.registro__corpo { display: flex; flex-direction: column; gap: var(--e-4); min-width: 0; }
/* Variante com o trilho à direita: usada quando ele é apoio à decisão (o que
   cada regime de acesso concede) e não índice do que está na tela. */
.registro--apoio { grid-template-columns: minmax(0, 1fr) 288px; }

/* Fatos-chave: o que se confere sem rolar. */
.fatos {
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--r-2);
  overflow: hidden;
}
.fato { padding: var(--e-4); border-bottom: 1px solid var(--linha); }
.fato:last-child { border-bottom: 0; }
.fato__rot {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
}
.fato__valor {
  display: flex;
  align-items: baseline;
  gap: var(--e-1);
  margin-top: 2px;
  font-size: var(--t-18);
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.fato__valor .unit { font-size: var(--t-11); font-weight: 600; color: var(--texto-3); letter-spacing: 0; }
.fato__sub { font-size: var(--t-11); color: var(--texto-3); margin-top: 1px; }

/* Índice das seções: âncoras da própria página. */
.ancoras { display: flex; flex-direction: column; gap: 1px; }
.ancoras__titulo {
  font-size: var(--t-12);
  font-weight: 600;
  color: var(--texto-3);
  padding: 0 var(--e-2) var(--e-1);
}
.ancoras a {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  padding: var(--e-2);
  border-radius: var(--r-1);
  color: var(--texto-2);
  font-size: var(--t-13);
  font-weight: 500;
}
.ancoras a:hover { background: var(--superficie-3); color: var(--texto); text-decoration: none; }
.ancoras .ancoras__n { margin-left: auto; font-size: var(--t-11); color: var(--texto-3); font-variant-numeric: tabular-nums; }

/* Seção de conteúdo: mesma superfície do painel, com título âncora. */
.secao-reg { scroll-margin-top: calc(var(--topo-h) + var(--e-4)); }
.secao-reg__head {
  display: flex;
  align-items: baseline;
  gap: var(--e-2);
  margin-bottom: var(--e-2);
  flex-wrap: wrap;
}
.secao-reg__head h2 { font-size: var(--t-14); }
.secao-reg__head .meta { color: var(--texto-3); font-size: var(--t-12); }
.secao-reg__head .btn, .secao-reg__head .export-btn { margin-left: auto; }

@media (max-width: 1100px) {
  .registro { grid-template-columns: minmax(0, 1fr); }
  .registro__rail { position: static; }
  .fatos { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
  .fato { border-bottom: 0; border-right: 1px solid var(--linha); }
  .fato:last-child { border-right: 0; }
  .ancoras { flex-direction: row; flex-wrap: wrap; }
  .ancoras__titulo { width: 100%; padding-bottom: 0; }
  .ancoras a { border: 1px solid var(--linha); background: var(--superficie); }
  .ancoras .ancoras__n { margin-left: var(--e-1); }
}

/* ==========================================================================
   18. Telas operacionais (Distribuidor · Comercializador · Penalidades)
   --------------------------------------------------------------------------
   Era a família que mais parecia um relatório de BI exportado: logotipo
   repetido dentro da página, coluna de filtros escura à esquerda, oito cartões
   soltos de KPI. Aqui ela passa a ser uma tela do produto — mesmo cartão, mesma
   tabela e mesma tipografia das demais —, com os filtros num painel próprio e
   os oito indicadores organizados na MATRIZ que eles de fato formam.
   ========================================================================== */

.relatorio {
  display: grid;
  grid-template-columns: 264px minmax(0, 1fr);
  gap: var(--e-4);
  align-items: start;
}
.relatorio__sidebar {
  position: sticky;
  top: calc(var(--topo-h) + var(--e-4));
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
}
.relatorio__main { display: flex; flex-direction: column; gap: var(--e-4); min-width: 0; }

.relatorio__filtros { display: flex; flex-direction: column; gap: var(--e-3); }
.relatorio__filtros-acao { margin-top: var(--e-1); }
.relatorio__filtros-acao .btn { width: 100%; }

.relatorio__graficos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: var(--e-4);
}
.relatorio__grafico { min-width: 0; }
.relatorio__matrizes { display: flex; flex-direction: column; gap: var(--e-4); }
.relatorio__legenda {
  font-size: var(--t-11);
  color: var(--texto-3);
  line-height: 1.7;
  padding: var(--e-3);
  border-top: 1px solid var(--linha);
}
.relatorio__legenda p { margin: 0; }
.relatorio__aviso {
  display: flex;
  align-items: flex-start;
  gap: var(--e-2);
  margin-top: var(--e-3);
  border-left: 3px solid var(--warn);
  background: var(--warn-suave);
  color: var(--texto-2);
  border-radius: 0 var(--r-1) var(--r-1) 0;
  padding: var(--e-2) var(--e-3);
  font-size: var(--t-12);
}
.relatorio__aviso .ic { color: var(--warn); flex: none; margin-top: 2px; }
/* --- Matriz de volumes ----------------------------------------------------
   Oito cartões soltos escondiam que os indicadores são 4 medições × 2 bases,
   e a distinção mensal/diária ficava só na cor do rótulo — duas cores que
   reprovavam em contraste. Como matriz, a estrutura fica no layout e a cor
   volta a ser apoio. É uma <table> de verdade: é o que ela é. */
.kpi-matriz { width: 100%; }
.kpi-matriz thead th { text-align: right; }
.kpi-matriz thead th:first-child { text-align: left; }
.kpi-matriz th[scope="row"] {
  text-align: left;
  font-weight: 700;
  font-size: var(--t-12);
  white-space: nowrap;
  padding: var(--e-3);
  border-bottom: 1px solid var(--linha);
}
.kpi-matriz__base { display: block; font-size: var(--t-11); font-weight: 500; color: var(--texto-3); }
.kpi-matriz td { text-align: right; padding: var(--e-3) !important; }
.kpi-matriz__sigla {
  display: block;
  font-size: var(--t-11);
  font-weight: 700;
  color: var(--texto-3);
}
.kpi-matriz__valor {
  display: block;
  font-size: var(--t-22);
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

.export-btn { display: inline-flex; align-items: center; gap: var(--e-1); }
.export-btn__rotulo { font-size: var(--t-11); color: var(--texto-3); margin-right: var(--e-1); }

/* ==========================================================================
   19. Autenticação
   --------------------------------------------------------------------------
   Tela dividida: à esquerda a identidade do portal e o que ele é (o cliente
   externo costuma chegar aqui por um link de e-mail e precisa reconhecer onde
   está); à direita o formulário. Abaixo de 900px sobra só o formulário — numa
   tela pequena, o painel institucional empurraria os campos para fora da vista.
   ========================================================================== */

.auth-page {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  background: var(--fundo);
}

.auth-marca {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--e-6);
  padding: var(--e-8) clamp(var(--e-8), 6vw, 80px);
  background: var(--rail-fundo);
  color: var(--rail-texto);
  background-image:
    radial-gradient(var(--rail-linha) 1px, transparent 1px),
    linear-gradient(165deg, var(--rail-fundo-2) 0%, var(--rail-fundo) 58%);
  background-size: 24px 24px, auto;
}
/* A marca traz a própria área de segurança; o painel já reserva pelo menos
   40px de padding, MAIOR que a reserva (48px x 0,728 = 35px). A margem negativa
   só evita contar a reserva duas vezes e desalinhar o logotipo da coluna de
   texto — o espaço livre ao redor continua garantido pelo painel. */
.auth-marca__logo { margin-inline-start: calc(-1 * var(--brand-h-auth) * var(--brand-e-ratio-logo)); }
/* O painel ficou só com logotipo e assinatura: as regras de título, chamada e
   lista de recursos saíram junto com o texto que as usava. */
.auth-marca__rodape {
  margin-top: auto;
  font-size: var(--t-11);
  color: var(--rail-texto-2);
}

.auth-wrap {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--e-4);
  padding: var(--e-6) clamp(var(--e-4), 5vw, 56px);
  width: 100%;
  max-width: 520px;
  margin-inline: auto;
}
.auth-logo { display: none; justify-content: center; }
.auth-logo .marca { align-items: center; }

.auth-card {
  width: 100%;
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: var(--r-3);
  padding: var(--e-6);
}
.auth-card .page-head__kicker { margin-bottom: var(--e-2); }
.auth-card h1 { font-size: var(--t-28); font-weight: 900; letter-spacing: -.03em; }
.auth-card .sub { color: var(--texto-2); font-size: var(--t-13); margin-bottom: var(--e-5); }
.auth-card form { display: flex; flex-direction: column; gap: var(--e-4); }
.auth-card .btn { width: 100%; height: 40px; }
.auth-card .field > label { font-size: var(--t-13); color: var(--texto); }
.auth-card input { height: 40px; }

.auth-err, .auth-msg {
  padding: var(--e-3);
  border-radius: var(--r-1);
  border-left: 3px solid var(--alert);
  background: var(--alert-suave);
  color: var(--alert);
  font-size: var(--t-12);
  font-weight: 600;
  margin-bottom: var(--e-4);
}
.auth-msg { border-left-color: var(--info); background: var(--info-suave); color: var(--info); }

.auth-pass { position: relative; display: flex; align-items: center; }
.auth-pass input { padding-right: 78px; }
.auth-pass-toggle {
  position: absolute;
  right: var(--e-1);
  height: 30px;
  padding: 0 var(--e-2);
  border: 1px solid var(--linha);
  border-radius: var(--r-1);
  background: var(--superficie-3);
  color: var(--texto-2);
  font-family: inherit;
  font-size: var(--t-11);
  font-weight: 600;
  cursor: pointer;
}
.auth-pass-toggle:hover { color: var(--acao); border-color: var(--acao-borda); }

.auth-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-2);
  font-size: var(--t-12);
}
.auth-remember { display: inline-flex; align-items: center; gap: var(--e-2); color: var(--texto-2); cursor: pointer; }
.auth-forgot { font-weight: 600; }
.auth-help { font-size: var(--t-11); color: var(--texto-3); line-height: 1.55; }
.auth-help ul { margin: var(--e-1) 0 0; padding-left: var(--e-4); }
.auth-foot {
  margin-top: var(--e-5);
  padding-top: var(--e-4);
  border-top: 1px solid var(--linha);
  text-align: center;
  font-size: var(--t-12);
  color: var(--texto-3);
}
.auth-resend {
  margin-top: var(--e-4);
  font-size: var(--t-12);
  color: var(--texto-3);
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-1);
  flex-wrap: wrap;
}
.auth-resend button {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-weight: 600;
  color: var(--acao);
  cursor: pointer;
  text-decoration: underline;
}
.auth-resend button[disabled] { color: var(--texto-3); cursor: default; text-decoration: none; }

/* Código de verificação: dígito grande, espaçado e monoespaçado — é copiado de
   um e-mail e conferido caractere a caractere. */
.auth-code {
  height: 58px !important;
  text-align: center;
  font-family: var(--fonte-mono);
  font-size: var(--t-28);
  font-weight: 500;
  text-indent: .34em;
}

@media (max-width: 900px) {
  .auth-page { grid-template-columns: minmax(0, 1fr); align-items: center; }
  .auth-marca { display: none; }
  .auth-logo { display: flex; }
  .auth-wrap { max-width: 440px; }
  .auth-card {
    background: var(--superficie);
    border: 1px solid var(--linha);
    border-radius: var(--r-3);
    padding: var(--e-5);
  }
}

/* ==========================================================================
   20. Páginas de erro e porta de entrada
   ========================================================================== */

.entrar {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--e-6);
  text-align: center;
}
.entrar .box {
  max-width: 460px;
  background: var(--superficie);
  border-radius: var(--r-3);
  padding: var(--e-7);
}
.entrar h1 { font-size: var(--t-34); margin-bottom: var(--e-2); }
.entrar .tagline { color: var(--texto-2); margin-bottom: var(--e-5); }
.entrar .code { font-size: var(--t-34); font-weight: 800; color: var(--acao); background: none; border: 0; padding: 0; }

/* Agrupamento visual de um painel de indicadores (Portfólio, Consumo). */
.dash { display: flex; flex-direction: column; gap: var(--e-4); }

/* ==========================================================================
   21. Responsivo
   --------------------------------------------------------------------------
   Três quebras: 1200px (o painel de duas colunas vira uma), 980px (grades de
   4 viram 2) e 860px (o trilho vira gaveta e as tabelas trocam colunas por
   .cel-extra). Abaixo de 860 nada rola na horizontal a não ser o que declara
   rolagem própria.
   ========================================================================== */

@media (max-width: 1200px) {
  .cols-12-8 { grid-template-columns: minmax(0, 1fr); }
  .relatorio { grid-template-columns: minmax(0, 1fr); }
  .relatorio__sidebar { position: static; }
}

@media (max-width: 980px) {
  .content { padding: var(--e-4) var(--e-4) var(--e-5); }
}

@media (max-width: 860px) {
  /* Trilho vira gaveta sobre a página. */
  .sidebar {
    transform: translateX(-100%);
    transition: transform var(--normal) var(--curva);
    box-shadow: 0 0 40px var(--sombra-3);
    width: min(280px, 86vw);
  }
  .nav-open .sidebar { transform: none; }
  .main, .nav-collapsed .main { margin-left: 0; }
  .nav-collapsed .sidebar { width: min(280px, 86vw); }
  .nav-collapsed .brand-full { display: block; }
  .nav-collapsed .brand-mini { display: none; }
  .nav-collapsed .nav-item { justify-content: flex-start; padding-inline: var(--e-2); }
  .nav-collapsed .nav-item .lbl { position: static; width: auto; height: auto; clip: auto; }
  .nav-collapsed .sidebar__section-label { font-size: var(--t-11); height: auto; text-align: left; padding: 0 var(--e-2); }
  .nav-collapsed .sidebar__footer { display: block; }

  .nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 35;
    background: var(--veu);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--normal) var(--curva);
  }
  .nav-open .nav-backdrop { opacity: 1; pointer-events: auto; }

  .topbar { padding: 0 var(--e-3); }
  .topbar__menu { display: inline-flex; }
  .usermenu .topbar__user-info { display: none; }
  .usermenu__painel { width: min(280px, calc(100vw - var(--e-6))); }
  .crumb-parent { display: none; }
  .crumb-sep { display: none; }

  .content { padding: var(--e-4) var(--e-3) var(--e-5); gap: var(--e-4); }

  .page-head { flex-direction: column; gap: var(--e-2); }
  .page-head h1 { font-size: var(--t-22); }
  .page-head .actions { margin-left: 0; width: 100%; }

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

  .resumo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .resumo__item { border-bottom: 1px solid var(--linha); }
  .resumo__item:nth-child(2n) { border-right: 0; }

  /* Colunas secundárias saem da tabela e reaparecem dentro da célula de
     identidade. Não é "esconder dado": é trocar sete colunas espremidas por
     uma linha legível — e o par é exclusivo, então nada é lido duas vezes. */
  .table .col-oculta-mobile { display: none; }
  .cel-extra {
    display: flex;
    flex-wrap: wrap;
    gap: var(--e-1) var(--e-3);
    margin-top: var(--e-1);
    padding-left: calc(28px + var(--e-2));
    font-size: var(--t-11);
    color: var(--texto-2);
  }
  .table .col-ident { min-width: 0; }
  .table-wrap { max-height: none; }

  .painel__topo { padding: var(--e-2); }
  .painel__acoes { width: 100%; }
  .painel__campos .filters-bar { padding: var(--e-2); }
  .filters-bar { padding: var(--e-3); }
  .filters-bar .field--inline,
  .topbar__search { flex: 1 1 100%; max-width: none; }

  .escopo__painel { width: calc(100vw - var(--e-6)); }
  .escopo__btn { width: 100%; }

  .pagination { flex-direction: column; align-items: stretch; }
  .pagination__nav { margin-left: 0; justify-content: center; }
  .pagination__salto { justify-content: center; }

  .card { padding: var(--e-3); }
  .auth-card { padding: var(--e-4); }
  .form-actions { flex-wrap: wrap; }
  .form-actions .btn { flex: 1 1 auto; }
}

@media (max-width: 520px) {
  .resumo { grid-template-columns: minmax(0, 1fr); }
  .resumo__item { border-right: 0; }
}

/* ==========================================================================
   22. Movimento reduzido e impressão
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  /* Sai da folha tudo o que é controle: navegação, filtros, paginação, ações.
     O que fica é o dado — que é o motivo de alguém imprimir uma tela destas. */
  .sidebar, .topbar, .nav-backdrop, .pular, .pagination, .painel__filtros,
  .painel__topo, .page-head .actions, .escopo, .tabs, .acoes-linha,
  .selecao-bar, .form-actions { display: none !important; }
  .main { margin-left: 0; }
  .content { max-width: none; padding: 0; gap: var(--e-3); }
  .card, .painel, .resumo, .fatos, .estagios, .table-wrap {
    border-color: var(--ink-300);
    break-inside: avoid;
  }
  /* Tabela impressa não rola: ela quebra em páginas, com o cabeçalho repetido. */
  .table-wrap { max-height: none; overflow: visible; }
  .table thead { display: table-header-group; }
  .table tbody tr { break-inside: avoid; }
  /* Vigências e formsets recolhidos apareceriam vazios no papel. */
  details { display: block !important; }
  details > summary { list-style: none; }
  details:not([open]) > *:not(summary) { display: revert !important; }
  .registro, .relatorio { grid-template-columns: minmax(0, 1fr); }
  body { background: var(--ink-0); }
  a[href]::after { content: ""; }
}
