/* ==========================================================================
   Solo Precificação — folha de estilo única
   ==========================================================================
   O sistema inteiro é desenhado aqui: não há Tailwind, não há build, não há
   framework de CSS. A página carrega este arquivo e pronto.

   A identidade vem de um punhado de VARIÁVEIS (o bloco :root do começo) e o
   resto do arquivo só usa essas variáveis. Trocar a marca inteira é trocar
   aquele bloco — nenhuma cor, fonte ou raio aparece escrito duas vezes.

   Organização do arquivo:
     1.  variáveis e modo escuro
     2.  reset e tipografia
     3.  esqueleto da página (lateral + topo + conteúdo)
     4.  navegação lateral
     5.  botões
     6.  formulários
     7.  painéis e cartões
     8.  indicadores (kpi) e listas de posição
     9.  tabelas
     10. etiquetas, alertas e avisos
     11. blocos de apoio (passos, medidores, gráficos, ranking)
     12. mensagens de sucesso/erro (flashes)
     13. utilidades mínimas (espaço, flex, texto)
     14. impressão

   --------------------------------------------------------------------------
   NOTA PARA QUEM FOR MEXER: nome de classe começa com o que o elemento É
   (`.painel`, `.kpi`, `.tabela`), não com o que ele parece. Cor, borda e
   fonte saem das variáveis — por isso quase nenhuma regra aqui escolhe uma
   cor "de verdade", todas dizem `var(--accent)` e cospem o resto.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. VARIÁVEIS E MODO ESCURO
   -------------------------------------------------------------------------- */
:root {
  --bg:        #eef2f8;
  --panel:     #ffffff;
  --panel-2:   #f4f7fb;
  --line:      #dde4ef;
  --line-forte:#c3cddd;
  --text:      #101828;
  --muted:     #5c6779;
  /* O texto mais apagado da tela: legenda de tabela, fórmula em monoespaçada,
     rodapé. É o que tem 4.5:1 de folga contra o fundo, não o menos apagado. */
  --faint:     #646c79;
  --accent:    #2054c9;
  --accent-2:  #5a86e0;
  --accent-frac: #eaf0fc;
  --navy:      #0b2559;
  --navy-2:    #14316e;
  --navy-texto:#b9c8ea;
  --navy-frac: rgba(255, 255, 255, .10);
  /* Cor de TEXTO "navy". `--navy` acima é fundo (lateral, faixa da marca) e no
     modo escuro fica quase preto; usá-lo como cor de texto deixaria a frase
     invisível. Este é o par textual: fundo escuro pede texto claro. */
  --navy-txt:  #0b2559;

  /* Estados. Estes quatro valores são escuros de propósito: cada um aparece
     como TEXTO (rótulo de produto ativo, selo de aviso) sobre branco, sobre o
     cinza do fundo e sobre o card, e o mínimo é 4.5:1 nos três. Um verde ou
     um âmbar mais claro passaria no botão e reprovaria no rótulo. */
  --good:  #177c53;
  --warn:  #8a5f1c;
  --bad:   #c23b32;
  --info:  #2b6cb0;
  /* Texto sobre a cor CHEIA. No claro o fundo é escuro e o texto é branco; no
     escuro o fundo clareia (para o botão continuar visível na tela escura) e o
     texto precisa virar escuro, senão o branco sobre verde-claro some. É o par
     `--good`/`--on-good`, `--bad`/`--on-bad`, `--accent`/`--on-accent`. */
  --on-accent: #ffffff;
  --on-good:   #ffffff;
  --on-bad:    #ffffff;
  --good-frac: rgba(26, 138, 92, .12);
  --warn-frac: rgba(194, 137, 43, .14);
  --bad-frac:  rgba(194, 59, 50, .12);
  --info-frac: rgba(43, 108, 176, .12);
  /* Texto sobre a TINTA (rótulo de estado, célula do mapa de calor). São tons
     separados de `--good`/`--bad` acima porque a tinta de 12% da própria cor
     clareia o fundo: o verde de marca daria 4,47:1 e o vermelho 4,44:1. Aqui
     os mesmos tons escurecem até 4,7:1, e continuam legíveis sobre o branco
     cheio (5,5:1 e 5,7:1) para o caso de a tinta sumir. */
  --good-texto: #167850;
  --warn-texto: #8a5f1c;
  --bad-texto:  #ba3930;
  --info-texto: #2054c9;

  --fonte-serif: 'Source Serif 4', Georgia, 'Times New Roman', serif;
  --fonte-sans:  'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --fonte-mono:  'SFMono-Regular', Consolas, 'Liberation Mono', monospace;

  --r-p: 4px;
  --r-m: 6px;
  --r-g: 8px;
  --r-cartao: 10px;

  --sombra-1: 0 1px 2px rgba(16, 24, 40, .05);
  --sombra-2: 0 4px 14px rgba(16, 24, 40, .09);
  --sombra-3: 0 12px 32px rgba(11, 37, 89, .18);

  --lateral-w: 236px;
  --topo-h: 56px;
  --pad-pagina: 20px;

  color-scheme: light;
}

/* Modo escuro: segue o sistema por padrão e aceita a escolha da pessoa
   (botão de tema, que grava em localStorage e vira data-theme="dark"). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="claro"]) {
    --bg:        #0b1220;
    --panel:     #111a2e;
    --panel-2:   #0e1830;
    --line:      #1f2c46;
    --line-forte:#2c3c5c;
    --text:      #e7ecf6;
    --muted:     #93a1b8;
    --faint:     #8b98b0;
    --accent:    #6f97e8;
    --accent-2:  #9bbcf2;
    --accent-frac:#16233d;
    --navy:      #0a1526;
    --navy-2:    #10203c;
    --navy-texto:#a9bcdd;
    --navy-txt:  #bcd0f0;
    --good:  #4cc38a;
    --warn:  #d9a24a;
    --bad:   #e0695f;
    --info:  #74a4e0;
    --on-accent: #06152e;
    --on-good:   #05291b;
    --on-bad:    #2b0a07;
    --good-frac: rgba(76, 195, 138, .16);
    --warn-frac: rgba(217, 162, 74, .16);
    --bad-frac:  rgba(224, 105, 95, .16);
    --info-frac: rgba(116, 164, 224, .16);
    --good-texto: #4cc38a;
    --warn-texto: #d9a24a;
    --bad-texto:  #e2756c;
    --info-texto: #6f97e8;
    --sombra-1: 0 1px 2px rgba(0, 0, 0, .4);
    --sombra-2: 0 4px 14px rgba(0, 0, 0, .45);
    --sombra-3: 0 12px 32px rgba(0, 0, 0, .55);
    color-scheme: dark;
  }
}
/* Escolha explícita da pessoa. As DUAS listas de variáveis acima precisam ser
   iguais: quem muda uma cor do modo escuro tem que mudar nas duas, senão quem
   escolheu "escuro" no botão vê cores diferentes de quem só tem o sistema
   escuro. A conferência é uma linha: `python checar_css.py --tema` (veja o
   comentário da seção 1). */
:root[data-theme="escuro"] {
  --bg:        #0b1220;
  --panel:     #111a2e;
  --panel-2:   #0e1830;
  --line:      #1f2c46;
  --line-forte:#2c3c5c;
  --text:      #e7ecf6;
  --muted:     #93a1b8;
  --faint:     #8b98b0;
  --accent:    #6f97e8;
  --accent-2:  #9bbcf2;
  --accent-frac:#16233d;
  --navy:      #0a1526;
  --navy-2:    #10203c;
  --navy-texto:#a9bcdd;
  --navy-txt:  #bcd0f0;
  --good:  #4cc38a;
  --warn:  #d9a24a;
  --bad:   #e0695f;
  --info:  #74a4e0;
  --on-accent: #06152e;
  --on-good:   #05291b;
  --on-bad:    #2b0a07;
  --good-frac: rgba(76, 195, 138, .16);
  --warn-frac: rgba(217, 162, 74, .16);
  --bad-frac:  rgba(224, 105, 95, .16);
  --info-frac: rgba(116, 164, 224, .16);
  --good-texto: #4cc38a;
  --warn-texto: #d9a24a;
  --bad-texto:  #e2756c;
  --info-texto: #6f97e8;
  --sombra-1: 0 1px 2px rgba(0, 0, 0, .4);
  --sombra-2: 0 4px 14px rgba(0, 0, 0, .45);
  --sombra-3: 0 12px 32px rgba(0, 0, 0, .55);
  color-scheme: dark;
}

/* --------------------------------------------------------------------------
   2. RESET E TIPOGRAFIA
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-padding-top: env(safe-area-inset-top, 0px);
  padding-top: env(safe-area-inset-top, 0px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--fonte-sans);
  font-size: 15px;
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--fonte-serif);
  color: var(--navy-txt);
  font-weight: 600;
  line-height: 1.25;
}
:root[data-theme="escuro"] h1, :root[data-theme="escuro"] h2,
:root[data-theme="escuro"] h3, :root[data-theme="escuro"] h4 { color: var(--text); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="claro"]) h1, :root:not([data-theme="claro"]) h2,
  :root:not([data-theme="claro"]) h3, :root:not([data-theme="claro"]) h4 { color: var(--text); }
}

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

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

img, svg, canvas { max-width: 100%; }

[x-cloak] { display: none !important; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-p);
}

/* Numbers in tables and figures line up column to column. */
.tabela td.num, .tabela th.num,
.kpi-num, .medidor-num, .num { text-align: right; font-variant-numeric: tabular-nums; }

.mono { font-family: var(--fonte-mono); font-size: .78em; }

/* Etiqueta técnica (parâmetro de cenário, código de fórmula). */
.chip {
  display: inline-block;
  padding: 1px 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-p);
  background: var(--panel-2);
  color: var(--muted);
  font-family: var(--fonte-mono);
  font-size: .7rem;
  white-space: nowrap;
}

/* Texto técnico (antes/depois da auditoria, JSON de exportação): fundo escuro
   e monoespaçada, para ficar evidente que é dado de máquina e não texto de
   leitura. */
.bloco-codigo {
  margin: 6px 0 0;
  max-width: 32rem; overflow-x: auto;
  white-space: pre-wrap; word-break: break-word;
  padding: 8px 10px;
  border-radius: var(--r-m);
  background: var(--navy); color: #d7e2f7;
  font-family: var(--fonte-mono); font-size: .72rem; line-height: 1.5;
}

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

.pular-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--on-accent); padding: .6rem 1rem;
  border-radius: var(--r-m); font-weight: 600;
}
.pular-link:focus { left: .5rem; top: .5rem; }

/* --------------------------------------------------------------------------
   3. ESQUELETO DA PÁGINA
   -------------------------------------------------------------------------- */
.app {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
}

.principal {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.barra-topo {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 10px;
  min-height: var(--topo-h);
  padding: 10px 20px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}
.barra-topo .quem {
  color: var(--muted);
  font-size: .8rem;
  min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.barra-topo .topo-crescer { flex: 1; min-width: 0; }

.faixa-filtros {
  display: flex; gap: 8px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  background: var(--panel-2);
}
.faixa-filtros .entrada { width: auto; min-width: 9rem; flex-shrink: 0; padding: 6px 9px; font-size: .82rem; }

.pagina {
  flex: 1;
  padding: var(--pad-pagina);
  width: 100%;
  max-width: 1480px;
  margin: 0 auto;
}
.pagina > :first-child { margin-top: 0; }

/* Telas sem menu (login, cadastro público, erro): não há lateral nem topo,
   então a página se centraliza e ocupa a tela inteira. */
.pagina.solto {
  max-width: 34rem;
  padding: 7vh 20px 40px;
}

.rodape {
  padding: 14px 20px 26px;
  text-align: center;
  color: var(--faint);
  font-size: .72rem;
}

/* Botão do menu: só existe no celular, onde a lateral vira gaveta. */
.btn-menu {
  display: none;
  align-items: center; justify-content: center;
  width: 38px; height: 38px;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--panel);
  color: var(--navy-txt);
  font-size: 1.1rem;
  cursor: pointer;
  flex-shrink: 0;
}
.btn-menu:hover { background: var(--panel-2); }

.veu {
  display: none;
  position: fixed; inset: 0; z-index: 30;
  background: rgba(11, 37, 89, .45);
}
.veu.visivel { display: block; }

/* --------------------------------------------------------------------------
   4. NAVEGAÇÃO LATERAL
   -------------------------------------------------------------------------- */
.lateral {
  width: var(--lateral-w);
  flex-shrink: 0;
  background: var(--navy);
  color: var(--navy-texto);
  padding: 18px 12px 26px;
  position: sticky; top: 0;
  align-self: flex-start;
  height: 100vh; height: 100dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* A assinatura no topo da lateral. Chama-se `marca-lateral` e não só `marca`
   porque `marca` também é o selo de texto dentro de uma lista de avisos
   (`excluir_dados.html`, `importar_previa.html`): com o mesmo nome, esta regra
   entregava a ela um texto branco sobre fundo claro — texto invisível. */
.marca-lateral {
  display: block;
  padding: 0 8px 14px;
  color: #fff;
  font-family: var(--fonte-serif);
  font-weight: 700;
  font-size: 1.05rem;
  text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, .12);
  margin-bottom: 14px;
}
.marca-lateral:hover { text-decoration: none; }
.marca-lateral small {
  display: block;
  font-family: var(--fonte-sans);
  font-weight: 400;
  font-size: .72rem;
  color: #9fb3dd;
  margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.nav-titulo {
  padding: 14px 10px 5px;
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #7e95c4;
}

.lateral nav { display: flex; flex-direction: column; gap: 1px; }

.nav-link {
  display: flex; align-items: center; gap: 9px;
  color: var(--navy-texto);
  padding: 7px 10px;
  border-radius: var(--r-m);
  font-size: .86rem;
  text-decoration: none;
  border-left: 2px solid transparent;
}
.nav-link:hover { background: var(--navy-frac); color: #fff; text-decoration: none; }
.nav-link.ativo {
  background: var(--navy-frac);
  color: #fff;
  font-weight: 500;
  border-left-color: #6fa0ff;
}
.nav-link .icone { width: 1.05rem; text-align: center; font-size: .95rem; flex-shrink: 0; }
.nav-link .conta {
  margin-left: auto;
  font-size: .68rem;
  color: #8ba4d2;
  font-variant-numeric: tabular-nums;
}

/* Grupo que abre e fecha (a lateral é longa; o grupo é o que mantém o
   caminho de 30 telas utilizável). */
.nav-grupo { margin-bottom: 2px; }
.nav-grupo > summary {
  display: flex; align-items: center; gap: 9px;
  list-style: none;
  cursor: pointer;
  color: var(--navy-texto);
  padding: 7px 10px;
  border-radius: var(--r-m);
  font-size: .86rem;
  user-select: none;
}
.nav-grupo > summary::-webkit-details-marker { display: none; }
.nav-grupo > summary:hover { background: var(--navy-frac); color: #fff; }
.nav-grupo[open] > summary { color: #fff; font-weight: 500; }
.nav-grupo > summary .seta {
  margin-left: auto;
  font-size: .7rem;
  color: #8ba4d2;
  transition: transform .15s ease;
}
.nav-grupo[open] > summary .seta { transform: rotate(90deg); }
.nav-grupo .sub {
  display: flex; flex-direction: column;
  margin: 2px 0 4px 12px;
  padding-left: 8px;
  border-left: 1px solid rgba(255, 255, 255, .14);
}
.nav-grupo .sub .nav-link {
  font-size: .82rem;
  padding: 5px 10px;
  border-left: 0;
  border-radius: var(--r-p);
}
.nav-grupo .sub .nav-link.ativo { border-left: 0; box-shadow: inset 2px 0 0 #6fa0ff; }

.lateral-rodape {
  margin-top: 18px;
  padding: 12px 10px 0;
  border-top: 1px solid rgba(255, 255, 255, .12);
  font-size: .7rem;
  color: #8ba4d2;
}
.lateral-rodape a { color: var(--navy-texto); }

/* No celular a lateral vira gaveta: sai da tela, entra com um toque. */
@media (max-width: 1023px) {
  .btn-menu { display: inline-flex; }
  .lateral {
    position: fixed; top: 0; left: 0; bottom: 0;
    z-index: 40;
    height: 100vh; height: 100dvh;
    transform: translateX(-100%);
    transition: transform .2s ease;
    box-shadow: var(--sombra-3);
  }
  .lateral.aberta { transform: none; }
  .pagina { padding: 14px; }
  .barra-topo, .faixa-filtros { padding-left: 14px; padding-right: 14px; }
  .rodape { padding-left: 14px; padding-right: 14px; }
}

/* No celular o campo precisa de 16px de fonte, mesmo que o desenho peça menos.
   Abaixo disso o Safari dá um zoom no foco que não desfaz sozinho: a pessoa
   digita o preço, a tela cresce, e o resto do formulário sai de vista. */
@media (max-width: 640px) {
  .entrada, .selecao, .area, .btn { font-size: 16px; }
}

/* --------------------------------------------------------------------------
   5. BOTÕES
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 16px;
  border: 1px solid transparent;
  border-radius: var(--r-m);
  background: var(--panel-2);
  color: var(--text);
  font-family: inherit;
  font-size: .86rem;
  font-weight: 500;
  line-height: 1.2;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.btn:hover { text-decoration: none; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

.btn-primario { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn-primario:hover:not(:disabled) { background: var(--navy); border-color: var(--navy); }

.btn-secundario {
  background: var(--panel); border-color: var(--line-forte); color: var(--navy-txt);
}
.btn-secundario:hover:not(:disabled) { background: var(--panel-2); border-color: var(--accent-2); }

/* A ação que grava de verdade ("Aplicar preço R$ 47,19") é verde, e não
   azul: no resto da tela o azul é navegação, verde é confirmar. */
.btn-confirmar { background: var(--good); border-color: var(--good); color: var(--on-good); }
.btn-confirmar:hover:not(:disabled) { filter: brightness(.9); }

.btn-perigo { background: var(--bad); border-color: var(--bad); color: var(--on-bad); }
.btn-perigo:hover:not(:disabled) { filter: brightness(.92); }

.btn-fantasma { background: transparent; border-color: var(--line); color: var(--muted); }
.btn-fantasma:hover:not(:disabled) { background: var(--panel-2); color: var(--text); }

.btn-pequeno { padding: 5px 10px; font-size: .78rem; }
.btn-largo { width: 100%; }

/* Botão de formulário: ocupa a linha no celular (dedo grosso, alvo grande) e
   encolhe no desktop para não virar uma barra de 40cm. */
.btn.cheio { width: 100%; }
@media (min-width: 640px) { .btn.cheio { width: auto; } }

.bloco-botoes { display: flex; flex-wrap: wrap; gap: 8px; }
.bloco-botoes.ao-fim { justify-content: flex-end; }
.bloco-botoes.ao-centro { justify-content: center; }

/* Número gigante da tela de erro. Fica apagado de propósito (é decoração,
   não informação), mas nunca a ponto de sumir: usa o mesmo `--faint` das
   legendas de tabela, que tem 4.5:1 nos dois temas. */
.codigo-erro {
  font-family: var(--fonte-serif);
  font-size: 4rem;
  font-weight: 700;
  line-height: 1;
  color: var(--faint);
  margin: 0 0 6px;
}

/* Botão que só existe como ícone (ver/ocultar senha, fechar aviso). */
.btn-icone {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--panel);
  color: var(--muted);
  cursor: pointer;
  font-size: .95rem;
}
.btn-icone:hover { background: var(--panel-2); color: var(--text); }
.btn-icone.plano { border: 0; background: none; }

/* Menu suspenso (usuário, grupos da lateral). */
.menu { position: relative; }
.menu-lista {
  position: absolute; right: 0; top: calc(100% + 6px);
  min-width: 13rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-g);
  box-shadow: var(--sombra-2);
  padding: 5px;
  z-index: 50;
}
.menu-lista a, .menu-lista button {
  display: block; width: 100%;
  padding: 7px 10px;
  border: 0; border-radius: var(--r-p);
  background: none;
  font: inherit; font-size: .84rem;
  color: var(--text);
  text-align: left; text-decoration: none;
  cursor: pointer;
}
.menu-lista a:hover, .menu-lista button:hover { background: var(--panel-2); text-decoration: none; }
.menu-lista .sep { height: 1px; background: var(--line); margin: 5px 2px; }
.menu-lista .cabeca { padding: 8px 10px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.menu-lista .cabeca strong { display: block; font-size: .84rem; }
.menu-lista .cabeca small { color: var(--muted); font-size: .74rem; }
.menu-lista .perigo { color: var(--bad); }

/* --------------------------------------------------------------------------
   6. FORMULÁRIOS
   -------------------------------------------------------------------------- */
.campo { margin-bottom: 12px; min-width: 0; }
.campo.largo { grid-column: 1 / -1; }
.campo.duas { grid-column: span 2; }
@media (max-width: 640px) { .campo.duas { grid-column: 1 / -1; } }

.rotulo {
  display: block;
  margin-bottom: 4px;
  font-size: .82rem;
  font-weight: 500;
  color: var(--muted);
}
.rotulo .obrigatorio { color: var(--bad); }
.rotulo .dica {
  font-weight: 400;
  color: var(--faint);
  font-size: .76rem;
}

.entrada, .selecao, .area {
  display: block;
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line-forte);
  border-radius: var(--r-m);
  background: var(--panel);
  color: var(--text);
  font-family: inherit;
  font-size: .92rem;
  line-height: 1.35;
}
.entrada::placeholder, .area::placeholder { color: var(--faint); }
.entrada:hover, .selecao:hover, .area:hover { border-color: var(--accent-2); }
.entrada:focus, .selecao:focus, .area:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-frac);
}
.entrada[readonly], .entrada:disabled, .selecao:disabled {
  background: var(--panel-2);
  color: var(--muted);
  cursor: not-allowed;
}
.area { min-height: 4.5rem; resize: vertical; }

.selecao {
  appearance: none;
  padding-right: 30px;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
                    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 15px) 50%, calc(100% - 10px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

input[type="color"].entrada { padding: 3px; height: 42px; cursor: pointer; }
input[type="date"].entrada, input[type="time"].entrada { min-height: 40px; }

.ajuda { margin: 4px 0 0; font-size: .76rem; color: var(--faint); }

.campo-senha { position: relative; }
.campo-senha .entrada { padding-right: 42px; }
.campo-senha .btn-icone {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  border: 0; background: none;
}

.linha-check {
  display: flex; align-items: flex-start; gap: 8px;
  margin-bottom: 10px;
  font-size: .88rem;
  color: var(--text);
  cursor: pointer;
}
.linha-check input[type="checkbox"], .linha-check input[type="radio"] {
  width: 16px; height: 16px; margin: 2px 0 0;
  accent-color: var(--accent);
  flex-shrink: 0;
  cursor: pointer;
}
.linha-check .ajuda { display: block; margin-top: 1px; }

.grade-campos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 16px;
}
.grade-campos.tres { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grade-campos.uma  { grid-template-columns: 1fr; }
@media (max-width: 700px) {
  .grade-campos, .grade-campos.tres { grid-template-columns: 1fr; }
}

fieldset.linha-campos { border: 0; padding: 0; margin: 0 0 12px; min-width: 0; }
fieldset.linha-campos legend { padding: 0; }

fieldset.agrupado {
  border: 1px solid var(--line);
  border-radius: var(--r-g);
  padding: 12px 14px;
  margin: 0 0 14px;
  min-width: 0;
}
fieldset.agrupado > legend {
  padding: 0 6px;
  font-size: .8rem;
  font-weight: 600;
  color: var(--navy-txt);
}

.linha-repetida { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.linha-repetida .entrada { flex: 1; min-width: 5rem; padding: 7px 9px; font-size: .86rem; }

/* Linha de conversão de unidades: "1 CX = [12] UN". Três colunas que não
   se mexem, senão a conta fica desalinhada e a pessoa erra o preenchimento. */
.linha-conversao {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 6px; align-items: center;
  margin-bottom: 6px;
}
.linha-conversao .meio {
  display: flex; align-items: center; gap: 4px;
  color: var(--muted); font-size: .8rem;
}
.linha-conversao .meio .entrada { width: 5.5rem; text-align: center; padding: 7px 6px; }

/* --------------------------------------------------------------------------
   7. PAINÉIS E CARTÕES
   -------------------------------------------------------------------------- */
.painel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-cartao);
  padding: 16px;
  margin-bottom: 14px;
}
.painel:last-child { margin-bottom: 0; }
.painel.compacto { padding: 12px; }
.painel.sem-margem { margin-bottom: 0; }
.painel.pleno { grid-column: 1 / -1; }

.painel-cab { margin-bottom: 12px; }
.painel-titulo { font-size: .95rem; font-weight: 600; }
.painel-sub { margin: 2px 0 0; color: var(--muted); font-size: .76rem; }
.painel-cab .linha { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; flex-wrap: wrap; }

.grade { display: grid; gap: 14px; }
.grade.dois    { grid-template-columns: 2fr 1fr; }
.grade.tres    { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grade.iguais  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grade.meia    { grid-template-columns: 1fr 1fr; }
@media (max-width: 1100px) {
  .grade.dois, .grade.tres { grid-template-columns: 1fr; }
}
@media (max-width: 700px) {
  .grade.iguais, .grade.meia { grid-template-columns: 1fr; }
}

/* Cabeçalho da página: título em serifa + subtítulo, como no topo do
   dashboard de referência. */
.cabecalho {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.cabecalho h1 { font-size: 1.25rem; }
.cabecalho .sub { margin: 2px 0 0; color: var(--muted); font-size: .8rem; max-width: 68ch; }

/* --------------------------------------------------------------------------
   8. INDICADORES E LISTAS DE POSIÇÃO
   -------------------------------------------------------------------------- */
.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}
.kpi {
  background: var(--panel);
  border: 1px solid var(--line);
  border-top: 3px solid var(--accent);
  border-radius: var(--r-g);
  padding: 13px 14px;
}
.kpi-num {
  font-family: var(--fonte-serif);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--navy-txt);
  line-height: 1.15;
}
.kpi-lbl { color: var(--muted); font-size: .72rem; margin-top: 3px; }
.kpi-delta { font-size: .72rem; margin-top: 6px; color: var(--muted); }
.kpi.bom   { border-top-color: var(--good); }
.kpi.atencao { border-top-color: var(--warn); }
.kpi.ruim  { border-top-color: var(--bad); }

.medidor {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-g);
  padding: 12px;
}
.medidores {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 10px;
}
/* O preço é a peça maior da fileira: ela ocupa duas colunas enquanto houver
   espaço, o que faz o olho ir nele antes dos outros números. */
@media (min-width: 700px) { .medidores > .destaque { grid-column: span 2; } }
.medidor-num {
  font-family: var(--fonte-serif);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--accent);
  line-height: 1.2;
}
.medidor-rot { font-size: .74rem; font-weight: 500; color: var(--text); margin-top: 2px; }
.medidor-det { font-size: .72rem; color: var(--faint); margin-top: 1px; }

.rank { display: flex; flex-direction: column; gap: 7px; }
.rank-linha {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: .82rem;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
}
.rank-linha:last-child { border-bottom: 0; padding-bottom: 0; }
.rank-linha .nome { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-linha .valor { font-weight: 600; flex-shrink: 0; font-variant-numeric: tabular-nums; }

/* Barra de proporção (composição de preço, faixas, uso do preço). */
.barra-prop { height: 8px; border-radius: 99px; background: var(--panel-2); overflow: hidden; display: flex; }
.barra-prop > span { display: block; height: 100%; }

.grafico { position: relative; height: 230px; }
.grafico.pequeno { height: 200px; }
.grafico.grande { height: 300px; }
.grafico .sem-grafico {
  display: flex; align-items: center; justify-content: center;
  height: 100%; padding: 0 12px;
  color: var(--muted); font-size: .8rem; text-align: center;
}

.vazio {
  padding: 22px 14px;
  text-align: center;
  color: var(--muted);
  font-size: .86rem;
}

/* Paginação: um link de cada lado e o "página X de Y" no meio. */
.paginacao {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-top: 12px;
}
.paginacao .atual { color: var(--muted); font-size: .78rem; }

/* Linha de produto fora de operação: continua legível, mas recua. */
.recessada { opacity: .55; }

/* Filtros: um painel só, com os campos encolhidos para caber na linha. */
.filtros .entrada, .filtros .selecao { padding: 7px 10px; font-size: .84rem; }
.filtros .busca { min-width: 12rem; flex: 1 1 12rem; }
.filtros .opcoes { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; }
.filtros .opcoes .linha-check { margin: 0; font-size: .8rem; }

/* --------------------------------------------------------------------------
   9. TABELAS
   -------------------------------------------------------------------------- */
.tabela-envolve { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tabela {
  width: 100%;
  border-collapse: collapse;
  font-size: .84rem;
}
.tabela caption {
  caption-side: top;
  text-align: left;
  padding-bottom: 5px;
  color: var(--faint);
  font-size: .72rem;
}
.tabela th, .tabela td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.tabela th {
  color: var(--muted);
  font-weight: 500;
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  border-bottom: 1px solid var(--line-forte);
}
.tabela td.num, .tabela th.num { text-align: right; }
.tabela tbody tr:hover { background: var(--panel-2); }
.tabela tbody tr.atual { background: var(--accent-frac); }
.tabela tbody tr.atual:hover { background: var(--accent-frac); }
/* Linha duvidosa: o mapeamento da importação marca em âmbar a coluna que a IA
   não teve certeza, e a marca precisa ser da LINHA, não de um número solto. */
.tabela tbody tr.atual-aviso { background: var(--warn-frac); }
.tabela tbody tr.atual-aviso:hover { background: var(--warn-frac); }
/* Linha que quebrou uma regra da empresa (reajuste abaixo do piso de margem):
   a linha inteira fica vermelha-fraca, porque o problema é dela e não da coluna. */
.tabela tbody tr.atual-ruim { background: var(--bad-frac); }
.tabela tbody tr.atual-ruim:hover { background: var(--bad-frac); }

/* Tabela com rolagem por dentro do cartão: a lista pode ser longa, mas o botão
   que age sobre ela precisa continuar à vista. */
.rolagem-v { max-height: 32rem; overflow: auto; }

/* Coluna que só faz sentido em tela larga (amostra de valores do mapeamento):
   no celular ela sai e a tabela cabe sem rolagem lateral. */
@media (max-width: 767px) { .esconde-md { display: none; } }
.tabela tbody tr:last-child td { border-bottom: 0; }
.tabela .secundario { color: var(--muted); font-size: .95em; }
.tabela-secundario { display: block; color: var(--faint); font-size: .78rem; }
.tabela .acao-col { width: 1%; }
.tabela-larga { min-width: 42rem; }
.tabela-media { min-width: 30rem; }
.tabela-pequena { min-width: 16rem; font-size: .82rem; }

/* --------------------------------------------------------------------------
   10. ETIQUETAS, ALERTAS E AVISOS
   -------------------------------------------------------------------------- */
.etiqueta {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 99px;
  font-size: .72rem;
  font-weight: 500;
  background: var(--panel-2);
  color: var(--muted);
  white-space: nowrap;
}
.etiqueta.bom    { background: var(--good-frac); color: var(--good-texto); }
.etiqueta.atencao{ background: var(--warn-frac); color: var(--warn-texto); }
.etiqueta.ruim   { background: var(--bad-frac);  color: var(--bad-texto); }
.etiqueta.info   { background: var(--info-frac); color: var(--info-texto); }
.etiqueta.acento { background: var(--accent-frac); color: var(--accent); }
.etiqueta.silhueta { background: none; border: 1px solid var(--line-forte); color: var(--muted); }

.alerta {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--r-m);
  background: var(--panel-2);
  font-size: .84rem;
  margin-bottom: 12px;
}
.alerta p { margin: 0; min-width: 0; }
.alerta .marca-alerta { flex-shrink: 0; font-weight: 700; line-height: 1.4; }
.alerta.sem-margem { margin-bottom: 0; }
.alerta.a-ok    { background: var(--good-frac); border-color: var(--good); color: var(--text); }
.alerta.a-erro  { background: var(--bad-frac);  border-color: var(--bad);  color: var(--text); }
.alerta.a-aviso { background: var(--warn-frac); border-color: var(--warn); color: var(--text); }
.alerta.a-info  { background: var(--info-frac); border-color: var(--info); color: var(--text); }

.alerta-lista { display: flex; flex-direction: column; gap: 6px; font-size: .84rem; }
.alerta-lista li {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 8px 11px;
  border-radius: var(--r-m);
  background: var(--panel-2);
  color: var(--text);
  list-style: none;
}
.alerta-lista li.marca-erro  { background: var(--bad-frac); }
.alerta-lista li.marca-aviso { background: var(--warn-frac); }
.alerta-lista li.marca-info  { background: var(--info-frac); }
/* O selo é a letra que dá a gravidade; a cor sai do `li` para não repetir
   `--bad`/`--warn`/`--info` duas vezes no mesmo bloco. `color: inherit`
   primeiro porque o selo é também o nome de uma peça da lateral. */
.alerta-lista .marca {
  flex-shrink: 0;
  font-weight: 700;
  line-height: 1.4;
  color: var(--info);
}
.alerta-lista li.marca-erro  .marca { color: var(--bad); }
.alerta-lista li.marca-aviso .marca { color: var(--warn); }

/* O aviso gerencial do módulo tributário, obrigatório em toda tela de
   tributo. É o mesmo texto em cinco lugares, então é a MESMA classe. */
.aviso-tributario {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 10px 12px;
  margin-bottom: 14px;
  border: 1px solid var(--warn);
  border-radius: var(--r-m);
  background: var(--warn-frac);
  font-size: .78rem;
  color: var(--text);
}
.aviso-tributario p { margin: 0; min-width: 0; }

.t-ok    { color: var(--good); }
.t-aviso { color: var(--warn); }
.t-ruim  { color: var(--bad); }
.t-info  { color: var(--info); }
.t-acento{ color: var(--accent); }
.t-navy  { color: var(--navy-txt); }
.t-suave { color: var(--muted); }
.t-fraco { color: var(--faint); }
.t-negrito { font-weight: 600; }
.t-forte { font-weight: 700; }
.t-serifa { font-family: var(--fonte-serif); }
.t-peq { font-size: .74rem; }
.t-med { font-size: .86rem; }
.t-gra { font-size: 1rem; }
.t-num  { font-family: var(--fonte-serif); font-weight: 700; font-size: 1.15rem; color: var(--navy-txt); }
.t-riscar { text-decoration: line-through; color: var(--faint); }

/* --------------------------------------------------------------------------
   11. BLOCOS DE APOIO
   -------------------------------------------------------------------------- */
/* Assistente de importação: 4 etapas. */
.passos { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-bottom: 14px; }
.passo { display: flex; align-items: center; gap: 7px; font-size: .78rem; color: var(--muted); }
.passo-num {
  display: grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  font-size: .72rem; font-weight: 700;
  background: var(--line);
  color: var(--text);
  flex-shrink: 0;
}
.passo.feito .passo-num { background: var(--good); color: var(--on-good); }
.passo.atual { color: var(--text); font-weight: 600; }
.passo.atual .passo-num { background: var(--accent); color: var(--on-accent); }

/* Barra de progresso da gravação (importação). */
.progresso {
  height: 10px;
  border-radius: 99px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  overflow: hidden;
}
.progresso > div {
  height: 100%;
  background: var(--accent);
  transition: width .3s ease;
}

/* Acordeão de termos (LGPD): o texto começa oculto. */
.termo-conteudo {
  max-height: 0; overflow: hidden;
  transition: max-height .25s ease;
  font-size: .8rem;
  color: var(--muted);
}
.termo-conteudo.aberto { max-height: 26rem; overflow-y: auto; padding-top: 8px; }

/* Cabeçalho de seção numerada dentro de um formulário longo (cadastro
   público): a pessoa precisa saber em que passo está sem ler tudo. */
.secao-titulo {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 12px;
  font-size: .74rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent);
}
.secao-titulo .num {
  display: grid; place-items: center;
  width: 20px; height: 20px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  font-size: .68rem; font-weight: 700; letter-spacing: 0;
}

/* Termos de uso (LGPD): texto corrido e legível, nunca com a cara de
   formulário — a leitura não pode competir com os campos. */
.prose-termos { font-size: .8rem; line-height: 1.65; color: var(--muted); }
.prose-termos p { margin: 0 0 .5rem; }
.prose-termos strong { color: var(--text); }
.prose-termos ul { margin: 0 0 .5rem; padding-left: 1.1rem; list-style: disc; }
.prose-termos li { margin-bottom: .2rem; }

/* Bloco de marca das telas de acesso e do console da operadora: fundo
   azulmarinho, o mesmo da lateral, para o olho saber onde está. */
.faixa-marca {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px;
  border-radius: var(--r-cartao);
  background: var(--navy);
  color: #fff;
  margin-bottom: 14px;
}
.faixa-marca .sigla {
  display: grid; place-items: center;
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: var(--r-g);
  background: rgba(255, 255, 255, .13);
  font-family: var(--fonte-serif);
  font-size: 1.2rem; font-weight: 700;
}
.faixa-marca .nome {
  font-family: var(--fonte-serif); font-size: 1.05rem; font-weight: 700;
  margin: 0; line-height: 1.25;
}
.faixa-marca .sub { font-size: .76rem; color: var(--navy-texto); margin: 0; }

/* Cartão de destaque do preço calculado. */
.destaque {
  background: var(--accent-frac);
  border: 1px solid var(--accent-2);
  border-radius: var(--r-g);
  padding: 12px 14px;
}
.destaque .rotulo-destaque {
  font-size: .72rem; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--accent);
}
.destaque .valor-destaque {
  font-family: var(--fonte-serif);
  font-size: 1.8rem; font-weight: 700; color: var(--navy-txt);
  line-height: 1.15;
}
:root[data-theme="escuro"] .destaque .valor-destaque { color: var(--text); }

/* Lista de definição usada em resumos (par chave/valor). */
.pares { display: grid; gap: 0; font-size: .84rem; }
.pares > div {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--line);
}
.pares > div:last-child { border-bottom: 0; }
.pares dt { color: var(--muted); }
.pares dd { margin: 0; font-weight: 600; text-align: right; }

/* Abas (usadas em telas com mais de um conjunto de dados). */
.abas { display: flex; gap: 2px; border-bottom: 1px solid var(--line); margin-bottom: 14px; overflow-x: auto; }
.aba {
  padding: 8px 13px;
  color: var(--muted);
  font-size: .85rem;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.aba:hover { color: var(--text); text-decoration: none; }
.aba.ativa { color: var(--accent); border-bottom-color: var(--accent); font-weight: 500; }

/* Lista numerada explicativa: usada onde o sistema precisa ENSINAR um
   conceito (comparador, importação), não só descrever um dado. */
.numerada {
  margin: 0;
  padding-left: 1.3rem;
  list-style: decimal;
}
.numerada > li { margin-bottom: 8px; }
.numerada > li:last-child { margin-bottom: 0; }
.numerada > li::marker { color: var(--accent); font-weight: 600; }

/* Barra de ação fixa no rodapé (tela de precificar): o botão fica ao alcance
   do polegar mesmo com a lista de parâmetros longa. No desktop ela solta e vira
   uma faixa comum, para não cobrir a tabela de resultado. */
.barra-acao {
  position: sticky;
  bottom: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 calc(var(--pad-pagina) * -1) var(--pad-pagina);
  padding: 10px var(--pad-pagina);
  background: var(--panel);
  border-top: 1px solid var(--line);
}
@media (min-width: 900px) {
  .barra-acao {
    position: static;
    margin: 0 0 var(--pad-pagina);
    border: 1px solid var(--line);
    border-radius: var(--r-cartao);
  }
}

/* Empurra o elemento para o fim da linha, dejando o espaço no meio. */
.fim-direita { margin-left: auto; text-align: right; }

/* Botão de arquivo: o `input[type=file]` cru é ilegível no celular e em quase
   todo desktop, então o campo real fica escondido e o botão nativo é
   estilizado por cima dele (`:focus-within` devolve o foco ao teclado). */
.entrada.arquivo {
  padding: 7px;
  font-size: .82rem;
  cursor: pointer;
}
.entrada.arquivo::file-selector-button {
  margin-right: 10px;
  padding: 6px 12px;
  border: 1px solid var(--line-forte);
  border-radius: var(--r-m);
  background: var(--panel-2);
  color: var(--text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.entrada.arquivo::file-selector-button:hover { background: var(--accent-frac); border-color: var(--accent-2); }

/* Atalhos de navegação em forma de botão (topo das telas do módulo). */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 10px; }
.tile {
  display: block; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: var(--r-g);
  background: var(--panel); color: var(--text); text-decoration: none;
}
.tile:hover { border-color: var(--accent-2); background: var(--panel-2); text-decoration: none; }
.tile .titulo { font-weight: 600; font-size: .88rem; }
.tile .detalhe { color: var(--muted); font-size: .76rem; margin-top: 2px; }
.tile.perigo { border-color: var(--bad); color: var(--bad); }
.tile.perigo .detalhe { color: var(--muted); }
.atalhos { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 14px; }
.atalho {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  background: var(--panel);
  color: var(--navy-txt);
  font-size: .82rem;
  font-weight: 500;
}
.atalho:hover { background: var(--panel-2); border-color: var(--accent-2); text-decoration: none; }
.atalho .conta { color: var(--faint); font-weight: 400; }
.atalho.destaque { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.atalho.destaque:hover { background: var(--navy); border-color: var(--navy); }
.atalho.destaque .conta { color: rgba(255, 255, 255, .75); }

/* Faixa de advertência grande (usada no topo do painel e do simulador). */
/* Faixa de aviso que ocupa a largura da página (fora de um cartão): diferente de
   `.alerta`, que é uma linha. Aqui cabe uma frase, um botão e uma ressalva. */
.faixa-aviso {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 14px;
  margin-bottom: 14px;
  border: 1px solid var(--warn);
  border-left-width: 3px;
  border-radius: var(--r-g);
  background: var(--warn-frac);
  font-size: .84rem;
}
.faixa-aviso p { margin: 0; min-width: 0; }
.faixa-aviso .marca-alerta { flex-shrink: 0; font-weight: 700; line-height: 1.4; }
.faixa-aviso.sem-margem { margin-bottom: 0; }

/* Indicador de requisição do HTMX: invisível em repouso. */
.htmx-indicator { opacity: 0; transition: opacity .15s ease; }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { opacity: 1; }

/* Anel girando ("o servidor está trabalhando"). O desenho é uma borda
   circular com um lado de outra cor: só dois elementos, nenhum arquivo de
   imagem, e some quando a tela troca de lugar. */
.giro {
  width: 30px; height: 30px;
  margin: 0 auto;
  border: 3px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: girar .8s linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .giro { animation-duration: 2.4s; }
}

/* Bloco que abre e fecha (<details>): o resumo é a alça, o conteúdo fica
   escondido até a pessoa pedir. Usado para "as N colunas mapeadas" e para os
   detalhes de um método que ficou sem preço. */
.revelavel {
  border-top: 1px solid var(--line);
  padding-top: 8px;
}
.revelavel > summary {
  cursor: pointer;
  list-style: none;
  color: var(--accent);
}
.revelavel > summary::-webkit-details-marker { display: none; }
/* O triângulo do navegador some acima; o desenho do próprio marcador entra. */
.revelavel > summary::before {
  content: "▸";
  display: inline-block;
  width: 1em;
  color: var(--muted);
  transition: transform .15s ease;
}
.revelavel[open] > summary::before { transform: rotate(90deg); }
.revelavel > summary:hover { text-decoration: underline; }

/* --------------------------------------------------------------------------
   12. MENSAGENS (FLASH)
   -------------------------------------------------------------------------- */
.flashes {
  position: fixed; top: 10px; right: 10px; left: 10px; z-index: 60;
  display: flex; flex-direction: column; gap: 8px;
  pointer-events: none;
}
.flash {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 11px 13px;
  border-radius: var(--r-g);
  border: 1px solid var(--line);
  border-left-width: 3px;
  background: var(--panel);
  box-shadow: var(--sombra-2);
  font-size: .85rem;
  pointer-events: auto;
  animation: entra-flash .18s ease-out;
}
@keyframes entra-flash { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; } }
.flash-texto { flex: 1; min-width: 0; }
.flash-marca { font-weight: 700; font-size: .72rem; letter-spacing: .04em; flex-shrink: 0; padding-top: 1px; }
.flash.f-ok    { border-left-color: var(--good); }
.flash.f-ok .flash-marca { color: var(--good); }
.flash.f-erro  { border-left-color: var(--bad); }
.flash.f-erro .flash-marca { color: var(--bad); }
.flash.f-aviso { border-left-color: var(--warn); }
.flash.f-aviso .flash-marca { color: var(--warn); }
.flash.f-info  { border-left-color: var(--info); }
.flash.f-info .flash-marca { color: var(--info); }
.flash.saindo { opacity: 0; transition: opacity .4s ease; }

@media (max-width: 640px) {
  .flashes { top: 8px; right: 8px; left: 8px; }
}

/* --------------------------------------------------------------------------
   13. UTILIDADES MÍNIMAS
   --------------------------------------------------------------------------
   O suficiente para espaçar e alinhar sem virar um framework. Tudo que tem
   cor, borda, raio ou sombra é componente — utilidade aqui é só geometria.
   -------------------------------------------------------------------------- */
/* Esconde da tela sem esconder do leitor de tela. O nome diz o que é (`.sr`
   é "screen reader") e o comentário diz por quê: o "×" de um chip precisa de
   um texto que diga o que o "×" faz, senão o leitor anuncia só "multiplicação". */
.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.linha    { display: flex; align-items: center; }
.linha-topo { display: flex; align-items: flex-start; }
.entre    { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.entre-topo{ display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.quebra   { flex-wrap: wrap; }
.coluna   { display: flex; flex-direction: column; }
.crescer  { flex: 1; min-width: 0; }
.direita  { margin-left: auto; }
.inicio   { align-items: flex-start; }
.fim      { align-items: flex-end; }
.centralizado { text-align: center; }
.ajustar   { text-align: right; }
.truncar  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

.g1 { gap: 4px; }  .g2 { gap: 8px; }  .g3 { gap: 12px; } .g4 { gap: 16px; }

.m0 { margin: 0; }
.mt0 { margin-top: 0; }  .mt1 { margin-top: 4px; }  .mt2 { margin-top: 8px; }
.mt3 { margin-top: 12px; } .mt4 { margin-top: 16px; } .mt5 { margin-top: 24px; }
.mb0 { margin-bottom: 0; } .mb1 { margin-bottom: 4px; } .mb2 { margin-bottom: 8px; }
.mb3 { margin-bottom: 12px; } .mb4 { margin-bottom: 16px; } .mb5 { margin-bottom: 24px; }

.p0 { padding: 0; } .p2 { padding: 8px; } .p3 { padding: 12px; } .p4 { padding: 16px; }
/* Padding vertical sozinho: usado para dar "respiro" a um bloco vazio — uma
   tela de espera, um cartão sem resultado — sem precisar de classe de borda. */
.py2 { padding-top: 8px; padding-bottom: 8px; }
.py3 { padding-top: 12px; padding-bottom: 12px; }
.py4 { padding-top: 16px; padding-bottom: 16px; }
.py6 { padding-top: 24px; padding-bottom: 24px; }
.pt3 { padding-top: 12px; } .pl0 { padding-left: 0; }

.l1 { width: 1%; } .w100 { width: 100%; }
.mw-longa { max-width: 46rem; } .mw-media { max-width: 62rem; }

/* --------------------------------------------------------------------------
   14. PAINEL DE BI
   --------------------------------------------------------------------------
   A grade do painel é de duas colunas, não de três: cada cartão tem um gráfico
   que precisa de largura para os rótulos do eixo caberem sem rotação, e a
   leitura de margem é comparando lado a lado. Três colunas caberiam em 1920px e
   em 1366px — a largura de monitor que ainda é a maioria no comércio — cada
   cartão cairia para 300px, e o nome da categoria viraria "Merce…".
   -------------------------------------------------------------------------- */
.grade-painel { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 14px; }
@media (max-width: 1000px) { .grade-painel { grid-template-columns: 1fr; } }

/* Barra de filtros: uma fileira de campos estreitos. O campo de busca cresce
   sozinho e é o único que ocupa a linha inteira no celular. */
.barra-filtros {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-cartao);
  padding: 14px;
  margin-bottom: 14px;
}
.barra-filtros .linha-campos {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end;
}
.barra-filtros .campo { margin: 0; flex: 0 1 11rem; min-width: 8rem; }
.barra-filtros .campo.busca { flex: 1 1 16rem; min-width: 12rem; }
.barra-filtros .campo .rotulo { font-size: .68rem; }
.barra-filtros .entrada, .barra-filtros .selecao { padding: 6px 9px; font-size: .82rem; }
.barra-filtros .acoes { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* Ajudas do filtro: o período tem uma ressalva que muda o significado do
   número, e ela precisa estar junto do campo, não no rodapé da tela. */
.barra-filtros .ajuda { font-size: .68rem; margin: 3px 0 0; color: var(--faint); line-height: 1.35; }

/* Filtros ligados: cada chip é um link que remove aquele filtro. */
.chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: 7px;
  margin-bottom: 12px;
}
.chips-titulo { font-size: .74rem; color: var(--muted); }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 99px;
  background: var(--accent-frac); color: var(--accent);
  font-size: .74rem; text-decoration: none;
  border: 1px solid transparent;
}
.chip:hover { border-color: var(--accent); }
.chip-rotulo { color: var(--muted); }
.chip-valor { font-weight: 600; }
.chip-x { font-weight: 700; font-size: .9rem; }
.chip-limpar { background: transparent; color: var(--muted); text-decoration: underline; }
.chip-limpar:hover { border-color: var(--line-forte); color: var(--text); }

/* Mapa de calor em HTML. A célula usa `--text` como cor em TODAS as faixas: as
   cinco cores são toldos claros (as próprias frações de estado), e assim o
   contraste do número impresso não depende da faixa — a cor é o segundo canal,
   nunca o único. */
.tabela-mapa { table-layout: fixed; min-width: 24rem; }
.tabela-mapa th.rotulo-linha { width: 32%; white-space: normal; font-weight: 500; color: var(--muted); }
.tabela-mapa td { text-align: right; font-variant-numeric: tabular-nums; border-radius: 3px; }
/* A cor aqui é a da TINTA, não a da marca: a célula é o segundo canal do mapa
   de calor e o número dentro dela é o dado. `--bad` sobre `--bad-frac` dava
   4,43:1 e `--good` sobre `--good-frac` dava 4,47:1 — pouco, mas reprovado. */
.tabela-mapa td.hc1 { background: var(--bad-frac);  color: var(--bad-texto); font-weight: 600; }
.tabela-mapa td.hc2 { background: var(--warn-frac); color: var(--warn-texto); font-weight: 600; }
.tabela-mapa td.hc3 { background: var(--panel-2);   color: var(--muted); }
.tabela-mapa td.hc4 { background: var(--info-frac); color: var(--info-texto); font-weight: 600; }
.tabela-mapa td.hc5 { background: var(--good-frac); color: var(--good-texto); font-weight: 700; }

.legenda-calor {
  display: flex; flex-wrap: wrap; gap: 12px;
  list-style: none; margin: 10px 0 0; padding: 0;
  font-size: .72rem; color: var(--muted);
}
.legenda-calor li { display: inline-flex; align-items: center; gap: 5px; }
.legenda-calor span {
  width: 12px; height: 12px; border-radius: 3px;
  border: 1px solid var(--line); display: inline-block;
}
.legenda-calor span.hc1 { background: var(--bad-frac); }
.legenda-calor span.hc2 { background: var(--warn-frac); }
.legenda-calor span.hc3 { background: var(--panel-2); }
.legenda-calor span.hc4 { background: var(--info-frac); }
.legenda-calor span.hc5 { background: var(--good-frac); }

/* Cabeçalho de coluna que ordena: o link precisa parecer link de cabeçalho,
   não texto solto, e a coluna ativa precisa dizer qual sentido está valendo. */
.ordem { color: inherit; text-decoration: none; }
.ordem:hover { color: var(--accent); text-decoration: underline; }
.tabela th[aria-current] .ordem { color: var(--accent); font-weight: 600; }
.tabela th .ordem { display: inline-flex; align-items: center; gap: 2px; }

/* Cabeçalho da coluna que abre a linha (o nome do produto). Não é `th` de dado:
   é o rótulo da linha, e a coluna de número ao lado é que leva `scope="col"`. */
.tabela tbody th.rotulo-linha {
  text-align: left; font-weight: 500; white-space: normal;
  min-width: 13rem; max-width: 22rem;
}
.tabela tbody th.rotulo-linha .tabela-secundario { font-weight: 400; }

/* Botões de exportação acima da tabela: ficam na linha do cabeçalho do cartão
   para que a pessoa não precise rolar até o fim de 200 linhas para achar. */
.ferramentas-tabela { gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }

/* Faixa das visões salvas: fica ENTRE a barra de filtros e o painel, e não
   dentro da barra, porque salvar é um POST com token e os dois formulários são
   irmãos — `<form>` dentro de `<form>` é HTML inválido e o navegador joga o
   `action` do de dentro fora. No celular a faixa quebra em duas linhas: a
   lista de visões em cima, o campo de nome e o botão embaixo. */
.visoes-faixa {
  display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center;
  margin-top: 12px; padding: 10px 14px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
}
.visoes-faixa > form { flex: 1 1 22rem; justify-content: flex-end; }
.visoes-faixa > form .entrada { flex: 1 1 11rem; max-width: 20rem; }

/* Visões salvas: um link por visão, com o botão de apagar ao lado. */
.visoes { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.visao-link {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 4px 2px 10px; border-radius: 99px;
  background: var(--panel-2); border: 1px solid var(--line);
  font-size: .74rem; text-decoration: none; color: var(--text);
}
.visao-link:hover { border-color: var(--accent); }
.visao-apagar {
  border: 0; background: none; cursor: pointer; padding: 0 5px;
  color: var(--muted); font-size: .9rem; line-height: 1;
  border-radius: 99px;
}
.visao-apagar:hover { color: var(--bad); background: var(--bad-frac); }

/* A tela avisa quando o HTMX está trocando o pedaço. A opacidade no container
   inteiro escureceria os números; o piscar só no painel, que é a parte cara de
   redesenhar, mantém a leitura enquanto o dado chega. */
.painel-trocando { opacity: .55; transition: opacity .12s ease; }
@media (prefers-reduced-motion: reduce) { .painel-trocando { transition: none; } }

/* Aviso de que a tela está sem JavaScript: só aparece quando ele falta, e some
   assim que o HTMX assume. A classe nasce no HTML e o script a remove. */
.sem-htmx { display: block; }
.htmx-ativo .sem-htmx { display: none; }

/* Coluna de ação da tabela do painel: a única que não é número nem rótulo, e a
   única cujo conteúdo é um botão. Fica estreita e some no celular, onde o PDF
   por produto continua acessível pelo nome do produto. */
.acao-col { width: 1%; }
@media (max-width: 700px) { .tabela .acao-col { display: none; } }

/* Formulário que cabe dentro de uma linha: o "×" de apagar visão salva mora
   dentro de um <span> ao lado de um link, e um <form> é bloco por padrão —
   sem isto, o × desceria para a linha de baixo. */
.inline { display: inline; }

/* Uma visão salva é o par [link][× de apagar]. O par precisa ficar junto e
   alinhado — o × solto na linha de baixo parece o botão de fechar uma janela
   que não existe. */
.visao { display: inline-flex; align-items: center; }

/* Lista de fases da entrega. Cada linha é número + texto + selo, e o número
   tem largura fixa para as descrições começarem todas no mesmo ponto. */
.fases { display: flex; flex-direction: column; gap: 7px; }
.fase { display: flex; align-items: center; gap: 10px; }
.fase-num {
  flex: 0 0 2.1rem; text-align: center;
  font-family: var(--fonte-serif); font-size: .78rem; font-weight: 700;
  color: var(--accent);
  background: var(--accent-frac);
  border-radius: 99px; padding: 2px 0;
}
.fase-texto { font-size: .82rem; color: var(--text); line-height: 1.35; }

/* Checklist do painel: "feito" some o círculo e pinca o texto, "falta" pinta a
   borda. Sem pintar a linha inteira — oito linhas de fundo colorido são oito
   barras de ruído, e a pessoa para de ler as linhas. */
.checklist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.checklist li { display: flex; align-items: center; gap: 9px; font-size: .84rem; }
.checklist .marca { flex: 0 0 1rem; text-align: center; font-weight: 700; }
.checklist .feito .marca { color: var(--good); }
.checklist .falta .marca { color: var(--faint); }
.checklist .falta { color: var(--muted); }

/* Lista de atalhos do painel, com a mesma forma da lista de pares: rótulo
   crescendo à esquerda e ação à direita. */
.pares-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.pares-lista li { display: flex; align-items: center; gap: 10px; font-size: .84rem; }

/* --------------------------------------------------------------------------
   15. IMPRESSÃO
   --------------------------------------------------------------------------
   Relatório impresso não pode sair com a lateral no meio do papel. A barra de
   filtros e os botões somem: no papel eles não filtram nada, e quem imprimiu a
   página já leu os chips logo acima.
   -------------------------------------------------------------------------- */
@media print {
  .lateral, .barra-topo, .flashes, .rodape, .btn, .atalhos, .btn-menu,
  .barra-filtros, .chips, .grafico, .paginacao { display: none !important; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .pagina { padding: 0; max-width: none; }
  .painel { border: 1px solid #ccc; break-inside: avoid; margin-bottom: 10px; }
  .tabela th, .tabela td { border-bottom: 1px solid #ccc; }
  .tabela-mapa td.hc1, .tabela-mapa td.hc2, .tabela-mapa td.hc3,
  .tabela-mapa td.hc4, .tabela-mapa td.hc5 { background: #fff !important; color: #000 !important; }
  a { color: #000; text-decoration: none; }
}

/* --------------------------------------------------------------------------
   16. SEGUNDO FATOR DE AUTENTICAÇÃO
   --------------------------------------------------------------------------
   Quatro peças: o segredo em blocos de quatro, o campo do código de 6
   dígitos, a lista de códigos de resgate e o botão de copiar. Todas nascem
   aqui porque só a tela de 2FA precisa delas — não são "utilidades" e não
   merecem entrar na seção 13.
   -------------------------------------------------------------------------- */
/* O segredo: 32 caracteres em blocos de quatro, para a pessoa conferir grupo
   por grupo em vez de linha por linha. Monoespaçada, tamanho de leitura de
   código, e com destaque de cópia sem depender de script. */
.segredo-2fa {
  font-family: var(--fonte-mono);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: .06em;
  line-height: 2;
  color: var(--text);
  background: var(--panel-2);
  border: 1px dashed var(--line-forte);
  border-radius: var(--r-m);
  padding: 12px 14px;
  margin: 0;
  word-break: break-all;
  user-select: all;
}

/* O campo do código: números grandes, centralizados e bem espaçados. Dígito
   colado de uma mensagem na tela tem que ser fácil de conferir dígito a
   dígito, e 6 caracteres em 1.8rem não deixam dúvida sobre o que foi escrito. */
.entrada-codigo {
  font-family: var(--fonte-mono);
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: .45em;
  text-align: center;
  padding-left: .45em;   /* o letter-spacing empurra o primeiro dígito para a
                            direita; o padding devolve o alinhamento ao centro */
  min-height: 56px;
}
.entrada-mono { font-family: var(--fonte-mono); letter-spacing: .08em; }

/* Lista de códigos de resgate. Lista de verdade (`ul`) e não uma div: o leitor
   de tela anuncia "item 1 de 8", e quem precisa copiar pode passar o mouse
   sobre a linha e seleção por linha sem apagar a quebra. */
.lista-codigos {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 8px;
}
.lista-codigos li {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  padding: 10px 12px;
  text-align: center;
}
.lista-codigos code {
  font-family: var(--fonte-mono);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: .08em;
  color: var(--text);
  user-select: all;
}

/* Acordeão do "perdeu o celular". `details`/`summary` sem estilo nenhum é um
   texto sublinhado que parece link e não parece que abre algo. */
.recolhivel {
  border: 1px solid var(--line);
  border-radius: var(--r-m);
  padding: 10px 12px;
  background: var(--panel-2);
}
.recolhivel > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  user-select: none;
}
.recolhivel > summary::-webkit-details-marker { display: none; }
.recolhivel > summary::before {
  content: "›";
  display: inline-block;
  transition: transform .2s ease;
  font-size: 1.1rem;
  line-height: 1;
  color: var(--muted);
}
.recolhivel[open] > summary::before { transform: rotate(90deg); }
.recolhivel > summary:hover { color: var(--text); }
.recolhivel[open] > summary { margin-bottom: 8px; }

/* Par de botões no rodapé de um bloco de ação. */
.linha-botoes { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.mt6 { margin-top: 32px; }
/* Frase que não pode ser lida em cima do cartão. `--bad-texto` é o tom de
   texto, não o de marca: ele passa de 4.5:1 sobre o branco e sobre o cinza
   do cartão nos dois temas (a tinta de `--bad` reprovaria). */
.t-perigo { color: var(--bad-texto); }

@media print {
  /* Os códigos precisam SAIR no papel — é a raison d'être do botão "imprimir
     esta página". A tela em volta some (o bloco `.btn` já é escondido pela
     seção 16). */
  .segredo-2fa { border-style: solid; }
  .lista-codigos { grid-template-columns: 1fr 1fr; gap: 4px; }
  .lista-codigos li { padding: 4px 6px; }
  .recolhivel { border: 0; padding: 0; background: none; }
}
