/* =============================================================================
   AQBR_DashOnLine — sistema visual do dashboard
   =============================================================================
   Ritmo de 8 px, escala tipografica real e cor com significado. A paleta vem
   das medidas HTML do Power BI (plan/07), aplicada com mais parcimonia: o azul
   estrutura; laranja e verde ficam RESERVADOS para desconto e variacao.

   O par azul/laranja das barras foi validado para daltonismo antes de entrar:
   DeltaE 22,8 em protanopia e 31,2 em visao normal, acima dos pisos exigidos.
   ========================================================================== */
:root {
  --tinta:      #16202e;   /* texto primario */
  --tinta-2:    #5a6b7f;   /* secundario     */
  --tinta-3:    #8b98a8;   /* rotulos, eixos */
  --linha:      #e5e9ef;
  --superficie: #ffffff;
  --pagina:     #f7f8fa;

  --serie-liquida:  #2b6cb0;
  --serie-desconto: #dd6b20;
  --serie-fraca:    #a9c8e8;   /* meses anteriores, recuados */
  --acento:         #2b6cb0;   /* numero heroi */
  --trilho:         #eef2f7;

  /* Status — RESERVADO. Nunca vira "serie 3": se o verde de "positivacao boa"
     aparecer tambem como cor de dado, o semaforo deixa de significar algo.
     Todos conferidos com 4,5:1 sobre o cartao, porque aqui a cor vira TEXTO. */
  --bom:     #2f855a;   /* 4,54:1 */
  --atencao: #a16207;   /* 4,92:1 — o #b7791f anterior dava 3,64:1 e reprovava */
  --ruim:    #c53030;   /* 5,47:1 */

  /* ⚠️ EXCECAO CONSCIENTE a reserva declarada logo acima, a pedido do Rafael em
     13/08/2026: a comissao recebida na tabela de parcelas sai em VERDE.
     Token PROPRIO, e nao `--bom`, por dois motivos. Primeiro, para a reserva
     continuar verdadeira: se um dia o verde do semaforo mudar, o dado nao muda
     junto. Segundo, para quem ler depois ver que foi DECIDIDO, e nao que alguem
     gastou a cor de status por descuido.
     O que torna a excecao segura: aqui o verde e da COLUNA INTEIRA e nunca
     varia, entao nao ha o que ler como sinal — e naquela tabela nao existe
     nenhum selo de variacao com que confundir. Mesmo hex do `--bom` DE
     PROPOSITO: dois verdes diferentes seriam pior que um verde reaproveitado.
     Contraste medido sobre o cartao: 4,54:1 no claro, 6,65:1 no escuro. */
  --serie-comissao: #2f855a;

  /* Baixas de contas a pagar. Hue PROPRIA e usada em UM lugar so: as faixas da
     barra de baixas por dia. Nao e serie nem status — todos os segmentos sao a
     mesma coisa (um documento pago), e quem os separa e o VAO, nao a cor.
     Validada com o validador de paleta contra a superficie do cartao:
     banda de luminosidade, piso de croma e 3:1 de contraste, nos dois temas. */
  /* As OITO matizes das baixas, na ORDEM VALIDADA. A ordem nao e cosmetica: e
     ela que garante a separacao entre vizinhos na pilha, e por isso os
     segmentos sao desenhados NESTA sequencia, nao por valor.
     Medido contra a superficie do cartao: banda de luminosidade PASSA, piso de
     croma PASSA, separacao em daltonismo pior par 9,1 (protan) e visao normal
     pior par 19,6 — os dois acima do piso.
     ⚠️ Em ordem ARBITRARIA elas reprovam feio: vermelho x laranja da 7,1 em
     visao NORMAL, "dificil de distinguir mesmo com visao de cores completa".
     Quem mantem isso de pe e a ordenacao por slot. */
  --baixa-1: #2a78d6;   /* azul     */
  --baixa-2: #eb6834;   /* laranja  */
  --baixa-3: #1baf7a;   /* aqua     */
  --baixa-4: #eda100;   /* amarelo  */
  --baixa-5: #e87ba4;   /* magenta  */
  --baixa-6: #008300;   /* verde    */
  --baixa-7: #4a3aa7;   /* violeta  */
  --baixa-8: #e34948;   /* vermelho */
  /* Do 9o fornecedor do dia em diante. Cinza de propriedade, nao uma 9a matiz:
     gerar a nona e o jeito conhecido de produzir duas cores indistinguiveis. */
  --baixa-outros: #8b98a8;

  /* Matriz cliente x marca: escala sequencial de um hue so. O JS le daqui para
     nao ter cor cravada no codigo. */
  --matriz-rgb:   43,108,176;
  --matriz-forte: #ffffff;    /* tinta sobre celula saturada */

  /* Pares do grafico de 6 meses. Cada dupla e ORDINAL, nao categorica: o
     subtotal esta contido no bruto, e a liquida na bruta. Por isso sao dois
     passos do MESMO hue, e nao duas cores — luminosidade codifica "parte de".
     Validados: monotonos, com salto de L suficiente e com o passo claro acima
     do piso de 2:1 contra a superficie. */
  --par-a-fraco:  #8dbde1;   /* vendas: total bruto      (2,00:1) */
  --par-a-forte:  #2b6cb0;   /* vendas: subtotal         (5,42:1) */
  --par-b-fraco:  #e9a87c;   /* comissao: bruta          (2,03:1) */
  --par-b-forte:  #dd6b20;   /* comissao: liquida        (3,39:1) */

  /* Cores de vendedor no mapa — as 9 da medida `Cor do Vendedor` do Power BI,
     por NOME, para a diretoria reconhecer o mesmo codigo de cores do relatorio
     que ja usa. Decisao do Rafael em 12/08/2026.

     ⚠️ ELA REPROVA no validador de daltonismo, e o numero esta aqui para quem
     vier depois nao "consertar" sem saber: SHYRLEI x JEAN dao DeltaE 7,2 em
     visao NORMAL (o piso e 15) e 0,7 em protanopia — a mesma cor. SILVANA x
     SHYRLEI, 1,8 em deuteranopia. E o SWITCH do DAX nomeia 9 vendedores
     enquanto a API devolve 25; os outros 16 dividem o cinza.

     Por isso a cor NUNCA anda sozinha no mapa: cada bolha leva tambem um anel
     proprio (cheio, tracejado, pontilhado), a dica nomeia o vendedor e a
     legenda isola com um clique. O anel separa ate impresso em preto e branco. */
  --vend-1: #2b6cb0;   /* CLAUDIO */
  --vend-2: #2f855a;   /* DANILO  */
  --vend-3: #d69e2e;   /* DTR     */
  --vend-4: #805ad5;   /* HUGO    */
  --vend-5: #dd6b20;   /* JEAN    */
  --vend-6: #d53f8c;   /* LIANE   */
  --vend-7: #319795;   /* MARX    */
  --vend-8: #b7791f;   /* SHYRLEI */
  --vend-9: #e53e3e;   /* SILVANA */
  --vend-outros: #718096;

  --e1: 8px; --e2: 16px; --e3: 24px; --e4: 32px;
  --raio: 8px;

  /* O FATOR DE CORPO DE LETRA DA TELA DE METAS — 1 aqui, de proposito.

     ⚠️ O valor neutro mora no `:root` para que todo `calc(Npx * var(--f-metas))`
     deste arquivo devolva EXATAMENTE `Npx` em qualquer lugar que nao seja um
     cartao de Metas. Varias das regras que ele multiplica (`.meta-mes-tag`,
     `.meta-rodape`, `.meta-porteiro`) nao estao presas ao seletor do cartao e
     poderiam ser reusadas noutra tela; sem este 1 elas cairiam num `calc`
     invalido — e `font-size` invalida nao da erro, so herda o tamanho do pai.
     Regra que nao alcanca nao da erro, so nao acontece: aqui o risco e o
     gemeo, uma regra que alcanca com o valor errado.

     Quem sobe o numero e `.cartao-metas`, uma vez so. Ver a secao "O CORPO DE
     LETRA DOS CARTOES DE METAS", mais abaixo. */
  --f-metas: 1;

  /* Largura util do painel. Era 1240px fixo, o que sobrava margem demais nas
     laterais — a queixa do Rafael em 2026-08-11. Agora sao ~20% a mais, e o
     `min()` faz a tela menor tambem aproveitar: num notebook de 1366 px o
     conteudo ocupa 95vw em vez de parar em 1240. */
  --largura: min(1490px, 95vw);
  --sombra: 0 1px 2px rgba(16,32,52,.05), 0 1px 3px rgba(16,32,52,.04);
}

/* =============================================================================
   TEMA ESCURO — paleta sugerida pelo Rafael, cada cor no papel que ela aguenta
   =============================================================================
   NAO e o tema claro invertido. Cada tom foi validado contra o fundo escuro; a
   banda de luminosidade exigida no escuro (L 0,48–0,67) e mais estreita que a
   do claro, entao azuis "bonitos e claros" reprovam como marca de dado.

   Onde cada cor da paleta caiu, e por que:
     Deep Navy      #091540  fundo da pagina
     Persian Blue   #1B2CC1  barra do topo e cabecalho do login (branco 9,65:1)
     Cornflower     #7692FF  serie primaria — escurecido 4% para entrar na banda
     Icy Blue       #ABD2FA  numero heroi e anel de foco (11,17:1 sobre o fundo)
     Dusk Blue      #3D518C  bordas; clareado a #4F66AF quando vira marca, porque
                             puro dava 2,31:1 e o piso de marca e 3:1

   O laranja NAO saiu da paleta azul de proposito: o painel precisa de duas
   series distinguiveis (liquida x descontado) e dois azuis nao carregam essa
   distincao — muito menos em daltonismo. Burnt Orange #CC5500, o 01 da paleta
   de laranjas, passou em tudo: DeltaE 29,1 em deuteranopia, 31,1 em normal.
   ========================================================================== */
:root[data-tema="escuro"] {
  --tinta:      #eaf1fb;   /* 15,49:1 — AAA */
  --tinta-2:    #9fb3d9;   /*  8,32:1 — AAA */
  --tinta-3:    #7286b5;   /*  4,86:1 — AA  */
  --linha:      #263573;
  --superficie: #101b52;
  --pagina:     #091540;

  --serie-liquida:  #718cf5;
  --serie-desconto: #cc5500;
  --serie-fraca:    #4f66af;   /* 3,23:1 sobre a pagina */
  --acento:         #abd2fa;
  --trilho:         #16225e;

  --bom:     #48bb78;   /* 6,65:1 */
  --atencao: #ecc94b;   /* 10,01:1 */
  --ruim:    #fc8181;   /* 6,61:1 */
  --serie-comissao: #48bb78;   /* 6,65:1 sobre #101b52 */
  /* ⚠️ Os degraus do escuro sao ESCOLHIDOS, nao clareados por conta — a banda do
     escuro e mais estreita (L 0,48-0,67) e cor clara e bonita reprova nela.
     Validados como CONJUNTO contra #101b52: banda PASSA, croma PASSA,
     contraste PASSA nas oito, pior par 8,4 em daltonismo e 19,3 em visao
     normal. */
  --baixa-1: #3987e5;
  --baixa-2: #d95926;
  --baixa-3: #199e70;
  --baixa-4: #c98500;
  --baixa-5: #d55181;
  --baixa-6: #008300;
  --baixa-7: #9085e9;
  --baixa-8: #e66767;
  --baixa-outros: #5a6b7f;

  --matriz-rgb:   113,140,245;
  --matriz-forte: #091540;

  /* No escuro a escada inverte: "forte" passa a ser o mais CLARO, porque e o
     que se destaca do fundo. Validados contra o cartao #101b52. */
  --par-a-fraco:  #3f5599;   /* 2,28:1 */
  --par-a-forte:  #8fa6f8;   /* 6,90:1 */
  --par-b-fraco:  #a4571b;   /* 3,04:1 */
  --par-b-forte:  #f0954a;   /* 7,00:1 */

  /* Vendedores no escuro: o MESMO tom, um passo mais claro. A identidade e o
     que o Rafael escolheu preservar ("CLAUDIO e azul"), mas as cores do Power
     BI foram feitas para fundo branco — o #2b6cb0 do CLAUDIO da 2,98:1 sobre
     este fundo, ou seja, some. Todas as dez conferidas: >= 3:1 contra #101b52. */
  --vend-1: #5588d0;
  --vend-2: #3d9a72;
  --vend-3: #b8933c;
  --vend-4: #9276d8;
  --vend-5: #c96d37;
  --vend-6: #d55e9b;
  --vend-7: #3aa8a6;
  --vend-8: #a87c34;
  --vend-9: #e05f5f;
  --vend-outros: #7d8da3;

  /* Sombra clara nao existe no escuro: profundidade vem de escurecer o vao. */
  --sombra: 0 1px 2px rgba(0,0,0,.45), 0 2px 6px rgba(0,0,0,.30);

  /* Tokens do estilo.css (login e menu), remapeados. */
  --fundo:   #091540;
  --borda:   #263573;
  --texto:   #eaf1fb;
  --suave:   #9fb3d9;
  --ambar:   #ecc94b;
}

/* O gradiente do topo usa Deep Navy -> Persian Blue. Herdar o do tema claro
   deixaria uma faixa azul-clara com texto branco por cima — ilegivel. */
:root[data-tema="escuro"] .topo,
:root[data-tema="escuro"] .cartao > header {
  background: linear-gradient(135deg, #091540, #1b2cc1);
}
:root[data-tema="escuro"] .cartao { background: var(--superficie); }
:root[data-tema="escuro"] input,
:root[data-tema="escuro"] .filtros-mestres select,
:root[data-tema="escuro"] .filtros-mestres input[type=date] {
  background: #0c1747; color: var(--tinta); border-color: var(--linha);
}
/* O azul da serie e claro demais para carregar texto branco: no escuro o botao
   inverte — fundo claro, letra do fundo da pagina. */
:root[data-tema="escuro"] button { background: var(--serie-liquida); color: #091540; }
:root[data-tema="escuro"] button:hover:not(:disabled) { background: var(--acento); }
:root[data-tema="escuro"] .secundario { background: none; color: var(--tinta-2); }
:root[data-tema="escuro"] .secundario:hover:not(:disabled) { background: none; color: var(--acento); }
:root[data-tema="escuro"] .topo button { background: rgba(255,255,255,.16); color: #fff; }
:root[data-tema="escuro"] .topo button:hover:not(:disabled) { background: rgba(255,255,255,.26); }
:root[data-tema="escuro"] .pagina { background: var(--superficie); color: var(--tinta); }
:root[data-tema="escuro"] .segredo { background: #0c1747; }
:root[data-tema="escuro"] .aviso.erro { background: #3a1220; color: #fed7d7; border-color: var(--ruim); }
:root[data-tema="escuro"] .aviso.info { background: #0e1d5e; color: var(--acento); border-color: var(--serie-liquida); }
/* O QR precisa de fundo branco SEMPRE: e imagem em preto sobre branco, e o
   leitor do celular nao decodifica invertido. */
:root[data-tema="escuro"] .qr { background: #fff; }
:root[data-tema="escuro"] .tabela tbody tr:hover { background: #16225e; }
:root[data-tema="escuro"] .tabela td { border-bottom-color: #1a2760; }
:root[data-tema="escuro"] .kpi.heroi {
  background: linear-gradient(180deg, #12205c, #0d1a4e); border-color: #2c3d80;
}
:root[data-tema="escuro"] .filtros-mestres { background: rgba(9,21,64,.92); }

/* Botao de alternar tema — quadrado, discreto, ao lado de "Sair". */
.btn-tema {
  width: auto; padding: .4rem .7rem; font-size: .95rem; line-height: 1;
  background: rgba(255,255,255,.15);
}
.btn-tema:hover:not(:disabled) { background: rgba(255,255,255,.25); }

body.dash { background: var(--pagina); color: var(--tinta); }

/* O titulo da pagina alinha com os titulos das secoes. So no painel: no menu a
   barra continua colada na borda, como barra de aplicativo. */
body.dash .topo {
  padding-left:  calc(max(0px, (100% - var(--largura)) / 2) + var(--e3));
  padding-right: calc(max(0px, (100% - var(--largura)) / 2) + var(--e3));
}

/* ---------------------------------------------- filtros mestres (sticky) --
   Fixos ao rolar: numa pagina com cinco secoes, perder de vista qual periodo
   esta selecionado e facil — e caro, porque o numero continua fazendo sentido. */
.filtros-mestres {
  position: sticky; top: 0; z-index: 20;
  background: rgba(255,255,255,.93);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--linha);
  /* A FAIXA atravessa a tela, mas o CONTEUDO alinha com o das secoes. Sem isto
     o filtro de periodo ficava colado na borda enquanto os titulos comecavam
     bem mais para dentro — desalinho que a largura maior so faria crescer.
     A conta reproduz a margem automatica da secao e soma o padding dela. */
  padding: 10px calc(max(0px, (100% - var(--largura)) / 2) + var(--e3));
  display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
}
.filtros-mestres .campo { display: flex; align-items: center; gap: 7px; }
.filtros-mestres .campo > span {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--tinta-3);
}

/* O PERÍODO SELECIONADO não é um rótulo — é a resposta a "o que estou vendo?".
   Ele nasceu dentro de `.campo > span` e herdou estilo de rótulo por acidente
   do HTML: 10,5 px, maiúsculas forçadas e a tinta mais fraca das três. Fica ao
   lado de nomes de campo, mas não é um deles.

   Aumentado a pedido do Rafael em 14/08/2026 ("está muito pequeno"), e junto
   saiu o `text-transform`, que transformava "Agosto/2026" em "AGOSTO/2026" —
   caixa alta forçada é mais lenta de ler, e o texto já vem do JS com a caixa
   certa. A cor sobe para a tinta principal pelo mesmo motivo: conteúdo, e não
   legenda.

   ⚠️ 17px por posição na escada, não por gosto: acima do título de cartão (13)
   e abaixo do título de seção (23). Passar de 23 acharia a escada que o
   `testar_css.mjs` guarda — quem manda na tela continua sendo o número. */
#rotulo-periodo, #g-rotulo-periodo {
  font-size: 17px; font-weight: 650; letter-spacing: -.01em;
  text-transform: none; color: var(--tinta);
}
.filtros-mestres select,
.filtros-mestres input[type=date] {
  width: auto; margin: 0; padding: 6px 10px; font: inherit; font-size: 13px;
  border: 1px solid var(--linha); border-radius: 6px; background: #fff;
  color: var(--tinta); transition: border-color .15s, box-shadow .15s;
}
.filtros-mestres select:focus, .filtros-mestres input:focus {
  border-color: var(--serie-liquida);
  box-shadow: 0 0 0 3px rgba(43,108,176,.13); outline: none;
}
.atalhos { display: flex; gap: 4px; }
.atalhos button {
  width: auto; padding: 6px 12px; font: inherit; font-size: 12.5px; font-weight: 500;
  background: transparent; color: var(--tinta-2);
  border: 1px solid var(--linha); border-radius: 6px; transition: all .15s;
}
.atalhos button:hover:not(:disabled) { background: #fff; color: var(--tinta); border-color: #cfd8e3; }
.atalhos button[aria-pressed=true] {
  background: var(--serie-liquida); border-color: var(--serie-liquida); color: #fff;
}
.periodo-livre { display: none; gap: 7px; align-items: center; }
.periodo-livre.aberto { display: flex; }
/* Aviso de periodo invertido, ao lado dos campos. Cor de erro porque e erro de
   entrada, nao dado. */
/* A barra de período desligada, nas páginas que não recortam por data. O
   cinza é o mesmo da aba desabilitada — a tela já usa esse sinal para dizer
   "isto não se aplica aqui". */
.filtros-mestres.inerte { opacity: .55; }
.filtros-mestres.inerte #aqt-rotulo-periodo { font-style: italic; }
.aqt-aviso-per:not(:empty) { font-size: 11px; color: var(--ruim); font-weight: 600;
                             max-width: 210px; line-height: 1.2; }

/* O icone de calendario do campo de data e desenhado pelo navegador, sempre
   preto: no tema escuro ele some contra o fundo. `invert` e a unica forma de
   recolori-lo — nao ha propriedade de cor para esse pseudo-elemento. */
input[type=date]::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .65; }
input[type=date]::-webkit-calendar-picker-indicator:hover { opacity: 1; }
:root[data-tema="escuro"] input[type=date]::-webkit-calendar-picker-indicator {
  filter: invert(1) brightness(1.8);
  opacity: .8;
}

/* ------------------------------------------------------------- secoes --- */
.secao { max-width: var(--largura); margin: 0 auto; padding: var(--e4) var(--e3) 0; }
.secao > header { margin-bottom: var(--e2); }
/* 23px = os 19px originais +20%, pedido em 12/08/2026 para as divisoes de
   secao saltarem mais. Sao os nomes das abas do Power BI, e e por eles que o
   Rafael se localiza na pagina longa.
   A hierarquia continua de pe e ate melhora: 23 (secao) > 13 (titulo de cartao)
   com o numero heroi em 26. Titulo de secao competindo com o numero heroi seria
   ruim; 23 fica abaixo dele.
   Os tres numeros sao lidos por admin/testar_css.mjs, que confere a ESCADA
   inteira — nao adianta so o titulo crescer se ele passar o numero heroi. */
.secao h2 { margin: 0; font-size: 23px; font-weight: 650; letter-spacing: -.01em; }
.secao .sub { margin: 3px 0 0; font-size: 13px; color: var(--tinta-3); }

/* ------------------------------------------------------------------ KPIs --
   Um numero heroi por vista; os demais recuam. Quatro cartoes com o mesmo peso
   nao destacam nada — que e o problema do painel atual. */
/* 190 px, nao 215: com o heroi ocupando dois cartoes sao SETE espacos para seis
   KPIs, e em 1442 px de conteudo so cabem sete colunas se cada uma couber em
   192 px. Com 215 cabiam seis, e o ultimo cartao caia sozinho numa segunda
   linha — orfao pior que o problema que se estava resolvendo. */
.kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--e2); margin-bottom: var(--e3);
}
/* Painel do Vendedor e Desempenho: os SETE cartões numa faixa só.
   `auto-fit` decide sozinho quantas colunas cabem e, na tela do Rafael, decidiu
   seis — o sétimo caía sozinho embaixo. Aqui o número de colunas é declarado,
   não negociado.
   As proporções são as do relatório (`1fr 1fr 1fr` e depois `0.85fr`): os três
   cartões de dinheiro carregam "R$ 11.521.251,85" e precisam de mais espaço que
   os quatro de contagem.
   ⚠️ `minmax(0, …)` e não `1fr` puro: item de grid tem `min-width: auto`, e sem
   isso o cartão do valor mais comprido empurraria os outros para fora.

   ⚠️ A GERENCIAL SAIU DAQUI EM 03/09/2026, e a tentativa de mantê-la junto é o
   que provou por que ela tinha de sair. Ao ganhar o oitavo cartão ela precisou
   de um degrau em 1500 px; mexer nele AQUI derrubou o Painel e o Desempenho
   para duas linhas em 1440, 1366 e 1280 — duas telas que estavam boas, e que
   não têm nada com o assunto. Sete cartões e oito cartões não cabem na mesma
   regra. Ver `.kpis.linha-oito`. */
.kpis.linha-unica {
  grid-template-columns:
    repeat(3, minmax(0, 1fr)) repeat(4, minmax(0, 0.85fr));
}
/* Sete colunas abaixo de ~1250 px viram sete colunas ilegíveis. Cai para
   quatro e depois para duas — nunca para uma, que faria a página inteira
   virar uma pilha de cartões. */
@media (max-width: 1250px) {
  .kpis.linha-unica { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .kpis.linha-unica { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* A faixa de OITO da Gerencial — 03/09/2026, quando entrou `Contabilizado no
   ano` e o `Acumulado do ano` virou `Vendas acum. no ano`. São QUATRO
   cartões de dinheiro (mês e ano, vendas e contabilizado) e quatro de contagem.

   ⚠️ GRADE PRÓPRIA, e não a de sete com um cartão a mais. Mesma decisão que a
   faixa de 26/08 (`linha-quatro`) já tinha tomado, e desta vez com a prova: a
   primeira tentativa cresceu a `linha-unica` e derrubou o Painel e o Desempenho
   de Vendas para duas linhas em 1440, 1366 e 1280 px — medido no Chrome, sete
   checagens vermelhas em telas que ninguém tinha tocado. **Classe compartilhada
   é acoplamento silencioso: a mudança certa para uma tela é a errada para a
   outra, e o CSS não avisa.**

   `0.75fr` nas contagens, e não `0.85fr` como na de sete: com QUATRO cartões de
   dinheiro em vez de três, os 0,10 fr que saem de cada contagem levam a folga
   do maior valor de 8 px para 16 px. As contagens carregam "271" e "788" e não
   sentem; os valores sentem. */
.kpis.linha-oito {
  grid-template-columns:
    repeat(4, minmax(0, 1fr)) repeat(4, minmax(0, 0.75fr));
}
/* ⚠️ 1500 px, e o número saiu de MEDIÇÃO, não de gosto. Com oito colunas o
   cartão de dinheiro cai para ~190 px, e o Chrome mediu a folga do maior valor
   ("R$ 12.785.481,50", o acumulado do ano) assim:

       ≥ 1570 px .... 16 px de folga     (a largura satura em --largura)
         1440 px ....  0 px
         1366 px ....  0 px
         1280 px .... −6 px com 0.85fr — VAZAVA, com a contagem de linhas VERDE

   Zero de folga passa no teste e quebra na primeira fonte diferente. Acima do
   degrau os oito cabem com margem; abaixo dele viram DUAS LINHAS CHEIAS de
   quatro — que com oito cartões fecha exato, sem o órfão de três que sete
   cartões deixavam. Depois cai para duas colunas, nunca para uma. */
@media (max-width: 1500px) {
  .kpis.linha-oito { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .kpis.linha-oito { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* A faixa de 26/08/2026 — vendas × contabilizações, do dia e do período.
   ⚠️ GRADE PRÓPRIA, e não os 11 cartões dentro de `.linha-unica`. Aquela
   declara sete colunas com larguras DESIGUAIS (`1fr 1fr 1fr` e depois
   `0.85fr`), pensadas para três cartões de dinheiro e quatro de contagem:
   quatro cartões novos caindo nas colunas 1 a 4 sairiam com a quarta mais
   estreita que as outras três, sem nada explicando por quê. Aqui os quatro
   são de dinheiro e valem o mesmo, então as colunas são iguais.
   E é a MESMA grade de sete que quebrou a linha da Gerencial em 13/08/2026 —
   não se mexe nela para acrescentar cartão. */
.kpis.linha-quatro { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Quatro cartões de moeda longa não cabem legíveis abaixo de ~1000 px: dois
   por linha, e nunca um só — a faixa inteira viraria uma pilha. */
@media (max-width: 1000px) {
  .kpis.linha-quatro { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* O rótulo da faixa. Existe porque dois dos quatro cartões IGNORAM o filtro
   de datas, logo abaixo de sete que o seguem — sem dizer isso, um número que
   não muda ao trocar o mês é indistinguível de um defeito. Recuado como
   legenda: é procedência, não dado. */
.kpis-titulo {
  font-size: 12px; color: var(--tinta-3); margin: 0 0 var(--e1);
  line-height: 1.4;
}
.kpis-titulo b { color: var(--tinta-2); font-weight: 600; }

.kpi {
  background: var(--superficie); border: 1px solid var(--linha);
  border-radius: var(--raio); padding: var(--e2) var(--e2) 14px;
  box-shadow: var(--sombra);
}
.kpi .rotulo {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--tinta-3); margin-bottom: 7px;
}
/* Figuras PROPORCIONAIS aqui: tabular-nums daria a cada digito a largura de um
   zero, e o numero ficaria frouxo neste tamanho. Tabular so em coluna. */
.kpi .valor { font-size: 26px; font-weight: 640; letter-spacing: -.02em; line-height: 1.05; }
/* Escada de tamanho por comprimento do numero — quem decide a classe e o JS.
   Os valores saem do cartao mais ESTREITO possivel (190 px, sobrando 158 px de
   conteudo): se cabe ali, cabe em qualquer largura.
   A classe fica no GRUPO, para os cartoes vizinhos nao ficarem com corpos
   diferentes; o heroi e o unico que decide sozinho. */
.kpis.longo       .kpi:not(.heroi) .valor { font-size: 22px; }
.kpis.muito-longo .kpi:not(.heroi) .valor { font-size: 19px; }
.kpi .contexto { font-size: 12px; color: var(--tinta-3); margin-top: 6px; }
.kpi.heroi { background: linear-gradient(180deg,#fbfdff,#f3f8ff); border-color: #d9e8f7; }
.kpi.heroi .valor { font-size: 32px; color: var(--acento); }
.kpi.heroi .valor.longo       { font-size: 26px; }
/* 19, nao 22: num monitor de 1366 o cartao do heroi fica com 195 px, e
   "R$ 11.446.111,85" — o faturamento da empresa no ano — vazava 9 px a 22.
   Aqui o heroi perde o corpo maior, mas continua distinto pela cor e pelo
   fundo; numero cortado seria pior que numero menor. */
.kpi.heroi .valor.muito-longo { font-size: 19px; }

/* Com espaco de sobra, o numero principal ocupa DOIS cartoes: ele volta a ter
   presenca de heroi e deixa de precisar encolher.
   1560 px nao e um numero redondo escolhido a esmo — e onde passam a caber SETE
   colunas de 190. Abaixo disso, seis KPIs com o heroi valendo dois dariam sete
   espacos em seis colunas, e o ultimo cartao quebraria a linha. Um 1366 ou um
   1440 ficariam PIORES do que sem heroi largo. */
@media (min-width: 1560px) {
  .kpi.heroi { grid-column: span 2; }
  .kpi.heroi .valor,
  .kpi.heroi .valor.longo,
  .kpi.heroi .valor.muito-longo { font-size: 34px; }
}
/* ⚠️ Na faixa única o herói NÃO ocupa dois cartões.
   Este é o defeito que foi à tela do Rafael em 13/08/2026: sete cartões com o
   herói valendo dois pedem OITO espaços numa grade de sete, e o último quebra
   a linha. Da tela, parecia que a regra de sete colunas não tinha pegado — e
   eu culpei o cache do navegador antes de conferir o herói.
   Vem depois do @media de propósito, e com quatro classes no seletor: a regra
   de 34px lá em cima tem três, e empate de especificidade se decide pela ordem.
   O herói continua distinto pela cor e pelo fundo, que é o que ele tem de
   fazer; largura dobrada não cabe em sete colunas. */
/* ⚠️ AS DUAS FAIXAS, e não só a de sete. O herói não pode valer dois espaços
   numa grade de colunas declaradas — foi exatamente isso que quebrou a linha da
   Gerencial em 13/08/2026 (sete colunas recebendo oito unidades). A faixa de
   oito herda a mesma regra pelo mesmo motivo; esquecer o seletor aqui não daria
   erro nenhum, só o defeito de volta. */
.kpis.linha-unica .kpi.heroi,
.kpis.linha-oito  .kpi.heroi                    { grid-column: auto; }
.kpis.linha-unica .kpi.heroi .valor,
.kpis.linha-oito  .kpi.heroi .valor             { font-size: 26px; }
.kpis.linha-unica .kpi.heroi .valor.longo,
.kpis.linha-oito  .kpi.heroi .valor.longo       { font-size: 22px; }
.kpis.linha-unica .kpi.heroi .valor.muito-longo,
.kpis.linha-oito  .kpi.heroi .valor.muito-longo { font-size: 19px; }

.kpi.negativo .valor { color: var(--serie-desconto); }

/* ---------------------------------------------------------------- cartao - */
.cartao-dados {
  background: var(--superficie); border: 1px solid var(--linha);
  border-radius: var(--raio); box-shadow: var(--sombra); margin-bottom: var(--e3);
}
.cartao-dados > header {
  padding: 10px var(--e2); border-bottom: 1px solid var(--linha);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e2); flex-wrap: wrap;
}
.cartao-dados > header h3 { margin: 0; font-size: 13px; font-weight: 650; }

/* Botão de ação no cabeçalho do cartão.
   ⚠️ Precisa anular `width: 100%` e `margin-top`, que vêm do `button` do
   formulário de login (estilo.css). Sem isso ele ocupa a linha inteira e
   empurra a si mesmo para baixo dos filtros — foi exatamente o que aconteceu
   com o "Exportar para Excel", que virou uma segunda linha no cabeçalho. */
/* ⚠️ `.filtros-locais .acao` entrou em 03/09/2026 com a tela de Descontos, e
   NAO e enfeite: `estilo.css` da `width: 100%` a todo <button>, e ate aqui o
   `.acao` so era desfeito dentro de um <header> de cartao. O botao "Limpar" da
   barra de filtros nasceu ocupando a LARGURA INTEIRA da tela — regra de estilo
   que nao alcanca nao da erro, so nao acontece.
   Conferido por grep antes de ampliar o seletor: nenhuma outra tela tem `.acao`
   dentro de `.filtros-locais`, entao isto nao muda nada do que ja existe. */
.cartao-dados > header .acao,
.filtros-locais .acao {
  width: auto; margin: 0; padding: 6px 12px;
  font: inherit; font-size: 12.5px; font-weight: 500;
  background: transparent; color: var(--tinta-2);
  border: 1px solid var(--linha); border-radius: 6px; transition: all .15s;
}
.cartao-dados > header .acao:hover:not(:disabled),
.filtros-locais .acao:hover:not(:disabled) {
  background: var(--serie-liquida); border-color: var(--serie-liquida); color: #fff;
}
.cartao-dados .conteudo { padding: var(--e2); }

/* filtros locais: no cabecalho da propria secao, refinando so o que esta abaixo */
.filtros-locais { display: flex; gap: var(--e1); flex-wrap: wrap; align-items: center; }
.filtros-locais input, .filtros-locais select {
  width: auto; margin: 0; padding: 5px 9px; font: inherit; font-size: 12.5px;
  border: 1px solid var(--linha); border-radius: 6px;
}
.filtros-locais input { width: 150px; }
/* Rótulo e campo como uma peça só, para a quebra de linha nunca separá-los.
   ⚠️ `inline-flex` e não `flex`: dentro de uma flex-container, um filho `flex`
   viraria bloco e quebraria a linha sozinho — o oposto do que se quer. */
.filtros-locais .par-filtro {
  display: inline-flex; align-items: center; gap: var(--e1); white-space: nowrap;
}
.filtros-locais input:focus, .filtros-locais select:focus {
  border-color: var(--serie-liquida);
  box-shadow: 0 0 0 3px rgba(43,108,176,.13); outline: none;
}

/* --------------------------------------------------------------- legenda -
   Sempre presente com duas ou mais series: identidade nunca depende so da cor. */
.legenda { display: flex; gap: var(--e2); font-size: 12px; color: var(--tinta-2); }
.legenda span { display: inline-flex; align-items: center; gap: 6px; }
.legenda i { width: 10px; height: 10px; border-radius: 2px; }

/* ---------------------------------------------------------------- barras -
   Marca fina (20 px), extremidade arredondada no fim do dado e reta na base.
   O vao entre os segmentos e feito com a COR DA SUPERFICIE, nunca com borda:
   borda adiciona tinta que nao e dado. */
.barras { display: flex; flex-direction: column; gap: 10px; }
.barra { display: grid; grid-template-columns: 200px 1fr 165px; align-items: center; gap: var(--e2); }
.barra .nome {
  font-size: 12.5px; color: var(--tinta-2); text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.barra .trilho { position: relative; height: 20px; background: var(--trilho); border-radius: 4px; }
.barra .seg { position: absolute; top: 0; height: 20px; transition: width .2s ease; }
.barra .liq   { left: 0; background: var(--serie-liquida); border-radius: 4px 0 0 4px; }
.barra .desc  { background: var(--serie-desconto); border-radius: 0 4px 4px 0;
                box-shadow: -2px 0 0 var(--superficie); }
.barra .unico { border-radius: 4px; }
.barra .valores { font-size: 12.5px; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.barra .valores b { font-weight: 600; }
.barra .valores small { display: block; color: var(--tinta-3); font-size: 11px; }
.barra:hover .trilho { box-shadow: 0 0 0 3px rgba(43,108,176,.08); }

/* --------------------------------------------------------------- tabela -
   Numeros em coluna usam tabular-nums e alinhamento a direita: e o detalhe que
   mais separa um painel profissional de um amador. */
.rolagem { overflow-x: auto; }
/* Rolagem VERTICAL dentro da tabela, com o cabecalho grudado no topo. Serve
   para listas que precisam sair inteiras sem esticar a pagina — hoje a de
   comissao por cliente, que num ano passa de 500 linhas.
   O fundo do <th> precisa ser opaco: sem ele as linhas passariam por baixo do
   cabecalho enquanto rolam.

   Altura: 500 px. Era 384, e o Rafael pediu 30% a mais para ver mais linhas de
   uma vez (384 x 1,3 = 499,2). Vale para as tres tabelas rolaveis — comissao
   por cliente, parcelas recebidas e clientes do periodo. Se mudar aqui, mudar
   tambem a checagem em admin/testar_comissao.mjs, que le este numero. */
.rolagem.alta { max-height: 500px; overflow-y: auto; }
.rolagem.alta thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--superficie); box-shadow: 0 1px 0 var(--linha);
}
/* A linha TOTAL gruda embaixo pelo mesmo motivo do cabecalho em cima: numa
   lista de 561 clientes ela ficaria a 500 linhas de distancia do que se esta
   olhando. As bordas viram box-shadow porque, com `border-collapse: collapse`,
   a borda pertence a celula colapsada e rola junto — some justamente no
   elemento fixo. */
.rolagem.alta tfoot td {
  position: sticky; bottom: 0; z-index: 1;
  background: var(--superficie); box-shadow: 0 -2px 0 var(--linha);
}
.tabela { width: 100%; border-collapse: collapse; }
/* Largura declarada em tabela so vale com layout fixo — no automatico e apenas
   uma sugestao, e o navegador atende primeiro o conteudo minimo de cada
   celula. Ja custou uma rodada nas barras das marcas. */
.tabela th {
  text-align: left; font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--tinta-3);
  padding: 0 12px 10px; border-bottom: 1px solid var(--linha); white-space: nowrap;
}
.tabela th.num, .tabela td.num { text-align: right; }
.tabela th.ord { cursor: pointer; user-select: none; }
.tabela th.ord:hover { color: var(--tinta); }
.tabela th.ord::after { content: '\2195'; opacity: .3; margin-left: 4px; }
.tabela th.ord[data-dir=asc]::after  { content: '\2191'; opacity: 1; }
.tabela th.ord[data-dir=desc]::after { content: '\2193'; opacity: 1; }
.tabela td { padding: 9px 12px; font-size: 13px; color: var(--tinta-2); border-bottom: 1px solid #f2f5f9; }
.tabela td.num { font-variant-numeric: tabular-nums; color: var(--tinta); }
.tabela td.nome { color: var(--tinta); font-weight: 500; }
.tabela tbody tr:hover { background: #fafbfd; }

/* Largura declarada em tabela so vale com layout fixo — no automatico e apenas
   uma sugestao, e o navegador atende primeiro o conteudo minimo de cada
   celula. Ja custou uma rodada nas barras das marcas. */
.tabela.fixa { table-layout: fixed; }
/* Densa: linha e fonte apertadas, para caber mais cliente na mesma altura. */
.tabela.densa th { padding: 5px 8px; }
.tabela.densa td { padding: 4px 8px; font-size: 12.5px; }
.tabela.densa td.nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Compacta: um passo ANTES da densa, para a matriz cliente x marca. A densa
   apertaria 28%, e o pedido do Rafael em 12/08/2026 foi "uns 15%".
   A conta: a linha e padding + padding + 13px x 1,55 de entrelinha = 38 px.
   15% menos da 32,4; com 6 px de padding sai 32,1 — 15,7% mais baixa. A fonte
   fica em 13 px de proposito: a matriz e feita de numero, e encolher digito
   custa leitura mais rapido do que encolher espaco em branco.
   O numero e lido por admin/testar_marca.mjs; mudar aqui e mudar la. */
.tabela.compacta th { padding: 0 12px 7px; }
.tabela.compacta td { padding: 6px 12px; }
/* Parcela paga com juro de atraso: o valor pago passa da base da comissão, e
   por isso `valor × % ≠ comissão` naquela linha. O pontilhado só diz "tem
   explicação aqui" — quem conta é a dica. Cor não serve: laranja já significa
   desconto e verde/vermelho são status. */
.com-juro { border-bottom: 1px dotted var(--tinta-3); cursor: help; }
.tabela tfoot td {
  padding: 12px; font-size: 13px; font-weight: 650; color: var(--tinta);
  border-top: 2px solid var(--linha); border-bottom: 0;
}
/* ⚠️ `td.desconto`, e nao `.desconto`. A regra antiga era `.tabela .desconto`
   (0-2-0) e PERDIA de `.tabela td.num` (0-2-1), que pinta toda celula numerica
   com a tinta normal — ou seja, ela nunca valeu em lugar nenhum, porque a
   coluna de desconto e sempre numerica. Medido no navegador em 13/08/2026:
   rgb(22,32,46), a tinta comum, e nao o laranja.
   Com a mesma especificidade de `td.num`, quem vem depois no arquivo ganha —
   por isso esta regra fica AQUI, abaixo dela. */
.tabela td.desconto,
.tabela tfoot td.desconto { color: var(--serie-desconto); }
.tabela td.comissao,
.tabela tfoot td.comissao { color: var(--serie-comissao); }
.rodape-tabela { padding: 10px var(--e2); font-size: 12px; color: var(--tinta-3); border-top: 1px solid var(--linha); }

/* Aviso de tabela cortada. Nunca silencioso: se a linha TOTAL nao fecha com a
   soma da coluna, quem conferir na mao conclui — com razao — que o numero esta
   errado. Melhor dizer antes. */
.corte {
  margin: 0 var(--e2) var(--e1); padding: 9px 12px;
  background: color-mix(in srgb, var(--atencao) 12%, transparent);
  border-left: 3px solid var(--atencao);
  border-radius: 0 6px 6px 0;
  font-size: 12.5px; color: var(--tinta-2);
}
.corte b { color: var(--tinta); }

/* ------------------------------------------------- esqueleto e vazio ---- */
@keyframes pulsar { 0%,100% { opacity: .5 } 50% { opacity: .22 } }
.esqueleto { background: var(--trilho); border-radius: 4px; animation: pulsar 1.4s ease-in-out infinite; }
.esqueleto.linha { height: 13px; margin-bottom: 10px; }
.esqueleto.bloco { height: 86px; }
.vazio { padding: var(--e4); text-align: center; color: var(--tinta-3); font-size: 13.5px; }

/* -------------------------------------------- colunas pareadas (6 meses) --
   Forma copiada do painel HTML do Power BI: duas barras por mes, valor escrito
   na diagonal sobre cada uma, nome do mes e variacao contra o mes anterior
   embaixo. As cores sao as nossas.

   O rotulo na diagonal e o truque do proprio DAX: `width:0` para o texto nao
   empurrar o layout, e giro em torno de `left bottom` para ele subir a partir
   do topo da barra. Sem `width:0` cada rotulo reservaria a largura do texto
   inteiro e as barras ficariam a metros uma da outra. */
/* ⚠️ `minmax(0, 1fr)` e nao `1fr`. Item de grid nasce com `min-width: auto`, o
   que significa "nunca menor que o meu conteudo minimo". O grafico de pedidos
   por semana tem uma coluna de 34 px por semana; com um periodo de 8 meses sao
   33 semanas, ~1.400 px de conteudo minimo, e a coluna do grid INCHAVA para
   caber tudo — o cartao vazava para fora da largura da pagina em vez de rolar,
   e ainda roubava a largura do cartao vizinho (o de dia da semana ficava
   espremido).
   O `.rolagem` de dentro ja estava la, pronto para rolar; ele so nunca chegava
   a receber uma largura menor que o conteudo. `minmax(0, ...)` autoriza a
   coluna a encolher, e ai a rolagem interna finalmente entra em acao.
   Conferido por admin/testar_css.mjs. */
.par-graficos { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--e3); }
@media (max-width: 1100px) { .par-graficos { grid-template-columns: minmax(0, 1fr); } }

/* Recorte declarado dentro do cartão — a regra fechada em 12/08: todo quadro
   diz de que período ele fala. */
.sub-cartao {
  font-size: 11.5px; color: var(--tinta-3); margin: 0 0 var(--e2);
  line-height: 1.35;
}

.resumo-serie { font-size: 12px; color: var(--tinta-2); margin: 2px 0 var(--e2); }
.resumo-serie b { color: var(--tinta); font-variant-numeric: tabular-nums; }
.tend-alta  { color: var(--bom);  font-weight: 600; }
.tend-baixa { color: var(--ruim); font-weight: 600; }

.meses { display: flex; align-items: flex-end; justify-content: space-around; gap: var(--e1); }
.mes-grupo { display: flex; flex-direction: column; align-items: center; flex: 1; }
/* 200 px para 120 px de haste: os 80 px que sobram sao para o rotulo girado.
   A conta que define isso: "11.446.111" (o maior numero que este ERP produz)
   mede ~72 px deitado a 12,5 px, o que vira 72 x sen(58 graus) = 61 px de
   altura, mais a margem. Subir a fonte sem subir esta caixa cortaria o numero
   do mes mais alto — justamente o que mais interessa ler. */
.mes-par { display: flex; align-items: flex-end; gap: 6px; height: 200px; }
.mes-col { display: flex; flex-direction: column; align-items: center; justify-content: flex-end; }
.mes-col .rot {
  font-size: 12.5px; white-space: nowrap; width: 0;
  transform: rotate(-58deg); transform-origin: left bottom;
  font-variant-numeric: tabular-nums;
}
.mes-col .rot.fraco { color: var(--tinta-2); margin: 0 0 2px; }
.mes-col .rot.forte { color: var(--tinta);   margin: 0 0 9px; font-weight: 600; }
.mes-col .haste { width: 18px; border-radius: 3px 3px 0 0; min-height: 2px; }
.mes-col .haste.a-fraco { background: var(--par-a-fraco); }
.mes-col .haste.a-forte { background: var(--par-a-forte); }
.mes-col .haste.b-fraco { background: var(--par-b-fraco); }
.mes-col .haste.b-forte { background: var(--par-b-forte); }
.mes-nome { font-size: 13px; color: var(--tinta-2); margin-top: 8px; }
.mes-var  { font-size: 12px; font-weight: 600; white-space: nowrap; margin-top: 3px; }
.mes-var.alta   { color: var(--bom); }
.mes-var.baixa  { color: var(--ruim); }
.mes-var.neutra { color: var(--tinta-3); font-weight: 400; }
.mes-grupo:hover .haste { filter: brightness(1.08); }

/* ------------------------------------------- colunas simples (contagens) --
   "Pedidos por dia da semana" e "Pedidos por semana": uma barra por categoria,
   valor por cima na horizontal. Sao numeros de dois digitos, que cabem sem
   girar — girar aqui seria enfeite, nao necessidade. */
.colunas-simples { display: flex; align-items: flex-end; justify-content: space-around; gap: var(--e1); }
.col-grupo {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  flex: 1; min-width: 34px;          /* min-width: com um ano no filtro sao 53
                                        semanas, e o .rolagem assume a partir daqui */
}
.col-topo {
  font-size: 12.5px; font-weight: 600; color: var(--tinta);
  margin-bottom: 5px; font-variant-numeric: tabular-nums;
}
.col-haste {
  width: 100%; max-width: 46px; min-height: 2px;
  border-radius: 4px 4px 0 0; background: var(--serie-liquida);
}
.col-base { font-size: 12px; color: var(--tinta-3); margin-top: 8px; white-space: nowrap; }
.col-grupo:hover .col-haste { filter: brightness(1.1); }

/* ------------------------------------------------- rankings em lista ------
   "Top 15 clientes" e "Vendas por marca", no formato do painel do Power BI:
   linha compacta com nome, uma coluna do meio (UF ou barra fina) e o valor a
   direita com o selo de variacao. Cabem lado a lado justamente por nao terem
   barra grossa por linha. */
.lista { width: 100%; border-collapse: collapse; }
.lista td { padding: 5px 8px; font-size: 12.5px; border-bottom: 1px solid var(--linha); }
.lista tr:last-child td { border-bottom: 0; }
.lista tr:hover td { background: color-mix(in srgb, var(--serie-liquida) 7%, transparent); }
/* max-width:0 com overflow e o jeito de forcar reticencias em celula de tabela:
   sem ele a celula cresce e empurra a coluna de valor para fora. */
.lista .nome {
  color: var(--tinta); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 0; width: 100%;
}
.lista .uf {
  text-align: center; color: var(--tinta-3); font-size: 11.5px;
  width: 38px; white-space: nowrap;
}
.lista .val {
  text-align: right; white-space: nowrap; color: var(--tinta);
  font-weight: 600; font-variant-numeric: tabular-nums;
}
.lista .barra-mini { width: 34%; min-width: 90px; }
.trilho-mini { background: var(--trilho); border-radius: 3px; height: 9px; }
.trilho-mini .preench { height: 9px; border-radius: 3px; background: var(--serie-liquida); }

/* Barra de duas partes dentro da tabela de comissao: liquida a pagar + o que
   foi descontado do acrescimo. As duas somam a bruta, entao dividem a mesma
   escala e ficam encostadas — sao pedacos de um valor so, nao duas series. */
.tabela.densa td.barra-com { padding-right: 16px; }   /* folga antes do número */
.trilho-com {
  display: flex; height: 10px; border-radius: 3px;
  background: var(--trilho); overflow: hidden;
}
.trilho-com .liq  { background: var(--serie-liquida); }
.trilho-com .desc { background: var(--serie-desconto); }

/* Comissao por vendedor (Gerencial - Comissoes). Mesma barra de duas partes da
   tabela acima, agora como grafico: a barra INTEIRA e a comissao bruta, e a
   escala e o primeiro colocado. As duas metades somam a bruta, entao dividem a
   mesma escala — nao sao duas series, sao pedacos de um valor so.

   Reusa `.barras/.barra`, so trocando a altura do trilho: `.trilho-com` nasceu
   com 10 px para caber numa celula de tabela densa, e aqui ele e o proprio
   grafico. Sem esta linha a barra fica com metade da altura do nome ao lado. */
/* A barra de mistura da Gerencial (22/09/2026): pedido x nota, e a terceira
   com a categoria do cliente. Mais larga a direita que a de comissoes porque o
   valor vem acompanhado de dois percentuais na mesma linha. */
.barras.mix .barra      { grid-template-columns: 150px 1fr 230px; }
.barras.mix .trilho-com { height: 22px; border-radius: 4px; }
/* ⚠️ As duas classes abaixo NAO podem reusar .liq/.desc: ali elas significam
   "peixes e vivos" e "produtos", e aqui significariam outra coisa no mesmo
   documento. Cor e reforco, nunca a informacao — a legenda escreve os dois. */
/* ⚠️ O % ESCRITO DENTRO DA FATIA (23/09/2026, pedido do Rafael). A tinta de
   cada uma foi MEDIDA em contraste WCAG, e nao escolhida a olho — as cores
   trocam entre os temas e duas delas ficam CLARAS no escuro, onde texto branco
   sumiria. Os oito pares medidos estao no comentario de cada linha.

   ⚠️ `overflow:hidden` na fatia e `>= 8%` no JS sao a mesma defesa: sem os dois,
   o rotulo de uma fatia estreita vaza para a vizinha e passa a parecer que mede
   a outra. */
.barras.mix .trilho-com > div {
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.barras.mix .dentro {
  font-size: 10.5px; font-weight: 700; line-height: 1;
  white-space: nowrap; letter-spacing: .2px;
}
.barras.mix .liq   .dentro { color: #fff;     }  /* sobre #2b6cb0 → 5,42:1 */
.barras.mix .desc  .dentro { color: #11182a;  }  /* sobre #dd6b20 → 5,22:1 (branco daria 3,39) */
.barras.mix .cat-c .dentro { color: #fff;     }  /* sobre #2b6cb0 → 5,42:1 */
.barras.mix .cat-b .dentro { color: #11182a;  }  /* sobre #dd6b20 → 5,22:1 */
.barras.mix .cat-x .dentro { color: #11182a;  }  /* sobre #a9c8e8, cor fraca   */

:root[data-tema="escuro"] .barras.mix .liq   .dentro { color: #11182a; }  /* #718cf5 → 5,70:1 */
:root[data-tema="escuro"] .barras.mix .cat-c .dentro { color: #11182a; }  /* #8fa6f8 → 7,56:1 */
:root[data-tema="escuro"] .barras.mix .cat-b .dentro { color: #11182a; }  /* #f0954a → 7,66:1 */
:root[data-tema="escuro"] .barras.mix .cat-x .dentro { color: #11182a; }
/* ⚠️ O UNICO CASO EM QUE NENHUMA TINTA SERVIA: o laranja do tema escuro
   (`--serie-desconto`, #cc5500) da 4,31:1 com branco e 4,10:1 com escuro — os
   dois abaixo de 4,5. A saida NAO foi mexer na variavel, que e compartilhada
   com Comissoes e com o resto do site: e um tom proprio, so dentro desta barra,
   escolhido por medicao (#c05000 → 4,78:1 com branco, e 3,69:1 contra o fundo,
   que e o minimo de um objeto grafico). */
:root[data-tema="escuro"] .barras.mix .desc          { background: #c05000; }
:root[data-tema="escuro"] .barras.mix .desc  .dentro { color: #fff; }

.trilho-com .cat-c { background: var(--par-a-forte); }
.trilho-com .cat-b { background: var(--par-b-forte); }
.trilho-com .cat-x { background: var(--serie-fraca); }
.legenda-com .chave.cat-c { background: var(--par-a-forte); }
.legenda-com .chave.cat-b { background: var(--par-b-forte); }
.legenda-com .chave.cat-x { background: var(--serie-fraca); }

.barras.comissoes .barra { grid-template-columns: 170px 1fr 190px; }
.barras.comissoes .trilho-com { height: 20px; border-radius: 4px; }
.barras.comissoes .valores b.negativo { color: var(--serie-desconto); }
.tabela b.negativo { color: var(--serie-desconto); }
/* O valor descontado na linha de baixo da barra sai no MESMO laranja do
   segmento que ele descreve — a cor é o que liga o número ao pedaço da barra.
   O resto da linha ("bruta R$ …") continua na tinta apagada, senão a linha
   inteira grita e a informação principal, que é a líquida, perde o destaque. */
.barras.comissoes .valores small .desconto { color: var(--serie-desconto); }

/* A legenda e obrigatoria aqui: as duas cores nao se explicam sozinhas, e sem
   ela a barra laranja parece "o que ele vendeu a menos" em vez de "o que foi
   descontado da comissao". */
.legenda-com { font-size: 11.5px; color: var(--tinta-3); margin: 0 0 10px; }
.legenda-com .chave {
  display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  margin: 0 4px 0 12px; vertical-align: -1px;
}
.legenda-com .chave:first-child { margin-left: 0; }
.legenda-com .chave.liq  { background: var(--serie-liquida); }
.legenda-com .chave.desc { background: var(--serie-desconto); }

/* Marcas: nome curto, barra LONGA.
   O nome de marca cabe em pouco espaco ("MAXXI BRAZIL", "ACESSORIOS"), enquanto
   razao social de cliente nao — por isso a largura so muda aqui. Sem isso a
   coluna do nome tomava tudo e a barra virava um toco: as marcas de 0,3% a 4%
   ficavam todas do mesmo tamanho, e a barra deixava de comparar.

   PRECISA de table-layout fixed. Em tabela com layout automatico — o padrao —
   largura em porcentagem e apenas uma SUGESTAO: o navegador atende primeiro o
   conteudo minimo de cada celula e so depois distribui o resto. Declarar
   22%/50% ali nao mudou nada na tela.

   O valor leva px, nao porcentagem: precisa de ~210 px fixos para caber o
   numero, a fatia e o selo mais largo. Em porcentagem sobraria espaco a toa no
   cartao largo e faltaria no estreito.

   Nome em 24% e seguro: a marca mais longa COM VENDA tem 18 caracteres
   (CONTINUUM AQUATICS, ~130 px) e 24% do cartao mais estreito — os dois
   quadros lado a lado — da ~162 px. Existe no cadastro uma marca de 40
   caracteres, mas ela nunca vendeu; se vender, o nome trunca com reticencias e
   este e o lugar de rever o numero. */
.lista.marcas             { table-layout: fixed; }
.lista.marcas .nome       { width: 24%; }
.lista.marcas .val        { width: 210px; }
.lista.marcas .barra-mini { width: auto; }   /* fica com todo o resto */

/* Clientes: mesma ideia, proporcoes diferentes.
   Razao social e bem mais longa que nome de marca — mediana de 15 caracteres,
   mas chega a 43 ("TIM FISH IMPORTACAO E EXPORTACAO EIRELI EPP"). Por isso o
   nome leva 32% aqui contra 24% nas marcas.
   O valor cabe em menos: nao tem a fatia percentual ao lado, so o numero e o
   selo — 165 px contra 210 px. O que sobra vai para a barra. */
.lista.clientes             { table-layout: fixed; }
.lista.clientes .nome       { width: 32%; }
.lista.clientes .uf         { width: 38px; }
.lista.clientes .val        { width: 165px; }
.lista.clientes .barra-mini { width: auto; }

/* Clientes mais frequentes: o valor traz duas coisas — o numero de pedidos, que
   e o criterio da ordem, e o faturamento como referencia. Por isso 150 px e o
   nome mais estreito que nos outros dois: aqui a UF e a barra dividem o meio. */
.lista.frequentes             { table-layout: fixed; }
.lista.frequentes .nome       { width: 30%; }
.lista.frequentes .uf         { width: 38px; }
.lista.frequentes .val        { width: 150px; }
.lista.frequentes .barra-mini { width: auto; }
.lista.frequentes .val .ped   { color: var(--serie-desconto); }
.lista.frequentes .val .fat   { color: var(--tinta-3); font-weight: 400; font-size: 11.5px; }

/* -------------------------------------------- colunas empilhadas ----------
   "Atendimento da carteira": cada coluna e um mes, partido em recorrentes
   (base) e novos (topo). Os dois passos do mesmo azul, porque sao partes de um
   todo — duas cores diferentes diriam "duas series independentes". */
.empilhadas { display: flex; align-items: flex-end; justify-content: space-around; gap: var(--e1); }
.emp-grupo {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-end;
  flex: 1; min-width: 46px;
}
.emp-pos   { font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.emp-topo  {
  font-size: 12.5px; font-weight: 600; color: var(--tinta);
  margin: 1px 0 5px; font-variant-numeric: tabular-nums;
}
.emp-pilha { display: flex; flex-direction: column; justify-content: flex-end; width: 100%; max-width: 30px; }
.emp-seg   { width: 100%; min-height: 2px; }
/* 2 px de folga entre os dois segmentos: sem ela as duas cores encostam e a
   divisa some justamente onde o grafico precisa dela. */
.emp-seg.novos { background: var(--par-a-forte); border-radius: 3px 3px 0 0; margin-bottom: 2px; }
.emp-seg.recor { background: var(--par-a-fraco); }
.emp-seg.recor.so { border-radius: 3px 3px 0 0; }
.emp-base  { font-size: 12px; color: var(--tinta-3); margin-top: 8px; white-space: nowrap; }
.emp-base.parcial { font-style: italic; }
.emp-novos { font-size: 11px; color: var(--tinta-3); margin-top: 2px; white-space: nowrap; }
.emp-grupo:hover .emp-seg { filter: brightness(1.1); }

/* --------------------------------------------- quadro da carteira ---------
   Uma barra so, ativos contra inativos, e os quatro numeros que a explicam.

   ⚠️ A COR AQUI DEIXOU DE SER STATUS EM 20/08/2026. Ela era o semaforo da
   positivacao da carteira — que, medido nos 16 vendedores em 12 meses, tem
   MAXIMO 48,8% e nunca alcancou o verde de 60%: a barra saia vermelha em 149 dos
   159 vendedor-meses. Cor de status que nunca troca nao informa, e ainda gasta o
   verde que o resto da tela usa para dizer algo. Agora e a cor de SERIE padrao,
   a mesma de `.trilho-mini .preench`, com contraste ja medido nos dois temas.
   O verde/ambar/vermelho ficou so com a positivacao de ATIVOS, que varia de
   verdade. Ver plan/16-pagina-vendas.md. */
.carteira-barra {
  display: flex; height: 26px; border-radius: 5px; overflow: hidden;
  background: var(--trilho); margin-bottom: var(--e2);
}
.carteira-barra .cheia {
  display: flex; align-items: center; justify-content: center; min-width: 46px;
  background: var(--serie-liquida);
  color: #fff; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.carteira-barra .resto {
  flex: 1; display: flex; align-items: center; justify-content: center;
  color: var(--tinta-3); font-size: 12px; font-weight: 600; white-space: nowrap;
}
/* No tema escuro a cor de serie clareia (#2b6cb0 -> #718cf5) e texto branco
   sobre ela fica ilegivel. A tinta passa a ser o fundo da pagina — escuro sobre
   claro. Valia para o semaforo antigo pelo mesmo motivo, e continua valendo. */
:root[data-tema="escuro"] .carteira-barra .cheia { color: var(--pagina); }
.mini-cartoes { display: grid; grid-template-columns: 1fr 1fr; gap: var(--e1); }
.mini { border: 1px solid var(--linha); border-radius: 6px; padding: 7px 10px; }
.mini .rotulo {
  font-size: 10.5px; color: var(--tinta-3); text-transform: uppercase;
  letter-spacing: .04em; font-weight: 600;
}
.mini .valor {
  font-size: 19px; font-weight: 640; color: var(--tinta);
  font-variant-numeric: tabular-nums; line-height: 1.2;
}

/* Selo de variacao contra o mes anterior. Fundo tenue derivado da propria cor
   de status — assim ele acompanha os dois temas sem uma segunda paleta. */
.mom {
  display: inline-block; margin-left: 6px; padding: 1px 5px;
  font-size: 10.5px; font-weight: 600; border-radius: 3px;
}
.mom.alta  { color: var(--bom);     background: color-mix(in srgb, var(--bom) 15%, transparent); }
.mom.baixa { color: var(--ruim);    background: color-mix(in srgb, var(--ruim) 15%, transparent); }
.mom.novo  { color: var(--atencao); background: color-mix(in srgb, var(--atencao) 18%, transparent); }

/* ------------------------------------------------------------------ dica -
   Camada propria no lugar do `title` do navegador, que demora ~1 s, nao aceita
   formatacao e nao existe no toque. Sempre escura, nos dois temas: e cromo
   flutuante, e mudar de cor com o tema faria a dica competir com o cartao
   embaixo dela em vez de se destacar. */
.dica {
  position: fixed; z-index: 80; pointer-events: none;   /* nunca rouba o hover */
  max-width: 300px; padding: 9px 11px;
  background: #16202e; color: #fff;
  border-radius: 6px; box-shadow: 0 6px 20px rgba(0,0,0,.28);
  font-size: 12px; line-height: 1.45;
}
.dica.oculto { display: none; }
.dica strong { display: block; font-size: 12.5px; font-weight: 600; margin-bottom: 3px; }
.dica span   { display: block; color: #c3cdda; font-variant-numeric: tabular-nums; }
:root[data-tema="escuro"] .dica { background: #050d2e; box-shadow: 0 6px 20px rgba(0,0,0,.55); }

/* Realce da coluna sob o cursor: a area inteira responde, nao so a barra. */
.col rect:first-child { cursor: default; }
.col:hover rect:not(:first-child) { filter: brightness(1.12); }

/* ------------------------------------------------------------------ mapa -
   Altura fixa: o mapa e a unica secao que precisa saber quanto espaco tem, para
   enquadrar os pontos e converter raio de pixel em unidade de mundo. Se mudar
   aqui, mudar ALTURA_MAPA_PX em site/vendas.js — os dois numeros sao o mesmo
   numero, e admin/testar_mapa.mjs confere que continuam iguais. */
.mapa-quadro {
  height: 520px; border-radius: var(--raio); overflow: hidden;
  background: var(--trilho); cursor: grab; touch-action: none;
}
.mapa-quadro.arrastando { cursor: grabbing; }
.mapa { width: 100%; height: 100%; display: block; }

/* O contorno dos estados e CONTEXTO, nao dado: recuado o bastante para as
   bolhas mandarem na tela. `non-scaling-stroke` mantem a linha com 1 px em
   qualquer zoom — sem ele, aproximar engorda a fronteira ate cobrir cidade. */
.mapa-fundo path {
  fill: var(--superficie); stroke: var(--linha); stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
/* Sobre um mapa de ruas a bolha disputa atencao com o desenho de baixo: a
   opacidade sobe para .82 e o traco fica em branco/preto do tema, que separa a
   bolha do fundo em qualquer cor de rua. Com o contorno de estados sozinho .72
   bastava — a troca de fundo cobrou isto. */
.mapa-bolha {
  stroke: var(--superficie); stroke-width: 1.4; fill-opacity: .82;
  transition: fill-opacity .12s;
}
.mapa-bolha:hover { fill-opacity: 1; stroke: var(--tinta); stroke-width: 2; cursor: pointer; }

/* Atribuicao do mapa: OBRIGATORIA pelos termos do OpenStreetMap e do CARTO.
   Discreta, mas nunca ausente. */
.atribuicao { float: right; color: var(--tinta-3); font-size: 11px; }

/* Legenda que tambem filtra: clicar num vendedor o isola. E o que salva a
   leitura quando duas cores do Power BI sao parecidas — isolado, a cor deixa
   de importar. */
.mapa-legenda { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--e2); }
.vend-chip {
  width: auto; margin: 0; display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 9px; font: inherit; font-size: 12px;
  color: var(--tinta); background: none;
  border: 1px solid var(--linha); border-radius: 999px; cursor: pointer;
  transition: border-color .15s, opacity .15s;
}
.vend-chip:hover:not(:disabled) { border-color: var(--tinta-3); background: none; color: var(--tinta); }
.vend-chip b { font-variant-numeric: tabular-nums; color: var(--tinta-2); font-weight: 600; }
.vend-chip.apagado { opacity: .38; }
.vend-chip.todos { font-weight: 600; }

/* Quando a selecao do mapa difere do filtro do topo, a pagina passa a mostrar
   dois escopos ao mesmo tempo. Sem dizer isso, rola-se comparando coisas
   diferentes achando que sao a mesma. */
.aviso-escopo {
  margin: 0 var(--e2) var(--e2); padding: 7px 11px;
  font-size: 12.5px; color: var(--tinta-2);
  background: color-mix(in srgb, var(--atencao) 10%, transparent);
  border-left: 3px solid var(--atencao); border-radius: 0 4px 4px 0;
}
.aviso-escopo b { color: var(--tinta); }

/* ------------------------------------------------------------ descontos --
   Os selos da tela de Descontos de Clientes (03/09/2026).

   ⚠️ O SELO NAO E ENFEITE, e o dado explica por que. No cliente 3925, JBL e
   MAXXI mostram os MESMOS 25% — mas MAXXI tem linha negociada e JBL so esta
   seguindo a regra geral. Sao dois fatos comerciais diferentes, e sem o selo
   ficam com a mesma aparencia. E a razao de a coluna existir tambem no .xlsx.

   As cores saem dos tokens ja validados (`--bom`, `--tinta-3`, `--atencao`),
   e nao de literais: os tres sao remapeados no tema escuro. */
.desc-selo {
  display: inline-block; font-size: 11px; font-weight: 600;
  padding: 1px 7px; border-radius: 10px; white-space: nowrap;
  border: 1px solid;
}
.desc-selo.exclusivo { color: var(--bom); border-color: var(--bom);
                       background: color-mix(in srgb, var(--bom) 10%, transparent); }
/* Herdado e o caso COMUM, entao ele e o discreto: sem preenchimento e sem
   negrito. Pintar os dois com a mesma forca faria a tela parecer cheia de
   exceçoes quando a maioria e regra.

   ⚠️ MAS DISCRETO NAO E ILEGIVEL, e a primeira versao errou nisso: usava
   `--tinta-3`, que e tinta de LEGENDA — medido, 2,94:1 no tema claro, contra o
   piso de 4,5:1 de texto de 11px. Era a terceira vez do mesmo engano neste
   projeto (o nome do vendedor a 2,9:1, e o rotulo do menu a 3,78:1 na manha do
   MESMO DIA). `--tinta-2` da 5,46:1 no claro e 7,63:1 no escuro e continua
   secundario. A discricao vem do peso e do fundo, nao de apagar a cor. */
.desc-selo.herdado   { color: var(--tinta-2); border-color: var(--linha);
                       background: transparent; font-weight: 400; }
.desc-selo.conflito  { color: var(--atencao); border-color: var(--atencao);
                       background: color-mix(in srgb, var(--atencao) 12%, transparent); }

/* A lista de clientes achados pela busca por parte do nome (03/09/2026).
   Rolagem interna com teto: "COMERCIO" acha centenas, e uma lista sem teto
   empurraria o resto da tela para fora da vista. */
.desc-achados {
  display: flex; flex-direction: column;
  max-height: 380px; overflow-y: auto;
  margin: 0 var(--e2) var(--e2);
  border: 1px solid var(--linha); border-radius: 6px;
}
/* Cada achado e um <button>, e nao um <div> com onclick: quem usa teclado
   alcanca com Tab e aciona com Enter sem nada a mais. ⚠️ `width: 100%` aqui e
   DE PROPOSITO — e o unico lugar deste arquivo em que o `width: 100%` que o
   estilo.css da a todo <button> e o comportamento certo, e por isso ele nao e
   desfeito como em `.acao`.

   ⚠️ MAS O SELETOR PRECISA DO `button`, e nao e enfeite: o tema escuro tem
   `:root[data-tema="escuro"] button { background: var(--serie-liquida) }`, que
   pesa (0,2,1). Escrito so como `.desc-achado` (0,1,0), este bloco PERDIA a
   disputa e a lista inteira saia com o AZUL de botao — 60 barras azuis no
   lugar de uma lista. Com `.desc-achados button.desc-achado` (0,2,1) empata em
   peso e vence por vir depois, que e exatamente como `.acao` resolve o mesmo
   conflito algumas centenas de linhas acima. Segunda vez nesta mesma tela. */
.desc-achados button.desc-achado {
  width: 100%; margin: 0; padding: 8px 12px;
  display: flex; align-items: baseline; gap: 10px;
  font: inherit; font-size: 13px; text-align: left;
  background: transparent; color: var(--tinta);
  border: 0; border-bottom: 1px solid var(--linha); border-radius: 0;
  cursor: pointer;
}
.desc-achados button.desc-achado:last-child { border-bottom: 0; }
.desc-achados button.desc-achado:hover:not(:disabled) {
  background: color-mix(in srgb, var(--acento) 12%, transparent);
}
.desc-achados button.desc-achado .nome { font-weight: 600; }
/* O codigo empurrado para a direita: quem procura por nome le o nome, e o
   codigo so precisa estar disponivel. */
.desc-achados button.desc-achado .desc-cod { margin-left: auto; }

/* "sem %" — a ausencia de percentual, que NAO e zero. O italico faz o olho ler
   "isto nao e um numero"; a cor e `--tinta-2` pelo mesmo motivo do selo acima —
   e informacao que alguem precisa LER, nao rotulo de eixo. */
.sem-valor { color: var(--tinta-2); font-style: italic; font-weight: 400; }

/* O codigo do cliente ao lado da razao social, sem competir com ela. Aqui
   `--tinta-3` tambem serve: o codigo repete o que o filtro ja diz. */
.desc-cod { color: var(--tinta-3); font-weight: 400; font-size: .85em; }

/* Nota no cabecalho do cartao, empurrando o botao de exportar para a direita.
   Mesmo efeito que Comissao faz com estilo embutido — aqui virou classe porque
   dois cartoes usam. `--tinta-3` E O CERTO AQUI: isto e legenda de cabecalho,
   nao dado, e e o papel para o qual o token foi feito. */
.cabec-nota { font-size: 12px; color: var(--tinta-3); margin-left: auto;
              max-width: 46ch; line-height: 1.3; text-align: right; }

/* ------------------------------------------------- aviso de fim de sessao -
   Aparece nos ultimos minutos, no canto inferior direito: perto o bastante do
   olho para nao passar batido, longe o bastante dos filtros para nao atrapalhar
   quem esta trabalhando.

   Fundo cinza-escuro, nao ambar: cor de serie e RESERVADA para dado. Um aviso
   pintado de laranja competiria com a barra de desconto logo ao lado. O ponto
   pulsante carrega o alerta, e o texto diz o que a cor sozinha nao diria. */
.aviso-sessao {
  position: fixed; right: var(--e3); bottom: var(--e3); z-index: 60;
  display: flex; align-items: center; gap: 12px;
  max-width: 400px; padding: 12px 14px;
  background: #16202e; color: #fff;
  border-radius: var(--raio);
  box-shadow: 0 8px 28px rgba(16,32,52,.30);
  animation: surgir .22s ease-out;
}
.aviso-sessao.oculto { display: none; }
.aviso-sessao .ponto {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: #f6ad55; animation: pulsar 1.6s ease-in-out infinite;
}
.aviso-sessao .texto { line-height: 1.35; }
.aviso-sessao strong { display: block; font-size: 13px; font-weight: 600; }
.aviso-sessao small  { display: block; font-size: 11.5px; color: #a9b6c6; margin-top: 2px; }
.aviso-sessao button {
  width: auto; flex: none; padding: 7px 12px; font: inherit; font-size: 12.5px; font-weight: 550;
  color: #16202e; background: #fff; border: 0; border-radius: 6px; cursor: pointer;
  transition: background .15s;
}
.aviso-sessao button:hover { background: #dfe7f0; }
@keyframes surgir { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: none } }

/* Rolagem suave ate a secao quando se chega por link com ancora. */
html { scroll-behavior: smooth; }
.secao { scroll-margin-top: 64px; }

/* Busca inversa da marca: "quem NÃO comprou". Fica colado ao campo de marca
   porque é dele que a inversão fala — solto no cabeçalho, ninguém saberia o que
   está sendo invertido. Desligado enquanto não há marca escolhida: inverter
   nada não é pergunta. */
.filtros-locais .inverter {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12.5px; color: var(--tinta-2); white-space: nowrap; cursor: pointer;
}
.filtros-locais .inverter b { color: var(--serie-desconto); font-weight: 650; }
.filtros-locais .inverter input { width: auto; margin: 0; accent-color: var(--serie-desconto); }
.filtros-locais .inverter.desligado { color: var(--tinta-3); cursor: default; }
.filtros-locais .inverter.desligado b { color: var(--tinta-3); font-weight: 500; }

/* ==========================================================================
   AQUARISMO TOTAL — página Geral
   ==========================================================================
   Tradução do painel `Dash Marketplaces (HTML)` do Power BI. O layout, os
   tamanhos e as cores de marca vieram de lá; o que MUDOU aqui foi o cromo:
   o painel do Power BI crava `#1f2937`, `#fff` e `#6b7280` no HTML, e num
   dashboard com tema escuro isso daria texto cinza sobre fundo azul-marinho.
   Por isso tudo o que é cromo usa os tokens (`--tinta`, `--superficie`,
   `--linha`) e só as CORES DE MARCA continuam fixas — essas são dado, não
   decoração: o amarelo é do Mercado Livre em qualquer tema.
   ========================================================================== */
/* ⚠️ MESMA LARGURA E MESMO RESPIRO DE `.secao`. A primeira versão não tinha
   contêiner: o título encostava na borda esquerda e o total era CORTADO na
   direita, em 1400 px. O painel do Power BI vive dentro de um visual, que já
   tem margem; aqui o div é filho direto da página e precisa da sua. */
.aqt { color: var(--tinta); max-width: var(--largura); margin: 0 auto;
       padding: var(--e4) var(--e3) 0; }

.aqt-hd { display: flex; justify-content: space-between; align-items: flex-end;
          gap: 16px;
          border-bottom: 2px solid var(--linha); padding-bottom: 8px; margin-bottom: 12px; }
/* ⚠️ `min-width: 0` no bloco da esquerda: sem isso o texto longo do cabeçalho
   não deixa o flex encolher, e quem cede é o número da direita — "R$ 7.627"
   quebrava em duas linhas com o R$ sozinho em cima. */
.aqt-hd > div:first-child { min-width: 0; }
.aqt-ttl { font-size: 17px; font-weight: 800; }
.aqt-per { font-size: 11px; color: var(--tinta-2); margin-top: 2px; }
/* O número-herói NUNCA quebra: é a primeira coisa que se lê na tela. */
.aqt-tw  { text-align: right; flex: 0 0 auto; white-space: nowrap; }
.aqt-tv  { font-size: 22px; font-weight: 800; color: var(--acento); }
.aqt-tl  { font-size: 10px; color: var(--tinta-2); letter-spacing: .5px; text-transform: uppercase; }

/* Bloco do Mercado Livre: destacado porque ML Normal e ML Full são o mesmo
   marketplace com duas logísticas, e juntos são quase metade do faturamento. */
.aqt-ml { background: var(--superficie); border: 1px solid #ffe600; border-radius: 14px;
          padding: 9px 12px; margin-bottom: 10px; }
.aqt-mlh { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.aqt-mlbadge { width: 44px; height: 26px; border-radius: 8px; background: #fff;
               border: 1px solid var(--linha); display: flex; align-items: center;
               justify-content: center; }
.aqt-mlt { font-weight: 800; font-size: 14px; }
.aqt-mls { font-size: 11px; color: var(--tinta-2); margin-left: auto; text-align: right; }
.aqt-mlb { display: flex; gap: 10px; flex-wrap: wrap; }
.aqt-mlc { flex: 1 1 180px; background: var(--pagina); border-radius: 10px;
           padding: 7px 10px; border-left: 4px solid; }
.aqt-tag { color: #fff; font-size: 8px; padding: 1px 5px; border-radius: 4px;
           margin-left: 5px; vertical-align: 1px; font-weight: 700; }

.aqt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 10px; }
.aqt-card { background: var(--superficie); border: 1px solid var(--linha);
            border-top: 3px solid; border-radius: 12px; padding: 7px 11px;
            box-shadow: 0 1px 3px rgba(0,0,0,.05); }

/* Cartão de canal que aparece MESMO ZERADO — hoje só o Balcão, que o Rafael
   passou a acompanhar de perto em 31/08/2026. Sóbrio de propósito: precisa
   estar lá para ser conferido, sem competir por atenção com quem vendeu.

   ⚠️ `.aqt-card.aqt-zerado`, com as DUAS classes, e não `.aqt-zerado` sozinha:
   `.aqt-card` já vale (0,1,0), e uma variação com uma classe só empataria —
   deixando o resultado por conta da ordem no arquivo, que é como `.aqt-fxsec`
   perdeu para `.aqt-sec` e a moldura simplesmente não apareceu. */
.aqt-card.aqt-zerado { opacity: .58; box-shadow: none; }
.aqt-card.aqt-zerado .aqt-kv { color: var(--tinta-2); }

/* A fonte do "recebido" está atrasada — hoje só o extrato do Mercado Pago,
   parado em 30/06/2026 porque a integração da origem responde HTTP 500.

   ⚠️ É uma classe NOVA em vez de `.aqt-ress`, e a diferença é de peso: aquela
   tem 10px e é uma nota de rodapé de cartão. Esta diz que um TERÇO do número
   principal da tela não está lá, e precisa ser lida antes dos números — a tela
   do ML mostraria "R$ 0 recebido" em agosto, que sem este aviso se lê como
   inadimplência em vez de integração parada.

   Cor do próprio tema (`--atencao`), sem hex solto: o mesmo aviso tem de
   funcionar no claro e no escuro, e cor cravada só é conferida num deles. */
.aqt-defasado { border: 1px solid var(--atencao); border-left-width: 3px;
                border-radius: 8px; padding: 8px 11px; margin-bottom: 12px;
                font-size: 11.5px; line-height: 1.45; color: var(--tinta); }
.aqt-defasado b { color: var(--atencao); }

/* ===================== Valor do Estoque =====================================
   ⚠️ CLASSE PROPRIA, e NAO `.aqt-defasado`. Aquela pinta de `--atencao` porque
   diz "o dado esta atrasado" — e um problema. Estes avisos declaram ESCOPO ("a
   serie comeca aqui", "variacao fica de fora"), que e informacao permanente e
   correta. Pintar de ambar treina a ignorar o ambar de verdade, que na tela do
   ML significa integracao parada. */
.aqt-escopo { border: 1px solid var(--linha); border-left: 3px solid var(--tinta-3);
              border-radius: 8px; padding: 8px 11px; margin-bottom: 10px;
              font-size: 11.5px; line-height: 1.45; color: var(--tinta-2);
              background: var(--superficie); }
.aqt-escopo b { color: var(--tinta); }

.aqt-vazio { font-size: 12px; line-height: 1.5; color: var(--tinta-2);
             padding: 18px 14px; text-align: center; border-radius: 8px;
             background: var(--trilho); }

/* ⚠️ `width:100%` + `height:auto` e o viewBox mandam no tamanho. Sem altura
   automatica o SVG nasce com os 150px do padrao do navegador e os rotulos se
   amassam contra a linha. */
.aqt-es-svg { width: 100%; height: auto; display: block; margin-top: 4px;
              overflow: visible; }
/* Os rotulos sao TEXTO SVG, entao herdam nada do resto da folha: cor, tamanho e
   peso precisam ser ditos aqui, e a cor sai do token para valer nos dois temas. */
.aqt-es-rot  { font-size: 15px; font-weight: 700; fill: var(--tinta);
               font-family: inherit; }
.aqt-es-eixo { font-size: 13px; fill: var(--tinta-3); font-family: inherit; }

.aqt-ic { width: 26px; height: 26px; border-radius: 7px; display: flex;
          align-items: center; justify-content: center; margin-bottom: 3px;
          overflow: hidden; }
.aqt-cn { font-size: 12px; font-weight: 700; color: var(--tinta); }
.aqt-cv { font-size: 17px; font-weight: 800; margin-top: 1px; }
.aqt-cs { font-size: 11px; color: var(--tinta-2); }
.aqt-bar { height: 5px; border-radius: 3px; background: var(--trilho);
           margin-top: 4px; overflow: hidden; }
.aqt-bf  { height: 100%; border-radius: 3px; }

/* Gráfico de 6 meses: colunas AGRUPADAS por canal — ver o bloco `.aqt-grp`. */
.aqt-chart { margin-top: 12px; background: var(--superficie); border: 1px solid var(--linha);
             border-radius: 12px; padding: 12px; }
.aqt-mh { font-size: 13px; font-weight: 800; }
.aqt-mp { font-size: 11px; color: var(--tinta-2); margin-bottom: 14px; }
.aqt-cols { display: flex; align-items: flex-end; gap: 18px; padding-top: 26px; }
.aqt-col  { flex: 1; display: flex; flex-direction: column; align-items: center;
            justify-content: flex-end; min-width: 0; }

/* Barras AGRUPADAS: uma por marketplace, lado a lado dentro do mês.
   ⚠️ A primeira versão empilhou. Empilhado responde "quanto vendemos no mês";
   agrupado responde "qual marketplace vendeu mais, e quanto um é maior que o
   outro" — e é essa a pergunta da página. O painel do Power BI é agrupado. */
.aqt-grp { width: 100%; height: 130px; display: flex; align-items: flex-end;
           justify-content: center; gap: 4px; }
.aqt-gb  { position: relative; flex: 1; display: flex; align-items: flex-end;
           justify-content: center; min-width: 4px; }
.aqt-gbar { width: 100%; min-width: 4px; border-radius: 3px 3px 0 0;
            /* Barra de valor baixo mas não-zero tem de continuar visível: sem
               isto um canal de R$ 55 num mês de R$ 44 mil desaparece e parece
               que não vendeu. */
            min-height: 2px; }
/* Girado −45° como no modelo: em seis meses × cinco canais são 30 rótulos, e na
   horizontal eles se sobrepõem. `bottom` é posto por JS, na altura da barra. */
.aqt-gval { position: absolute; left: 50%; transform: translateX(-50%) rotate(-45deg);
            transform-origin: left bottom; font-size: 8.5px; font-weight: 700;
            color: var(--tinta-2); white-space: nowrap; pointer-events: none; }
.aqt-clbl { font-size: 11px; margin-top: 7px; font-weight: 700; text-align: center; }
.aqt-clbl small { display: block; font-weight: 500; font-size: 9.5px;
                  color: var(--tinta-3); margin-top: 1px; }
.aqt-leg  { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 12px;
            margin-top: 12px; font-size: 10px; color: var(--tinta-2); }
.aqt-leg span { display: inline-flex; align-items: center; gap: 4px; }
.aqt-leg i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }

/* O crachá do ML é branco em qualquer tema: o logo tem fundo amarelo próprio. */
:root[data-tema="escuro"] .aqt-mlbadge { background: #fff; }

/* ===========================================================================
   O LOGO DO AQUARISMO TOTAL, no lugar do título da página.
   O arquivo é um JPEG sobre fundo branco, e o texto dele é verde-escuro: solto
   sobre o azul do topo sumiria. O crachá claro é o mesmo recurso usado no logo
   do Mercado Livre (`.aqt-mlbadge`) — e vale nos DOIS temas, porque a cor do
   fundo aqui é do ATIVO, não do tema.
   ========================================================================= */
.aqt-marca { margin: 0; line-height: 0; }
/* 44px, e não os 34 da primeira tentativa: o logo tem o nome escrito dentro, e
   abaixo disso as letras viram um borrão — um logo ilegível não é um logo. */
.aqt-marca img { display: block; height: 44px; width: auto; background: #fff;
                 border-radius: 8px; padding: 2px 6px; }

/* ===========================================================================
   ABAS — uma por página do relatório do Aquarismo Total.
   A aba desabilitada (página ainda não construída) fica visível de propósito:
   sumir com ela confundiria "não existe ainda" com "não tenho acesso".
   ========================================================================= */
.aqt-abas { display: flex; flex-wrap: wrap; gap: 4px; max-width: var(--largura);
            margin: 0 auto; padding: 10px var(--e3) 0; }
/* ⚠️ `width: auto` E `flex: 0 0 auto`: o estilo.css põe `width: 100%` em TODO
   `button` (é o que faz os botões do formulário de login ocuparem a linha), e
   sem desfazer isso aqui cada aba virava uma faixa e as dez empilhavam. */
.aqt-aba { font: inherit; font-size: 12px; font-weight: 600; color: var(--tinta-2);
           background: transparent; border: 1px solid transparent; border-radius: 999px;
           width: auto; flex: 0 0 auto; padding: 5px 12px; cursor: pointer;
           white-space: nowrap; }
.aqt-aba:hover:not(:disabled) { background: var(--superficie); border-color: var(--linha);
                                color: var(--tinta); }
.aqt-aba.ativa { background: var(--acento); border-color: var(--acento);
                 color: #fff; font-weight: 700; }
/* Página ainda não construída: visível, mas apagada. Ver o comentário do HTML —
   sumir com ela confundiria "não existe ainda" com "não tenho acesso". */
.aqt-aba.aqt-obra { color: var(--tinta-3); cursor: not-allowed; opacity: .5;
                    background: transparent; }

/* ⚠️ O tema escuro pinta TODO `button` (linha 184), e com especificidade maior
   que `.aqt-aba` — as dez abas viravam pílulas azuis e a ativa sumia no meio
   delas. Só se vê abrindo no escuro: no claro estava certo. */
:root[data-tema="escuro"] .aqt-aba { background: transparent; color: var(--tinta-2); }
:root[data-tema="escuro"] .aqt-aba:hover:not(:disabled) { background: rgba(255,255,255,.12);
                                                          color: #fff; }
/* Letra do FUNDO DA PÁGINA sobre o azul claro, pela mesma razão já escrita na
   linha 183: no escuro o azul da série não carrega texto branco. */
:root[data-tema="escuro"] .aqt-aba.ativa { background: var(--acento); color: #091540; }
:root[data-tema="escuro"] .aqt-aba.aqt-obra { background: transparent; color: var(--tinta-3); }

/* ===========================================================================
   RESUMO VENDAS — tradução de `Dash Vendas Temporais (HTML)`.
   ⚠️ As cores das barras estão no JS, e são as do modelo (ver aqtotal.js): são
   o código visual do relatório, não série de negócio. Aqui fica só a forma.
   ========================================================================= */
.aqt-ress { font-size: 10px; color: var(--atencao); margin-top: 2px; }

.aqt-kpis { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
/* ⚠️ As telas de detalhe têm de 8 a 10 KPIs, e em `flex` isso nunca fecha
   bonito: o cartão que sobra na última linha ou se estica pela página inteira
   ou fica sozinho com um vão enorme ao lado (foi o que aconteceu na Amazon,
   com 10). Em GRADE de 5 colunas, todo cartão tem a mesma largura, as linhas
   têm a mesma altura mesmo com subtítulo de duas linhas, e 8, 9 ou 10 cartões
   ficam alinhados em colunas. As telas de agregado (3 ou 4 cartões) continuam
   em flex, porque lá esticar é o certo. */
.aqt-kpis.aqt-kpis-det { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 1250px) {
  .aqt-kpis.aqt-kpis-det { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .aqt-kpis.aqt-kpis-det { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.aqt-kpi { flex: 1 1 160px; background: var(--superficie); border: 1px solid var(--linha);
           border-left: 3px solid var(--acento); border-radius: 8px; padding: 8px 11px; }
.aqt-kl { font-size: 10px; color: var(--tinta-2); text-transform: uppercase;
          letter-spacing: .4px; }
/* O valor do cartão não quebra: preferir corte a duas linhas. */
.aqt-kv { font-size: 18px; font-weight: 800; margin-top: 3px;
          white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aqt-ks { font-size: 10px; color: var(--tinta-3); margin-top: 2px; }

/* Dois blocos lado a lado, para os dois gráficos de motivo da tela de
   canceladas: o mesmo dado por quantidade e por valor, que quase nunca
   contam a mesma história. Empilhados, a comparação exige rolar. */
.aqt-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* As duas listas de 20 do ranking. A barra é o FUNDO do nome, e não uma barra
   ao lado: com 20 linhas e nomes longos, uma coluna de barras roubaria a
   largura de que o nome precisa. `--w` é a proporção contra o primeiro. */
.aqt-rk { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.aqt-rkl { display: grid; grid-template-columns: 22px minmax(0, 1fr) 92px;
           align-items: center; gap: 6px; font-size: 11px; }
.aqt-rkn { color: var(--tinta-3); text-align: right; font-variant-numeric: tabular-nums; }
/* A barra em DEGRADE, como no painel: forte na esquerda, clara na ponta. As
   duas cores vêm translúcidas (`color-mix` com transparente) porque a mesma
   barra tem de ficar legível sobre o fundo claro E sobre o escuro — cor sólida
   obrigaria a inverter o texto num dos dois. */
.aqt-rkb { position: relative; overflow: hidden; border-radius: 4px;
           padding: 3px 6px;
           background: linear-gradient(to right, var(--c1), var(--c2))
                       left / var(--w) 100% no-repeat; }
.aqt-rkt { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⚠️ No tema ESCURO a letra é clara, e clara sobre a barra viva quase some. A
   sombra escura só aparece onde há barra: sobre o fundo do cartão ela é
   invisível. Resolve os dois casos sem trocar a cor do texto no meio da linha,
   o que uma barra de largura variável não deixa fazer. */
:root[data-tema="escuro"] .aqt-rkt { text-shadow: 0 1px 2px rgba(0,0,0,.65); }
.aqt-rkv { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
/* ---- Lucro x Prejuizo: legenda das faixas, cabeçalho e tabela mensal ---- */
.aqt-legenda { display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
               font-size: 11px; color: var(--tinta-2); }
.aqt-lg { display: inline-flex; align-items: center; gap: 5px; }
/* ⚠️ `aqt-fxpt`, e NAO `aqt-pt`: essa classe ja existe, e é o total de cada
   plataforma na tela de Custos. Com o nome repetido o `width: 9px` daqui
   esmagava aquele número dentro de um quadradinho — e a tela de Custos não tem
   nada a ver com esta. Nome de classe é espaço global, igual a `const`. */
.aqt-lg i, .aqt-fxpt { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.aqt-fxpt { margin-right: 6px; vertical-align: baseline; }
/* O nome da plataforma com o símbolo ao lado. */
.aqt-fxnome { display: flex; align-items: center; gap: 8px; }
.aqt-fxhd { display: flex; justify-content: space-between; align-items: flex-end;
            gap: 12px; margin-bottom: 4px; }
.aqt-fxkpi { font-size: 20px; font-weight: 800; text-align: right; white-space: nowrap; }
.aqt-fxkpi span { display: block; font-size: 10px; font-weight: 400;
                  color: var(--tinta-3); text-transform: uppercase; letter-spacing: .4px; }
/* A moldura de cada bloco, na cor da plataforma.
   ⚠️ `.aqt-sec.aqt-fxsec`, com as DUAS classes: `.aqt-sec` define
   `border: 1px solid var(--linha)` mais abaixo no arquivo, e com a mesma
   especificidade quem vem depois ganha — a moldura colorida simplesmente não
   aparecia. */
.aqt-sec.aqt-fxsec { border: 2px solid var(--borda-plat); }
/* ⚠️ O preto da Amazon desaparece no cartão escuro — no escuro ele vira o
   cinza claro, do mesmo jeito que um logo preto é invertido. */
:root[data-tema="escuro"] .aqt-fxsec[data-plat="amazon"] { border-color: #8fa3bf; }
/* ⚠️ `table-layout: fixed` NÃO é cosmético aqui: é o que faz a largura das
   colunas obedecer ao `colgroup`, e é o `colgroup` que alinha cada mês com o
   ponto do gráfico logo acima. Sem ele o navegador escolhe as larguras pelo
   conteúdo e o alinhamento se perde. */
.aqt-tab-fx { font-size: 11px; table-layout: fixed; }
/* O nome do mês no centro da coluna, sobre o ponto do gráfico. Vale só no
   cabeçalho: os números continuam alinhados à direita. */
.aqt-tab .aqt-cen { text-align: center; }
.aqt-tab-fx td:first-child, .aqt-tab-fx th:first-child { white-space: nowrap; }
.aqt-tab-fx .aqt-fg { margin-left: 4px; }
.aqt-tab-fx .aqt-tot td { border-top: 1px solid var(--linha); color: var(--tinta-2); }

/* ---- Cronometro da proxima carga (topo da tela do AqTotal) --------------
   ⚠️ As tres primeiras linhas ANULAM heranca do estilo.css, que foi escrito
   para a tela de login: `button { width: 100% }` esticaria o cronometro pela
   barra inteira, `input/button { margin-bottom }` desalinharia do logo, e no
   tema escuro o `button` ganha fundo proprio. As tres ja morderam elementos
   novos neste projeto — ver o README do AqTot_DashOnline. */
/* ⚠️ `.topo .aqt-crono`, com o PAI no seletor — e nao `.aqt-crono` sozinha.
   `.topo button` (estilo.css) e `:root[data-tema="escuro"] .topo button` sao
   MAIS especificos que uma classe solta, entao a versao curta perdia as duas
   cores sem erro nenhum. A primeira escrita deste bloco caiu nisso: o fundo
   pedido era .14 e o navegador media .15 no claro e .16 no escuro — parecido
   o bastante para passar despercebido, e o VERDE de "novos dados" simplesmente
   nao aparecia. Mesma familia do `.aqt-fxsec` que perdia para `.aqt-sec`. */
.topo .aqt-crono {
  width: auto; margin: 0; padding: 4px 10px;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .22); border-radius: 999px;
  color: #fff; font: inherit; font-size: 11.5px; line-height: 1.2;
  white-space: nowrap; cursor: default; align-self: center;
}
:root[data-tema="escuro"] .topo .aqt-crono { background: rgba(255, 255, 255, .10); }
/* O tempo em fonte de largura fixa: sem isso os numeros dancam a cada segundo,
   porque "1" e mais estreito que "8" na fonte do topo. */
.aqt-crono b { font-weight: 700; font-variant-numeric: tabular-nums; }
/* Passou da hora e a carga ainda nao apareceu. */
.topo .aqt-crono-esperando { opacity: .75; }
/* Chegou dado novo: aqui o cronometro vira BOTAO de verdade. O verde vale nos
   dois temas de proposito — e um aviso, nao um elemento de fundo. */
.topo .aqt-crono-novo,
:root[data-tema="escuro"] .topo .aqt-crono-novo {
  background: #16a34a; border-color: #16a34a; cursor: pointer; font-weight: 600;
}
.topo .aqt-crono-novo:hover,
:root[data-tema="escuro"] .topo .aqt-crono-novo:hover {
  background: #15803d; border-color: #15803d;
}

/* A celula de data com hora nao pode quebrar em duas linhas: "18/08" em cima e
   "14:32" embaixo dobra a altura de TODAS as linhas da tabela. */
.aqt-tab .aqt-dh { white-space: nowrap; }

/* ---- Tabelas de marketplace: tudo centralizado, menos Produto -----------
   Pedido do Rafael em 19/08/2026, para as cinco telas de ML, Shopee e Amazon.

   ⚠️ `.aqt-tab.aqt-tab-cen` com as DUAS classes, e nao `.aqt-tab-cen` sozinha:
   `.aqt-tab .n { text-align: right }` vale (0,2,0), e uma classe solta (0,1,1)
   perderia para ela sem erro nenhum — as colunas de numero continuariam a
   direita e o resto centrado, com cara de que so metade do pedido foi feito.
   E a mesma armadilha do `.aqt-fxsec` e do cronometro.

   ⚠️ A classe e NOVA em vez de reusar `.aqt-tab-det`: seis tabelas usam
   aquela, e a sexta e a lista do Ranking, que nao entra neste pedido. */
.aqt-tab.aqt-tab-cen th,
.aqt-tab.aqt-tab-cen td { text-align: center; }

/* Produto fica a esquerda: centrado, cada nome comeca num ponto diferente e a
   coluna vira um borrao. Vale para o corpo E para o titulo.

   ⚠️ A MARCA E `aqt-esq`, E NAO `aqt-prod`. A `aqt-prod` faz outra coisa —
   corta o texto longo com reticencias — e a coluna **Motivo** das Canceladas a
   usava so por isso, sem ser produto nenhum. Marcar o alinhamento por ela
   deixava o Motivo a esquerda no meio de tudo centrado: uma celula em treze,
   que so apareceu porque o teste mede coluna por coluna. Uma classe, um
   proposito. */
.aqt-tab.aqt-tab-cen th.aqt-esq,
.aqt-tab.aqt-tab-cen td.aqt-esq { text-align: left; }

/* O pódio do ranking: as três primeiras linhas da tabela. */
.aqt-rk-podio td { font-weight: 700; }
@media (max-width: 1000px) { .aqt-duo { grid-template-columns: 1fr; } }
.aqt-duo .aqt-sec { margin-bottom: 12px; }
.aqt-sec { background: var(--superficie); border: 1px solid var(--linha);
           border-radius: 12px; padding: 12px; margin-bottom: 12px; }
.aqt-st { font-size: 13px; font-weight: 800; }
.aqt-ss { font-size: 10px; color: var(--tinta-3); margin-bottom: 10px; }

/* Dia do mês: até 31 barras. `position: relative` é o que ancora a linha da
   média — ela é posicionada por `bottom`, na MESMA escala das barras. */
.aqt-dplot { position: relative; display: flex; align-items: flex-end; gap: 2px;
             height: 120px; border-bottom: 1px solid var(--linha); }
.aqt-dcol { flex: 1; display: flex; justify-content: center; align-items: flex-end;
            min-width: 0; }
.aqt-dbar { width: 72%; border-radius: 2px 2px 0 0; min-height: 1px; }
.aqt-daxis { display: flex; gap: 2px; margin-top: 3px; }
.aqt-dlbl { flex: 1; text-align: center; font-size: 8px; color: var(--tinta-3);
            min-width: 0; }
.aqt-avg { position: absolute; left: 0; right: 0; border-top: 1px dashed var(--ruim);
           pointer-events: none; }
.aqt-avg span { position: absolute; right: 0; top: -13px; font-size: 8px;
                color: var(--ruim); background: var(--superficie); padding: 0 3px;
                font-weight: 700; }

/* Os dois gráficos de baixo, lado a lado — e um sobre o outro quando não cabem.
   ⚠️ `min-width` nos filhos: sem ele o flex encolhe as duas colunas até os
   rótulos se sobreporem, em vez de quebrar a linha. */
.aqt-cols2 { display: flex; gap: 14px; flex-wrap: wrap; }
.aqt-cols2 > .aqt-sec { flex: 1 1 280px; min-width: 260px; }
.aqt-brow { display: flex; align-items: flex-end; gap: 8px; height: 175px; }
.aqt-bcol { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
            align-items: center; min-width: 0; }
.aqt-bbar { width: 55%; border-radius: 3px 3px 0 0; min-height: 2px; }
.aqt-bval { font-size: 9px; font-weight: 700; color: var(--tinta-2); margin-bottom: 3px; }
.aqt-bx { font-size: 10px; color: var(--tinta-2); margin-top: 5px; text-align: center;
          line-height: 1.25; }
.aqt-rg { display: block; color: var(--tinta-3); font-size: 8px; }

/* ===========================================================================
   CUSTOS — tradução de `Dash Custos Marketplaces (HTML)`.
   Aqui vermelho e verde NÃO são exceção à reserva do topo: custo e crédito são
   exatamente o que `--ruim` e `--bom` significam. Um abatimento pintado de
   vermelho leria como despesa.
   ========================================================================= */
.aqt-ruim { color: var(--ruim); }
.aqt-bom  { color: var(--bom); }

/* `align-items: start` — cada cartão com a SUA altura. Esticados, o do ML (4
   linhas) ficava com um palmo de vazio embaixo para acompanhar o da Shopee, que
   tem 9. É o que o painel do modelo faz. */
.aqt-plats { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
             gap: 10px; margin-bottom: 12px; align-items: start; }
.aqt-pc { background: var(--superficie); border: 1px solid var(--linha);
          border-top: 3px solid; border-radius: 12px; padding: 9px 11px; }
.aqt-ph { display: flex; align-items: center; gap: 7px; font-weight: 800; font-size: 13.5px; }
/* O crachá é branco (ou da cor da marca) em qualquer tema: o fundo aqui é do
   ATIVO, não do tema — mesma razão do logo no topo. */
.aqt-pic { width: 30px; height: 24px; border-radius: 6px; display: inline-flex;
           align-items: center; justify-content: center; flex: 0 0 auto;
           overflow: hidden; }
.aqt-pic svg { height: 18px; width: auto; }
.aqt-pt { margin-left: auto; text-align: right; font-size: 15px; font-weight: 800; }
.aqt-ps { font-size: 9.5px; color: var(--tinta-2); margin: 2px 0 7px; }

.aqt-fr { display: flex; align-items: baseline; gap: 6px; margin-top: 5px; font-size: 11px; }
.aqt-fl { flex: 1; color: var(--tinta); min-width: 0; }
.aqt-fv { font-weight: 700; white-space: nowrap; }
.aqt-fp { width: 46px; text-align: right; color: var(--tinta-3); font-size: 9px;
          white-space: nowrap; }
.aqt-fb { height: 3px; border-radius: 2px; background: var(--trilho);
          overflow: hidden; margin-top: 2px; }
.aqt-fb i { display: block; height: 100%; border-radius: 2px; }
.aqt-ft { display: flex; align-items: baseline; gap: 6px; border-top: 2px solid var(--linha);
          margin-top: 9px; padding-top: 6px; font-size: 12px; font-weight: 800; }
.aqt-ft .aqt-fp { font-weight: 700; }
.aqt-fn { font-size: 8.5px; color: var(--tinta-3); margin-top: 7px; line-height: 1.4; }

/* Os chips de categoria reusam .aqt-kl/.aqt-kv/.aqt-ks do bloco de KPI, só
   menores — são a mesma ideia visual, e dois conjuntos de nomes para a mesma
   coisa é como uma cor de série muda sozinha entre duas telas. */
.aqt-cat { display: flex; gap: 8px; flex-wrap: wrap; }
.aqt-cc { flex: 1 1 120px; background: var(--pagina); border: 1px solid var(--linha);
          border-radius: 8px; padding: 5px 8px; min-width: 0; }
.aqt-cat .aqt-kv { font-size: 13px; }
.aqt-cc-tot { border-color: var(--ruim); }

.aqt-per-bl { flex: 1 1 260px; min-width: 240px; }
.aqt-pbt { font-size: 11px; font-weight: 800; border-bottom: 1px solid var(--linha);
           padding-bottom: 4px; margin-bottom: 4px; display: flex; }
.aqt-pbt span { margin-left: auto; color: var(--ruim); }
.aqt-pr { display: flex; align-items: baseline; gap: 8px; font-size: 11px; padding: 2px 0; }
.aqt-pl { flex: 1; min-width: 0; color: var(--tinta); }
.aqt-pn { color: var(--tinta-3); font-size: 9px; white-space: nowrap; }
.aqt-pv { font-weight: 700; white-space: nowrap; }

.aqt-tab { width: 100%; border-collapse: collapse; font-size: 11px; }
.aqt-tab th { text-align: left; font-size: 9px; text-transform: uppercase;
              letter-spacing: .4px; color: var(--tinta-3); font-weight: 700;
              padding: 0 6px 4px; border-bottom: 1px solid var(--linha); }
.aqt-tab td { padding: 4px 6px; border-bottom: 1px solid var(--linha); }
.aqt-tab .n { text-align: right; }
.aqt-tab .aqt-tot td { font-weight: 800; border-bottom: 0; border-top: 2px solid var(--linha); }

/* ===========================================================================
   ML - VENDAS — a primeira tela de DETALHE: filtros próprios e tabela larga.
   ========================================================================= */
.aqt-filtros { display: flex; gap: 8px; flex-wrap: wrap; align-items: flex-end;
               background: var(--superficie); border: 1px solid var(--linha);
               border-radius: 12px; padding: 9px 11px; margin-bottom: 12px; }
.aqt-f { display: flex; flex-direction: column; gap: 3px; font-size: 10px;
         color: var(--tinta-2); text-transform: uppercase; letter-spacing: .3px; }
/* ⚠️ ALTURA FIXA nos tres tipos de campo. `input[type=search]` e `select`
   calculam alturas diferentes sozinhos, e com `align-items: flex-end` a
   diferenca empurra os ROTULOS para alturas diferentes — a barra fica torta e
   parece desalinhamento de margem, que nao e. */
.aqt-f input, .aqt-f select { font: inherit; font-size: 12px; text-transform: none;
         letter-spacing: 0; color: var(--tinta); background: var(--pagina);
         border: 1px solid var(--linha); border-radius: 6px; padding: 3px 7px;
         min-width: 96px; height: 28px; box-sizing: border-box;
         /* ⚠️ `margin: 0` ANULA o `margin-bottom: 1.1rem` que o estilo.css poe em
            TODO `input` (para espacar os campos do formulario de login). Sao
            17,6 px invisiveis que empurravam so os blocos com input, e a barra
            ficava com os rotulos em duas alturas diferentes. Terceira vez que
            uma regra global do estilo.css morde um elemento novo: antes foram
            `button { width: 100% }` e o fundo do botao no tema escuro. */
         margin: 0; }
.aqt-f input[type=search] { min-width: 220px; }
/* Dois campos (mín/máx) dentro do mesmo rótulo. */
.aqt-f2 { display: grid; grid-template-columns: auto auto; gap: 3px 5px; }
.aqt-f2 > span { grid-column: 1 / 3; }
.aqt-f2 input { min-width: 66px; width: 66px; }
/* ⚠️ Precisa anular `width: 100%` do `button` global — a mesma pegadinha das
   abas, e do `.atalhos` antes delas. */
.aqt-limpar { width: auto; margin-left: auto; font-size: 11px; padding: 5px 12px;
              background: var(--pagina); color: var(--tinta-2);
              border: 1px solid var(--linha); border-radius: 6px; }
.aqt-limpar:hover:not(:disabled) { background: var(--superficie); color: var(--tinta); }
:root[data-tema="escuro"] .aqt-limpar { background: var(--pagina); color: var(--tinta-2); }

/* Exportar: mesma forma do Limpar, mas com peso — e o unico botao da barra que
   faz algo alem de filtrar, e o unico que produz um arquivo. */
.aqt-exportar { width: auto; margin-left: 8px; font-size: 11px; font-weight: 700;
                padding: 5px 12px; background: var(--acento); color: #fff;
                border: 1px solid var(--acento); border-radius: 6px; white-space: nowrap; }
.aqt-exportar:hover:not(:disabled) { filter: brightness(1.08); }
.aqt-exportar:disabled { opacity: .6; cursor: progress; }
/* No escuro o azul e claro demais para carregar branco — mesma inversao da aba
   ativa e do `button` do tema. */
:root[data-tema="escuro"] .aqt-exportar { background: var(--acento); color: #091540; }

/* A tabela é larga de propósito — 19 colunas, como o painel do modelo. Rola
   DENTRO do próprio quadro, para a página não rolar de lado inteira. */
.aqt-rolagem { overflow-x: auto; }
.aqt-tab-det { font-size: 10.5px; white-space: nowrap; }
.aqt-tab-det td, .aqt-tab-det th { padding: 3px 6px; }
.aqt-tab-det tbody tr:hover { background: var(--pagina); }

/* Compras: a linha em que o custo CADASTRADO esta abaixo do unitario do pedido.
   ⚠️ Uma BARRA na lateral, e nao fundo colorido: sao ~72% das linhas (o unitario
   do pedido e ~2,8x o da nota, entao o cadastro fica abaixo dele quase sempre),
   e pintar tres de cada quatro linhas nao destaca nada — cansa e some. A barra
   se le ao correr o olho pela coluna da esquerda e nao briga com o texto.
   Quem quer SO essas linhas usa o filtro "Custo cadastrado".
   ⚠️ `box-shadow` interno em vez de `border-left`: borda mexeria na largura da
   celula e desalinharia a coluna Produto das linhas vizinhas. */
.aqt-tab-det tbody tr.aqt-cpsub > td:first-child {
  box-shadow: inset 3px 0 0 var(--atencao);
}
.aqt-prod { max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
/* Cabeçalho que ordena. A seta só aparece na coluna ativa — seta em todas as
   colunas vira ruído e some justamente onde importa. */
.aqt-ord { cursor: pointer; user-select: none; }
.aqt-ord:hover { text-decoration: underline; }
.aqt-ord:focus-visible { outline: 2px solid var(--acento); outline-offset: -2px; }
.aqt-ord-on { font-weight: 700; }
.aqt-seta { font-size: 8px; margin-left: 2px; }
.aqt-ped { font-variant-numeric: tabular-nums; }
.aqt-conta { font-size: 10.5px; color: var(--tinta-3); margin-top: 8px; }

/* Selos. `aqt-bg` é o de status; os dois de logística têm cor de marca. */
.aqt-bg { display: inline-block; font-size: 9px; font-weight: 700; padding: 1px 5px;
          border-radius: 4px; }
.aqt-b-ok  { background: #dcfce7; color: #166534; }
.aqt-b-mau { background: #fee2e2; color: #991b1b; }
.aqt-b-avi { background: #fef3c7; color: #92400e; }
.aqt-b-ext { background: #ede9fe; color: #5b21b6; }
.aqt-b-neu { background: var(--trilho); color: var(--tinta-2); }
.aqt-bg-full { background: #00a650; color: #fff; font-size: 8px; font-weight: 700;
               padding: 1px 4px; border-radius: 3px; }
.aqt-bg-flex { background: #3483fa; color: #fff; font-size: 8px; font-weight: 700;
               padding: 1px 4px; border-radius: 3px; }
/* As duas transportadoras da Shopee que MUDAM O CUSTO ganham cor: a Entrega
   Direta paga motoboy, e a Turbo tem tarifa propria. As outras tres saem em
   texto — cor para tudo e cor para nada. */
.aqt-bg-direta { background: #ede9fe; color: #5b21b6; }
.aqt-bg-turbo  { background: #ffedd5; color: #9a3412; }
/* FBA = quem entrega e a Amazon, e por isso o custo de frete aparece na
   fatura dela. O FBM sai em texto: e a maioria, e selo em quase toda linha
   nao distingue nada. */
.aqt-bg-fba { background: #fff7ed; color: #c2410c; }
.aqt-fg { color: var(--tinta-3); font-size: 8.5px; }
/* Cinza = "não dá para afirmar", e não "zero". Vale para lucro e margem de
   pedido sem custo confiável. */
.aqt-c-na { color: var(--tinta-3); }
.aqt-aten { color: var(--atencao); }

/* =============================================================================
   FINANCEIRO — Contas a Pagar (site/financeiro.js)
   =============================================================================
   ⚠️ Tudo com prefixo `fin-`. O `site/` e compartilhado com o dashboard do
   Aquarismo Total, e nome de classe CSS e espaco global entre as telas: uma
   classe curta inventada aqui pode esmagar um elemento de la sem erro de JS e
   sem nada nos testes. Ja aconteceu com `.aqt-pt`. Ver plan/24.
   ========================================================================== */

/* Dois quadros lado a lado, empilhando quando nao cabem. `minmax(0, 1fr)` e
   nao `1fr`: item de grid nasce com `min-width: auto` e a coluna incharia para
   caber a tabela inteira, levando a rolagem interna a nunca acionar — foi
   exatamente assim que o grafico de semanas vazou para fora da pagina. */
.fin-par {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
  gap: var(--e2); margin-bottom: var(--e2);
}
.fin-par > .cartao-dados { margin-bottom: 0; }

/* Selo "rever": herdado do relatorio, que marca assim o fornecedor interno 614
   (AQUATICA) e as linhas sem grupo ou sem despesa no cadastro. Cor de atencao,
   que aqui e legitima — e status, nao serie. */
.fin-selo {
  font-size: 9px; font-weight: 700; padding: 1px 6px; border-radius: 9px;
  margin-left: 6px; background: var(--atencao); color: #fff; vertical-align: 1px;
  text-transform: uppercase; letter-spacing: .04em;
}

/* ------------------------------------------------------------------ aging */
.fin-aging { display: flex; flex-direction: column; gap: 7px; }
.fin-faixa {
  display: grid; grid-template-columns: 130px minmax(0, 1fr) 150px;
  align-items: center; gap: var(--e2); font-size: 12.5px;
}
.fin-faixa .nome { color: var(--tinta-2); }
.fin-faixa .trilho {
  background: var(--trilho); border-radius: 3px; height: 12px; overflow: hidden;
}
.fin-faixa .trilho i { display: block; height: 12px; border-radius: 3px; }
.fin-faixa .valor { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

/* O residuo do ERP. Fica com a marca de atencao a esquerda porque e uma
   ressalva sobre o numero de cima, nao um dado a mais. */
.fin-residuo {
  margin-top: var(--e2); padding: 9px 12px; font-size: 12px; line-height: 1.55;
  color: var(--tinta-2); background: var(--pagina);
  border: 1px solid var(--linha); border-left: 3px solid var(--atencao);
  border-radius: 8px;
}
.fin-residuo b { color: var(--tinta); }

/* --------------------------------------------------------- classificacoes */
.fin-cls { display: flex; flex-direction: column; }
.fin-cls-linha {
  display: flex; justify-content: space-between; align-items: center; gap: var(--e2);
  padding: 7px 0; border-bottom: 1px solid var(--linha); font-size: 12.5px;
}
.fin-cls-linha:last-child { border-bottom: none; }
.fin-cls-linha i {
  width: 10px; height: 10px; border-radius: 3px; display: inline-block; margin-right: 8px;
}
.fin-cls-linha b { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ baixas por dia */
.fin-baixas {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 500px; overflow-y: auto;
}
.fin-dia {
  display: grid; grid-template-columns: 90px minmax(0, 1fr) 175px;
  align-items: center; gap: var(--e2); font-size: 12px;
}
.fin-dia .data { color: var(--tinta-2); font-variant-numeric: tabular-nums; }
/* A largura da pilha e o total do dia contra o maior dia; dentro dela, cada
   faixa e a fatia daquele documento. Duas escalas encaixadas, de proposito:
   comparar dias pelo comprimento e documentos pela fatia. */
/* ⚠️ O QUE SEPARA UM DOCUMENTO DO OUTRO E O VAO, NAO A COR.
   A primeira versao alternava dois tons de azul por POSICAO na lista — e
   posicao e rank, nao identidade: reordenar repintava tudo. Duas coisas erradas
   de uma vez, as duas catalogadas: cor seguindo o rank, e borda desenhada para
   separar marcas. O prescrito e um vao de 2px na cor da superficie, e uma cor
   so para todos os segmentos, porque todos sao a mesma coisa.
   Medido em 19/08/2026: mediana de 7 documentos por dia, p99 20, MAXIMO 22 em
   398 dias. Com 22 faixas o vao come 7% da barra; na mediana, 1%. */
.fin-dia .pilha {
  display: flex; gap: 2px; height: 16px; background: var(--trilho);
  border-radius: 3px; overflow: hidden; min-width: 2px;
}
.fin-dia .pilha i {
  height: 100%; background: var(--baixa-outros);
  /* Documento pequeno nao pode sumir: 1px e o piso para ele continuar
     existindo na barra e continuar tendo dica. */
  min-width: 1px;
}
.fin-dia .pilha i[data-cor="1"] { background: var(--baixa-1); }
.fin-dia .pilha i[data-cor="2"] { background: var(--baixa-2); }
.fin-dia .pilha i[data-cor="3"] { background: var(--baixa-3); }
.fin-dia .pilha i[data-cor="4"] { background: var(--baixa-4); }
.fin-dia .pilha i[data-cor="5"] { background: var(--baixa-5); }
.fin-dia .pilha i[data-cor="6"] { background: var(--baixa-6); }
.fin-dia .pilha i[data-cor="7"] { background: var(--baixa-7); }
.fin-dia .pilha i[data-cor="8"] { background: var(--baixa-8); }
.fin-dia .total {
  text-align: right; font-weight: 700; font-variant-numeric: tabular-nums;
}
.fin-dia .total small {
  display: block; font-weight: 400; font-size: 10.5px; color: var(--tinta-3);
}

/* O rotulo do filtro local, que os outros paineis nao tinham porque usavam
   `input` com placeholder. Aqui sao `select`, e select sem rotulo nao diz o
   que filtra. */
.filtros-locais label {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; color: var(--tinta-3); text-transform: uppercase;
  letter-spacing: .04em; font-weight: 600;
}

/* =============================================================================
   FINANCEIRO — Contas a Receber (site/financeiro.js)
   =============================================================================
   Mesmo prefixo `fin-`, mesma razao: o `site/` e compartilhado com o AqTotal.
   ========================================================================== */

/* --------------------------------------------- Previsao x Real por dia ----
   DUAS SERIES, e por isso DUAS MATIZES — nao dois tons da mesma. Aqui a cor
   codifica IDENTIDADE (o que vencia x o que entrou), que e trabalho categorico:
   dois tons do mesmo azul leriam como "mais" e "menos" da mesma coisa.

   ⚠️ As quatro cores foram VALIDADAS pelo `validate_palette.js`, nao escolhidas
   a olho — a regra da casa desde a barra de baixas:
     claro  #2b6cb0 x #2f855a  -> tudo PASS (AE 17,4 em visao normal; 16,6 protan)
     escuro #3987e5 x #199e70  -> tudo PASS (AE 20,9 em visao normal; 19,6 deutan)
   O par escuro obvio (--acento #abd2fa com --bom #48bb78) REPROVOU em duas
   checagens: o azul claro do tema escuro e cor de TEXTO heroi, tem croma 0,07 e
   le como cinza quando vira preenchimento. Token de texto nao e token de marca.

   E a cor nunca e o unico canal: cada linha traz os dois valores escritos e o
   quadro tem legenda. */
:root {
  --cr-prev: #2b6cb0;
  --cr-real: #2f855a;
}
:root[data-tema="escuro"] {
  --cr-prev: #3987e5;
  --cr-real: #199e70;
}

.fin-dias {
  display: flex; flex-direction: column; gap: 5px;
  max-height: 500px; overflow-y: auto;
}
.fin-linha-dia {
  display: grid; grid-template-columns: 84px minmax(0, 1fr) 132px 132px;
  align-items: center; gap: var(--e2); font-size: 12px;
}
.fin-linha-dia .data { color: var(--tinta-2); font-variant-numeric: tabular-nums; }
/* As duas barras empilhadas na vertical, uma por serie. O vao de 2px entre elas
   e o mesmo separador da barra de baixas: superficie, nao borda. */
.fin-linha-dia .barras { display: flex; flex-direction: column; gap: 2px; }
.fin-linha-dia .barras i { display: block; height: 6px; border-radius: 3px; min-width: 1px; }
.fin-linha-dia .barras i.prev { background: var(--cr-prev); }
.fin-linha-dia .barras i.real { background: var(--cr-real); }
.fin-linha-dia .v-prev,
.fin-linha-dia .v-real {
  text-align: right; font-weight: 700; font-variant-numeric: tabular-nums;
}
.fin-linha-dia .v-prev { color: var(--cr-prev); }
.fin-linha-dia .v-real { color: var(--cr-real); }

/* Legenda: presente sempre que ha duas series, pela regra de acessibilidade. */
.fin-legenda {
  display: flex; gap: var(--e3); align-items: center; flex-wrap: wrap;
  font-size: 11.5px; color: var(--tinta-2); margin-bottom: 8px;
}
.fin-legenda span { display: inline-flex; align-items: center; gap: 6px; }
.fin-legenda i { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.fin-legenda i.prev { background: var(--cr-prev); }
.fin-legenda i.real { background: var(--cr-real); }

/* ------------------------------------------------- parcelas em aberto ----
   A coluna que lista as parcelas de cada cliente. Quebra linha (ao contrario
   das colunas de numero) e nunca empurra a tabela: e texto longo dentro de uma
   celula com teto. */
.fin-parc {
  font-size: 10.5px; line-height: 1.5; color: var(--tinta-2);
  white-space: normal; max-width: 340px;
}
.fin-parc b { color: var(--acento); font-weight: 700; }
.fin-parc .nenhuma { color: var(--tinta-3); }

/* Barra de filtros locais desta pagina — mesma linha dos filtros de Vendas. */
/* A barra dos tres filtros de Contas a Receber. Ela usa `.filtros-locais` (a
   mesma de Vendas) e so acrescenta o espaco embaixo — ⚠️ NAO redeclara
   `align-items`: com `flex-end`, herdado do desenho antigo em que cada campo
   vinha dentro do proprio <label>, o <select> e o <input> encostavam pela base e
   ficavam com o TOPO desalinhado. Parecem duas linhas na medicao e ficam tortos
   na tela. */
.fin-locais { margin-bottom: var(--e2); }
.fin-locais label {
  font-size: 12.5px; color: var(--tinta-2); font-weight: 600; white-space: nowrap;
}

/* ------------------------------------- as duas abas do Financeiro ---------
   ⚠️ Classes PROPRIAS (`fin-aba`), e nao as `aqt-aba` do Aquarismo Total, ainda
   que o desenho seja o mesmo. O `site/` e compartilhado entre os dois
   dashboards: reusar a classe de la amarraria esta tela as decisoes de estilo
   daquela — as dez abas do AqTotal e os dois botoes daqui nao tem por que
   caber sempre na mesma regra. Ver plan/24.

   ⚠️ `width: auto` E `flex: 0 0 auto`: o estilo.css poe `width: 100%` em TODO
   `button` (e o que faz os botoes do formulario de login ocuparem a linha), e
   sem desfazer isso aqui cada aba viraria uma faixa e as duas empilhariam — foi
   exatamente o que aconteceu com as abas do AqTotal. */
.fin-abas {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-width: var(--largura); margin: 0 auto; padding: 12px var(--e3) 0;
}
.fin-aba {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--tinta-2);
  background: transparent; border: 1px solid var(--linha); border-radius: 999px;
  width: auto; flex: 0 0 auto; padding: 6px 16px; cursor: pointer;
  white-space: nowrap;
}
.fin-aba:hover:not(.ativa) { background: var(--superficie); color: var(--tinta); }
.fin-aba.ativa {
  background: var(--acento); border-color: var(--acento);
  color: #fff; font-weight: 700;
}

/* ⚠️ O tema escuro pinta TODO `button` com especificidade maior que a classe —
   sem estas quatro linhas as duas abas virariam pilulas azuis e a ativa sumiria
   entre elas. So se ve abrindo no escuro: no claro esta certo. Mesma armadilha
   ja documentada nas abas do AqTotal, algumas centenas de linhas acima. */
:root[data-tema="escuro"] .fin-aba {
  background: transparent; color: var(--tinta-2); border-color: var(--linha);
}
:root[data-tema="escuro"] .fin-aba:hover:not(.ativa) {
  background: rgba(255, 255, 255, .12); color: #fff;
}
/* Letra do FUNDO DA PAGINA sobre o azul claro: no escuro o `--acento` nao
   carrega texto branco com contraste. */
:root[data-tema="escuro"] .fin-aba.ativa { background: var(--acento); color: #091540; }

/* ------------------------------------- as duas abas da pagina de Vendas ---
   Vendas e Metas. Classes PROPRIAS (`ven-aba`), e nao as `fin-aba` do
   Financeiro nem as `aqt-aba` do Aquarismo Total, ainda que o desenho seja o
   mesmo. O `site/` e compartilhado entre os dois dashboards: reusar a classe de
   outra tela amarraria esta as decisoes de estilo daquela. Ver plan/24 e plan/27.

   ⚠️ `width: auto` E `flex: 0 0 auto`: o estilo.css poe `width: 100%` em TODO
   `button` (e o que faz os botoes do formulario de login ocuparem a linha), e
   sem desfazer isso aqui cada aba viraria uma faixa e as duas empilhariam — foi
   exatamente o que aconteceu com as abas do AqTotal. */
.ven-abas {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-width: var(--largura); margin: 0 auto; padding: 12px var(--e3) 0;
}

/* ⚠️ ESTA LINHA NAO E REDUNDANTE, e o `.fin-abas`/`.aqt-abas` NAO a tem.
   `montarAbasVen()` esconde a barra com `classList.toggle('oculto', ...)` quando
   ha um grupo so. Mas `.oculto { display: none }` mora no estilo.css e
   `.ven-abas { display: flex }` mora aqui, no dash.css, carregado DEPOIS: mesma
   especificidade (0,0,1,0), vence a regra mais tardia, e a barra nao sumiria.
   O seletor duplo sobe a especificidade e resolve. Descoberto em 19/08/2026 ao
   replicar o mecanismo do Financeiro — onde o defeito continua, anotado em
   plan/27 como pendencia. */
.ven-abas.oculto { display: none; }

.ven-aba {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--tinta-2);
  background: transparent; border: 1px solid var(--linha); border-radius: 999px;
  width: auto; flex: 0 0 auto; padding: 6px 16px; cursor: pointer;
  white-space: nowrap;
}
.ven-aba:hover:not(.ativa) { background: var(--superficie); color: var(--tinta); }
.ven-aba.ativa {
  background: var(--acento); border-color: var(--acento);
  color: #fff; font-weight: 700;
}

/* ⚠️ O tema escuro pinta TODO `button` com especificidade maior que a classe —
   sem estas quatro regras as duas abas virariam pilulas azuis e a ativa sumiria
   entre elas. So se ve abrindo no escuro: no claro esta certo. Mesma armadilha
   ja documentada nas abas do AqTotal e do Financeiro. */
:root[data-tema="escuro"] .ven-aba {
  background: transparent; color: var(--tinta-2); border-color: var(--linha);
}
:root[data-tema="escuro"] .ven-aba:hover:not(.ativa) {
  background: rgba(255, 255, 255, .12); color: #fff;
}
/* Letra do FUNDO DA PAGINA sobre o azul claro: no escuro o `--acento` nao
   carrega texto branco com contraste. */
:root[data-tema="escuro"] .ven-aba.ativa { background: var(--acento); color: #091540; }

/* ---------------------------------------------------------------- metas ---
   ⚠️ A cor aqui e STATUS, nao serie: aberta/fechada e um estado, e por isso usa
   `--bom` e `--linha`, os tokens reservados ao semaforo, e nunca uma cor de
   dado. Ver a reserva declarada no topo deste arquivo. */
/* =============================================================================
   O CORPO DE LETRA DOS CARTOES DE METAS — 08/09/2026
   =============================================================================
   POR QUE ELE E MAIOR QUE O DO RESTO DO SITE. Estas duas secoes tem um segundo
   uso, que nenhuma outra tela deste projeto tem: o Rafael tira PRINT delas e
   manda por WhatsApp para os vendedores. O aplicativo comprime a imagem e o
   destinatario a le num telefone — o texto chega a uma fracao do tamanho em que
   foi desenhado. Numa tela de 1600 px medida em 08/09, o menor texto dos dois
   quadros era o CABECALHO DA TABELA, a 10,5 px: justamente o que diz de que e
   cada coluna. Sem ele o print vira uma grade de numeros sem rotulo.

   ⚠️ NAO E UMA TROCA DE TAMANHO, E UM FATOR — e o fator existe porque "um
   pouco maior" e um ajuste que se refaz. Todas as fontes destas secoes sao
   `calc(<o tamanho de sempre> * var(--f-metas))`, entao mexer no numero abaixo
   move as quinze de uma vez, e o tamanho original continua legivel na regra —
   qual era e quanto cresceu ficam os dois escritos.

   ⚠️⚠️ E POR QUE O ESCOPO E UMA CLASSE, e nao um ajuste nas regras de tabela.
   A tabela de chaves usa `.tabela.densa`, e `.tabela.densa` e do projeto
   INTEIRO: Vendas, Financeiro, Gerencial, AqTotal e Motoristas leem a mesma
   regra. Crescer a fonte la dentro atenderia este pedido e derrubaria telas que
   ninguem tocou — foi exatamente o que a `.kpis.linha-unica` fez em 03/09,
   quando caber o oitavo cartao da Gerencial quebrou o Painel do Vendedor e o
   Desempenho em tres larguras. A saida e a mesma daquele dia: seletor proprio,
   o compartilhado devolvido intacto. **Antes de mexer numa regra, grep em quem
   a usa.**

   O QUE NAO CRESCE, e de proposito:
     - `p.sub`, a frase que explica a secao. Ela e contexto, nao dado; crescendo
       junto disputaria leitura com os numeros. Ficando onde estava, a hierarquia
       do cartao MELHORA — o dado sobe e a explicacao recua.
     - a faixa de KPIs do topo, que e `kpis()`, compartilhada com todas as telas
       e montada FORA deste cartao. O numero heroi dela ja tem 26 px.
     - a secao "Cadastro do mes", que ninguem manda por WhatsApp: ela e de
       digitar, e um editor maior so ocuparia mais tela.
   ========================================================================== */
.cartao-metas { --f-metas: 1.25; }
/* ⚠️ E OS QUADROS DE CADA VENDEDOR, em "Chave a chave", sobem MAIS: 1,5 desde
   14/09/2026, pedido do Rafael — o print deles e o que vai para o vendedor pelo
   WhatsApp, e com 1,25 ainda chegava pequeno no telefone.

   Nenhuma regra nova de tamanho: a variavel e HERDADA, entao declarar o fator no
   `.meta-vend` vale para tudo dentro dele (tabela de chaves, nome, selos, barra
   da meta do mes, rodape), e quem manda e o ancestral MAIS PROXIMO que a
   declara — nao a especificidade. O ranking e as Medias, que sao `.cartao-metas`
   mas nao `.meta-vend`, continuam em 1,25. */
.meta-vend { --f-metas: 1.5; }

/* As regras COMPARTILHADAS, alcancadas por seletor mais especifico em vez de
   alteradas. A especificidade de cada uma esta anotada porque e ela que decide
   se a regra acontece — classe sozinha nao vence regra de elemento, licao que
   mordeu duas vezes na tela de Descontos em 03 e 04/09. */
/* (0,2,1) contra (0,1,1) de `.tabela th` */
.cartao-metas .tabela th { font-size: calc(10.5px * var(--f-metas)); }
/* (0,3,1) contra (0,2,1) de `.tabela.densa td` */
.cartao-metas .tabela.densa td { font-size: calc(12.5px * var(--f-metas)); }
/* ⚠️ NAO ha regra para `tfoot` aqui, e a ausencia foi MEDIDA. Parecia faltar:
   `.tabela tfoot td` declara 13px, e sem uma linha escapada a linha TOTAL das
   Medias ficaria menor que as celulas dela. So que ela ja nao vale nesta tabela
   — `.tabela.densa td` pesa (0,2,1) e `.tabela tfoot td` pesa (0,1,2), e classe
   conta antes de elemento: em toda tabela densa deste projeto o TOTAL sempre
   valeu os mesmos 12,5px das outras celulas. A regra que eu havia escrito aqui
   pesava (0,2,2) contra (0,3,1) da linha acima e tambem nao seria acionada:
   morreria calada, e o TOTAL cresceria pelo motivo certo por acidente.
   Quem descobriu foi a checagem nova de `testar_metas_layout.mjs`, reprovando
   na estreia — a suposicao era minha, nao um defeito do codigo. */
/* (0,3,1) contra (0,2,1) de `.cartao-dados > header h3`. ⚠️ `.cartao-dados`
   junto NAO e enfeite: sem ele os dois seletores empatam em (0,2,1) e quem vence
   passa a ser a ordem no arquivo — uma dependencia que se quebra sozinha no dia
   em que alguem mover um bloco. */
.cartao-dados.cartao-metas > header h3 { font-size: calc(13px * var(--f-metas)); }
/* (0,2,0) contra (0,1,0) nas duas */
.cartao-metas .corte { font-size: calc(12.5px * var(--f-metas)); }
.cartao-metas .rodape-tabela { font-size: calc(12px * var(--f-metas)); }
/* ⚠️ NAO ha regra para `.vazio` aqui, e a ausencia e medida. O unico `.vazio`
   que aparece dentro destes cartoes e o `<td class="vazio">sem chaves</td>`, e
   nele a regra de tabela logo acima (0,3,1) vence a de `.vazio` (0,2,0) — como
   ja vencia antes da mudanca. O `.vazio` das telas de "nenhuma meta cadastrada"
   e montado por `metaVazio()`, num `.cartao-dados` que NAO leva esta classe.
   Uma regra escrita aqui nunca seria acionada, e regra que nao alcanca nao da
   erro: so nao acontece. Escrita a ausencia para nao parecer esquecimento. */

/* O respiro acompanha a letra. Uma pilula de 15 px de texto com os 2 px de folga
   que servia a 12 px fica apertada, e linhas de tabela mais altas nao se colam
   umas nas outras — que e o que faz uma tabela continuar legivel depois de a
   imagem ser comprimida. */
.cartao-metas .tabela.densa td { padding: 6px 10px; }
.cartao-metas .tabela.densa th { padding: 6px 10px; }
.meta-vend .meta-porteiro, .meta-vend .meta-selo { padding: 3px 12px; }
.meta-vend .meta-mes-tag { padding: 3px 9px; }

/* =============================================================================
   O RANKING DO MES — a barra de cada vendedor e a linha do ritmo (08/09/2026)
   =============================================================================
   ⚠️ O SVG tem `viewBox` e NAO largura em pixel: ele ocupa a largura do cartao e
   escala o desenho inteiro junto. E o unico jeito de o corpo de letra de dentro
   dele acompanhar o resto da tela — `font-size` em SVG e ATRIBUTO, e atributo
   nao le `--f-metas` nem a largura da janela. Sem isto o grafico ficaria com
   letra encravada de 11,5 px no meio de um cartao que cresceu 25% em 08/09.

   `height: auto` junto com o viewBox e o que preserva a proporcao; sem ele o
   navegador impoe a altura padrao de 150 px e achata o desenho.
   ========================================================================== */
.rk-svg { display: block; width: 100%; height: auto; }
.rk-col { cursor: help; }
.rk-col:hover .rk-barra { opacity: .82; }

/* A REGUA da linha — o numero que a gerou, escrito. Uma reta sem isso nao e
   conferivel: "estou abaixo da linha" pode ser desempenho ou pode ser a carga
   da madrugada que ainda nao chegou, e so a data separa os dois casos. */
.rk-regua {
  font-size: calc(12px * var(--f-metas)); color: var(--tinta-2);
  padding-bottom: var(--e2);
}
.rk-regua strong { color: var(--tinta); }
/* Quantos vendedores o grafico mostra de quantos o mes tem. Sublinhado
   pontilhado porque HA explicacao atras — os seis nomes, na dica —, e e o mesmo
   sinal que a tabela de Comissao ja usa para "tem explicacao aqui". */
.rk-fora { border-bottom: 1px dotted var(--tinta-3); cursor: help; }

/* A LEGENDA QUE ESCOLHE QUEM APARECE (14/09/2026) — um checkbox por vendedor e
   um para a GERAL, embaixo do grafico.

   ⚠️ TRES REGRAS GLOBAIS DO estilo.css precisam ser desfeitas aqui, e cada uma
   quebraria a legenda de um jeito diferente, sem erro:
     `label`  e display:block, MAIUSCULO e com margem — cada nome viraria uma
              linha inteira, gritando;
     `input`  tem width:100%, padding e margin-bottom de campo de texto — o
              checkbox esticaria a linha toda;
     `button` tem width:100% e fundo azul — e no ESCURO a regra e
              `:root[data-tema="escuro"] button`, especificidade MAIOR que a
              classe, por isso os botoes tem override proprio para o escuro.
   Mesma familia do defeito das abas de 19/08 (plan/27). */
.rk-leg {
  display: flex; flex-direction: column; gap: 8px;
  margin-top: var(--e2); padding-top: var(--e2);
  border-top: 1px solid var(--linha);
}
.rk-leg-tit {
  font-size: calc(11.5px * var(--f-metas)); font-weight: 600; color: var(--tinta-2);
  text-transform: uppercase; letter-spacing: .05em;
}
.rk-leg-itens { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.rk-leg .rk-leg-item {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0; font-size: calc(12.5px * var(--f-metas)); font-weight: 400;
  color: var(--tinta); text-transform: none; letter-spacing: normal;
  cursor: pointer; white-space: nowrap;
}
.rk-leg .rk-leg-item.rk-leg-geral { font-weight: 700; }
/* Desmarcado fica apagado mas LEGIVEL: e o nome que se procura para marcar de
   volta, entao nao pode sumir. `--tinta-3` e a tinta de legenda do projeto. */
.rk-leg .rk-leg-item.desmarcado { color: var(--tinta-3); }
.rk-leg .rk-leg-item input {
  width: auto; margin: 0; padding: 0; border: 0; background: none;
  box-shadow: none; accent-color: var(--acento); cursor: pointer;
}
.rk-leg .rk-leg-item input:focus-visible { outline: 2px solid var(--acento); outline-offset: 2px; }
.rk-leg-acoes { display: flex; flex-wrap: wrap; gap: 6px; }
.rk-leg .rk-leg-acao {
  width: auto; flex: 0 0 auto; margin: 0; padding: 4px 11px;
  font: inherit; font-size: calc(12px * var(--f-metas)); font-weight: 600;
  color: var(--tinta-2); background: transparent;
  border: 1px solid var(--linha); border-radius: 999px; cursor: pointer;
}
.rk-leg .rk-leg-acao:hover:not(:disabled) { background: var(--superficie); color: var(--tinta); }
:root[data-tema="escuro"] .rk-leg .rk-leg-acao {
  background: transparent; color: var(--tinta-2); border-color: var(--linha);
}
:root[data-tema="escuro"] .rk-leg .rk-leg-acao:hover:not(:disabled) {
  background: rgba(255, 255, 255, .12); color: #fff;
}
.rk-vazio { padding: var(--e3) 0; }

/* ⚠️ UM cartao por linha, sempre — e nao dois lado a lado, como era ate
   20/08/2026. Com quinze vendedores em ordem alfabetica, duas colunas obrigam a
   varrer em ziguezague para achar um nome, e a tabela de chaves de cada cartao
   fica estreita demais para a barra de progresso significar alguma coisa.
   Pedido pelo Rafael depois de ver a tela cheia. */
.meta-grade { display: grid; gap: var(--e3); grid-template-columns: minmax(0, 1fr); }

/* ⚠️ O CARTAO PRECISA PARECER UM CARTAO. Ate 20/08/2026 os quinze vendedores
   eram blocos sem moldura, empilhados com um respiro entre eles — e a leitura
   ficava confusa: o rodape de um (`Meta do mes ... Premio ...`) encostava no
   nome do proximo, e nao dava para saber onde um terminava. Com quinze deles a
   rolagem vira uma parede de texto.

   Tres coisas resolvem, e as tres importam juntas: SUPERFICIE propria (o cartao
   se destaca do fundo da secao), BORDA (o limite e explicito, nao sugerido) e o
   NOME numa faixa (a fronteira de cima fica onde o olho procura). O espaco
   sozinho nao bastava: espaco separa, mas nao delimita. */
.meta-vend {
  background: var(--superficie);
  border: 1px solid var(--linha);
  border-radius: 10px;
  padding: 0;
  overflow: hidden;
}
.meta-vend > header {
  display: flex; align-items: baseline; gap: var(--e2);
  justify-content: space-between; flex-wrap: wrap;
  /* A faixa do nome: e ela que diz "aqui comeca outro vendedor". */
  background: var(--fundo-suave, rgba(0, 0, 0, .04));
  border-bottom: 1px solid var(--linha);
  padding: 10px var(--e3);
  margin: 0;
}
/* ⚠️ `color` EXPLICITO. O nome do vendedor e o rotulo mais importante do cartao
   e vinha herdando `--tinta-3` de `.sub-cartao`, que e tinta de legenda: 2,9:1
   sobre a faixa neutra, ABAIXO dos 4,5:1 de texto. O defeito e anterior a cor do
   mes — ela so o tornou mensuravel, porque a medicao da faixa colorida passou a
   calcular a razao de contraste do que esta escrito em cima dela. Herdar tinta
   de legenda num titulo e o tipo de coisa que ninguem ve olhando. */
.meta-vend h3 { margin: 0; font-size: calc(15px * var(--f-metas)); letter-spacing: .01em;
  color: var(--tinta); }
.meta-vend > *:not(header) { padding-left: var(--e3); padding-right: var(--e3); }
.meta-vend .corte { margin: var(--e2) var(--e3); }
.meta-vend .meta-rodape {
  border-top: 1px solid var(--linha);
  margin-top: var(--e2); padding: var(--e2) var(--e3) var(--e3);
}
.meta-vend .rodape-tabela { padding-bottom: var(--e3); }
:root[data-tema="escuro"] .meta-vend:not([data-mes]) > header {
  background: rgba(255, 255, 255, .05);
}

/* =============================================================================
   A COR DO MES — 12 cores fixas, as MESMAS nos dois temas
   =============================================================================
   Pedido do Rafael em 20/08/2026: que a troca de mes se veja sem ler. A faixa do
   nome do vendedor recebe a cor do mes, e todo cartao da tela usa a mesma — nao
   e para comparar vendedores, e para responder "ja estamos em outro mes?".

   ⚠️ A PALETA FOI CALCULADA, NAO ESCOLHIDA. Doze matizes igualmente espacadas em
   OKLCH reprovaram no validador: fev x mar davam dE 6,7 em VISAO NORMAL — a
   matiz sozinha, a 30 graus de passo, nao separa vizinhos, porque a matiz nao e
   perceptualmente uniforme (corre depressa no laranja, devagar no ciano). O que
   resolveu foi ALTERNAR A LUMINOSIDADE entre meses consecutivos (L 0,49 e 0,66,
   dentro da faixa que serve aos DOIS temas) e deixar o passo de matiz variavel.

   Resultado, medido com scripts/validate_palette.js nas duas superficies reais
   (#ffffff e #101b52): faixa de luminosidade, piso de croma, separacao para
   daltonismo e piso de visao normal PASSAM nos dois temas. O pior par vizinho da
   17,1 em visao normal e 15,0 sob protanopia.

   ⚠️ E A VIRADA DO ANO foi conferida A PARTE. O validador so olha pares
   CONSECUTIVOS DA LISTA, e dezembro e janeiro sao vizinhos no CALENDARIO e ficam
   nas pontas opostas do array: a checagem padrao aprovaria uma paleta em que a
   troca de ano nao se nota, que e justamente a mais importante. A sequencia e
   ciclica, entao girar a lista nao muda nenhum par — muda so ONDE cada par cai.
   Ela foi girada de modo que o par MAIS FORTE (dE 19,7) caia em dez -> jan.

   ⚠️ O unico aviso do validador e contraste abaixo de 3:1 contra a superficie,
   que ele mesmo classifica como "relief required (visible labels)". O alivio
   existe e e explicito: a etiqueta escreve o mes em letras. A cor NUNCA esta
   sozinha — nem aqui, nem no resto do projeto.

   O valor e guardado como TRIPLA RGB para servir aos dois usos a partir de uma
   declaracao so: `rgb(var(--mes-rgb))` no traco e `rgb(var(--mes-rgb) / .16)` na
   lavagem de fundo. Guardar um hex obrigaria a repetir cada cor em duas formas,
   e duas formas da mesma cor e como elas comecam a divergir. */
.meta-vend[data-mes="1"]  { --mes-rgb: 176 123 201; }   /* jan · lilás     */
.meta-vend[data-mes="2"]  { --mes-rgb: 146  55 117; }   /* fev · magenta   */
.meta-vend[data-mes="3"]  { --mes-rgb: 213 112 125; }   /* mar · rosa      */
.meta-vend[data-mes="4"]  { --mes-rgb: 155  63   0; }   /* abr · ferrugem  */
.meta-vend[data-mes="5"]  { --mes-rgb: 193 134  41; }   /* mai · dourado   */
.meta-vend[data-mes="6"]  { --mes-rgb: 109  97   0; }   /* jun · oliva     */
.meta-vend[data-mes="7"]  { --mes-rgb: 127 161  70; }   /* jul · verde-limão */
.meta-vend[data-mes="8"]  { --mes-rgb:   0 118  65; }   /* ago · verde     */
.meta-vend[data-mes="9"]  { --mes-rgb:   0 170 174; }   /* set · turquesa  */
.meta-vend[data-mes="10"] { --mes-rgb:   0 105 161; }   /* out · petróleo  */
.meta-vend[data-mes="11"] { --mes-rgb: 108 145 225; }   /* nov · azul      */
.meta-vend[data-mes="12"] { --mes-rgb:  82  81 173; }   /* dez · índigo    */

/* A faixa: lavagem no fundo e o traco em forca total embaixo.

   ⚠️ LAVAGEM, e nao cor cheia. O cabecalho carrega o nome do vendedor e DOIS
   selos que ja tem cor propria e significado proprio (o porteiro em verde,
   vermelho ou acento; as chaves em verde). Uma faixa saturada atras deles
   quebraria o contraste dos tres de uma vez e faria a cor do MES disputar leitura
   com a cor do ESTADO — duas escalas diferentes no mesmo centimetro quadrado. A
   16% a faixa fica perto da superficie: o texto nao muda de contraste, e a cor
   aparece na area, que e onde ela precisa aparecer. */
.meta-vend[data-mes] > header {
  background: rgb(var(--mes-rgb) / .16);
  border-bottom: 3px solid rgb(var(--mes-rgb));
}

/* O nome e a etiqueta do mes andam juntos, à esquerda; os selos ficam à direita
   pelo `space-between` que o cabecalho ja tinha. */
.meta-vend-nome { display: flex; align-items: baseline; gap: var(--e2);
  min-width: 0; }

/* ⚠️ A ETIQUETA E O QUE TIRA A COR DA CONDICAO DE UNICO SINAL. Ela escreve o
   mes — quem nao distingue as matizes le "AGO" igual a todo mundo, e quem
   distingue nao precisa aprender doze cores de cor para saber qual e qual.
   Texto em `--tinta`: assim nenhuma das doze precisa passar em contraste de
   TEXTO, o que exigiria doze decisoes separadas e duas variantes por tema. */
.meta-mes-tag { font-size: calc(11px * var(--f-metas)); font-weight: 700; letter-spacing: .06em;
  border-radius: 4px; padding: 2px 7px; white-space: nowrap;
  color: var(--tinta);
  background: rgb(var(--mes-rgb) / .3);
  border: 1px solid rgb(var(--mes-rgb));
}

.meta-selo { font-size: calc(12px * var(--f-metas)); font-weight: 600; color: var(--tinta-2);
  border: 1px solid var(--linha); border-radius: 999px; padding: 2px 10px; }
.meta-selo.ganhou { color: var(--bom); border-color: var(--bom); }
.ganhou { color: var(--bom); }
.bloqueado { color: var(--ruim); }

/* O SELO DO PORTEIRO — a meta do mes, que decide se as chaves valem dinheiro.

   ⚠️ Cor de STATUS, e nunca cor sozinha: os tres estados vem com cadeado E
   rotulo por extenso ("meta do mes batida"), porque quem nao distingue verde de
   vermelho tem de ler a mesma coisa que os outros. O `title` traz a consequencia
   inteira — e a consequencia, nao o estado, e o que a pessoa foi buscar. */
.meta-porteiro { font-size: calc(12px * var(--f-metas)); font-weight: 600; border-radius: 999px;
  padding: 2px 10px; border: 1px solid var(--linha); color: var(--tinta-2);
  white-space: nowrap; }
.meta-porteiro.batida     { color: var(--bom);    border-color: var(--bom); }
.meta-porteiro.nao-batida { color: var(--ruim);   border-color: var(--ruim); }
.meta-porteiro.indefinida { color: var(--tinta-3); border-style: dashed; }
/* MES EM CURSO, abaixo da meta: `--acento`, e nem vermelho nem ambar.

   ⚠️ Vermelho no dia 10 anuncia uma derrota que nao aconteceu, e desanima quem
   a tela existe para fazer correr; ambar diz "atencao", que tambem e um juizo.
   O acento e a cor de NUMERO, sem carga de juizo — o estado aqui e "andando",
   nao "mal". E `--acento` e token de TEXTO nos dois temas (no escuro ele e claro
   demais para virar preenchimento, licao do painel Previsao x Real), que e
   exatamente o uso aqui. Quem carrega o significado e a frase: "faltam R$ X". */
.meta-porteiro.a-caminho  { color: var(--acento); border-color: var(--acento); }

.meta-chaves td.nome small { display: block; font-size: calc(11px * var(--f-metas));
  color: var(--tinta-3); }
/* A FRAÇÃO por trás do percentual, nas chaves de positivação (20/08/2026):
   "45,5%" em cima e "30 de 66" embaixo, na tinta de legenda. Ela responde a
   pergunta que o percentual sozinho deixava no ar — *quantos clientes faltam?*
   `tabular-nums` porque as duas linhas da mesma coluna têm de alinhar dígito
   com dígito; sem isso o "de" dança de posição entre as linhas da tabela. */
.meta-chaves td.num small {
  display: block; font-size: calc(11px * var(--f-metas)); color: var(--tinta-3);
  font-weight: 500; font-variant-numeric: tabular-nums;
}
.meta-chaves td.cadeado { text-align: center; width: 34px; }
/* Sem fundo verde na linha inteira: com quatro chaves abertas o cartao viraria
   um bloco de cor e o cadeado, que e o sinal, deixaria de saltar. */
.meta-chaves tr.chave-aberta td.nome { font-weight: 600; }
.meta-chaves tr.chave-inativa { opacity: .55; }
.meta-chaves .trilho-mini { min-width: 90px; }
/* A barra so muda de cor quando ABRE. Enquanto nao abriu ela e neutra — pintar
   97,5% de verde diria "conseguiu", e nao conseguiu.

   ⚠️ O seletor e `.meta-vend`, e nao `.meta-chaves`. Nasceu preso a tabela de
   chaves, e quando a META DO MES ganhou barra propria (20/08/2026) ela ficou de
   fora: batida, continuava azul. O `.cheia` estava no HTML, certinho, e nao
   fazia nada — regra de estilo que nao alcanca nao da erro, so nao acontece.
   Quem viu foi a medicao no Chrome, comparando as cores das duas barras. */
.meta-vend .preench.cheia { background: var(--bom); }

.meta-rodape { display: flex; flex-wrap: wrap; gap: var(--e2) var(--e3);
  font-size: calc(12px * var(--f-metas)); color: var(--tinta-2); padding-top: var(--e2); }
.meta-rodape strong { color: var(--tinta); }

/* O BLOCO DA META DO MES — acima da tabela de chaves, porque e ele que decide se
   as chaves valem alguma coisa.

   A barra usa o mesmo `.trilho-mini`/`.preench` das chaves de proposito: sao a
   mesma leitura ("quanto do alvo ja foi"), e duas barras diferentes no mesmo
   cartao fariam o olho procurar uma diferenca que nao existe. O que as separa e
   a POSICAO e a largura — esta atravessa o cartao inteiro, as das chaves cabem
   numa coluna. */
.meta-geral { padding-top: var(--e2); padding-bottom: var(--e2); }
.meta-geral-linha { display: flex; flex-wrap: wrap; gap: 2px var(--e3);
  align-items: baseline; font-size: calc(12px * var(--f-metas)); color: var(--tinta-2);
  padding-bottom: 6px; }
.meta-geral-linha strong { color: var(--tinta); }
.meta-geral-pct { font-size: calc(14px * var(--f-metas)); }
.meta-geral .trilho-mini { height: 11px; }
.meta-geral-nota { display: block; padding-top: 6px;
  font-size: calc(11px * var(--f-metas)); color: var(--tinta-3); }
.meta-geral-nota strong { color: var(--tinta-2); }
.meta-geral-nota.bom { color: var(--bom); }
.meta-geral-nota.bom strong { color: var(--bom); }

/* A celula do historico em que a meta do mes NAO foi batida: o percentual das
   chaves esta ali e e verdadeiro, mas nao virou dinheiro.

   ⚠️ Nada de cor aqui, de proposito. A celula JA usa cor — o semaforo do
   percentual — e uma segunda cor por cima brigaria com a primeira: verde-escuro
   sobre 100% diria uma coisa e vermelho diria outra, no mesmo numero. O italico
   qualifica sem disputar, e quem carrega o significado sao o cadeado no texto e
   o `title` que explica. */
.meta-historico td.meta-trancada { font-style: italic; }

.meta-barra { display: flex; align-items: center; gap: var(--e2);
  flex-wrap: wrap; padding-bottom: var(--e2); }
.meta-espaco { flex: 1 1 auto; }

/* A lista de chaves do cadastro: a coluna "Cobra de" traz um segundo numero
   embaixo ("5 sem cobrar"), e sem `display: block` os dois sairiam colados na
   mesma linha. Mesma regra que `.meta-chaves td.num small` ja usa no painel —
   escrita a parte porque aquela esta presa ao seletor `.meta-chaves`, e esta
   tabela nao e ele. (Regra que nao alcanca nao da erro, so nao acontece: foi o
   que aconteceu com o verde da barra da meta em 20/08/2026.) */
.meta-lista-chaves td.num small {
  display: block; font-size: 11px; color: var(--tinta-3);
  font-weight: 500; font-variant-numeric: tabular-nums;
}
.meta-editor { border: 1px solid var(--acento); margin-top: var(--e2); }
.meta-editor h3 { margin: 0; font-size: 14px; }
.meta-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: var(--e2) 0; }

/* ------------------------------------------- importar escopo de uma planilha
   ⚠️ A regra de `.acao` mora em `.cartao-dados > header .acao` — ou seja, fora
   de um cabecalho de cartao ela NAO vale, e o botao volta a herdar
   `button { width: 100% }` do estilo.css, ocupando a linha inteira. E o mesmo
   defeito do "Exportar para Excel" de 12/08/2026 (ver plan/16), aqui num lugar
   onde ele nunca tinha sido medido.

   O conserto e ESCOPADO nesta linha, de proposito: os botoes "Salvar escopo" e
   "Fechar" do mesmo editor tem o comportamento antigo ha semanas e o Rafael usa
   assim. Mudar a largura deles de carona seria trocar a aparencia de algo que
   ninguem pediu, escondido dentro de um recurso novo. */
.meta-import { display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
               margin: var(--e2) 0 0; }
.meta-import .acao {
  width: auto; margin: 0; padding: 6px 12px;
  font: inherit; font-size: 12.5px; font-weight: 500;
  background: transparent; color: var(--tinta-2);
  border: 1px solid var(--linha); border-radius: 6px; transition: all .15s;
}
.meta-import .acao:hover:not(:disabled) {
  background: var(--serie-liquida); border-color: var(--serie-liquida); color: #fff;
}
.meta-import .sub { margin: 0; }

/* Os campos do cadastro. Estreitos de proposito: numero de meta cabe em 10
   caracteres, e um <input> de largura total numa tabela de sete colunas empurra
   o nome do vendedor para fora. */
.meta-form input[type="number"] { width: 110px; }
.meta-form input[type="text"]   { width: 100%; min-width: 120px; }
.meta-form select { width: auto; }
.meta-form td { vertical-align: middle; }

.meta-historico td.vazio-cel { color: var(--tinta-3); }
/* Mes ainda aberto: o numero dele ainda anda. O tracejado embaixo diz isso sem
   gastar cor, que aqui ja esta ocupada pelo semaforo. */
.meta-historico td.ao-vivo { border-bottom: 2px dashed var(--linha); }
.ao-vivo-legenda { border-bottom: 2px dashed var(--linha); }

.corte-inline { color: var(--atencao); font-weight: 600; }

/* Os ganchos do cadastro. Cada um tem regra de verdade — largura de campo e
   espaco entre botoes que dividem a mesma celula. Classe sem regra no CSS e
   estilo que nao existe, e `testar_metas.mjs` reprova. */
.meta-ed-escopo, .meta-ed-chave, .meta-regra, .meta-del-chave {
  margin-right: 4px;
}
/* Vermelho porque apaga a chave E todos os alvos dela — a acao destrutiva nao
   pode parecer com as outras tres do mesmo canto. */
.meta-del-chave { color: var(--ruim); border-color: var(--ruim); }
.meta-form .meta-origem { min-width: 96px; }
.meta-form .meta-total, .meta-form .meta-premio, .meta-form .meta-desconto {
  width: 110px; text-align: right;
}
.meta-form .meta-obs { width: 100%; min-width: 140px; }

/* Ação destrutiva. ⚠️ Cor de status (`--ruim`), a mesma do semáforo — não uma
   cor nova: "isto destrói" é exatamente o que o vermelho reservado significa
   neste arquivo. E não é fundo cheio: um botão vermelho sólido ao lado de
   "Fechar o mês" atrairia o clique em vez de afastá-lo. */
.acao.perigo { color: var(--ruim); border-color: var(--ruim); }
.acao.perigo:hover { background: color-mix(in srgb, var(--ruim) 12%, transparent); }

/* Cabecalho ordenavel do seletor de produtos. A regra da seta ja existe em
   `th.ord[data-dir]`; aqui so o cursor, porque estes <th> nao passam pelo
   `ligarOrdenacao` das outras tabelas — a ordem deles mora em `metasEd.ordem`. */
.meta-produtos th.ord { cursor: pointer; user-select: none; }

/* O seletor de vendedor da aba Metas. Largura propria: nome de vendedor e curto,
   mas "Todos os vendedores" nao pode ser cortado — e justamente a opcao que o
   filtro mestre nao tem, entao ela precisa ser legivel de primeira. */
.meta-filtro-vend { min-width: 220px; }

/* ------------------------------------- as tres abas da pagina de Estoque ---
   Saldo atual, Movimentacao e Saldo em uma data (08/09/2026).

   Classes PROPRIAS (`est-aba`), e nao as `ven-aba`/`fin-aba`/`aqt-aba`, ainda
   que o desenho seja o mesmo: o `site/` e servido aos TRES dashboards, e reusar
   a classe de outra tela amarraria esta as decisoes de estilo daquela. E a
   quarta barra irma, e a duplicacao continua sendo deliberada. Ver plan/24.

   ⚠️ `width: auto` E `flex: 0 0 auto`: o estilo.css poe `width: 100%` em TODO
   `button` (e o que faz os botoes do login ocuparem a linha). Sem desfazer isso
   aqui cada aba vira uma faixa e as tres empilham — medido nas abas do AqTotal:
   1442px em 2 linhas, contra 121/132px em 1. */
.est-abas {
  display: flex; flex-wrap: wrap; gap: 6px;
  max-width: var(--largura); margin: 0 auto; padding: 12px var(--e3) 0;
}

/* ⚠️ ESTA LINHA NAO E REDUNDANTE, e nasce aqui de PRIMEIRA — `.fin-abas` e
   `.aqt-abas` ainda nao a tem, e e pendencia anotada em plan/27.
   `.oculto { display: none }` mora no estilo.css e `.est-abas { display: flex }`
   mora aqui, no dash.css, carregado DEPOIS: mesma especificidade (0,0,1,0),
   vence a regra mais tardia, e a barra nao sumiria. O seletor duplo sobe a
   especificidade e resolve. */
.est-abas.oculto { display: none; }

.est-aba {
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--tinta-2);
  background: transparent; border: 1px solid var(--linha); border-radius: 999px;
  width: auto; flex: 0 0 auto; padding: 6px 16px; cursor: pointer;
  white-space: nowrap;
}
.est-aba:hover:not(.ativa) { background: var(--superficie); color: var(--tinta); }
.est-aba.ativa {
  background: var(--acento); border-color: var(--acento);
  color: #fff; font-weight: 700;
}

/* ⚠️ O tema escuro pinta TODO `button` com especificidade maior que a classe —
   sem estas tres regras as abas virariam pilulas azuis e a ativa sumiria entre
   elas. So se ve abrindo NO ESCURO: no claro esta certo. Mesma armadilha ja
   documentada nas abas do AqTotal, do Financeiro e de Vendas. */
:root[data-tema="escuro"] .est-aba {
  background: transparent; color: var(--tinta-2); border-color: var(--linha);
}
:root[data-tema="escuro"] .est-aba:hover:not(.ativa) {
  background: rgba(255, 255, 255, .12); color: #fff;
}
/* Letra do FUNDO DA PAGINA sobre o azul claro: no escuro o `--acento` nao
   carrega texto branco com contraste. */
:root[data-tema="escuro"] .est-aba.ativa { background: var(--acento); color: #091540; }

/* A linha de um movimento de ENTRADA e de SAIDA no kardex.
   ⚠️ A cor NAO e o unico portador: a celula leva tambem a palavra ("entrada" /
   "saida"), porque cor sozinha nao chega a quem nao a distingue — e porque a
   coluna vai para o .xlsx, onde nao ha cor nenhuma. */
.mov-e { color: var(--bom); font-weight: 700; }
.mov-s { color: var(--ruim); font-weight: 700; }

/* O nome do produto na aba de Saldo, que LEVA a movimentacao dele.

   ⚠️ E um `<button>` de verdade, e nao uma `<tr>` com `onclick`: `tabela()` nao
   emite atributo por linha, e acrescentar isso la mexeria numa funcao usada por
   cinco telas no ar para atender uma. Botao tambem e o elemento certo — ele
   TROCA A VISAO, nao navega para um documento —, e vem com foco e teclado de
   graca.

   ⚠️ `width: auto` outra vez: o estilo.css poe `width: 100%` em TODO `button`,
   e sem isto o nome do produto viraria uma faixa dentro da celula. */
.lig-mov {
  width: auto; background: none; border: 0; padding: 0; margin: 0;
  font: inherit; color: var(--acento); text-align: left; cursor: pointer;
  text-decoration: underline dotted; text-underline-offset: 2px;
}
.lig-mov:hover { text-decoration: underline solid; }
