
/* Fontes AUTO-HOSPEDADAS. Nada de CDN: o container é privado e não busca nada de fora — e
   uma fonte que não carrega troca a métrica da tela inteira no meio do uso. Cada arquivo é
   uma fonte VARIÁVEL: um só cobre a faixa de peso inteira. */
@font-face {
  font-family:"Onest"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url("/estatico/fontes/onest-var.woff2") format("woff2");
}
@font-face {
  font-family:"DM Sans"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url("/estatico/fontes/dmsans-var.woff2") format("woff2");
}

:root {
  --fundo:#F8FAFC; --superficie:#FFFFFF; --superficie-2:#F1F5F9;
  --tinta:#0F172A; --tinta-fraca:#55637A; --tinta-inversa:#FFFFFF;
  --acento:#0369A1; --acento-hover:#075985;
  --ok:#15803D; --alerta:#B45309; --critico:#B91C1C;
  --ok-fundo:#EEF8F2; --alerta-fundo:#FEF3C7; --critico-fundo:#FEE2E2;
  --acento-fundo:#DCEEFA;
  --borda:#E2E8F0; --borda-campo:#64748B;
  --fonte-titulo:"Onest", "Segoe UI Variable Display", "Segoe UI", system-ui, sans-serif; --fonte-texto:"DM Sans", "Segoe UI Variable Text", "Segoe UI", system-ui, sans-serif; --fonte-mono:"Cascadia Mono", Consolas, ui-monospace, "SF Mono", monospace;
  --raio:10px; --raio-grande:14px;
  /* Altura da faixa do topo. É token porque DUAS regras precisam concordar: a própria
     faixa (`min-height`, que a impõe) e o teto da barra lateral, que desconta esta
     altura do viewport. Sem o desconto, a barra media 100vh a partir de baixo da
     faixa e o rodapé de identidade caía inteiro para fora da tela — medido: viewport
     720, faixa 59, rodapé terminando em 779. */
  --faixa-altura:60px;
  --largura-max:1420px;
  --sombra:0 2px 10px rgba(15,23,42,.07);
  --sombra-alta:0 10px 22px rgba(15,23,42,.10);
  /* aliases dos nomes antigos, para as telas já escritas */
  --painel:#FFFFFF; --linha:#E2E8F0; --acento2:#075985; --erro:#B91C1C;
}

/* Camada 2 da otimização de transição (25/08/2026): liga a View Transitions API NATIVA do
   navegador pra toda navegação same-origin — sem isto era reload puro, sem transição nenhuma.
   Zero JS: é 1 at-rule só, e navegador sem suporte (fora de Chromium) simplesmente ignora e
   navega como sempre — progressive enhancement de verdade, nunca quebra. */
@view-transition { navigation: auto; }

*, *::before, *::after { box-sizing:border-box; }
html, body { margin:0; padding:0; }
body {
  background:var(--fundo); color:var(--tinta);
  font-family:var(--fonte-texto); font-size:16px; line-height:1.5;
  -webkit-font-smoothing:antialiased; min-height:100vh;
  display:flex; flex-direction:column;
}
h1, h2, h3, .titulo { font-family:var(--fonte-titulo); color:var(--tinta); margin:0;
  letter-spacing:-.015em; }
a { color:var(--acento); text-decoration:none; }
a:hover { color:var(--acento-hover); text-decoration:underline; }
:focus-visible { outline:3px solid var(--acento); outline-offset:2px; border-radius:4px; }
code { font-family:var(--fonte-mono); font-size:.85em; }

/* ── faixa do topo ─────────────────────────────────────────────────────────────────── */
.faixa {
  /* space-between virou flex-start + `.idiomas{margin-left:auto}` (28/08/2026, pedido do
     Matheus): com o sino no meio, o `space-between` original espalhava marca/sino/idiomas em
     3 pontas iguais e o sino sobrava sozinho no centro do cabeçalho. Agora marca+sino ficam
     juntos à ESQUERDA (nesta ordem no DOM) e só idiomas é empurrado pro extremo direito —
     funciona igual para quem não tem sino (só marca+idiomas, `{% if notif %}` ausente). */
  display:flex; align-items:center; justify-content:flex-start; gap:16px;
  min-height:var(--faixa-altura);
  padding:.85rem clamp(1rem,4vw,2rem);
  border-bottom:1px solid var(--borda); background:var(--superficie);
  /* Nome próprio = fora do crossfade padrão do <root>: a faixa é IDÊNTICA de página a
     página, então sem isto ela pisca junto com o conteúdo a cada navegação. */
  view-transition-name: oj-topo;
}
.marca { display:flex; align-items:baseline; gap:2px; font-family:var(--fonte-titulo);
  font-weight:800; font-size:1.25rem; letter-spacing:-.03em; }
.marca .o { color:var(--acento); }
.marca .bar { color:var(--borda); font-weight:400; margin:0 3px; }
.marca .j { color:var(--tinta); }
.marca .sub { font-family:var(--fonte-texto); font-size:.75rem; font-weight:600;
  color:var(--tinta-fraca); margin-left:.7rem; letter-spacing:.02em; }

a.marca { text-decoration:none; }
a.marca:hover { text-decoration:none; }
a.marca:hover .sub { color:var(--acento); }

/* ── sino de Comunicados (RM-68; ícone customizado 28/08/2026, pedido do Matheus) ───────
   Único ícone do Portal fora do sistema Material Symbols — os outros ~70 continuam
   flat/mono de propósito (ver icones.py). Aqui o pedido foi um tratamento dedicado (metal
   + halo + badge "glassmorphic"), com referência visual em hex; gradiente metálico não dá
   pra fazer numa ligadura de fonte, então o SVG mora inline no template
   (`templates/_moldura.html`). O número do badge segue `<span>` de verdade, não imagem —
   `{{ notif.unread }}` continua ao vivo. */
.sino { position:relative; display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:50%; text-decoration:none;
  filter:drop-shadow(0 0 6px rgba(187,222,251,.55)) drop-shadow(0 0 2px rgba(187,222,251,.35)); }
.sino:hover { background:var(--superficie-2); text-decoration:none; }
.sino-ic { width:22px; height:22px; display:block; }
.sino-contador { position:absolute; top:-2px; right:-2px; min-width:18px; height:18px;
  padding:0 4px; border-radius:999px; display:flex; align-items:center; justify-content:center;
  font-size:.69rem; font-weight:700; line-height:1; color:#fff;
  background:linear-gradient(150deg, rgba(238,68,68,.92), rgba(255,107,107,.85));
  backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px);
  border:1px solid rgba(255,255,255,.45);
  box-shadow:0 2px 6px rgba(211,47,47,.45), inset 0 1px 1px rgba(255,255,255,.5); }

/* ── pop-up de comunicado novo (RM-68) ────────────────────────────────────────────────── */
.comunicado-popup-fundo { position:fixed; inset:0; z-index:200; display:flex;
  align-items:center; justify-content:center; padding:1rem;
  background:rgba(15,23,42,.5); }
.comunicado-popup { width:100%; max-width:420px; background:var(--superficie);
  border-radius:var(--raio-grande); padding:1.4rem 1.5rem; box-shadow:0 20px 50px rgba(15,23,42,.25); }
.comunicado-popup-ic { font-size:1.8rem; color:var(--acento); }
.comunicado-popup h2 { font-family:var(--fonte-titulo); font-size:1.1rem; margin:.5rem 0 .8rem; }
.comunicado-popup-lista { list-style:none; margin:0 0 1.1rem; padding:0; display:flex;
  flex-direction:column; gap:.5rem; font-size:.88rem; color:var(--tinta); }
.comunicado-popup-lista .tag { margin-right:.4rem; }
.comunicado-popup-acoes { display:flex; gap:.6rem; }
.comunicado-popup-acoes .botao, .comunicado-popup-acoes .botao.secundario { flex:1; }

/* ── calendário (vencimentos e chegadas) ──────────────────────────────────────────── */
/* Calendário: a grade é do MÊS, e a cor da célula é por URGÊNCIA, não por volume — o que
   decide a ação é a data ter passado, não quantos títulos caem nela. Cada dia é um LINK com
   a data na querystring: assim o estado inteiro da tela cabe na URL e dá para mandar
   «olha o dia 28» para o gerente regional. */
.cal { padding:1rem 1.1rem 1.2rem; }
.cal-topo { display:flex; align-items:center; justify-content:space-between; gap:1rem;
  margin-bottom:.9rem; }
.cal-mes { font-family:var(--fonte-titulo); font-weight:700; font-size:1.1rem; }
.cal-mes span { font-family:var(--fonte-texto); font-size:.8rem; font-weight:500;
  color:var(--tinta-fraca); margin-left:.5rem; }
.cal-nav { display:inline-flex; align-items:center; justify-content:center; width:34px;
  height:34px; border:1px solid var(--borda-campo); border-radius:8px; color:var(--tinta);
  text-decoration:none; font-weight:700; }
.cal-nav:hover { background:var(--superficie-2); text-decoration:none; }
.cal-grade { display:grid; grid-template-columns:repeat(7,1fr); gap:6px; }
.cal-dw { text-align:center; font-size:.7rem; font-weight:700; letter-spacing:.04em;
  text-transform:uppercase; color:var(--tinta-fraca); padding-bottom:.2rem; }
.cal-vazio { min-height:62px; }
.cal-dia { display:flex; flex-direction:column; gap:1px; min-height:66px; padding:.4rem .55rem;
  border:1px solid var(--borda); border-radius:9px; text-decoration:none; color:var(--tinta);
  background:var(--superficie); }
.cal-dia b { font-size:.85rem; font-weight:700; font-variant-numeric:tabular-nums; }
/* O valor em uma linha só: em célula estreita ele quebrava em duas e a altura da semana
   inteira pulava. Com o calendário na largura da página, cabe. */
.cal-dia i { font-style:normal; font-size:.74rem; color:var(--tinta-fraca);
  font-variant-numeric:tabular-nums; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; }
.cal-dia u { text-decoration:none; font-size:.8rem; font-weight:700; }
a.cal-dia:hover { text-decoration:none; box-shadow:var(--sombra); }
/* Os tons são os mesmos do calendário do Streamlit, para quem alterna entre os dois mundos
   não achar que está lendo outra coisa. */
.cal-dia.venceu { background:#FEE2E2; border-color:#B91C1C; }
.cal-dia.hoje   { background:#FFE4CC; border-color:#B45309; }
.cal-dia.perto  { background:#FEF3C7; border-color:#B45309; }
.cal-dia.longe  { background:#E0F2FE; border-color:#0369A1; }
.cal-dia.vazio  { background:var(--fundo); color:var(--tinta-fraca); }
.cal-dia.sel { outline:3px solid var(--tinta); outline-offset:-3px; }

/* ── barra lateral, do mesmo lado e com as mesmas seções do Portal ────────────────── */
/* A primeira versão pôs os atalhos numa tira no TOPO. Funcionava e estava errada: o Portal
   tem menu à ESQUERDA, e trocar o lado no meio da navegação faz a pessoa procurar o menu
   onde ele não está. Continuidade vale mais que originalidade aqui.

   Passe de 24/08, no desenho do Portal de RH (`estatico/painel.css`, «barra lateral»): a
   barra deixou de ser uma pilha de pílulas com borda e virou TRÊS faixas — busca fixa no
   topo, navegação que rola, identidade fixa no rodapé. O que mudou, e por quê:

   • **Só a navegação rola.** São 61 itens em 14 seções no perfil interno. Com a barra
     inteira rolando, o campo de busca subia para fora da tela justamente quando ele começa
     a ser útil, e o nome de quem está logado nunca aparecia sem rolar até o fim.
   • **Item sem borda.** 61 retângulos desenhados são 61 linhas competindo com o texto que
     a pessoa foi ler. O que precisa de contorno é UM item — o atual. O resto se separa por
     espaçamento e responde no hover.
   • **Ícone à esquerda de tudo.** Os dados sempre existiram (`internal_view._NAV_ICONS`,
     `dealer_view._DLR_ICONS`) e a moldura os descartava; ver `icones.py`. A coluna do ícone
     tem largura fixa: sem ela, um item sem ícone desalinha o rótulo de todos os vizinhos.
   • **A seção da página atual nasce ABERTA.** O comentário do `_moldura.html` já prometia
     isso desde que a barra existe, mas `menu_lateral` nunca gravava a chave que o template
     lia — 14 seções fechadas, e nenhuma pista de onde se está. */

/* `align-items:stretch` continua: é ele que faz a linha divisória correr a página inteira.
   Quem gruda no topo é o miolo (`.lat-interno`) — um elemento esticado até o rodapé já
   ocupa toda a altura do container e não tem para onde o `sticky` movê-lo. */
.quadro-app { display:flex; align-items:stretch; flex:1; min-height:0; }
.lateral { flex:none; width:var(--lat-largura,264px); background:var(--superficie);
  border-right:1px solid var(--borda); position:relative;
  /* Mesmo motivo da `.faixa`: nome próprio tira a barra do crossfade do <root>, então só
     o miolo troca visualmente — a barra fica ESTÁVEL entre páginas. */
  view-transition-name: oj-lateral; }
.lat-interno { position:sticky; top:0;
  max-height:calc(100vh - var(--faixa-altura));
  display:flex; flex-direction:column; }
.miolo-app { flex:1; min-width:0; display:flex; flex-direction:column; }
.lateral a { display:block; text-decoration:none; }
/* `.lateral a` vence o `[hidden]` da folha do navegador por especificidade (0,1,1 vs
   0,0,1). Sem esta linha, a busca marcaria os itens filtrados como escondidos e eles
   continuariam à vista — o filtro «funcionaria» sem filtrar nada. */
.lateral [hidden] { display:none; }

/* ── redimensionar a lateral ──────────────────────────────────────────────────────────
   Tira de 8px sobre a borda (não a borda inteira: 1px é alvo pequeno demais pro mouse, e
   coarse/touch nem tenta). `--lat-largura` fica no `:root` (portal.js grava lá, com
   `localStorage` por navegador — não por papel, é preferência de tela, não de conteúdo).
   Nasce `display:none`: sem JS a lateral fica nos 264px de sempre, e uma alça que não
   arrasta nada é só confusão — o script mostra (`display:block`) só depois de prender o
   listener, mesmo padrão do `.lat-limpar` da busca. */
.lat-resize { position:absolute; top:0; right:-4px; width:8px; height:100%; display:none;
  cursor:col-resize; z-index:5; touch-action:none; }
.lat-resize:hover, .lat-resize.arrastando { background:
  linear-gradient(to right, transparent 3px, var(--acento) 3px, var(--acento) 5px, transparent 5px); }

/* Ícones Material Symbols, AUTO-HOSPEDADOS — 11 KB com exatamente os 69 nomes que o menu
   usa (`icones.NOMES`), gerados por `tools/gerar_fonte_icones.py`. O `ui.py` do Streamlit
   busca a fonte inteira no CDN do Google; aqui vale a mesma regra das outras duas fontes.
   `font-display:block` de propósito: o ícone é uma LIGADURA, então durante o `swap` a
   pessoa leria a palavra «storefront» no meio do menu. Bloquear esconde o glifo até a fonte
   chegar — e ela chega da mesma origem, junto com o resto. */
@font-face {
  font-family:"OJ Symbols"; font-style:normal; font-weight:400; font-display:block;
  src:url("/estatico/fontes/material-symbols-sub.woff2") format("woff2");
}
.msym {
  font-family:"OJ Symbols"; font-weight:400; font-style:normal; font-size:20px;
  line-height:1; letter-spacing:normal; text-transform:none; display:inline-block;
  white-space:nowrap; word-wrap:normal; direction:ltr; -webkit-font-smoothing:antialiased;
  user-select:none; flex:none;
}

/* ── busca do menu ──────────────────────────────────────────────────────────────────
   Volta o que o Streamlit tinha (`nav.render_sidebar`, «Buscar módulo…») e a travessia
   perdeu. Duas diferenças deliberadas em relação ao original:
   • vale para TODO papel, não só o interno — o concessionário tem 20 itens e também
     procura por nome;
   • filtra a barra no lugar, sem recarregar: no Streamlit cada tecla era um rerun. */
.lat-busca { padding:.7rem .65rem; border-bottom:1px solid var(--borda); position:relative;
  flex:none; }
.lat-busca .msym.lupa { position:absolute; left:1.25rem; top:50%; margin-top:-9px;
  font-size:19px; color:var(--tinta-fraca); pointer-events:none; }
.lat-busca input {
  width:100%; padding:.5rem 2rem .5rem 2.15rem; font-family:var(--fonte-texto);
  font-size:.92rem; color:var(--tinta); background:var(--fundo);
  border:1px solid var(--borda-campo); border-radius:var(--raio);
}
.lat-busca input::placeholder { color:var(--tinta-fraca); }
.lat-busca input:focus { border-color:var(--acento); outline:none;
  box-shadow:0 0 0 3px color-mix(in srgb, var(--acento) 18%, transparent); }
/* O «X» só existe quando há o que limpar: botão permanente num campo vazio é ruído, e
   ocupa a metade direita do campo mais estreito da tela. */
.lat-limpar { position:absolute; right:1.1rem; top:50%; margin-top:-13px; width:26px;
  height:26px; display:none; align-items:center; justify-content:center; padding:0;
  border:none; background:none; color:var(--tinta-fraca); cursor:pointer;
  border-radius:6px; }
.lat-limpar:hover { background:var(--superficie-2); color:var(--tinta); }
.lat-limpar .msym { font-size:19px; }
.lat-busca.tem-texto .lat-limpar { display:flex; }
/* A contagem responde «achei, mas está fora da tela» — sem ela, uma busca cujo único
   resultado caiu abaixo da dobra parece uma busca sem resultado. */
.lat-conta { display:none; padding:.5rem .95rem 0; font-size:.76rem;
  color:var(--tinta-fraca); }
.lateral.buscando .lat-conta { display:block; }

/* ── navegação ─────────────────────────────────────────────────────────────────────── */
.lat-nav { flex:1; min-height:0; overflow-y:auto; padding:.6rem .65rem .9rem; }
/* ⚠️ `.lateral .mitem`, e não `.mitem`: `.lateral a` (0,1,1) vence uma classe sozinha
   (0,1,0), então o `display:flex` daqui NUNCA valeu — desde a v1. Não dava erro nem parecia
   errado (em `block` os <span> fluem inline e a linha sai reta), mas `flex:1` e
   `margin-left:auto` ficavam inertes: foi assim que o caminho da busca caiu para uma segunda
   linha na v2. Medido no preview: rótulo em y=190, caminho em y=210. */
.lateral .mitem { padding:.48rem .6rem; margin-bottom:2px; border-radius:var(--raio);
  color:var(--tinta); font-size:calc(.95rem * var(--lat-escala,1)); font-weight:500;
  display:flex; align-items:center; gap:.6rem; }
.mitem:hover { background:var(--fundo); color:var(--acento); text-decoration:none; }
.mitem .msym { color:var(--tinta-fraca); font-size:20px; }
.mitem:hover .msym { color:var(--acento); }

.msec { margin-bottom:1px; }
.msec > summary { cursor:pointer; list-style:none; padding:.48rem .6rem;
  border-radius:var(--raio); font-size:calc(.93rem * var(--lat-escala,1)); font-weight:600;
  color:var(--tinta-fraca); display:flex; align-items:center; gap:.6rem; user-select:none; }
.msec > summary::-webkit-details-marker { display:none; }
.msec > summary .rot-sec { flex:1; min-width:0; }
.msec > summary .msym { font-size:20px; }
/* A seta é o ÚLTIMO filho e gira no `open` — antes era um `›` de texto num `::after`, que
   herdava a fonte do corpo e mudava de tamanho a cada nível de zoom. */
.msec > summary .seta { font-size:19px; color:var(--tinta-fraca); transition:transform .15s;
  opacity:.35; }
.msec > summary:hover .seta, .msec[open] > summary .seta { opacity:.75; }
.msec[open] > summary .seta { transform:rotate(90deg); }
.msec > summary:hover { background:var(--fundo); color:var(--acento); }
.msec[open] > summary { color:var(--tinta); }
/* Fio vertical ligando os itens à seção que os contém: com várias seções abertas ao mesmo
   tempo — que é o que a busca produz — sem ele não dá para ver onde uma acaba. */
.msec > .msec-itens { margin:1px 0 .35rem .95rem; padding-left:.6rem;
  border-left:1px solid var(--borda); }
.lateral .msub { padding:.38rem .55rem; margin-bottom:1px; border-radius:var(--raio);
  font-size:calc(.90rem * var(--lat-escala,1)); color:var(--tinta-fraca);
  display:flex; align-items:center; gap:.55rem; }
.msub .msym { font-size:18px; color:var(--tinta-fraca); }
/* DIETA (v2): dentro de uma seção aberta o ícone por item é textura, não âncora — o fio já
   estrutura. Escondido por CSS e NÃO removido do template de propósito: os FIXADOS clonam
   estes <a>, e o clone (fora de .msec-itens) volta a mostrar o ícone, que lá é âncora. */
.msec-itens .msym { display:none; }
.msub:hover { color:var(--acento); background:var(--fundo); text-decoration:none; }
.msub:hover .msym { color:var(--acento); }

/* A página em que se está fica marcada — sem isso a barra não responde "onde eu estou".
   O filete à esquerda é o que sobrevive ao daltonismo: o tint sozinho é diferença só de
   cor, e o fio é diferença de FORMA. */
.mitem.atual, .msub.atual { color:var(--acento); font-weight:700;
  background:color-mix(in srgb, var(--acento) 10%, var(--superficie));
  box-shadow:inset 3px 0 0 var(--acento); }
.mitem.atual .msym, .msub.atual .msym { color:var(--acento); }
/* Seção que CONTÉM a página atual: some destaque, para achá-la de relance quando ela está
   fechada (a busca fecha e abre seções o tempo todo). */
.msec.tem-atual > summary { color:var(--acento); }

/* Recado de busca sem resultado. Fica no fluxo da navegação, e não sobre ela: sobreposto,
   cobriria justamente os itens que a pessoa acabou de filtrar. */
.lat-vazio { display:none; padding:.9rem .6rem; font-size:.88rem; color:var(--tinta-fraca); }
.lateral.sem-resultado .lat-vazio { display:block; }
/* Durante a busca as seções são abertas e fechadas pelo filtro, não pela pessoa: a seta
   apontaria um estado que ela não escolheu. */
.lateral.buscando .msec > summary .seta { visibility:hidden; }

/* ── rodapé: quem está logado ──────────────────────────────────────────────────────── */
/* Vem do Portal de RH (`.side-foot`), e resolve aqui algo que lá não existia: no mundo
   FastAPI não havia NENHUMA indicação de quem está logado nem caminho de saída — para
   sair, a pessoa tinha de voltar ao Portal do Streamlit e achar o botão lá. */
.lat-pe { flex:none; border-top:1px solid var(--borda); padding:.6rem .65rem;
  display:flex; align-items:center; gap:.55rem; }
.lat-quem { flex:1; min-width:0; font-size:.82rem; line-height:1.25; }
.lat-quem b { display:block; color:var(--tinta); font-weight:600;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.lat-quem small { display:block; color:var(--tinta-fraca); font-size:.76rem;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.lat-avatar { width:30px; height:30px; border-radius:100px; flex:none;
  background-image:linear-gradient(135deg, var(--acento), var(--acento-hover));
  color:var(--tinta-inversa); display:flex; align-items:center; justify-content:center;
  font-family:var(--fonte-titulo); font-weight:700; font-size:.76rem; }
.lat-sair { flex:none; width:32px; height:32px; border-radius:var(--raio);
  display:flex; align-items:center; justify-content:center; color:var(--tinta-fraca); }
.lat-sair:hover { background:var(--fundo); color:var(--critico); text-decoration:none; }

/* ── v2: zonas, fixados, atalho e caminho (plano portal-barra-lateral-v2) ──────────── */
/* Rótulo de ZONA — rótulo, não porta: sem cursor, sem hover, sem foco. É ele que troca
   «ler 16 linhas» por «varrer 4 grupos». */
.lat-zona { margin:1.05rem .4rem .15rem; font-size:calc(.72rem * var(--lat-escala,1));
  font-weight:800; letter-spacing:.09em; text-transform:uppercase; color:var(--tinta-fraca); }
.lat-nav > .lat-zona:first-child { margin-top:.2rem; }
/* Gestão é utilitário: desce para o fim com um divisor — configuração mora perto da
   identidade, não no meio do trabalho do dia. */
.lat-zona-util { border-top:1px solid var(--borda); padding-top:.95rem; margin-top:1.15rem; }

/* FIXADOS — fora do <nav> que rola: pin existe para não procurar. */
.lat-fix-rot { margin:.7rem 1.05rem .15rem; }
.lat-fixados { padding:0 .6rem .55rem; border-bottom:1px solid var(--borda);
  max-height:38vh; overflow-y:auto; flex:none; }
.lat-fixados a { display:flex; align-items:center; gap:.6rem; padding:.44rem .6rem;
  margin-bottom:1px; border-radius:var(--raio); font-size:calc(.94rem * var(--lat-escala,1));
  font-weight:500; color:var(--tinta); }
.lat-fixados a:hover { background:var(--fundo); color:var(--acento); }
.lat-fixados a .msym { font-size:20px; color:var(--tinta-fraca); }
.lat-fixados a:hover .msym { color:var(--acento); }

/* A ESTRELA de fixar — só aparece com o ponteiro em cima (ou foco): permanente, seriam 60
   estrelas competindo com o texto. Em tela de toque não há hover, então ela fica sempre
   meio visível lá. */
.lat-nav a[data-busca], .lat-fixados a { position:relative; }
.lat-estrela { position:absolute; right:.3rem; top:50%; transform:translateY(-50%);
  width:26px; height:26px; display:flex; align-items:center; justify-content:center;
  padding:0; border:none; background:none; border-radius:6px; cursor:pointer;
  color:var(--tinta-fraca); opacity:0; }
.lat-estrela .msym { font-size:17px; display:inline-block; }
.lat-nav a:hover .lat-estrela, .lat-fixados a:hover .lat-estrela,
.lat-estrela:focus-visible { opacity:.6; }
.lat-estrela:hover { background:var(--superficie-2); opacity:.9; }
.lat-estrela[aria-pressed="true"] { color:var(--acento); }
.lat-fixados a:hover .lat-estrela[aria-pressed="true"] { opacity:.9; }
@media (pointer:coarse) { .lat-estrela { opacity:.4; } }

/* O chip do atalho «/» — some quando há texto (o lugar é o do botão de limpar). */
.lat-atalho { position:absolute; right:1.05rem; top:50%; transform:translateY(-50%);
  font-family:var(--fonte-texto); font-size:.72rem; font-weight:700;
  color:var(--tinta-fraca); border:1px solid var(--borda); border-bottom-width:2px;
  border-radius:5px; padding:.05rem .38rem; background:var(--superficie);
  pointer-events:none; }
.lat-busca.tem-texto .lat-atalho { display:none; }

/* O CAMINHO («Vendas › Emplacamento») só existe ENQUANTO SE BUSCA: fora dela é ruído, e é
   durante a busca que ele ensina o mapa. Zonas e fixados saem de cena junto — o resultado
   aparece uma vez, com o caminho, e não duplicado no bloco de cima. */
.mitem .rot, .msub .rot, .lat-fixados .rot { flex:1; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Badge de "pendente de triagem" no item de menu (só master, só Central de Solicitações —
   `moldura._pendentes_csol_master`; próxima iteração do RM-68/RM-71, 2026-09-01). Mesmo
   gradiente vermelho de `.sino-contador` — não é selo novo, é o MESMO selo em outro lugar.
   Sem CSS de posicionamento: `.rot` já é `flex:1` dentro do `.mitem`/`.msub` `display:flex`
   (ver a nota de especificidade ⚠️ acima, "`.lateral .mitem`, e não `.mitem`"), então o badge
   cai naturalmente encostado à direita como o próximo filho do flex. */
.lat-badge { display:inline-flex; align-items:center; justify-content:center; flex:none;
  min-width:18px; height:18px; padding:0 5px; border-radius:9px; font-size:.68rem;
  font-weight:800; line-height:1; color:#fff;
  background:linear-gradient(150deg, rgba(238,68,68,.92), rgba(255,107,107,.85)); }
.lat-caminho { display:none; margin-left:auto; padding-left:.5rem; font-size:.72rem;
  color:var(--tinta-fraca); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  max-width:46%; flex:none; }
.lateral.buscando .lat-caminho { display:block; }
/* Item de topo que está fixado some do corpo — mas VOLTA durante a busca: filtrando, a
   lista tem de ser o mapa inteiro, e o resultado aparece com o caminho. */
.lat-nav .mitem.fixado-acima { display:none; }
.lateral.buscando .lat-nav .mitem.fixado-acima { display:flex; }
.lat-nav .mitem.fixado-acima { display:none; }
.lateral.buscando .lat-zona, .lateral.buscando .lat-fix-rot,
.lateral.buscando .lat-fixados { display:none; }

/* ── celular ───────────────────────────────────────────────────────────────────────── */
/* A versão anterior virava uma tira ROLÁVEL no topo. Com 14 seções, achar um item exigia
   arrastar a tira de lado às cegas — o menu inteiro vivia numa janelinha de uma linha.
   Aqui ele vira um painel que abre e fecha: fechado ocupa uma linha, aberto ocupa a tela.

   `<details>` nativo, e nasce ABERTO no HTML: sem JavaScript o comportamento é o de hoje
   (menu à vista), e é o script que o fecha no celular. Falha para o lado seguro. */
.lat-abrir { display:none; }
@media (max-width:820px) {
  .quadro-app { display:block; }
  /* F-PWA2 (27/08/2026): a folha do Menu da `.pwa-tabbar` (`.pwa-menu`, css_pwa()) passou a
     ser a navegação inteira do celular — o mesmo `menu` desta barra, só que numa folha que
     sobe de baixo (design do HR & Corp Suite) em vez de um painel que empurra a página. Manter
     as DUAS seria menu duplicado (a lateral ainda reachable rolando até `#app-topo`). As regras
     de `.lat-interno`/`.lat-movel`/`.lat-abrir`/`.lat-resize` abaixo ficam órfãs de propósito —
     é dead CSS inofensivo, e apagá-las agora só aumentaria o diff deste achado sem mudar nada
     visível. */
  .lateral { display:none; }
  .lat-interno { position:static; max-height:none; }
  /* `.lat-interno` saiu de dentro do `<details>` (sticky não gruda lá dentro — ver o
     comentário em `_lateral.html`), então o «fechado esconde o conteúdo» que antes vinha de
     graça do `<details>` agora precisa de CSS: escondido por padrão, mostrado só quando o
     `<details>` irmão está aberto. `~` e não `+`: `.lat-resize` fica entre os dois no DOM. */
  .lat-interno { display:none; }
  .lat-movel[open] ~ .lat-interno { display:flex; }
  .lat-resize { display:none !important; }
  .lat-abrir { display:flex; align-items:center; gap:.6rem; cursor:pointer;
    list-style:none; padding:.7rem .95rem; font-size:.9rem; font-weight:600;
    color:var(--tinta); }
  .lat-abrir::-webkit-details-marker { display:none; }
  .lat-movel[open] > .lat-abrir { border-bottom:1px solid var(--borda); }
  /* 70vh e não 100%: o painel aberto tem de deixar ver que existe página embaixo dele,
     senão ele lê como uma tela nova e o caminho de volta some. */
  .lat-nav { max-height:70vh; }
}

.idiomas { display:flex; gap:2px; margin-left:auto; }
.idiomas a { font-size:.78rem; font-weight:700; padding:.35rem .7rem; border-radius:8px;
  color:var(--tinta-fraca); border:1px solid transparent; }
.idiomas a:hover { background:var(--fundo); text-decoration:none; color:var(--acento); }
.idiomas a[aria-current="true"] { color:var(--acento);
  background:color-mix(in srgb, var(--acento) 10%, var(--superficie));
  border-color:color-mix(in srgb, var(--acento) 28%, var(--superficie)); }

/* ── página ────────────────────────────────────────────────────────────────────────── */
/* `width:100%` NÃO é redundante com o max-width: o body é flex-column, e filho de flex com
   margem AUTO no eixo transversal PERDE o stretch e encolhe ao conteúdo. */
.pagina { width:100%; max-width:var(--largura-max); margin:0 auto; flex:1;
  padding:clamp(1.2rem,3vw,2rem) clamp(1rem,3vw,1.5rem) 3rem; }

.cab-tela { margin-bottom:1.6rem; }
.cab-tela h1 { font-size:clamp(1.35rem,3vw,1.7rem); font-weight:700; margin-bottom:.25rem; }
.cab-tela p { margin:0; color:var(--tinta-fraca); font-size:.92rem; max-width:70ch; }
.selo { font-family:var(--fonte-mono); font-size:.72rem; letter-spacing:.03em;
  color:var(--tinta-fraca); }

/* ── seção ─────────────────────────────────────────────────────────────────────────── */
.secao { display:flex; align-items:center; gap:.6rem; margin:1.9rem 0 .8rem;
  font-family:var(--fonte-titulo); font-size:1.02rem; font-weight:700;
  text-transform:none; letter-spacing:-.01em; color:var(--tinta); border:none;
  padding:0; }
.secao::before { content:""; width:4px; height:1.05rem; border-radius:2px; flex:none;
  background:linear-gradient(var(--acento), var(--acento-hover)); }

/* ── KPI ───────────────────────────────────────────────────────────────────────────── */
.kpis { display:grid; grid-template-columns:repeat(auto-fit,minmax(165px,1fr));
  gap:.85rem; margin-bottom:1.2rem; }
.kpi {
  position:relative; background:var(--superficie); border:1px solid var(--borda);
  border-radius:var(--raio-grande); padding:1.05rem 1.1rem; overflow:hidden;
  box-shadow:var(--sombra);
  transition:transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.kpi::before { content:""; position:absolute; left:0; top:0; height:3px; width:100%;
  background:var(--tom, var(--acento)); }
.kpi:hover { border-color:var(--tom, var(--acento)); transform:translateY(-2px);
  box-shadow:var(--sombra-alta); }
.kpi.ok   { --tom:var(--ok); }
.kpi.warn { --tom:var(--alerta); }
.kpi.crit { --tom:var(--critico); }
.kpi.info { --tom:var(--acento); }
.kpi .rot { color:var(--tinta-fraca); font-size:.72rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.04em; line-height:1.3; margin-bottom:0; }
.kpi .val { font-family:var(--fonte-titulo); font-size:1.6rem; font-weight:700;
  color:var(--tinta); margin-top:.3rem; font-variant-numeric:tabular-nums;
  letter-spacing:-.02em; }
.kpi.ok .val { color:var(--ok); }
.kpi.warn .val { color:var(--alerta); }
.kpi.crit .val { color:var(--critico); }
.kpi .sub { color:var(--tinta-fraca); font-size:.75rem; margin-top:.15rem; }

/* ── quadro e tabela ───────────────────────────────────────────────────────────────── */
.quadro { background:var(--superficie); border:1px solid var(--borda);
  border-radius:var(--raio-grande); box-shadow:var(--sombra); overflow:hidden; }
.rolagem { overflow:auto; max-height:var(--altura,420px); }
table.tab { width:100%; border-collapse:collapse; font-size:.88rem; }
table.tab thead th {
  position:sticky; top:0; z-index:1; background:var(--superficie-2);
  color:var(--tinta-fraca); font-size:.72rem; font-weight:700;
  text-transform:uppercase; letter-spacing:.04em; white-space:nowrap;
  text-align:left; padding:.6rem .75rem; border-bottom:1px solid var(--borda);
}
table.tab td { padding:.55rem .75rem; border-bottom:1px solid var(--borda); }
table.tab tbody tr:nth-child(even) { background:var(--superficie-2); }
table.tab tbody tr:hover td {
  background:color-mix(in srgb, var(--acento) 6%, var(--superficie)); }
table.tab tbody tr:last-child td { border-bottom:none; }
table.tab td.num, table.tab th.num { text-align:center; font-variant-numeric:tabular-nums;
  white-space:nowrap; }
/* Dinheiro e data NUNCA quebram em duas linhas: «R$ 170.190,80» partido no meio deixa de ser
   um número e vira duas palavras, e a coluna inteira perde a leitura de cima para baixo. */
table.tab td.dinheiro, table.tab td.data { white-space:nowrap;
  font-variant-numeric:tabular-nums; }

/* ── ordenação por cabeçalho ───────────────────────────────────────────────────────── */
/* Só a tabela que PEDE (`.ordenavel`) ganha o comportamento — o ordenador mora no
   `_moldura.html`, uma implementação para todas as telas, e ele não toca em tabela que não
   se declarou. A seta é INLINE, não posicionada em absoluto: `th.num` é centralizado, e um
   `::after` no canto direito desloca o texto do centro em algumas colunas e não em outras.
   Ela também é o único sinal de que a coluna é clicável — sem ela, o recurso existe e
   ninguém descobre. */
table.tab.ordenavel thead th { cursor:pointer; -webkit-user-select:none; user-select:none; }
table.tab.ordenavel thead th::after { content:"↕"; margin-left:.35rem; font-size:.9em;
  opacity:.3; font-weight:400; }
table.tab.ordenavel thead th[aria-sort="ascending"]::after { content:"↑"; opacity:1;
  color:var(--acento); }
table.tab.ordenavel thead th[aria-sort="descending"]::after { content:"↓"; opacity:1;
  color:var(--acento); }
table.tab.ordenavel thead th:hover { color:var(--tinta); }
table.tab.ordenavel thead th:focus-visible { outline:2px solid var(--acento);
  outline-offset:-2px; }

/* ── estado vazio ──────────────────────────────────────────────────────────────────── */
/* Coluna de TEXTO que se lê como código curto (UF, sigla, percentual já formatado). O
   `td.num` já centraliza; esta existe para o texto que anda no meio de colunas numéricas e
   ficaria sozinho à esquerda. */
table.tab td.centro, table.tab th.centro { text-align:center; }
.vazio { text-align:center; padding:2.4rem 1.5rem; color:var(--tinta-fraca);
  font-size:.9rem; }
.vazio strong { display:block; font-family:var(--fonte-titulo); font-weight:600;
  color:var(--tinta); margin-bottom:.35rem; font-size:1rem; }

/* ── aviso ─────────────────────────────────────────────────────────────────────────── */
/* Barra à ESQUERDA no tom, não fundo colorido inteiro: o texto fica sobre superfície já
   medida, e o tom não precisa carregar contraste de leitura. */
.aviso { border:1px solid var(--borda); border-left:4px solid var(--tom, var(--acento));
  border-radius:var(--raio); padding:.7rem .9rem; background:var(--superficie);
  font-size:.88rem; display:flex; gap:.55rem; align-items:flex-start; margin:0; }
.aviso.alerta { --tom:var(--alerta); }
.aviso.erro { --tom:var(--critico); }
.aviso.info { --tom:var(--acento); }
.aviso.ok { --tom:var(--ok); }

/* ── conteúdo colapsável ─────────────────────────────────────────────────────────────────────────────
   `<details class="det">`: texto que a pessoa PODE precisar (metodologia, detalhamento
   opcional) mas não deve ver por padrão — ao contrário do `.aviso`, que é sempre visível.
   ⚠️ Usada em 6 telas (tendencia_mtd/fluxo_loja/test_drive/vom/_nps_miolo/metas_boletim)
   sem NENHUMA regra própria em nenhuma das duas folhas — caia no `<details>` nu do
   navegador (triângulo cinza, sem cartão, sem respiro). A seta reusa a mesma geometria e
   o mesmo `transform:rotate` do `.msec` do menu, para não inventar um segundo idioma de
   "abre/fecha" na mesma tela. */
.det { background:var(--superficie); border:1px solid var(--borda);
  border-radius:var(--raio-grande); box-shadow:var(--sombra); overflow:hidden;
  margin:1rem 0; }
.det > summary { cursor:pointer; list-style:none; padding:.85rem 1.1rem;
  font-family:var(--fonte-titulo); font-weight:700; font-size:.95rem; color:var(--tinta);
  display:flex; align-items:center; gap:.6rem; user-select:none; }
.det > summary::-webkit-details-marker { display:none; }
.det > summary::after { content:""; margin-left:auto; flex:none; width:.5rem; height:.5rem;
  border-right:2px solid var(--tinta-fraca); border-bottom:2px solid var(--tinta-fraca);
  transform:translateY(-2px) rotate(45deg); transition:transform .15s; }
.det[open] > summary::after { transform:translateY(1px) rotate(-135deg); }
.det[open] > summary { border-bottom:1px solid var(--borda); }
.det > summary:hover { color:var(--acento); }
.det > summary:hover::after { border-color:var(--acento); }
.det + .det { margin-top:.6rem; }
.det-corpo, .det > .miolo { padding:1rem 1.1rem 1.1rem; }

/* Prosa de texto legal/metodologia renderizado de Markdown (`markdown_it`, via
   `tela_metas_boletim._markdown`) — h1-h6/ul/ol/table/hr crus do navegador saem espremidos
   e sem hierarquia sem isto. `.legal` é a variante SEMPRE visível (fora de `.det`, usada em
   `metas_boletim.html` de propósito — texto legal não deve depender de clique); `.texto` é a
   mesma tipografia dentro de um `.det`. */
.texto, .legal { font-size:.92rem; line-height:1.6; color:var(--tinta); }
.texto :is(h1,h2,h3,h4), .legal :is(h1,h2,h3,h4) { font-family:var(--fonte-titulo);
  font-size:1rem; font-weight:700; margin:1.1rem 0 .5rem; }
.texto :first-child, .legal :first-child { margin-top:0; }
.texto p, .legal p { margin:.6rem 0; }
.texto ul, .texto ol, .legal ul, .legal ol { margin:.5rem 0; padding-left:1.3rem; }
.texto li, .legal li { margin:.3rem 0; }
.texto strong, .legal strong { color:var(--tinta); font-weight:700; }
.texto hr, .legal hr { border:none; border-top:1px solid var(--borda); margin:1rem 0; }
.texto table, .legal table { width:100%; border-collapse:collapse; margin:.7rem 0;
  font-size:.88rem; }
.texto th, .texto td, .legal th, .legal td { padding:.5rem .65rem;
  border-bottom:1px solid var(--borda); text-align:left; }
.texto th, .legal th { background:var(--superficie-2); font-weight:700;
  color:var(--tinta-fraca); font-size:.78rem; text-transform:uppercase; letter-spacing:.03em; }

/* ── formulário ────────────────────────────────────────────────────────────────────── */
label { display:block; font-size:.78rem; font-weight:700; color:var(--tinta-fraca);
  text-transform:uppercase; letter-spacing:.04em; margin:0 0 .35rem; }
input, select {
  width:100%; padding:.6rem .75rem; font-size:.95rem; font-family:inherit;
  color:var(--tinta); background:var(--superficie);
  border:1px solid var(--borda-campo); border-radius:var(--raio);
}
input:focus, select:focus { border-color:var(--acento); outline:none;
  box-shadow:0 0 0 3px color-mix(in srgb, var(--acento) 18%, transparent); }
.filtros { display:flex; gap:1rem; flex-wrap:wrap; align-items:flex-end;
  margin-bottom:1.3rem; }
/* `flex-basis:200px` (não `auto`) é o que importa aqui — com `auto` a caixa herda a largura do
   CONTEÚDO, e o `.ms-resumo` troca de texto a cada seleção («— todos —» -> "Primavia, Bari,
   GNC…"). Sem uma base fixa, essa troca de texto muda a largura da caixa e reflui a fileira
   inteira a cada clique numa opção — os filtros "pulam" de tamanho e a pessoa erra o alvo do
   clique seguinte. Com base fixa + `max-width`, a caixa nunca mais depende do texto: sobra pro
   `text-overflow:ellipsis` do `.ms-resumo` cortar a lista comprida, como já era a intenção.
   `min-width:200px` continua igual ao valor original — sem ele, uma fileira de 5 filtros (ex.:
   Acompanhamento de Fluxo) ENCOLHE cada caixa abaixo de 160px em vez de quebrar linha, e o
   `<input type="date">` fica espremido. Com o piso, a fileira quebra em vez de espremer, como
   sempre foi. */
.filtros > div { flex:1 1 200px; min-width:200px; max-width:280px; }
/* Multisseleção: altura fixa em vez de `size` no HTML, porque `size` conta LINHAS e a lista
   de lojas (93) e a de cursos (28) desenhariam caixas de alturas diferentes lado a lado. */
.filtros select[multiple] { height:8.6rem; padding:.3rem .25rem; overflow-y:auto; }
.filtros select[multiple] option { padding:.22rem .5rem; border-radius:4px; }
/* Item marcado no AZUL da marca, não no cinza do sistema. Sem isto o Chrome pinta a seleção
   de um cinza que lê como «desabilitado» — o oposto do que ela significa. O `linear-gradient`
   repetido não é enfeite: é a única forma de o Chrome aceitar cor de fundo em `option`. */
.filtros select[multiple] option:checked {
  background:var(--acento) linear-gradient(0deg, var(--acento) 0%, var(--acento) 100%);
  color:var(--tinta-inversa); font-weight:600; }
/* ── multisseleção em CAIXAS (opt-in por `data-caixas` no <select multiple>) ───────── */
/* O `<select multiple>` nativo exige Ctrl+clique, não diz quantos itens estão marcados sem
   contar no olho, e some com a seleção que rolou para fora da caixa. Com 92 lojas isso deixa
   de ser detalhe. O componente abaixo é o mesmo controle com outra pele: o `<select>` original
   CONTINUA no formulário (só escondido) e é ele que envia — sem JS, a tela cai no seletor
   nativo em vez de perder o filtro. O ordenador mora no `_moldura.html`, junto do de tabela. */
.ms { position:relative; }
/* ⚠️ O painel é `position:absolute` e o formulário de filtro costuma ser um `.quadro`, que tem
   `overflow:hidden` para arredondar tabela — o painel sairia CORTADO. Em vez de exigir que
   cada tela lembre de desligar isso, o `:has()` desliga sozinho onde o componente existe. */
.quadro:has(.ms) { overflow:visible; }
.ms-botao { width:100%; display:flex; align-items:center; gap:.5rem; padding:.6rem .75rem;
  font:inherit; font-size:.95rem; text-align:left; cursor:pointer; color:var(--tinta);
  background:var(--superficie); border:1px solid var(--borda-campo);
  border-radius:var(--raio); transition:border-color .14s, box-shadow .14s, background .14s; }
.ms-botao:hover { border-color:var(--acento); }
/* Filtro LIGADO tem de se ver de longe, sem abrir o painel: borda e tinta do acento sobre um
   fundo levissimo. Sem isto, «Rede inteira» e «3 grupos» sao a mesma caixa branca, e a pessoa
   le um numero recortado achando que e o total. O estado desligado (`ms-vazio`) fica neutro. */
.ms-botao:not(.ms-vazio) { border-color:var(--acento); font-weight:600;
  background:color-mix(in srgb, var(--acento) 6%, var(--superficie)); }
.ms-botao[aria-expanded="true"], .ms-botao:focus-visible { border-color:var(--acento);
  outline:none; box-shadow:0 0 0 3px color-mix(in srgb, var(--acento) 18%, transparent); }
.ms-resumo { flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ms-botao.ms-vazio .ms-resumo { color:var(--tinta-fraca); }
/* A contagem é PÍLULA e não texto: com o filtro fechado, «quantos estão marcados» é a única
   informação que o controle ainda mostra, e ela tem de saltar. */
.ms-conta { flex:none; background:var(--acento); color:var(--tinta-inversa);
  border-radius:999px; font-size:.72rem; font-weight:700; padding:.1rem .45rem; }
.ms-seta { flex:none; width:.42rem; height:.42rem; margin-right:.1rem;
  border-right:2px solid var(--tinta-fraca); border-bottom:2px solid var(--tinta-fraca);
  transform:translateY(-2px) rotate(45deg); transition:transform .16s; }
/* A seta GIRA ao abrir: o triangulo estatico nao dizia se o painel estava aberto ou fechado,
   e com o painel sobreposto a outra coluna isso e a unica pista. */
.ms-botao[aria-expanded="true"] .ms-seta { transform:translateY(1px) rotate(-135deg);
  border-color:var(--acento); }
.ms-painel { position:absolute; z-index:40; top:calc(100% + 4px); left:0; min-width:100%;
  max-width:min(32rem,92vw); padding:.5rem; background:var(--superficie);
  border:1px solid var(--borda); border-radius:var(--raio);
  box-shadow:0 12px 28px rgba(15,23,42,.16); }
.ms-busca { margin-bottom:.4rem; padding:.42rem .6rem; font-size:.88rem; }
.ms-acoes { display:flex; gap:.4rem; margin-bottom:.4rem; }
.ms-acoes button { flex:1; padding:.32rem .5rem; font:inherit; font-size:.78rem;
  font-weight:600; cursor:pointer; color:var(--acento); background:var(--superficie);
  border:1px solid var(--borda-campo); border-radius:6px; }
.ms-acoes button:hover { background:var(--superficie-2); }
.ms-lista { max-height:15rem; overflow-y:auto; }
/* `label` global é MAIÚSCULA, negrito e display:block (é rótulo de campo). Aqui ele é uma
   LINHA de opção — tudo isso precisa ser desfeito, item por item. */
.ms-lista label { display:flex; align-items:center; gap:.5rem; margin:0; padding:.34rem .45rem;
  border-radius:6px; font-size:.9rem; font-weight:400; text-transform:none; letter-spacing:0;
  color:var(--tinta); cursor:pointer; }
/* `.ms-lista label` vence o `[hidden]` da folha do navegador por especificidade de origem
   (mesma classe (0,1,0), e a folha do app vem depois). Sem esta linha, a busca do multisseleção
   marca as opções filtradas como escondidas e elas continuam à vista — o filtro «funcionaria»
   sem filtrar nada (mesmo padrão já corrigido em `.lateral [hidden]`). */
.ms-lista label[hidden] { display:none; }
.ms-lista label:hover { background:var(--superficie-2); }
.ms-lista input { width:auto; flex:none; margin:0; accent-color:var(--acento); }
.ms-nenhum { padding:.6rem .45rem; font-size:.82rem; color:var(--tinta-fraca); }

/* Ação de baixar arquivo. Vive aqui, e não copiada em cada tela, porque já são duas. */
.baixar { display:inline-flex; align-items:center; gap:.45rem; padding:.62rem 1.05rem;
  border-radius:var(--raio); background:var(--acento); color:var(--tinta-inversa);
  font-weight:700; font-size:.9rem; text-decoration:none; white-space:nowrap; }
.baixar:hover { text-decoration:none; color:var(--tinta-inversa); filter:brightness(1.07); }

.botao {
  display:inline-block; padding:.65rem 1.1rem; font-family:var(--fonte-texto);
  font-size:.92rem; font-weight:700; color:var(--tinta-inversa); cursor:pointer;
  background:var(--acento); border:none; border-radius:var(--raio); text-align:center;
  width:auto; margin:0;
}
.botao:hover { background:var(--acento-hover); text-decoration:none;
  color:var(--tinta-inversa); }
.botao.largo { width:100%; }
.botao.secundario { background:var(--superficie); color:var(--acento);
  border:1px solid var(--borda-campo); font-weight:600; }
.botao.secundario:hover { background:var(--superficie-2); color:var(--acento-hover); }

/* ── selo de status ────────────────────────────────────────────────────────────────── */
/* NUNCA só cor: alerta e crítico ficam próximos sob protanopia, então o selo sempre carrega
   TEXTO. O fundo é tint claro e o texto usa o tom medido. */
.tag { display:inline-block; font-size:.72rem; font-weight:700; padding:.2rem .6rem;
  border-radius:20px; white-space:nowrap; }
.tag.ok { background:var(--ok-fundo); color:var(--ok); }
.tag.pend, .tag.alerta { background:var(--alerta-fundo); color:var(--alerta); }
.tag.crit { background:var(--critico-fundo); color:var(--critico); }
.tag.neutro { background:var(--superficie-2); color:var(--tinta-fraca); }

table.tab tbody tr.nossa td { background:var(--acento-fundo); color:var(--acento);
  font-weight:700; }
table.tab tbody tr.media td { font-style:italic; color:var(--tinta-fraca);
  border-top:1px dashed var(--borda); }

/* ── gráfico ───────────────────────────────────────────────────────────────────────── */
.grafico { padding:1rem 1.1rem .5rem; }

/* ── telas de entrada ──────────────────────────────────────────────────────────────── */
/* Um card sozinho, centralizado numa janela larga, deixa um vazio cinza enorme dos dois
   lados — é a primeira tela do produto e não pode ler como inacabada. A textura abaixo é
   só FUNDO (duas manchas de luz suaves, mesmo desenho já aprovado no HR & Corp Suite —
   `body.tela-auth` de lá): nenhum bloco de cor nova, nenhum painel decorativo. A grade de
   pontos que existia aqui (26px, repetida na tela inteira) foi tirada — competia com o
   cartão por atenção; a mancha assimétrica sozinha já resolve o "vazio cinza" sem parecer
   papel de parede. `território escuro` é reservado a risco (ver `css_linguagem`), então a
   marca aqui fica sempre clara e some se o navegador não entender `color-mix`. */
body.pag-entrada {
  background-image:
    radial-gradient(50% 45% at 12% 8%, color-mix(in srgb, var(--acento) 9%, transparent), transparent 65%),
    radial-gradient(45% 45% at 90% 6%, color-mix(in srgb, var(--acento-hover) 8%, transparent), transparent 65%);
  background-repeat: no-repeat;
  background-attachment: fixed;
}
/* Sombra de repouso nos campos, só aqui: o `input,select` sitewide (acima) fica sem —
   mexer nele mudaria as 80 telas de filtro do Portal, decisão maior que "arrumar o
   login". Mesmo valor do HR & Corp Suite. */
body.pag-entrada input, body.pag-entrada select { box-shadow:0 1px 2px rgba(15,23,42,.04); }
main { flex:1; display:flex; align-items:center; justify-content:center;
  padding:clamp(1.5rem,5vw,3.5rem) 1.25rem; }
.caixa { width:100%; max-width:940px; }
.titulo-entrada { text-align:center; margin:0 0 .5rem;
  font-size:clamp(1.5rem,4vw,2rem); font-weight:700; }
.chamada { text-align:center; color:var(--tinta-fraca); margin:0 0 2rem; font-size:1rem; }
.portas { display:grid; grid-template-columns:repeat(auto-fit,minmax(280px,1fr)); gap:1.25rem; }
.portas-unica { grid-template-columns:minmax(0,460px); justify-content:center; }
.porta { background:var(--superficie); border:1px solid var(--borda);
  border-radius:var(--raio-grande); border-top:3px solid var(--cor, var(--acento));
  box-shadow:var(--sombra); padding:1.5rem; display:flex; flex-direction:column; gap:.6rem;
  transition:transform .15s ease, box-shadow .15s ease; }
.porta:hover { transform:translateY(-3px); box-shadow:var(--sombra-alta); }
/* A tela com UMA porta só (o formulário, depois de escolher) ganha mais respiro: com duas
   portas lado a lado o padding compacto faz sentido, sozinho no meio de um card ele lia
   como espremido. */
.porta-unica { max-width:460px; margin:0 auto; padding:2.35rem 2rem; }
/* O card com UMA porta só é formulário, não convite pra clicar — a elevação de hover que
   funciona nos 2 cards da escolha (`.porta:hover` acima) aqui só faria a tela "pular"
   enquanto a pessoa passa o mouse por cima pra ler ou preencher. */
.porta-unica:hover { transform:none; box-shadow:var(--sombra); }
.porta .ico { color:var(--cor, var(--acento)); }
.porta .ico svg { width:28px; height:28px; fill:none; stroke:currentColor;
  stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }
.porta .rotulo { font-size:.72rem; font-weight:700; letter-spacing:.08em;
  text-transform:uppercase; color:var(--cor, var(--acento)); }
.porta h2 { font-size:1.15rem; font-weight:700; }
.porta p { margin:0; color:var(--tinta-fraca); font-size:.88rem; }
.porta .rodape { margin-top:auto; padding-top:.9rem; font-size:.8rem;
  color:var(--tinta-fraca); }
.porta .rodape .botao { margin-top:.9rem; width:100%; }
.login-logo { text-align:center; font-family:var(--fonte-titulo); font-weight:800;
  font-size:2rem; letter-spacing:-.03em; margin-bottom:1.5rem; }
.login-logo .o { color:var(--acento); }
.login-logo .bar { color:var(--borda); font-weight:400; margin:0 4px; }
.login-foot { text-align:center; margin-top:2rem; font-size:.75rem;
  color:var(--tinta-fraca); }

/* legenda de campo, dentro do form de login (SAP Faturamento, cross-link p/ e-mail
   individual etc.) — `.porta p` já zera a margem; aqui ela volta, só por cima. */
.porta .microcopia { margin-top:.35rem; }

/* Link de volta para a escolha de porta — TEXTO simples no TOPO do cartão (era um botão
   contornado em largura quase cheia no RODAPÉ; mesmo padrão do `.voltar` do HR & Corp
   Suite). O peso visual de "botão" fica reservado pra ação que a pessoa veio fazer
   (Entrar) — desistir dela não precisa do mesmo destaque. */
.voltar { display:inline-flex; align-items:center; gap:.3rem; margin-bottom:1.1rem;
  color:var(--tinta-fraca); font-size:.85rem; font-weight:600; text-decoration:none; }
.voltar:hover { color:var(--acento); text-decoration:none; }

/* ── mostrar/ocultar a senha ──────────────────────────────────────────────────────────
   O Streamlit tem esse "olho" nativo há algumas versões; o <input type=password> puro do
   HTML não tem, então o botão é desenhado — ver o <script> no fim do template. */
.campo-senha { position:relative; }
.campo-senha input { padding-right:2.6rem; }
.ver-senha { position:absolute; right:.3rem; top:50%; transform:translateY(-50%);
  width:2.15rem; height:2.15rem; display:flex; align-items:center; justify-content:center;
  padding:0; border:none; background:none; color:var(--tinta-fraca); cursor:pointer;
  border-radius:6px; }
.ver-senha:hover { background:var(--superficie-2); color:var(--tinta); }
.ver-senha svg { width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round; }
.ver-senha .olho-fechado { display:none; }
.ver-senha[aria-pressed="true"] .olho-aberto { display:none; }
.ver-senha[aria-pressed="true"] .olho-fechado { display:block; }

/* ── manter-me conectado ──────────────────────────────────────────────────────────── */
.campo-checkbox { display:flex; align-items:center; gap:.55rem; margin:.9rem 0 .2rem; }
.campo-checkbox input[type=checkbox] { width:1.05rem; height:1.05rem; margin:0;
  accent-color:var(--acento); cursor:pointer; flex:none; }
.campo-checkbox label { margin:0; text-transform:none; font-weight:500; font-size:.88rem;
  color:var(--tinta); cursor:pointer; }

/* ── botão do login: gradiente + elevação, só AQUI ────────────────────────────────────
   Mesmo tratamento "premium" do HR & Corp Suite (`button,.btn` de lá) — mas escopado a
   `.pag-entrada`, não no `.botao` sitewide (linha ~660): o Portal tem dezenas de telas já
   auditadas/QA'd com o botão flat de hoje, e trocar a base pra TODO o app é uma decisão
   maior que "arrumar o login". `background-image`, nunca `background`: a versão sitewide
   já garante `background-color` (fallback se o navegador não entender gradiente). */
body.pag-entrada .botao {
  background-image:linear-gradient(135deg, var(--acento), var(--acento-hover));
  box-shadow:0 4px 12px color-mix(in srgb, var(--acento) 28%, transparent);
  transition:transform .1s ease, box-shadow .15s ease, filter .15s ease, background .15s ease;
}
body.pag-entrada .botao:hover {
  filter:brightness(1.06); transform:translateY(-1px);
  box-shadow:0 6px 16px color-mix(in srgb, var(--acento) 34%, transparent);
}

/* ── caminhos alternativos: recuperar senha / solicitar acesso ───────────────────────
   Ficam DEPOIS do card principal, sem competir com ele. Era uma pilha de caixas com
   borda própria (uma moldura dentro da outra); virou uma LISTA que se abre — divisor
   fino entre itens, sem cartão dentro do cartão. A seta reusa a MESMA geometria e o
   MESMO `transform:rotate` do `.det` deste arquivo (comentário lá em cima), pra não
   inventar um segundo idioma de "abre/fecha" no mesmo pacote de CSS. HR & Corp Suite não
   tem tela equivalente pra espelhar aqui (login de lá não pede recuperação/solicitação),
   então o padrão vem de dentro do próprio Portal. */
.acesso-alt { margin-top:1.3rem; border-top:1px solid var(--borda); }
.acesso-alt details { border-bottom:1px solid var(--borda); }
.acesso-alt summary { cursor:pointer; list-style:none; padding:.75rem 0;
  font-size:.85rem; font-weight:600; color:var(--acento); display:flex; align-items:center;
  gap:.6rem; user-select:none; }
.acesso-alt summary::-webkit-details-marker { display:none; }
.acesso-alt summary::after { content:""; margin-left:auto; flex:none; width:.45rem;
  height:.45rem; border-right:2px solid currentColor; border-bottom:2px solid currentColor;
  opacity:.7; transform:translateY(-2px) rotate(45deg); transition:transform .15s; }
.acesso-alt details[open] summary::after { transform:translateY(1px) rotate(-135deg); }
.acesso-alt summary:hover { color:var(--acento-hover); }
.acesso-alt .corpo { padding:0 0 1rem; }
.acesso-alt .corpo form { display:flex; flex-direction:column; gap:.55rem; }
.acesso-alt .corpo .microcopia { margin:0 0 .3rem; }
.acesso-alt .nota { margin-top:.9rem !important; padding-top:.8rem;
  border-top:1px solid var(--borda); font-size:.8rem; }

/* campo-armadilha (honeypot): invisível para gente, visível para robô de formulário —
   mesma técnica do `solic_acesso_form` do Streamlit, só que sem depender de CSS injetado
   por `st.container(key=...)`. */
.campo-armadilha { position:absolute; left:-9999px; top:-9999px; height:0; overflow:hidden; }

.carregando { opacity:.45; transition:opacity .12s; }

@media (prefers-reduced-motion: reduce) {
  * { animation:none; transition:none; }
  /* O `*{animation:none}` acima não alcança com certeza os pseudo-elementos que a View
     Transitions API cria (variam por motor); explícito com `!important` garante — uma das
     poucas exceções que abrem mão do "zero !important" do arquivo, aqui por acessibilidade. */
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation:none !important; }
}
