/* ============================================================
   Gestão de Desempenho — BCM Eletricidade e Automação
   Folha única do sistema: tokens da marca, shell (sidebar + topo)
   e todos os componentes. Nenhuma tela escreve cor, espaçamento
   ou raio fora daqui — é isso que mantém as telas iguais entre si.
   Referência: skill identidade-visual-bcm (sistema-padrao.md).
   ============================================================ */

/* ---------------- fontes ---------------- */
@font-face {
  font-family: 'Bebas Neue';
  src: url('../assets/fontes/BebasNeue-Regular.woff') format('woff');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Mulish';
  src: url('../assets/fontes/Mulish-Variable.woff') format('woff');
  font-weight: 200 900; font-style: normal; font-display: swap;
}

/* ----------------------------------------------------------------
   Tokens — espelho de assets/tokens.json do padrão "BCM Sistema" 3.15.4.
   Os NOMES são os do padrão (--prim, --sup, --esp-*, --raio-*, --dur-*):
   é isso que permite levar um componente de um sistema BCM para outro sem
   reescrever CSS. Os nomes antigos deste projeto continuam existindo logo
   abaixo, como apelidos, para nenhuma tela precisar ser reescrita de uma vez.
   ---------------------------------------------------------------- */
:root {
  /* marca */
  --marca-azul:#006EA5; --marca-azul-claro:#80B6E3; --marca-preto:#3C3C3B;
  --marca-cinza:#686969; --marca-gelo:#EBEBEA;

  --fonte-titulo:'Bebas Neue', Oswald, Impact, sans-serif;
  --fonte-texto:'Mulish', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* tipografia */
  --txt-xs:11.5px; --txt-sm:12.5px; --txt-md:13.5px; --txt-lg:15px;
  --tit-sm:16px; --tit-md:19px; --tit-lg:23px; --tit-xl:26px;

  /* espaçamento */
  --esp-1:4px; --esp-2:8px; --esp-3:12px; --esp-4:16px; --esp-5:22px; --esp-6:32px; --esp-7:48px;

  /* raio */
  --raio-0:4px; --raio-1:6px; --raio-2:8px; --raio-3:10px; --raio-4:12px; --raio-5:14px; --raio-pill:20px;

  /* movimento */
  --dur-1:.15s; --dur-2:.22s; --dur-3:.3s; --dur-4:.45s;
  --ease:cubic-bezier(.2,.8,.2,1);

  /* shell */
  --sidebar:242px; --sidebar-rail:68px; --topo:56px; --conteudo-max:1600px;
  --alt-ctrl:38px; --alt-ctrl-sm:32px; --alvo-toque:44px;

  /* A CALHA é UMA medida só, usada nos DOIS lados do conteúdo: entre ele e a
   * sidebar, e entre ele e a borda da tela. Enquanto cada tela carregava o próprio
   * padding, duas abas do mesmo sistema abertas lado a lado se denunciavam. Com um
   * token só, mexer num lado mexe no outro por construção, e não por disciplina.
   * 22px confortável, 16px compacta, 14px abaixo de 900px. */
  --calha:22px;

  /* ===== estado ativo do menu — FIXO nos dois temas =====
   * Antes o item selecionado usava --prim, que troca de valor com o tema: no claro
   * virava azul escuro com texto branco, no escuro azul claro com texto quase preto.
   * Eram dois desenhos para o mesmo estado, e quem alterna o tema percebe na hora.
   * Estado de navegação é informação, não decoração — e informação não muda de cara
   * quando muda a luz. Vale também para os chips de preset. */
  --nav-ativo:#006EA5; --nav-ativo-txt:#FFFFFF; --nav-ativo-qtd:rgba(255,255,255,.22);

  /* Sidebar: a CALHA reservada no fluxo e a LARGURA desenhada são medidas
   * independentes — é isso que deixa a barra crescer POR CIMA do conteúdo sem
   * empurrar a tela. Animar a largura dentro do fluxo faz a página sacudir a cada
   * passada de mouse. */
  --sb-reserva:242px; --sb-larg:242px; --sb-borda:14px;

  /* Escala da interface (Minha conta → Preferências → Tamanho da interface).
   * `zoom` na raiz é o único jeito de alcançar tudo, inclusive o <dialog>, que vive
   * no top layer e não herda transform do ancestral. A dívida do zoom é que ele não
   * escala unidades de viewport: por isso todo 100vh/100vw passa por --vp-h/--vp-w. */
  --escala:1;
  --vp-h:calc(100vh / var(--escala)); --vp-w:calc(100vw / var(--escala));

  /* Avatar: paleta fechada, e todas as oito carregam texto branco nos dois temas.
   * Seletor livre de cor vira texto ilegível na metade das vezes. */
  --av-1:#006EA5; --av-2:#0F6B72; --av-3:#2E7D5B; --av-4:#A46E1C;
  --av-5:#B3423C; --av-6:#5B4B8A; --av-7:#8A5A2B; --av-8:#3C3C3B;
  --av-cor:var(--av-1);

  /* Tela de carregamento: fixa nos dois temas — quando ela aparece, a preferência
   * de tema pode nem ter sido lida ainda. */
  --carga-fundo-1:#14303F; --carga-fundo-2:#0D1319; --carga-esfera:#2E90D9;
  --carga-ponto:#FFFFFF; --carga-txt:#EDF2F6; --carga-txt2:#7C8B98;

  /* apelidos dos nomes antigos deste projeto */
  --e-1:var(--esp-1); --e-2:var(--esp-2); --e-3:var(--esp-3); --e-4:var(--esp-4);
  --e-5:var(--esp-5); --e-6:var(--esp-6); --e-7:var(--esp-7);
  --raio:var(--raio-4); --raio-p:var(--raio-2); --raio-pilula:var(--raio-pill);
  --t-rapido:var(--dur-1); --t-medio:var(--dur-2); --t-lento:var(--dur-3);
  --curva:var(--ease);
  --sidebar-largura:var(--sidebar); --sidebar-recolhida:var(--sidebar-rail);
  --topo-altura:var(--topo);

  /* escala de azuis e cinzas usada em gráficos e no logo */
  --azul-900:#00293D; --azul-800:#003D5C; --azul-700:#004B70; --azul-600:#005A87;
  --azul-500:#006EA5; --azul-400:#3389B7; --azul-300:#66A5C9; --azul-200:#99C2DB;
  --azul-100:#CCE0ED; --azul-50:#E1EDF4; --azul-claro:#80B6E3;
  --cinza-900:#1B1B1A; --cinza-800:#262625; --cinza-700:#303030; --cinza-600:#3C3C3B;
  --cinza-500:#686969; --cinza-400:#8A8B8B; --cinza-300:#ADADAC; --cinza-200:#D0D0CF;
  --cinza-100:#E0E0DF; --gelo:#EBEBEA; --branco:#FFFFFF;
}

:root, [data-tema="claro"] {
  color-scheme:light;
  --fundo:#EBEBEA; --sup:#FFFFFF; --sup2:#F4F4F3; --borda:#DEDEDC;
  --txt:#3C3C3B; --txt2:#686969;
  --prim:#006EA5; --prim-txt:#FFFFFF; --prim-suave:#E1EDF4;
  --prim-hover:#005A87; --prim-ativa:#004B70;
  --ok:#2E7D5B; --ok-bg:#E1EFE8;
  --al:#A46E1C; --al-bg:#F4EAD8;
  --err:#B3423C; --err-bg:#F6E4E2; --err-txt:#FFFFFF;
  --neutro-bg:#F0F0EF; --neutro-txt:#686969;
  --hover:#F0F0EF;
  --sombra:0 1px 3px rgba(60,60,59,.08);
  --sombra-h:0 6px 16px rgba(60,60,59,.12);
  --sombra-2:0 16px 40px rgba(60,60,59,.16);
  --brilho:none; --veu:rgba(255,255,255,0);
  --anel:0 0 0 3px rgba(0,110,165,.16);
  --area-op:.12; --tdp:12px 14px;
  --tt-sup:#262D33; --tt-borda:#3A434B; --tt-txt:#EDF2F6; --tt-link:#80B6E3;

  /* apelidos */
  --cor-fundo:var(--fundo); --cor-superficie:var(--sup); --cor-superficie-2:var(--sup2);
  --cor-borda:var(--borda); --cor-texto:var(--txt); --cor-texto-fraco:var(--txt2);
  --cor-primaria:var(--prim); --cor-primaria-hover:var(--prim-hover);
  --cor-primaria-ativa:var(--prim-ativa); --cor-primaria-txt:var(--prim-txt);
  --cor-primaria-sut:var(--prim-suave);
  --cor-sucesso:var(--ok); --cor-sucesso-sut:var(--ok-bg);
  --cor-alerta:var(--al);  --cor-alerta-sut:var(--al-bg);
  --cor-erro:var(--err);   --cor-erro-sut:var(--err-bg);
  --cor-info:var(--prim);  --cor-info-sut:var(--prim-suave);
  --sombra-1:var(--sombra); --sombra-3:var(--sombra-2);

  /* a sidebar acompanha o tema (padrão BCM 3): é --sup com borda, não escura fixa */
  --sidebar-fundo:var(--sup); --sidebar-fundo-2:var(--sup);
  --sidebar-texto:var(--txt); --sidebar-rotulo:var(--txt2);
  --sidebar-ativo:var(--prim); --sidebar-hover:var(--hover);
  --sidebar-borda:var(--borda);
}

/* O escuro não é o claro invertido: canvas azul-ardósia, degraus de luz e a
 * primária viva. O azul da marca sobre fundo escuro dá 3,4:1 e reprovaria em
 * contraste; o azul-claro da marca ficaria lavado. */
[data-tema="escuro"] {
  color-scheme:dark;
  --fundo:#0D1319; --sup:#18212A; --sup2:#212C36; --borda:#2E3C48;
  --txt:#EDF2F6; --txt2:#9FB0BE;
  --prim:#4FA9EE; --prim-txt:#04121E; --prim-suave:#16324A;
  --prim-hover:#6FBAF3; --prim-ativa:#3E96D8;
  --ok:#46D39A; --ok-bg:#12332A;
  --al:#F0B357; --al-bg:#3A2C14;
  --err:#FF7B72; --err-bg:#3B1E1E; --err-txt:#2A0A08;
  --neutro-bg:#2C3946; --neutro-txt:#BFD0DC;
  --hover:#202B35;
  --sombra:0 2px 10px rgba(0,0,0,.5);
  --sombra-h:0 8px 22px rgba(0,0,0,.5);
  --sombra-2:0 22px 50px rgba(0,0,0,.62);
  --brilho:inset 0 1px 0 rgba(255,255,255,.05);
  --veu:rgba(255,255,255,.03);
  --anel:0 0 0 3px rgba(79,169,238,.24);
  --area-op:.22;
  --tt-sup:#2A3742; --tt-borda:#41525F; --tt-txt:#EDF2F6; --tt-link:#7CC0F5;
  --azul-50:#16324A;
}

/* Densidade — Minha conta → Preferências. Muda o respiro entre as coisas. */
[data-densidade="compacta"] { --tdp:7px 14px; --alt-ctrl:32px; --alt-ctrl-sm:28px; --esp-5:16px; --esp-6:22px; --calha:16px; }

/* ---------------- tamanho da interface ----------------
 * Um controle só escala texto, controles e espaçamento JUNTOS — é o que a pessoa
 * espera quando pede "aumentar a interface"; separar tipografia de espaçamento
 * produz telas desmontadas (fonte grande dentro de botão pequeno). Escala é
 * diferente de densidade: escala muda o tamanho de tudo, densidade só o respiro.
 * Quem escrever um `height:100vh` novo quebra o layout em "Maior" — use --vp-h. */
html { zoom:var(--escala); }
[data-escala="pequeno"] { --escala:.92; }
[data-escala="grande"]  { --escala:1.08; }
[data-escala="maior"]   { --escala:1.18; }

/* ---------------- base ---------------- */
*,*::before,*::after { box-sizing:border-box; }
[hidden] { display:none !important; }
html, body { height:100%; overflow-x:clip; }
/* Faixa da barra de rolagem reservada SEMPRE. Com barra clássica (Windows), uma tela
 * que rola e a seguinte que não rola trocavam a largura útil, e o conteúdo dava um
 * pulo lateral na troca de aba. A faixa fica FORA da calha, então os 22px continuam
 * sendo 22px dos dois lados. Nunca `both-edges`: ele reserva também à esquerda e
 * descola a sidebar da borda da janela. */
html { scrollbar-gutter:stable; }
body {
  margin:0; background:var(--cor-fundo); color:var(--cor-texto);
  font-family:var(--fonte-texto); font-size:13.5px; line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
* { scrollbar-width:thin; scrollbar-color:var(--cor-borda) transparent; }
::-webkit-scrollbar { width:9px; height:9px; }
::-webkit-scrollbar-thumb { background:var(--cor-borda); border-radius:var(--raio-1);
  border:2px solid transparent; background-clip:content-box; }
::-webkit-scrollbar-thumb:hover { background:var(--cor-texto-fraco);
  border:2px solid transparent; background-clip:content-box; }
::-webkit-scrollbar-track { background:transparent; }
.sidebar ::-webkit-scrollbar-thumb { background:var(--borda);
  border:2px solid transparent; background-clip:content-box; }
body,.card,.painel,.grafico,.entrada,td,th,.modal,.toast,.badge {
  transition:background-color var(--dur-2) ease, border-color var(--dur-2) ease, color var(--dur-2) ease;
}
@media (prefers-reduced-motion:reduce) {
  *,*::before,*::after { animation-duration:.01ms !important; transition-duration:.01ms !important; }
}
h1,h2,h3 { font-family:var(--fonte-titulo); font-weight:400; letter-spacing:.02em;
  text-transform:uppercase; margin:0; }
a { color:var(--cor-primaria); }
.ic { width:20px; height:20px; flex:none; fill:none; stroke:currentColor; stroke-width:2;
      stroke-linecap:round; stroke-linejoin:round; vertical-align:-.15em; }
.ic-p { width:16px; height:16px; } .ic-g { width:24px; height:24px; }
.sr { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
:is(a,button,input,select,textarea,[tabindex]):focus-visible {
  outline:2px solid var(--prim); outline-offset:2px; border-radius:var(--raio-1);
}

/* Primeiro Tab da página: pular a navegação e ir direto ao conteúdo. */
.pular-conteudo { position:absolute; left:var(--esp-3); top:-60px; z-index:200;
  background:var(--prim); color:var(--prim-txt); padding:10px 16px; border-radius:var(--raio-2);
  font-weight:700; text-decoration:none; transition:top var(--dur-1) var(--ease); }
.pular-conteudo:focus { top:var(--esp-3); }
.num { text-align:right; font-variant-numeric:tabular-nums; }
.forte { font-weight:800; }
.fraco { color:var(--cor-texto-fraco); }
.pequeno { font-size:12px; }

/* ---------------- tela de carregamento ----------------
 * Fundo colorido com o logo parado no meio não é animação: é uma imagem enquanto
 * se espera. Aqui a MARCA SE MONTA — o contorno da esfera entra, os 17 pontos
 * acendem de baixo para cima (a própria marca virando a barra de progresso), e só
 * então entram o nome, a barra e a linha de estado. Sai em fade de 420ms, com no
 * mínimo 1,15s em tela: ou dá tempo de ler, ou não aparece.
 * A mesma tela serve para qualquer espera longa — restaurar backup, gerar
 * relatório pesado —, trocando só o texto de estado. */
#carregando {
  position:fixed; inset:0; z-index:400; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:var(--esp-5);
  background:radial-gradient(circle at 50% 42%, var(--carga-fundo-1) 0%, var(--carga-fundo-2) 62%);
  transition:opacity var(--dur-4) ease, visibility var(--dur-4);
}
#carregando[hidden] { display:flex !important; opacity:0; visibility:hidden; pointer-events:none; }
.carregando-marca { position:relative; width:132px; height:132px; animation:esfPulsa 2.6s ease-in-out infinite; }
.carregando-marca svg { width:100%; height:100%; display:block; overflow:visible; }
/* os pontos precisam ser caminhos soltos no HTML: dentro de <symbol>+<use> o CSS
 * do autor não alcança o shadow tree e nada anima */
.esf-fora { fill:var(--carga-esfera); opacity:0; transform-box:fill-box; transform-origin:center;
  animation:esfEntra .5s var(--ease) forwards; }
.esf-ponto { fill:var(--carga-ponto); opacity:0; transform-box:fill-box; transform-origin:center;
  animation:esfPonto .34s var(--ease) forwards; animation-delay:calc(.22s + var(--i) * .038s); }
@keyframes esfEntra { from { opacity:0; transform:scale(.86); } to { opacity:1; transform:none; } }
@keyframes esfPonto { from { opacity:0; transform:scale(.2); } 60% { opacity:1; transform:scale(1.12); }
  to { opacity:1; transform:scale(1); } }
@keyframes esfPulsa { 0%,100% { transform:translateY(0); } 50% { transform:translateY(-5px); } }
.carregando-nome { font-family:var(--fonte-titulo); font-size:30px; letter-spacing:.06em;
  color:var(--carga-txt); opacity:0; animation:subirEntrar .5s var(--ease) .5s forwards; }
.carregando-barra { width:190px; height:3px; border-radius:var(--raio-0); overflow:hidden;
  background:rgba(255,255,255,.12); opacity:0; animation:subirEntrar .4s var(--ease) .6s forwards; }
.carregando-barra i { display:block; height:100%; width:40%; border-radius:var(--raio-0);
  background:linear-gradient(90deg, transparent, var(--marca-azul), transparent);
  animation:barraVai 1.15s var(--ease) infinite; }
@keyframes barraVai { from { transform:translateX(-120%); } to { transform:translateX(360%); } }
/* o texto de estado é útil, não decorativo: diz o que está acontecendo */
.carregando-txt { font-size:var(--txt-sm); font-weight:600; color:var(--carga-txt2);
  letter-spacing:.02em; opacity:0; animation:subirEntrar .4s var(--ease) .7s forwards; }
@keyframes subirEntrar { from { opacity:0; transform:translateY(6px); } to { opacity:1; transform:none; } }

/* ---------------- esqueleto de tela ----------------
 * Trocar de aba não mostra tela em branco nem spinner no meio do nada: entra o
 * DESENHO da tela em cinza, com a mesma estrutura do que vai aparecer. O olho já
 * se posiciona e o conteúdo não faz a página "pular" quando chega.
 * Um bloco cinza genérico no meio da tela não é esqueleto — é espera com cara de
 * erro. E se a resposta chega em menos de 120ms, não se mostra nada. */
#esqueleto { display:flex; flex-direction:column; gap:var(--esp-5); }
.esq-bloco { border-radius:var(--raio-4); background:var(--sup); border:1px solid var(--borda);
  position:relative; overflow:hidden; }
/* um brilho só, varrendo a tela inteira — não um por bloco em tempos diferentes */
.esq-bloco::after, .esq-chip::after { content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, var(--hover), transparent);
  background-size:420px 100%; background-repeat:no-repeat;
  animation:varrer 1.25s infinite linear; }
@keyframes varrer { 0% { background-position:-420px 0; } 100% { background-position:120% 0; } }
.esq-linha { height:14px; border-radius:var(--raio-0); background:var(--sup2); }
.esq-chips { display:flex; gap:var(--esp-3); flex-wrap:wrap; }
.esq-chip { height:var(--alt-ctrl); border-radius:var(--raio-2); background:var(--sup);
  border:1px solid var(--borda); position:relative; overflow:hidden; }
.esq-chip::after { background-size:220px 100%; }
.esq-grade { display:grid; grid-template-columns:repeat(auto-fit, minmax(210px,1fr)); gap:var(--esp-4); }
.esq-dupla { display:grid; grid-template-columns:repeat(auto-fit, minmax(320px,1fr)); gap:var(--esp-4); }
.esq-tabela { padding:var(--esp-5); display:flex; flex-direction:column; gap:var(--esp-4); }
.esq-tabela .esq-linha:first-child { height:18px; width:38%; }

/* ---------------- tooltip ---------------- */
[data-tip] { position:relative; }
[data-tip]::after {
  content:attr(data-tip); position:absolute; left:50%; bottom:calc(100% + 8px);
  transform:translateX(-50%) translateY(2px); white-space:nowrap; pointer-events:none;
  background:var(--cinza-600); color:var(--gelo); font-size:11.5px; font-weight:600;
  padding:4px 9px; border-radius:var(--raio-1); opacity:0; z-index:90;
  transition:opacity var(--t-rapido) ease-out, transform var(--t-rapido) ease-out;
}
[data-tema="escuro"] [data-tip]::after { background:var(--cinza-700); border:1px solid var(--cor-borda); }
[data-tip]:hover::after, [data-tip]:focus-visible::after {
  opacity:1; transform:translateX(-50%) translateY(0); transition-delay:350ms;
}
.sidebar [data-tip]::after { left:calc(100% + 10px); bottom:auto; top:50%;
  transform:translateY(-50%) translateX(-2px); }
.sidebar [data-tip]:hover::after { transform:translateY(-50%) translateX(0); }

/* ---------------- botões ---------------- */
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font:inherit; font-weight:700; font-size:13.5px; cursor:pointer; user-select:none;
  padding:9px 16px; border-radius:var(--raio-p); border:1px solid transparent;
  background:var(--cor-primaria); color:var(--cor-primaria-txt);
  transition:background-color var(--t-rapido) ease-out, transform var(--dur-1) ease-out,
             box-shadow var(--t-rapido) ease-out, border-color var(--t-rapido) ease-out;
}
.btn:hover { background:var(--cor-primaria-hover); box-shadow:var(--sombra-1); }
.btn:active { background:var(--cor-primaria-ativa); transform:translateY(1px); box-shadow:none; }
.btn:disabled { opacity:.55; cursor:not-allowed; transform:none; }
.btn-sec { background:transparent; color:var(--cor-texto); border-color:var(--cor-borda); }
.btn-sec:hover { background:var(--cor-superficie-2); border-color:var(--cor-texto-fraco); box-shadow:none; }
.btn-ter { background:transparent; color:var(--cor-primaria); padding-inline:10px; }
.btn-ter:hover { background:var(--cor-primaria-sut); box-shadow:none; }
.btn-perigo { background:var(--err); color:var(--err-txt); }
.btn-perigo:hover { filter:brightness(.92); }
.btn-p { padding:6px 12px; font-size:12.5px; }
.btn-g { padding:12px 20px; font-size:14.5px; }
.btn .girando { animation:girar .8s linear infinite; }
@keyframes girar { to { transform:rotate(360deg); } }
.btn-icone {
  display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:36px; height:36px; cursor:pointer; border-radius:var(--raio-p);
  background:transparent; color:var(--cor-texto); border:1px solid var(--cor-borda);
  transition:all var(--t-rapido) ease-out;
}
.btn-icone:hover { border-color:var(--cor-primaria); color:var(--cor-primaria); background:var(--cor-primaria-sut); }
.btn-icone:active { transform:translateY(1px); }

/* ---------------- campos ---------------- */
.campo { display:grid; gap:5px; }
.campo > label { font-size:12.5px; font-weight:700; color:var(--cor-texto-fraco); }
.campo .ajuda { font-size:11.5px; color:var(--cor-texto-fraco); }
.entrada {
  width:100%; font:inherit; padding:9px 14px; border-radius:var(--raio-2);
  background:var(--cor-superficie); color:var(--cor-texto); border:1px solid var(--cor-borda);
  transition:border-color var(--t-rapido) ease-out, box-shadow var(--t-rapido) ease-out;
}
/* o cinza padrão do navegador (e o texto-fraco desbotado) reprovam em contraste:
 * o placeholder usa o token de texto secundário cheio */
.entrada::placeholder { color:var(--txt2); opacity:1; }
.entrada:hover { border-color:var(--cor-texto-fraco); }
.entrada:focus { outline:none; border-color:var(--cor-primaria);
  box-shadow:0 0 0 4px color-mix(in srgb, var(--cor-primaria) 14%, transparent); }
.entrada:disabled { background:var(--cor-superficie-2); color:var(--cor-texto-fraco); cursor:not-allowed; }
input[type="search"].entrada { border-radius:var(--raio-pill); }
.entrada[aria-invalid="true"] { border-color:var(--cor-erro); }
textarea.entrada { min-height:76px; resize:vertical; line-height:1.55; }
.campo .erro-campo { font-size:12px; color:var(--cor-erro); display:flex; gap:4px; align-items:center; }
.grade-campos { display:grid; gap:var(--e-4); grid-template-columns:repeat(auto-fit,minmax(220px,1fr)); }
.campo-senha { position:relative; }
.campo-senha .entrada { padding-right:44px; }
.olho {
  position:absolute; right:6px; top:50%; transform:translateY(-50%);
  width:32px; height:32px; display:grid; place-items:center; cursor:pointer;
  background:none; border:0; border-radius:var(--raio-p); color:var(--cor-texto-fraco);
  transition:color var(--t-rapido), background-color var(--t-rapido);
}
.olho:hover { color:var(--cor-primaria); background:var(--cor-primaria-sut); }

/* select pesquisável */
.sel { position:relative; }
.sel-lista {
  position:absolute; z-index:70; inset-inline:0; top:calc(100% + 4px);
  max-height:14rem; overflow-y:auto; margin:0; padding:4px; list-style:none;
  background:var(--cor-superficie); border:1px solid var(--cor-borda);
  border-radius:var(--raio-p); box-shadow:var(--sombra-2);
  animation:surge var(--t-medio) var(--curva);
}
@keyframes surge { from { opacity:0; transform:translateY(-4px); } }
.sel-lista li { padding:8px 10px; border-radius:var(--raio-1); cursor:pointer; font-size:13px; }
.sel-lista li:hover, .sel-lista li[aria-selected="true"] { background:var(--cor-superficie-2); }
.sel-lista li.vazio { color:var(--cor-texto-fraco); cursor:default; }
.sel-lista li small { display:block; color:var(--cor-texto-fraco); font-size:11.5px; }
.sel-lista mark { background:transparent; color:var(--cor-primaria); font-weight:800; }

/* switch */
.switch { position:relative; display:inline-flex; align-items:center; gap:10px; cursor:pointer; font-size:13.5px; }
.switch input { position:absolute; opacity:0; width:40px; height:22px; cursor:pointer; }
.switch .trilho { width:40px; height:22px; border-radius:var(--raio-pill); background:var(--borda);
  flex:none; transition:background-color var(--t-rapido) ease-out; position:relative; }
.switch .trilho::after { content:""; position:absolute; top:3px; left:3px; width:16px; height:16px;
  border-radius:50%; background:var(--cor-superficie); box-shadow:var(--sombra-1);
  transition:transform var(--t-medio) var(--curva); }
.switch input:checked + .trilho { background:var(--cor-primaria); }
.switch input:checked + .trilho::after { transform:translateX(18px); }
.switch input:focus-visible + .trilho { outline:2px solid var(--cor-primaria); outline-offset:2px; }

/* badges */
.badge { display:inline-flex; align-items:center; gap:5px; font-size:11.5px; font-weight:700;
  padding:3px 9px; border-radius:var(--raio-pilula); border:1px solid transparent; white-space:nowrap; }
.badge-neutro  { background:var(--cor-superficie-2); color:var(--cor-texto-fraco); border-color:var(--cor-borda); }
.badge-info    { background:var(--cor-info-sut); color:var(--cor-info); }
.badge-sucesso { background:var(--cor-sucesso-sut); color:var(--cor-sucesso); }
.badge-alerta  { background:var(--cor-alerta-sut); color:var(--cor-alerta); }
.badge-erro    { background:var(--cor-erro-sut); color:var(--cor-erro); }
.badge .ponto { width:6px; height:6px; border-radius:50%; background:currentColor; }

/* ---------------- shell ----------------
 * A barra é FIXA na janela e o shell reserva no fluxo um espaço (--sb-reserva) do
 * tamanho dela. Reserva e largura desenhada (--sb-larg) são independentes: é isso que
 * a barra revelada passar POR CIMA do conteúdo sem a página sacudir.
 *
 * A preferência tem dois eixos, não uma lista de modos:
 *   em repouso   completa | só ícones | oculta
 *   ao passar o mouse   não muda | só ícones | completa
 * A combinação dá a barra fixa, a dinâmica (vive em 68px e abre sozinha) e a que
 * some por completo. Regra dura: repouso "oculta" nunca aceita mouse "não muda" —
 * seria um menu sem caminho de volta. */
.app { display:flex; min-height:var(--vp-h); padding-left:var(--sb-reserva);
       transition:padding-left var(--dur-2) var(--ease); }
.app[data-sb="completa"] { --sb-reserva:var(--sidebar); --sb-larg:var(--sidebar); }
.app[data-sb="icones"]   { --sb-reserva:var(--sidebar-rail); --sb-larg:var(--sidebar-rail); }
.app[data-sb="oculta"]   { --sb-reserva:0px; --sb-larg:var(--sidebar); }
.app[data-sb="oculta"] .sidebar { transform:translateX(-100%); }
/* revelada pelo mouse ou pelo foco do teclado: sombra, porque ela está por cima.
 * Repare que a CALHA não muda quando a barra é revelada — é isso que faz ela
 * sobrepor o conteúdo em vez de empurrar a tela. */
.app.sb-revelada .sidebar { transform:none; box-shadow:var(--sombra-2); }
.app.sb-revelada[data-sb-revela="icones"]   { --sb-larg:var(--sidebar-rail); }
.app.sb-revelada[data-sb-revela="completa"] { --sb-larg:var(--sidebar); }

/* zona quente: a faixa invisível da borda esquerda que traz de volta a barra
 * oculta. Sem ela, "oculta" viraria uma barra impossível de achar. */
.sb-borda { position:fixed; left:0; top:0; width:var(--sb-borda); height:var(--vp-h);
  z-index:59; display:none; }
.sb-borda::before { content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
  background:var(--borda); opacity:0; transition:opacity var(--dur-2) var(--ease); }
.sb-borda:hover::before { opacity:1; background:var(--nav-ativo); }
.app[data-sb="oculta"] .sb-borda { display:block; }

.sidebar { position:fixed; left:0; top:0; z-index:60; width:var(--sb-larg); height:var(--vp-h);
  overflow:hidden;
  background:var(--sup); color:var(--txt); border-right:1px solid var(--borda);
  box-shadow:var(--brilho); display:flex; flex-direction:column;
  transition:width var(--dur-2) var(--ease), transform var(--dur-2) var(--ease); }
/* véu de luz no topo, visível só no escuro */
.sidebar::before { content:""; position:absolute; inset:0 0 auto; height:120px;
  background:linear-gradient(180deg, var(--veu), transparent); pointer-events:none; }
/* cabeçalho da sidebar com a mesma altura do topo (56px), logo 128x34 */
.sidebar-logo { display:flex; align-items:center; gap:var(--esp-2); height:var(--topo);
  padding:0 var(--esp-4); border-bottom:1px solid var(--borda); }
.sidebar-logo img.completo { width:128px; height:34px; object-fit:contain; object-position:left center;
  transition:width var(--dur-3) var(--ease); }
.sidebar-logo .btn-rail { margin-left:auto; }
.app.rail .sidebar-logo { justify-content:center; padding:0 4px; gap:3px; }
.app.rail .sidebar-logo img.completo { display:none; }
/* em 68px o símbolo e o botão de expandir não cabem lado a lado em 34px */
.sidebar-logo img.simbolo { display:none; width:26px; height:26px; flex:none; }
.app.rail .sidebar-logo img.simbolo { display:block; }
.app.rail .sidebar-logo .btn-rail { margin-left:0; }
/* o logo troca de versão com o tema — nunca com filtro de inversão */
[data-tema="claro"] .sidebar-logo img.escuro,
[data-tema="escuro"] .sidebar-logo img.claro { display:none; }
.sidebar-separador { display:none; }
.sidebar-nav { flex:1; overflow-y:auto; overflow-x:hidden; padding:10px 0 12px; }

/* ===== três papéis no menu, três desenhos — e nada além disso =====
 *   TÓPICO  divisória com nome. O ÚNICO texto em caixa alta do menu, na cor cheia,
 *           com o filete correndo dele até a borda NA MESMA ALTURA.
 *   ABA     o item normal. A aba recolhível é uma aba igual às outras: mesmo
 *           tamanho, mesmo ícone, mesma altura — ela só ganha o chevron. Aba é
 *           aba; o que muda é ela abrir ou levar a uma tela.
 *   SUBABA  item de dentro de uma aba recolhível: um degrau menor, mais apagado e
 *           recuado 16px. Duas diferenças bastam — sem guia vertical, sem filete e
 *           sem moldura. Uma linha correndo pela altura da barra cobra caro em
 *           ruído para dizer o que o recuo já disse.
 * E vale sempre: azul sólido = você está aqui, e é o ÚNICO azul do menu. */
.nav-topico { display:flex; align-items:center; gap:10px; margin:26px 14px 6px; padding:0 10px;
  font-size:10.5px; font-weight:800; letter-spacing:.16em; text-transform:uppercase;
  color:var(--txt); white-space:nowrap; }
/* rótulo e linha são UMA PEÇA SÓ: o nome à esquerda e o filete correndo dele até a
 * borda, na mesma altura. Traço em cima e nome embaixo são dois elementos soltos
 * disputando o mesmo trabalho — é o que faz a divisão parecer montada em dois
 * momentos. O espaço é assimétrico de propósito (26px acima, 6px abaixo): o rótulo
 * pertence ao bloco que vem DEPOIS dele. */
.nav-topico span { min-width:0; overflow:hidden; text-overflow:ellipsis; }
.nav-topico::after { content:""; flex:1; height:1px; background:var(--borda); }
.nav-topico:first-child { margin-top:10px; }
/* no rail sobra só o filete entre os blocos de ícones */
.app.rail .nav-topico { margin:12px; padding:0; gap:0; }
.app.rail .nav-topico span { display:none; }

/* aba solta e aba recolhível são a MESMA coisa na lista: 2px entre elas, igual a
 * duas abas quaisquer. O respiro maior é do tópico, e só dele — espaço extra em
 * outro lugar abre um vão sem significado e concorre com a leitura de blocos. */
.nav-bloco { display:flex; flex-direction:column; gap:2px; padding:0 14px; margin-top:2px; }
.app.rail .nav-bloco { padding:0 12px; }

.nav-item { position:relative; display:flex; align-items:center; gap:11px; width:100%;
  padding:7px 10px; border-radius:var(--raio-3); color:var(--txt2); text-decoration:none;
  font-size:var(--txt-md); font-weight:600; white-space:nowrap; cursor:pointer; border:0; background:none;
  font-family:inherit; text-align:left; /* bcm-ok: herdar a fonte do sistema É o padrão */
  transition:background-color var(--dur-1) ease-out, color var(--dur-1) ease-out; }
.app.rail .nav-item { padding:7px; justify-content:center; }
.nav-item:hover { background:var(--hover); color:var(--txt); }
.nav-item .ic { width:17px; height:17px; flex:none; }
.nav-item .caixa-ic { display:flex; align-items:center; justify-content:center;
  width:26px; height:26px; flex:none; color:inherit; }
/* item ativo: --nav-ativo, IDÊNTICO nos dois temas. Sem filete, sem sombra e sem
 * brilho extra no escuro — ver o bloco de tokens lá em cima. */
.nav-item[aria-current="page"] { background:var(--nav-ativo); color:var(--nav-ativo-txt); font-weight:700; }
.nav-item[aria-current="page"]:hover { background:var(--nav-ativo); }
.nav-item .texto { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; }
.app.rail .nav-item .texto { display:none; }
.nav-item .contador { font-size:10.5px; font-weight:800; font-variant-numeric:tabular-nums;
  padding:2px 7px; border-radius:var(--raio-3); background:var(--sup2); color:var(--txt2);
  border:1px solid var(--borda); flex:none; }
.nav-item[aria-current="page"] .contador { background:var(--nav-ativo-qtd); color:var(--nav-ativo-txt); border:0; }
.app.rail .nav-item .contador { display:none; }
.nav-item:focus-visible { outline:2px solid var(--prim); outline-offset:-2px; }

/* aba recolhível: a mesma aba, mais o chevron */
.nav-grupo .chevron { flex:none; width:13px; height:13px; color:var(--txt2); opacity:.55;
  transition:transform var(--dur-2) var(--ease); }
.nav-grupo[aria-expanded="true"] .chevron { transform:rotate(180deg); }
/* a aba recolhível que contém a tela atual só escurece o texto: é de propósito
 * discreto, porque o azul da subaba já respondeu onde a pessoa está */
.nav-grupo.tem-ativo { color:var(--txt); }
.app.rail .nav-grupo { display:none; }

/* subaba: um degrau para dentro (16px) e um degrau abaixo em peso */
.nav-itens { display:flex; flex-direction:column; gap:2px; overflow:hidden; padding-left:16px; }
.nav-itens[hidden] { display:none; }
.nav-itens .nav-item { font-size:var(--txt-sm); padding:6px 10px; opacity:.85; }
.nav-itens .nav-item .caixa-ic { width:22px; height:22px; }
.nav-itens .nav-item .ic { width:15px; height:15px; }
.nav-itens .nav-item[aria-current="page"], .nav-itens .nav-item:hover { opacity:1; }
/* no rail não existe aba recolhível: o menu volta a ser a lista de ícones */
.app.rail .nav-itens { padding-left:0; }
.app.rail .nav-itens[hidden] { display:flex; }

/* ===== rodapé: a conta mora com o usuário =====
 * Meu perfil e Preferências são do dono da sessão, e o dono da sessão está no
 * rodapé — ninguém procura o próprio tema numa seção chamada Administração.
 * Duas peças que não competem: a IDENTIDADE (avatar + nome + cargo), que é o alvo
 * grande e não tem moldura, e as AÇÕES, dois botões de ícone iguais entre si
 * encostados à direita. Enfiar o ícone dentro do bloco do nome espremia o nome até
 * virar reticências e deixava dois ícones de desenhos diferentes lado a lado. */
.sidebar-rodape { border-top:1px solid var(--borda); padding:10px 14px;
  display:flex; align-items:center; gap:4px; white-space:nowrap; flex:none; }
.app.rail .sidebar-rodape { justify-content:center; padding:10px; gap:0; }
.nav-conta { flex:1; min-width:0; display:flex; align-items:center; gap:10px; background:transparent;
  border:0; cursor:pointer; text-align:left; padding:5px 6px; border-radius:var(--raio-3);
  color:inherit; font-family:inherit; /* bcm-ok: herda Mulish do sistema */
  transition:background-color var(--dur-1), color var(--dur-1); }
.nav-conta:hover { background:var(--hover); }
/* o bloco é um destino como qualquer outro e acende igual */
.nav-conta[aria-current="page"] { background:var(--nav-ativo); color:var(--nav-ativo-txt); }
.nav-conta[aria-current="page"] .nome b, .nav-conta[aria-current="page"] .nome span {
  color:var(--nav-ativo-txt); }
.nav-conta[aria-current="page"] .nome span { opacity:.85; }
/* anel claro para o avatar não encostar direto no azul */
.nav-conta[aria-current="page"] .avatar { box-shadow:0 0 0 2px rgba(255,255,255,.4); }
.app.rail .nav-conta { flex:none; padding:4px; }
.sidebar-rodape .nome { flex:1; min-width:0; display:block; line-height:1.3; }
.sidebar-rodape .nome b { display:block; font-size:12.5px; font-weight:700;
  overflow:hidden; text-overflow:ellipsis; }
.sidebar-rodape .nome span { display:block; font-size:10.5px; font-weight:600; color:var(--txt2);
  overflow:hidden; text-overflow:ellipsis; }
.app.rail .sidebar-rodape .nome, .app.rail .sidebar-rodape .acao { display:none; }
/* as duas ações: mesmo tamanho, mesmo raio, mesma cor de repouso. O que as
 * diferencia é só o hover — neutro para configurar, --err para sair. */
.sidebar-rodape .acao { width:30px; height:30px; display:flex; align-items:center; justify-content:center;
  border:0; background:transparent; color:var(--txt2); cursor:pointer; border-radius:var(--raio-2);
  flex:none; transition:background-color var(--dur-1), color var(--dur-1); }
.sidebar-rodape .acao:hover { background:var(--hover); color:var(--txt); }
.sidebar-rodape .acao.sair:hover { background:var(--err-bg); color:var(--err); }
.sidebar-rodape .acao .ic { width:17px; height:17px; }

/* ===== avatar — círculo, sempre =====
 * No menu, no topo, na tabela e no comentário. Quadrado com canto arredondado é
 * logo de aplicativo, não pessoa. A cor vem de --av-cor, escolhida em Meu perfil,
 * e um token só faz todos os avatares mudarem de uma vez. */
.avatar { width:34px; height:34px; border-radius:50%; flex:none; position:relative;
  background:var(--av-cor); color:#FFFFFF; /* bcm-ok: as oito cores da paleta carregam branco */
  background-size:cover; background-position:center; overflow:hidden;
  display:grid; place-items:center; font-size:12.5px; font-weight:800; }
.sidebar-rodape .avatar { width:32px; height:32px; font-size:12px; }
.avatar-gg { width:96px; height:96px; font-size:32px; }
/* o avatar do topo leva ao mesmo destino do bloco do rodapé */
.btn-conta-topo { border:0; padding:0; background:none; cursor:pointer; border-radius:50%;
  transition:box-shadow var(--dur-1); }
.btn-conta-topo:hover, .btn-conta-topo[aria-current="page"] { box-shadow:0 0 0 2px var(--nav-ativo); }

.btn-rail { all:unset; cursor:pointer; display:flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:var(--raio-2); color:var(--txt2); flex:none;
  transition:background-color var(--dur-1) ease-out, color var(--dur-1) ease-out; }
.btn-rail:hover { color:var(--txt); background:var(--hover); }
.btn-rail .ic { width:17px; height:17px; transition:transform var(--dur-3) var(--ease); }
.app.rail .btn-rail .ic { transform:rotate(180deg); }

.principal { flex:1; min-width:0; display:flex; flex-direction:column; }
/* a barra revelada passa por cima do topo: z-index 60 (barra) > 40 (topo) */
.topo { height:var(--topo-altura); position:sticky; top:0; z-index:40;
  display:flex; align-items:center; gap:var(--e-4); padding:0 var(--e-5);
  background:var(--cor-superficie); border-bottom:1px solid var(--cor-borda); }
/* "onde estou": a seção em cima, a tela embaixo. O menu é para escolher; o topo é
 * para confirmar — e com o menu recolhível a aba pode estar fechada, e sem esta
 * linha some a referência. Em tela de erro o grupo fica vazio e a linha some. */
.topo-onde { display:flex; flex-direction:column; justify-content:center; flex:none; min-width:0; }
.topo-secao { font-size:9.5px; font-weight:800; letter-spacing:.16em; text-transform:uppercase;
  color:var(--prim); line-height:1.1; margin-bottom:1px; }
.topo-secao:empty { display:none; }
.topo-titulo { font-size:var(--tit-lg); line-height:1; letter-spacing:.03em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.topo .espaco { margin-left:auto; }
.busca-global { position:relative; width:280px; }
.busca-global .ic { position:absolute; left:10px; top:50%; transform:translateY(-50%);
  color:var(--cor-texto-fraco); width:16px; height:16px; pointer-events:none; }
.busca-global .entrada { padding-left:32px; background:var(--cor-fundo); }
.busca-global kbd { position:absolute; right:8px; top:50%; transform:translateY(-50%);
  font:inherit; font-size:11px; color:var(--cor-texto-fraco); border:1px solid var(--cor-borda);
  border-radius:var(--raio-1); padding:0 5px; pointer-events:none; }
.busca-global .sel-lista { max-height:20rem; }

.conteudo { width:100%; max-width:var(--conteudo-max); margin:0 auto; padding:20px var(--calha) 36px; }

/* ===== movimento =====
 * Animação aqui tem uma função só: explicar uma mudança de estado. Se não explica
 * nada, sai. Tudo em transform e opacity — o que o navegador anima sem repintar.
 *
 * A classe .anima entra na troca de tela e SAI em 700ms. Sem isso, o gráfico se
 * redesenharia a cada passada de mouse e os KPIs piscariam a cada filtro:
 * animação de entrada é para ENTRAR, não para toda repintura. */
.tela.anima { animation:tela-entra .26s var(--ease); }
@keyframes tela-entra { from { opacity:0; transform:translateY(8px); } }
/* stagger curto e só onde há poucos itens (4 a 6 cards). Em linha de tabela,
 * nunca: atrasar linha por linha atrasa a leitura, que é o que a pessoa foi ali
 * fazer. */
.tela.anima .grade-kpi > * { animation:card-entra .34s var(--ease) backwards;
  animation-delay:calc(var(--k, 0) * .045s); }
@keyframes card-entra { from { opacity:0; transform:translateY(10px) scale(.99); } }
/* conteúdo de aba entra com um respiro de 6px: o suficiente para o olho perceber
 * que trocou, sem atrapalhar quem já sabe o que quer */
.aba-corpo { animation:aba-entra .2s var(--ease); }
@keyframes aba-entra { from { opacity:0; transform:translateY(6px); } }
/* fechar também é animação: <dialog> some na hora por padrão, e o olho perde o
 * objeto de vista sem entender para onde ele foi */
.modal.saindo { animation:modal-sai .16s ease-in forwards; }
@keyframes modal-sai { to { opacity:0; transform:translateY(6px) scale(.985); } }
.toast.saindo { animation:toast-sai .22s ease-in forwards; }
@keyframes toast-sai { to { opacity:0; transform:translateY(6px) scale(.98); } }
#btn-tema .ic { transition:transform var(--dur-4) var(--ease); }
#btn-tema.girando .ic { transform:rotate(180deg); }
.secao { margin-bottom:var(--esp-5); }
.secao-titulo { font-family:var(--fonte-texto); font-size:12.5px; font-weight:800;
  text-transform:uppercase; letter-spacing:.06em; color:var(--cor-texto-fraco); margin:0 0 var(--e-3); }
.cabecalho-tela { display:flex; flex-wrap:wrap; align-items:center; gap:var(--e-3); margin-bottom:var(--e-4); }
.cabecalho-tela .espaco { margin-left:auto; }
.cabecalho-tela p { margin:2px 0 0; color:var(--cor-texto-fraco); font-size:13px; }

/* ---------------- filtros ---------------- */
.filtros { display:flex; flex-wrap:wrap; gap:var(--e-2); align-items:center; }
.preset { font:inherit; font-size:13px; font-weight:600; cursor:pointer; padding:6px 13px;
  border-radius:var(--raio-pilula); border:1px solid var(--cor-borda);
  background:var(--cor-superficie); color:var(--cor-texto-fraco);
  transition:all var(--t-rapido) ease-out; }
.preset:hover:not(:disabled) { border-color:var(--cor-primaria); color:var(--cor-primaria); }
.preset:disabled { opacity:.45; cursor:not-allowed; }
/* o chip escolhido fala a MESMA língua do item ativo do menu: --nav-ativo, igual
 * nos dois temas. "É este aqui" é informação, não decoração. */
.preset[aria-pressed="true"] { background:var(--nav-ativo); color:var(--nav-ativo-txt);
  border-color:var(--nav-ativo); font-weight:800; }
.preset[aria-pressed="true"]:hover { background:var(--nav-ativo); color:var(--nav-ativo-txt);
  border-color:var(--nav-ativo); }
.chips { display:flex; flex-wrap:wrap; gap:var(--e-2); margin-top:var(--e-3); }
.chip { display:inline-flex; align-items:center; gap:6px; cursor:pointer; font:inherit;
  font-size:12.5px; font-weight:700; padding:4px 10px; border-radius:var(--raio-pilula);
  background:var(--cor-primaria-sut); color:var(--cor-primaria);
  border:1px solid color-mix(in srgb, var(--cor-primaria) 35%, transparent);
  animation:surge var(--t-medio) var(--curva); transition:all var(--t-rapido) ease-out; }
.chip:hover { border-color:var(--cor-primaria); }

/* ---------------- cards ---------------- */
.grade-kpi { display:grid; gap:var(--esp-4); grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); }
.card { display:block; text-align:left; width:100%; font:inherit; color:inherit; position:relative;
  background:var(--sup); border:1px solid var(--borda);
  border-radius:var(--raio-4); padding:14px 16px; box-shadow:var(--sombra), var(--brilho); cursor:pointer;
  transition:transform var(--t-rapido) ease-out, border-color var(--t-rapido) ease-out,
             box-shadow var(--t-rapido) ease-out; }
.card:hover { transform:translateY(-2px); border-color:var(--prim); box-shadow:var(--sombra-h); }
.card:active { transform:translateY(0); }
.card[aria-pressed="true"] { border-color:var(--cor-primaria);
  box-shadow:0 0 0 2px color-mix(in srgb, var(--cor-primaria) 25%, transparent); }
.card-icone { position:absolute; top:14px; right:14px; width:32px; height:32px;
  display:grid; place-items:center; border-radius:var(--raio-3);
  background:var(--cor-primaria-sut); color:var(--cor-primaria);
  transition:transform var(--t-rapido) ease-out; }
.card-icone .ic { width:17px; height:17px; }
.card:hover .card-icone { transform:scale(1.08); }
.card-rotulo { display:block; font-size:12.5px; font-weight:600; color:var(--cor-texto-fraco); padding-right:44px; }
.card-valor { display:block; font-size:26px; font-weight:800; font-variant-numeric:tabular-nums;
  line-height:1.2; margin-top:8px; }
.card-dica { display:block; margin-top:4px; font-size:11px; color:var(--cor-texto-fraco); }
.card[aria-pressed="true"] .card-dica { color:var(--cor-primaria); font-weight:800; }
.card-delta { display:inline-flex; align-items:center; gap:4px; margin-top:6px; font-size:12px; font-weight:700; }
.delta-bom { color:var(--cor-sucesso); } .delta-ruim { color:var(--cor-erro); }

/* ---------------- gráficos ---------------- */
.grade-graficos { display:grid; gap:14px; grid-template-columns:repeat(auto-fit,minmax(340px,1fr)); }
.grafico { background:var(--cor-superficie); border:1px solid var(--cor-borda);
  border-radius:var(--raio); box-shadow:var(--sombra-1); padding:var(--e-4) 18px; }
.grafico h3 { font-family:var(--fonte-texto); font-size:14px; font-weight:800;
  text-transform:none; letter-spacing:0; margin-bottom:var(--e-3); }
.grafico svg { width:100%; height:232px; display:block; }
.grafico text { font-family:var(--fonte-texto); font-size:11px; fill:var(--cor-texto-fraco); }
.grafico .grade-linha { stroke:var(--cor-borda); stroke-width:1; }
.grafico .barra { transition:opacity var(--t-medio) ease-out, filter var(--t-rapido) ease-out; cursor:pointer; }
.grafico .barra.esmaecida { opacity:.3; }
.grafico .barra.destaque { filter:brightness(1.12); }
.grafico circle { transition:r var(--t-rapido) ease-out; pointer-events:none; }
.grafico .guia { stroke:var(--cor-texto-fraco); stroke-width:1; stroke-dasharray:3 4;
  opacity:0; transition:opacity var(--t-rapido) ease-out; pointer-events:none; }
.grafico .zona { fill:transparent; cursor:crosshair; }
.grafico.atualizando svg, .grafico.atualizando .legenda { opacity:.35; filter:saturate(.5); }
.grafico svg, .grafico .legenda { transition:opacity var(--t-medio) ease-out, filter var(--t-medio) ease-out; }
.legenda { display:flex; gap:var(--e-4); margin-top:var(--e-2); font-size:12px;
  color:var(--cor-texto-fraco); flex-wrap:wrap; }
.legenda span, .legenda button { display:inline-flex; align-items:center; gap:6px; }
.legenda i { width:10px; height:10px; border-radius:var(--raio-1); display:inline-block; }
.legenda button { all:unset; cursor:pointer; padding:2px 6px; border-radius:var(--raio-1);
  transition:all var(--t-rapido) ease-out; }
.legenda button:hover { background:var(--cor-superficie-2); }
.legenda button[aria-pressed="false"] { opacity:.4; text-decoration:line-through; }
#graf-tip { position:fixed; z-index:95; pointer-events:none; opacity:0;
  background:var(--tt-sup); color:var(--tt-txt); border-radius:var(--raio-3); padding:8px 11px;
  font-size:12px; line-height:1.45; box-shadow:var(--sombra-2);
  transform:translate(-50%, calc(-100% - 10px)) translateY(3px);
  transition:opacity var(--t-rapido) ease-out, transform var(--t-rapido) ease-out; white-space:nowrap; }
[data-tema="escuro"] #graf-tip { background:var(--cinza-700); border:1px solid var(--cor-borda); }
#graf-tip.on { opacity:1; transform:translate(-50%, calc(-100% - 10px)); }
#graf-tip b { display:block; font-size:11px; text-transform:uppercase; letter-spacing:.05em;
  color:var(--cinza-300); margin-bottom:2px; }
#graf-tip .serie { display:flex; align-items:center; gap:6px; }
#graf-tip .serie i { width:8px; height:8px; border-radius:var(--raio-1); flex:none; }
#graf-tip .serie strong { font-variant-numeric:tabular-nums; margin-left:auto; padding-left:12px; }

/* ---------------- painel e tabela ---------------- */
.painel { background:var(--cor-superficie); border:1px solid var(--cor-borda);
  border-radius:var(--raio); box-shadow:var(--sombra-1); overflow:hidden; }
.painel + .painel { margin-top:14px; }
.painel-topo { display:flex; flex-wrap:wrap; gap:var(--e-3); align-items:center; padding:var(--e-4) 18px; }
.painel-topo .espaco { margin-left:auto; }
.painel-corpo { padding:var(--e-4) 18px var(--e-5); }
.painel-titulo { font-family:var(--fonte-texto); font-size:14px; font-weight:800;
  text-transform:none; letter-spacing:0; }
.campo-icone { position:relative; width:270px; }
.campo-icone .ic { position:absolute; left:10px; top:50%; transform:translateY(-50%);
  color:var(--cor-texto-fraco); width:16px; height:16px; pointer-events:none; }
.campo-icone .entrada { padding-left:32px; }
.rolagem { overflow-x:auto; }
table { width:100%; border-collapse:collapse; font-size:13.5px; }
thead th { background:var(--cor-superficie-2); text-align:left; padding:0;
  border-block:1px solid var(--cor-borda); white-space:nowrap; }
thead th.simples { padding:10px 14px; font-weight:700; font-size:12px; color:var(--cor-texto-fraco);
  text-transform:uppercase; letter-spacing:.04em; }
thead th button { all:unset; display:flex; align-items:center; gap:4px; width:100%;
  box-sizing:border-box; cursor:pointer; padding:10px 14px; font-weight:700; font-size:12px;
  color:var(--cor-texto-fraco); text-transform:uppercase; letter-spacing:.04em;
  transition:color var(--t-rapido); }
thead th button:hover { color:var(--cor-texto); }
thead th.num button { justify-content:flex-end; }
tbody td { padding:var(--tdp); border-bottom:1px solid var(--borda); }
tbody tr { transition:background-color var(--t-rapido) ease-out; }
tbody tr:hover { background:var(--hover); }
/* filete de 3px na primária marca a linha sob o mouse (padrão BCM) */
tbody tr:hover td:first-child { box-shadow:inset 3px 0 0 var(--prim); }
tbody tr:hover .acoes-linha { opacity:1; }
tbody tr.clicavel { cursor:pointer; }
.acoes-linha { opacity:0; display:flex; gap:2px; justify-content:flex-end; transition:opacity var(--t-rapido); }
.btn-linha { all:unset; cursor:pointer; padding:6px; border-radius:var(--raio-1); color:var(--txt2);
  display:inline-flex; transition:all var(--t-rapido); }
.btn-linha:hover { color:var(--cor-primaria); background:var(--cor-primaria-sut); }
.btn-linha.perigo:hover { color:var(--cor-erro); background:var(--cor-erro-sut); }
.rodape-tabela { display:flex; justify-content:space-between; gap:var(--e-3); padding:10px 14px;
  font-size:12.5px; color:var(--cor-texto-fraco); border-top:1px solid var(--cor-borda); }
.vazio-estado { padding:var(--e-7) var(--e-4); text-align:center; color:var(--cor-texto-fraco); }
.vazio-estado .ic { width:36px; height:36px; opacity:.5; margin-bottom:var(--e-2); }
.vazio-estado h3 { font-family:var(--fonte-texto); font-size:14px; font-weight:800;
  text-transform:none; letter-spacing:0; color:var(--cor-texto); margin-bottom:4px; }
@keyframes destacar { from { background:color-mix(in srgb, var(--cor-primaria) 20%, transparent); } }
.linha-nova { animation:destacar 1.5s ease-out; }

/* esqueleto */
.esqueleto { border-radius:var(--raio-1); background:linear-gradient(90deg, var(--sup2) 25%,
  color-mix(in srgb, var(--cor-superficie-2) 55%, var(--cor-texto-fraco) 14%) 37%, var(--cor-superficie-2) 63%);
  background-size:400% 100%; animation:brilho 1.4s ease-in-out infinite; }
@keyframes brilho { from { background-position:100% 0; } to { background-position:0 0; } }
.esq-linha { height:13px; margin:6px 0; }
.card-esqueleto { background:var(--cor-superficie); border:1px solid var(--cor-borda);
  border-radius:var(--raio); padding:14px 16px; box-shadow:var(--sombra-1); }
.card-esqueleto .a { height:12px; width:55%; margin-bottom:10px; }
.card-esqueleto .b { height:26px; width:40%; margin-bottom:10px; }
.card-esqueleto .c { height:11px; width:65%; }

/* ---------------- modais ---------------- */
.modal { padding:0; border:1px solid var(--borda); border-radius:var(--raio-5);
  background:var(--cor-superficie); color:var(--cor-texto); box-shadow:var(--sombra-3);
  max-width:460px; width:calc(100% - 2rem); }
.modal-largo { max-width:900px; }
.modal-medio { max-width:660px; }
.modal::backdrop { background:rgba(21,21,20,.55); }
.modal[open] { animation:modal-entra var(--t-lento) var(--curva); }
.modal[open]::backdrop { animation:aparece var(--t-medio) ease-out; }
@keyframes modal-entra { from { opacity:0; transform:translateY(10px) scale(.97); } }
@keyframes aparece { from { opacity:0; } }
.modal-caixa { margin:0; padding:var(--e-5); max-height:calc(var(--vp-h) * .85); overflow-y:auto; }

/* O X mora no <dialog>, e NÃO na caixa que rola: é isso que o mantém parado no canto
 * enquanto o conteúdo passa por baixo. Dentro da caixa ele subiria junto com o texto e
 * sumiria no primeiro modal comprido — que é justamente quando se procura por ele.
 * O fundo é o da superfície porque a caixa rola por trás dele. */
.modal-fechar { position:absolute; top:10px; right:10px; z-index:2; width:32px; height:32px;
  border-color:transparent; background:var(--cor-superficie); color:var(--cor-texto-fraco); }
.modal-fechar .ic { width:15px; height:15px; }
.modal-fechar:hover { background:var(--cor-primaria-sut); }
/* espaço para o título não correr por baixo do X */
.modal-topo { display:flex; align-items:center; gap:10px; margin-bottom:var(--e-2); padding-right:30px; }
.modal-topo .ic { color:var(--cor-alerta); }
.modal-topo h2 { font-family:var(--fonte-texto); font-size:16px; font-weight:800;
  text-transform:none; letter-spacing:0; }
.modal-texto { margin:0 0 var(--e-4); color:var(--cor-texto-fraco); font-size:13.5px; }
.modal-acoes { display:flex; justify-content:flex-end; gap:var(--e-2); margin-top:var(--e-5); }
.modal-form-campos { display:grid; gap:var(--e-4); }

/* ---------------- toasts ---------------- */
#toasts { position:fixed; right:var(--e-4); bottom:var(--e-4); display:grid; gap:var(--e-2); z-index:100; }
.toast { display:flex; align-items:center; gap:10px; padding:11px 14px; border-radius:var(--raio-3);
  background:var(--cor-superficie); border:1px solid var(--cor-borda); box-shadow:var(--sombra-2);
  animation:toast-entra var(--t-medio) var(--curva); font-size:13.5px; max-width:420px; }
@keyframes toast-entra { from { opacity:0; transform:translateY(8px); } }
.toast.sucesso .ic { color:var(--cor-sucesso); }
.toast.erro .ic { color:var(--cor-erro); }
.toast.info .ic { color:var(--cor-info); }
.toast-acao { font:inherit; font-weight:800; font-size:12.5px; cursor:pointer; background:none;
  border:0; color:var(--prim); padding:2px 6px; border-radius:var(--raio-1); }
.toast-acao:hover { background:var(--cor-primaria-sut); }

/* ---------------- avisos ---------------- */
.aviso { display:flex; gap:10px; align-items:flex-start; padding:11px 14px; border-radius:var(--raio-p);
  font-size:13px; border:1px solid transparent; }
.aviso .ic { flex:none; margin-top:1px; }
.aviso-info { background:var(--cor-info-sut); color:var(--cor-info);
  border-color:color-mix(in srgb, var(--cor-info) 25%, transparent); }
.aviso-alerta { background:var(--cor-alerta-sut); color:var(--cor-alerta);
  border-color:color-mix(in srgb, var(--cor-alerta) 25%, transparent); }
.aviso-erro { background:var(--cor-erro-sut); color:var(--cor-erro);
  border-color:color-mix(in srgb, var(--cor-erro) 25%, transparent); }
.aviso-sucesso { background:var(--cor-sucesso-sut); color:var(--cor-sucesso);
  border-color:color-mix(in srgb, var(--cor-sucesso) 25%, transparent); }
.aviso + .aviso { margin-top:var(--e-2); }

/* ---------------- responsivo e impressão ---------------- */
/* No celular nada da preferência de sidebar vale: a barra é sempre gaveta pelo
 * botão do topo. Barra que aparece sozinha ao toque é armadilha. */
@media (max-width:900px) {
  /* a tela é estreita: cada pixel de calha é um pixel a menos de conteúdo */
  .app, .app[data-sb] { --sb-reserva:0px; --sb-larg:var(--sidebar); --calha:14px; }
  .sidebar, .app[data-sb] .sidebar { z-index:80; transform:translateX(-100%); }
  .app[data-sb] .sidebar.aberta, .sidebar.aberta { transform:none; box-shadow:var(--sombra-2); }
  .app .sb-borda, .app[data-sb="oculta"] .sb-borda { display:none; }
  .btn-menu { display:inline-flex !important; }
  .busca-global { display:none; }
  .btn-rail { display:none; }
  .conteudo { padding:14px var(--calha) var(--e-6); }
  .campo-icone { width:100%; }
}
.btn-menu { display:none; }
@media print {
  .sidebar,.sb-borda,.topo,#toasts,#carregando,.acoes-linha,.filtros { display:none !important; }
  .app { padding-left:0; }
  .conteudo { max-width:100%; padding:0; }
  .painel, .card, .grafico { box-shadow:none; border-color:var(--borda); break-inside:avoid; }
}

/* ---------------- paleta de comandos (Ctrl+K) ---------------- */
.paleta::backdrop { background:rgba(15,22,28,.55); backdrop-filter:blur(2px); }
.paleta { border:0; padding:0; background:transparent; margin:calc(var(--vp-h) * .12) auto auto; width:min(560px, calc(var(--vp-w) - 32px)); }
.paleta-caixa { background:var(--sup); border:1px solid var(--borda); border-radius:var(--raio-5);
  box-shadow:var(--sombra-2); overflow:hidden; animation:paleta-entra var(--dur-2) var(--ease); }
@keyframes paleta-entra { from { opacity:0; transform:translateY(8px); } }
.paleta-busca { display:flex; align-items:center; gap:10px; padding:14px 16px;
  border-bottom:1px solid var(--borda); }
.paleta-busca .ic { color:var(--txt2); }
.paleta-busca input { flex:1; border:0; background:none; font:inherit; font-size:var(--txt-lg);
  color:var(--txt); outline:none; }
.paleta-lista { max-height:calc(var(--vp-h) * .46); overflow-y:auto; padding:var(--esp-2); margin:0; list-style:none; }
.paleta-grupo { font-size:10.5px; font-weight:800; letter-spacing:.12em; text-transform:uppercase;
  color:var(--txt2); padding:10px 10px 4px; }
.paleta-item { display:flex; align-items:center; gap:10px; padding:9px 10px; border-radius:var(--raio-2);
  cursor:pointer; font-size:var(--txt-md); }
.paleta-item .ic { width:17px; height:17px; color:var(--txt2); }
.paleta-item small { margin-left:auto; color:var(--txt2); font-size:var(--txt-xs); }
.paleta-item[aria-selected="true"] { background:var(--prim-suave); color:var(--prim); }
.paleta-item[aria-selected="true"] .ic { color:var(--prim); }
.paleta-item mark { background:none; color:var(--prim); font-weight:800; }
.paleta-vazio { padding:20px 12px; color:var(--txt2); text-align:center; font-size:var(--txt-md); }
.paleta-rodape { display:flex; gap:var(--esp-4); padding:10px 16px; background:var(--sup2);
  border-top:1px solid var(--borda); font-size:var(--txt-xs); color:var(--txt2); }
.tecla { display:inline-block; border:1px solid var(--borda); border-radius:var(--raio-1);
  padding:1px 6px; background:var(--sup); font-size:10.5px; font-weight:700; margin-right:4px; }

/* ---------------- tabela vira card no celular ---------------- */
@media (max-width:720px) {
  .rolagem table thead { display:none; }
  .rolagem table tbody tr { display:block; border:1px solid var(--borda); border-radius:var(--raio-4);
    margin-bottom:var(--esp-3); background:var(--sup); box-shadow:var(--sombra); }
  .rolagem table tbody td { display:flex; align-items:center; gap:var(--esp-3); border:0;
    border-bottom:1px solid var(--borda); padding:10px 14px; text-align:left !important; }
  .rolagem table tbody td:last-child { border-bottom:0; }
  .rolagem table tbody td::before { content:attr(data-rot); flex:none; width:40%;
    font-size:var(--txt-xs); font-weight:800; text-transform:uppercase; letter-spacing:.04em;
    color:var(--txt2); }
  .rolagem table tbody td[data-rot=""] { justify-content:flex-end; }
  .rolagem table tbody td[data-rot=""]::before { display:none; }
  .acoes-linha { opacity:1; }
}

/* ---------------- paginação ---------------- */
.paginacao { display:flex; align-items:center; gap:var(--esp-2); }
.paginacao .pagina-info { color:var(--txt2); font-size:var(--txt-sm); }
