/* Level Emit — mockups M0 — estrutura compartilhada entre as 3 direções.
   As cores/vibe vêm do CSS de cada direção (evolution.css, fintech.css, dark.css). */

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body { height: 100%; }

body {
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button { font: inherit; cursor: pointer; }

/* ---------- Layout ---------- */
.layout { display: flex; min-height: 100vh; }

/* ══ Barra lateral ═════════════════════════════════════════════════════════
   Dois estados no MESMO markup (29/07/2026, portada do Level Hub):
     recolhida  — 72px, só ícones, submenu em painel flutuante
     expandida  — 240px, nomes visíveis, submenu em sanfona DENTRO da barra
   O estado mora em html[data-barra] (no <html>, não no <body>: quem escreve é
   o barra.js, carregado no <head> antes do primeiro desenho) e a única coisa
   que muda de verdade é --rail-w; `.main` já usa margin-left: var(--rail-w),
   então o corpo da página acompanha sozinho, sem nenhuma tela saber disso. */
.barra {
  width: var(--rail-w);
  background: #fff; border-right: 1px solid var(--card-border);
  position: fixed; top: 0; bottom: 0; left: 0;
  display: flex; flex-direction: column;
  padding: 14px 0; z-index: var(--z-barra);
  transition: width .18s ease;
}
html[data-barra="aberta"] { --rail-w: var(--barra-w-aberta); }
@media (prefers-reduced-motion: reduce) { .barra { transition: none; } }

/* Tela estreita: a barra expandida NÃO empurra o conteúdo — 240px numa tela
   de 375px deixariam 135px úteis e tudo estouraria na horizontal. Aqui o
   conteúdo fica ancorado nos 72px e a barra aberta SOBREPÕE (ela já é fixed,
   com z-index acima da página). */
@media (max-width: 900px) {
  html[data-barra="aberta"] { --rail-w: 72px; }
  html[data-barra="aberta"] .barra {
    width: var(--barra-w-aberta);
    box-shadow: 12px 0 34px rgba(16, 42, 67, .18);
  }
}

/* ── Topo: marca + botão de alternar ── */
.barra-topo {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 0 8px 14px; flex-shrink: 0;
}
html[data-barra="aberta"] .barra-topo {
  flex-direction: row; align-items: center; gap: 8px; padding: 0 12px 16px;
}
.barra-marca { line-height: 0; display: block; }
.barra-marca .marca-icone { height: 34px; width: 34px; display: block; }
.barra-marca .marca-logo { height: 30px; width: auto; display: none; }
html[data-barra="aberta"] .barra-marca .marca-icone { display: none; }
html[data-barra="aberta"] .barra-marca .marca-logo  { display: block; }

.barra-alternar {
  border: none; background: none; cursor: pointer; padding: 0;
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: #9A9B9C; transition: all .15s;
}
.barra-alternar svg { width: 18px; height: 18px; }
.barra-alternar:hover { background: var(--bg); color: var(--text); }
html[data-barra="aberta"] .barra-alternar { margin-left: auto; }

/* ── Navegação ── */
.barra nav {
  flex: 1; min-height: 0;
  display: flex; flex-direction: column; gap: 4px; align-items: center;
  width: 100%; padding: 0 8px;
  overflow-y: auto; overflow-x: hidden; scrollbar-width: thin;
}
html[data-barra="aberta"] .barra nav { align-items: stretch; padding: 0 10px; }

/* `.ri` é o ITEM. flex-shrink:0 é obrigatório (bug real corrigido em
   29/07/2026): sem ele o nav (flex:1) espremia os ícones de 46px para 39px em
   1366×768 e 35px em 1280×720 — o sistema tinha aparência diferente em cada
   máquina. */
.ri {
  position: relative;
  width: 46px; height: 46px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 12px;
  color: #9A9B9C; text-decoration: none;
  transition: color .18s, background .18s;
}
.ri svg { width: 20px; height: 20px; flex-shrink: 0; }
.ri:hover { color: var(--text); background: var(--bg); }
.ri.ativo { color: var(--accent-ink); background: var(--accent-soft); }
.ri.ativo::before {
  content: ''; position: absolute; left: -13px; top: 50%;
  transform: translateY(-50%) skewX(var(--lo-skew));
  width: 4px; height: 22px; background: var(--accent); border-radius: 2px;
  box-shadow: 0 0 10px rgba(15,145,207,.5);
}
.ri-nome, .ri-seta { display: none; }

/* Alvo clicável dentro de um `.ri` que tem submenu (o `.ri` em si é <div>,
   porque não se aninha <a> dentro de <a>). Recolhido preenche os 46×46. */
.ri-alvo {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; height: 100%; min-width: 0;
  border: 0; background: none; padding: 0; font: inherit; text-align: left;
  color: inherit; text-decoration: none; cursor: pointer;
}
html[data-barra="aberta"] .ri-alvo { justify-content: flex-start; height: auto; }

.barra nav .divisor-menu {
  width: 28px; height: 1px; background: var(--card-border);
  margin: 4px 0; flex-shrink: 0; align-self: center;
}
html[data-barra="aberta"] .barra nav .divisor-menu { width: 100%; margin: 6px 0; }

/* ── Estado EXPANDIDO: o item vira linha com nome ── */
html[data-barra="aberta"] .ri {
  width: 100%; height: auto; min-height: 38px;
  justify-content: flex-start; gap: 10px;
  padding: 8px 10px; border-radius: 8px;
  font-size: 13px; font-weight: 500;
}
html[data-barra="aberta"] .ri svg { width: 18px; height: 18px; }
html[data-barra="aberta"] .ri-nome {
  display: block; flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
html[data-barra="aberta"] .ri.ativo { font-weight: 600; }
html[data-barra="aberta"] .ri.ativo::before { left: -10px; height: 19px; }
html[data-barra="aberta"] .ri-seta {
  display: flex; align-items: center; margin-left: auto; flex-shrink: 0;
  color: #9A9B9C; transition: transform .18s;
}
html[data-barra="aberta"] .ri-seta svg { width: 14px; height: 14px; }
html[data-barra="aberta"] .ri-grupo.aberto .ri-seta { transform: rotate(180deg); }
.ri-grupo { position: relative; width: 46px; flex-shrink: 0; }
html[data-barra="aberta"] .ri-grupo { width: 100%; }

/* Contador de pendências (Tarefas, 01/08/2026) — canto do ícone quando
   recolhida, vira uma pílula no fim da linha quando expandida (mesmo
   `margin-left: auto` já usado em `.ri-seta`). */
.badge-num {
  position: absolute; top: 2px; right: 2px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
html[data-barra="aberta"] .badge-num { position: static; margin-left: auto; flex-shrink: 0; }

/* ── Dica (item sem submenu, só no estado recolhido) ── */
.ri .dica {
  position: absolute; left: calc(100% + 12px); top: 50%;
  transform: translateY(-50%) translateX(-6px);
  background: var(--tip-bg); color: var(--tip-ink);
  font-size: 12px; font-weight: 600;
  padding: 7px 12px; border-radius: 8px; white-space: nowrap;
  opacity: 0; visibility: hidden; transition: all .15s; pointer-events: none;
  z-index: 3;
}
.ri:hover .dica, .ri:focus-visible .dica { opacity: 1; visibility: visible; transform: translateY(-50%) translateX(0); }
html[data-barra="aberta"] .ri .dica { display: none; }

/* ── Submenu ────────────────────────────────────────────────────────────
   RECOLHIDA: painel flutuante à direita. É position:FIXED de propósito — o
   nav agora tem overflow (para os ícones nunca espremerem), e overflow
   recorta filho absoluto: o painel abriria decepado pelo próprio menu.
   Elemento fixed não é recortado por overflow de ancestral; a posição
   (top/left) é calculada pelo JS a cada hover, presa à viewport.

   TODAS as regras do modo flutuante são escopadas em
   html:not([data-barra="aberta"]) — sem isso a regra de :hover venceria o
   transform:none do modo expandido e empurraria a SANFONA para cima,
   embaralhando o menu inteiro. */
html:not([data-barra="aberta"]) .submenu {
  position: fixed; left: calc(var(--rail-w) + 14px);
  transform: translateX(-8px);
  background: #fff; border: 1px solid var(--card-border); border-radius: 13px;
  box-shadow: var(--shadow-lift);
  padding: 8px; width: 238px; text-align: left;
  max-height: calc(100vh - 32px); overflow-y: auto; scrollbar-width: thin;
  opacity: 0; visibility: hidden; transition: opacity .2s, visibility .2s, transform .2s;
  z-index: var(--z-menu);
}
html:not([data-barra="aberta"]) .ri-grupo:hover .submenu,
html:not([data-barra="aberta"]) .ri-grupo:focus-within .submenu {
  opacity: 1; visibility: visible; transform: translateX(0);
}
/* ponte invisível: o mouse atravessa o vão de 14px sem fechar o painel */
html:not([data-barra="aberta"]) .submenu::before {
  content: ''; position: absolute; left: -18px; top: 0; bottom: 0; width: 18px;
}

/* EXPANDIDA: o mesmo elemento vira sanfona no fluxo, rola junto com o nav e
   nunca é cortado pela borda da tela. */
html[data-barra="aberta"] .submenu {
  position: static; transform: none !important;  /* cinto e suspensório: nem style inline do JS pode vazar */
  opacity: 1; visibility: visible;
  background: none; border: none; box-shadow: none; border-radius: 0;
  width: auto; max-height: none; overflow: visible;
  padding: 2px 0 4px 12px;
  margin-left: 19px; border-left: 1px solid var(--card-border);
}
html[data-barra="aberta"] .ri-grupo:not(.aberto) .submenu { display: none; }
html[data-barra="aberta"] .submenu .fly-titulo { display: none; }

.fly-titulo {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .14em;
  color: #9A9B9C; padding: 8px 12px 6px;
}
.submenu a {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 12px; border-radius: 8px;
  color: var(--muted); font-size: 13px; font-weight: 500; transition: all .15s;
}
html[data-barra="aberta"] .submenu a { padding: 6px 8px; font-size: 12.5px; }
.submenu a:hover { color: var(--accent-ink); background: var(--accent-soft); }
.submenu a.atual { color: var(--accent-ink); background: var(--accent-soft); font-weight: 600; }

.avatar {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  background: var(--accent); color: #fff; font-weight: 700; font-size: 12px;
  display: inline-flex; align-items: center; justify-content: center;
}

.main {
  flex: 1; min-width: 0; display: flex; flex-direction: column;
  margin-left: var(--rail-w);
}

/* ---------- Topbar ---------- */
.topbar {
  display: flex; align-items: center; gap: 14px;
  padding: 0 28px; height: 64px;
  background: var(--topbar-bg); border-bottom: 1px solid var(--card-border);
  position: sticky; top: 0; z-index: var(--z-topbar);
}
.topbar .spacer { flex: 1; }
.topbar .page-crumb { font-family: var(--font-body); font-size: 15px; font-weight: 600; color: var(--text); }

/* Seletor de empresa */
.empresa-switch { position: relative; }
.empresa-switch > button {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 14px; border-radius: 20px;
  border: 1px solid var(--card-border); background: var(--bg);
  color: var(--text-2); font-size: 12.5px; font-weight: 600;
  transition: all .18s;
}
.empresa-switch > button:hover { border-color: var(--accent); color: var(--accent-ink); }
.empresa-switch > button .e-ini { width: 22px; height: 22px; font-size: 10.5px; }
.empresa-switch > button .e-nome { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.empresa-switch > button .caret { font-size: 9px; color: var(--muted); }
.empresa-switch .menu {
  display: none; position: absolute; top: calc(100% + 6px); right: 0; min-width: 280px;
  background: var(--card); border: 1px solid var(--card-border); border-radius: 12px;
  box-shadow: var(--shadow-lift); padding: 6px; z-index: var(--z-menu);
}
.empresa-switch.open .menu { display: block; }
.empresa-switch .menu button {
  display: block; width: 100%; text-align: left; padding: 9px 10px;
  border: 0; background: none; border-radius: 8px; color: var(--text);
}
.empresa-switch .menu button:hover { background: var(--hover); }
.empresa-switch .menu button small { display: block; color: var(--muted); font-size: 11.5px; }
.empresa-switch .menu .trocar {
  display: block; border-top: 1px solid var(--card-border); margin-top: 4px; padding: 9px 10px;
  color: var(--accent-ink); font-weight: 600; font-size: 12.5px;
}

/* Menu de usuário (dropdown no topbar, 21/07/2026) — mesmo padrão visual
   do seletor de empresa (.empresa-switch), com conteúdo próprio. */
.menu-usuario { position: relative; }
.menu-usuario > button {
  display: flex; align-items: center; gap: 9px;
  border: 0; background: none; padding: 6px 8px; border-radius: 20px;
  transition: background .18s; text-align: left;
}
.menu-usuario > button:hover { background: var(--hover); }
.menu-usuario .nome { font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.25; }
.menu-usuario .cargo, .menu-usuario small { font-size: 11px; color: var(--muted); }
.menu-usuario .cargo a, .menu-usuario small a { color: var(--accent-ink); font-weight: 600; }
.menu-usuario .caret { font-size: 9px; color: var(--muted); }
.menu-usuario .menu {
  display: none; position: absolute; top: calc(100% + 6px); right: 0; min-width: 200px;
  background: var(--card); border: 1px solid var(--card-border); border-radius: 12px;
  box-shadow: var(--shadow-lift); padding: 6px; z-index: var(--z-menu);
}
.menu-usuario.open .menu { display: block; }
.menu-usuario .menu a {
  display: block; padding: 9px 10px; border-radius: 8px; color: var(--text);
  font-size: 13px; font-weight: 500;
}
.menu-usuario .menu a:hover { background: var(--hover); }
.menu-usuario .menu a.atual { color: var(--accent-ink); font-weight: 600; }

/* Menu de ações "..." por linha de tabela (23/07/2026, referência Conexa) —
   mesmo mecanismo de abrir/fechar do .menu-usuario (ver app.js), só que o
   painel cobre `a`, `button` E `form > button` (uma linha pode ter tanto
   navegação quanto POST direto misturados). */
.menu-linha { position: relative; display: inline-block; }
.menu-linha > button {
  border: 1px solid var(--card-border); background: var(--card); border-radius: 8px;
  padding: 4px 10px; font-size: 15px; line-height: 1; color: var(--text-2);
}
.menu-linha > button:hover { background: var(--hover); }
/* position:FIXED de propósito (29/07/2026): o painel é filho de um `<td>`
   dentro de `.table-wrap`, que tem `overflow: auto` para congelar o cabeçalho
   — e overflow recorta filho ABSOLUTO. Era por isso que o menu da última
   linha aparecia cortado. Elemento fixed não é recortado por overflow de
   ancestral; quem calcula top/left na abertura é o app.js, preso à viewport.
   Mesma técnica já usada no submenu da barra lateral. */
.menu-linha .menu {
  display: none; position: fixed; min-width: 210px;
  background: var(--card); border: 1px solid var(--card-border); border-radius: 12px;
  box-shadow: var(--shadow-lift); padding: 6px; z-index: var(--z-menu);
}
.menu-linha.open .menu { display: block; }
.menu-linha .menu a, .menu-linha .menu button, .menu-linha .menu form {
  display: block; width: 100%;
}
.menu-linha .menu a, .menu-linha .menu button {
  padding: 8px 10px; border-radius: 8px; color: var(--text); font-size: 13px;
  font-weight: 500; text-align: left; background: none; border: 0;
}
.menu-linha .menu a:hover, .menu-linha .menu button:hover { background: var(--hover); }
.menu-linha .menu hr { border: 0; border-top: 1px solid var(--card-border); margin: 6px 2px; }

/* Selo compacto de integração (Inter/Pix) ao lado do badge de status. */
.badge-mini {
  display: inline-block; margin-left: 4px; padding: 1px 7px; border-radius: 99px;
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  background: var(--hover); color: var(--text-2);
}
/* Variante de destaque (23/07/2026, coluna Fatura) — sinal mais forte
   (cliente abriu o link), mesmas cores de .badge.ok. */
.badge-mini.ok { background: var(--ok-bg); color: var(--ok-ink); }

/* Linha de filtros por coluna (23/07/2026) — cabeçalho congelado + filtro
   compacto por coluna, padrão do grupo (ver skill level-one-ui, componentes.md)
   aplicado pela primeira vez no Emit. */
tr.filtros input, tr.filtros select {
  width: 100%; font-size: 12px; padding: 4px 6px; border-radius: 6px;
  border: 1px solid var(--card-border); background: var(--bg);
}

/* Eyebrow — rótulo espaçado (assinatura da marca) */
.eyebrow {
  font-size: 11px; font-weight: 600; letter-spacing: .38em; text-transform: uppercase;
  color: var(--accent-ink);
}

/* Hero (saudação do dashboard) */
.hero {
  position: relative; overflow: hidden;
  background: #fff; border: 1px solid var(--card-border);
  border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 24px 28px; margin-bottom: 20px;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.hero::before {
  content: ''; position: absolute; top: -100px; left: -40px;
  width: 420px; height: 260px;
  background: radial-gradient(ellipse, rgba(15,145,207,.13), transparent 65%);
  pointer-events: none;
}
.hero > div { position: relative; }
.hero .eyebrow { margin-bottom: 6px; }
.hero h2 { font-size: 23px; font-weight: 800; }
.hero p { color: var(--muted); margin-top: 4px; font-size: 13.5px; }
.hero .actions { margin-left: auto; display: flex; gap: 10px; position: relative; }

/* ---------- Conteúdo ---------- */
.content { padding: 24px 28px 48px; }
.page-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 20px; flex-wrap: wrap; }
.page-head h1 { font-size: 21px; font-weight: 700; letter-spacing: -0.3px; }
.page-head p { color: var(--muted); font-size: 13px; margin-top: 2px; }
.page-head .actions { margin-left: auto; display: flex; gap: 10px; }

/* Raio 8px (--radius-sm) e primário SÓLIDO desde 29/07/2026: é o que o kit
   oficial define (.lo-btn--primary) e o que o Level Hub usa. O gradiente
   anterior era invenção dos mockups M0. */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; border-radius: var(--radius-sm); font-weight: 600; font-size: 13.5px;
  border: 1px solid var(--card-border); background: var(--card); color: var(--text);
  transition: background .15s, border-color .15s;
}
.btn:hover { background: var(--hover); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-ink); border-color: var(--accent-ink); }
.btn-ghost { border-color: transparent; background: transparent; color: var(--accent-ink); }
.btn-ghost:hover { background: var(--accent-soft); }
.btn-sm { padding: 5px 11px; font-size: 12.5px; border-radius: 6px; }
/* Botão que ocupa a linha inteira — substitui os 13 style="width:100%" */
.btn-largo { width: 100%; justify-content: center; }

/* ---------- Cards e KPIs ---------- */
.card {
  background: var(--card); border: 1px solid var(--card-border);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.card .card-head {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 20px 0;
}
.card .card-head h2 { font-size: 14.5px; font-weight: 600; }
.card .card-head .hint { color: var(--muted); font-size: 12px; }
.card .card-body { padding: 16px 20px 20px; }

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 14px; margin-bottom: 20px; }
.kpi { padding: 16px 18px; }
.kpi .k-label { font-size: 12.5px; color: var(--muted); font-weight: 500; }
.kpi .k-value { font-size: 26px; font-weight: 700; letter-spacing: -0.5px; margin-top: 4px; font-variant-numeric: tabular-nums; }
.kpi .k-delta { font-size: 12px; margin-top: 4px; font-weight: 600; }
.kpi .k-delta.up { color: var(--ok-ink); }
.kpi .k-delta.down { color: var(--bad-ink); }
.kpi .k-delta.flat { color: var(--muted); }
.kpi .k-delta span { color: var(--muted); font-weight: 400; }

.grid-2 { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; align-items: start; }
.grid-form { display: grid; grid-template-columns: 3fr 2fr; gap: 16px; align-items: start; }
@media (max-width: 960px) {
  .grid-2, .grid-form { grid-template-columns: 1fr; }
  .sidebar { display: none; }
}

/* ---------- Badges de status (sempre com texto — nunca só cor) ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 600; padding: 3px 9px; border-radius: 99px;
  white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.badge.ok   { background: var(--ok-bg);   color: var(--ok-ink); }
.badge.warn { background: var(--warn-bg); color: var(--warn-ink); }
.badge.bad  { background: var(--bad-bg);  color: var(--bad-ink); }
.badge.info { background: var(--info-bg); color: var(--info-ink); }
.badge.neutral { background: var(--hover); color: var(--text-2); }
.badge + .badge { margin-left: 4px; }

/* Valor monetário positivo/negativo em tabela (21/07/2026, DRE/Fluxo de
   Caixa) — mesmas cores de .badge.ok/.badge.bad, sem o formato pílula
   (é um número numa célula normal, não um rótulo de status). */
.valor-positivo { color: var(--ok-ink); }
.valor-negativo { color: var(--bad-ink); }

/* Faixa de resumo colorida (22/07/2026, referência Conexa) — cada bloco
   com a mesma cor de fundo/tinta já usada em .badge.ok/warn/bad/info,
   sem inventar tom novo. Usada acima de listagem financeira (Contas a
   Receber). */
.resumo-faixa { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; margin-bottom: 20px; }
.rf-bloco { display: flex; flex-direction: column; gap: 2px; padding: 12px 16px; border-radius: 10px; }
.rf-label { font-size: 12px; font-weight: 600; }
.rf-valor { font-size: 20px; font-weight: 700; letter-spacing: -0.3px; font-variant-numeric: tabular-nums; }
.rf-n { font-size: 11.5px; opacity: 0.85; }
.rf-bloco.ok   { background: var(--ok-bg);   color: var(--ok-ink); }
.rf-bloco.warn { background: var(--warn-bg); color: var(--warn-ink); }
.rf-bloco.bad  { background: var(--bad-bg);  color: var(--bad-ink); }
.rf-bloco.info { background: var(--info-bg); color: var(--info-ink); }
.rf-bloco.neutral { background: var(--hover); color: var(--text-2); }

/* ---------- Tabelas (cabeçalho fixo + filtros — padrão Level One) ----------
   Visual alinhado ao Level Hub em 29/07/2026: cabeçalho azul-petróleo escuro
   com texto branco, zebra nas linhas pares e hover em azul-claro. A altura
   deixou de ser 480px fixos (que sobrava tela num monitor grande e sumia num
   notebook) e passou a acompanhar a viewport. */
.table-wrap { overflow: auto; max-height: calc(100vh - 240px); border-radius: 0 0 var(--radius) var(--radius); }
/* `separate` é obrigatório para o cabeçalho congelado: com `collapse` o
   navegador descarta a borda das células sticky ao rolar. */
table {
  width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px;
  font-variant-numeric: tabular-nums;
}
thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--thead-bg); color: var(--thead-ink);
  text-align: left; font-size: 12px;
  font-weight: 600; padding: 10px 14px;
  white-space: nowrap;
}
/* A linha de filtros gruda ABAIXO da linha de títulos. Sem este `top` as duas
   parariam na mesma altura e ficariam uma em cima da outra ao rolar — era o
   que acontecia em Contas a Receber, a única tela que já tinha filtro.
   Desde 07/08/2026 o JS esconde esta linha e move cada input pro popover do
   cabeçalho (.th-filtro); a regra fica como fallback sem JS. */
thead tr.filtros th {
  top: 37px; background: var(--accent-soft);
  padding: 6px 8px; border-bottom: 1px solid var(--card-border);
}

/* Filtro de coluna no cabeçalho (07/08/2026) — botão de funil ao lado do
   título; popover fixed pela mesma razão do .menu-linha .menu (o overflow
   do .table-wrap recorta filho absoluto). O input dentro do popover é o
   MESMO nó da tr.filtros, movido pelo JS — o motor de filtro não muda. */
.th-filtro {
  border: none; background: transparent; color: var(--thead-ink); opacity: .45;
  padding: 1px 3px; margin-left: 5px; cursor: pointer; line-height: 1;
  vertical-align: middle; border-radius: 4px;
}
.th-filtro:hover { opacity: 1; background: rgba(255, 255, 255, .12); }
.th-filtro.ativo { opacity: 1; color: var(--accent-2); }
.th-filtro-pop {
  display: none; position: fixed; z-index: var(--z-menu);
  background: var(--card); border: 1px solid var(--card-border); border-radius: 10px;
  box-shadow: var(--shadow-lift); padding: 8px;
}
.th-filtro-pop.open { display: block; }
.th-filtro-pop input, .th-filtro-pop select {
  width: 190px; font-size: 12.5px; padding: 6px 9px; border-radius: 6px;
  border: 1px solid var(--card-border); background: var(--bg); color: var(--text);
}
tbody td { padding: 11px 14px; border-bottom: 1px solid var(--row-border); vertical-align: middle; background: var(--card); }
tbody tr:nth-child(even) td { background: var(--zebra); }
tbody tr:hover td { background: var(--accent-soft); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td .sub { display: block; color: var(--muted); font-size: 11.5px; }

/* Densidade compacta (07/08/2026, pedido do Felipe pra Contas a Receber:
   "linhas muito extensas... para clientes com muitas notas pode se tornar
   um problema", mantendo TODAS as colunas e informações — só encolhe
   espaçamento, fontes e badges). Aplicar no <table> via classe. */
.table--compacta { font-size: 12.5px; }
.table--compacta tbody td { padding: 6px 10px; }
.table--compacta td .sub { font-size: 10.5px; }
.table--compacta .badge { padding: 2px 8px 2px 6px; font-size: 10.5px; }
.table--compacta .badge::before { width: 5px; height: 5px; }
.table--compacta .badge-mini { padding: 1px 6px; font-size: 10px; }
.table--compacta .menu-linha > button { padding: 2px 8px; font-size: 13px; }
.table--compacta tfoot td { padding: 8px 10px; }
tfoot td { padding: 11px 14px; font-weight: 700; border-top: 1px solid var(--card-border);
  font-variant-numeric: tabular-nums; }

/* DRE — cascata de grupos (cabeçalho de grupo + subtotais calculados)
   Os seletores abaixo levam `tbody` na frente de propósito (29/07/2026): a
   zebra é `tbody tr:nth-child(even) td` e venceria `tr.classe td` por
   especificidade, apagando o fundo próprio destas linhas. E o fundo dos
   totais virou --linha-destaque: --thead-bg passou a ser escuro. */
tbody tr.dre-grupo td { background: var(--hover); }
tbody tr.dre-total td { background: var(--linha-destaque); border-top: 2px solid var(--card-border); border-bottom: 2px solid var(--card-border); }
/* DRE — subtotal por categoria totalizadora (22/07/2026), nível entre o
   grupo e a categoria-folha: indent menor que a folha, sem fundo cheio. */
.dre-subgrupo td:first-child { padding-left: 12px !important; font-weight: 600; }
.dre-subgrupo-filha td:first-child { padding-left: 36px !important; }

/* Fluxo de Caixa — matriz Realizado × Projetado (Fase 4, 23/07/2026)
   Mesma regra de especificidade da DRE acima: `tbody` na frente para vencer a
   zebra, e o saldo acumulado usa --linha-destaque no lugar de --thead-bg. */
/* A coluna do mês corrente é marcada no <th> E no <td>. Com o cabeçalho
   escuro, o destaque do <th> não pode ser o amarelo claro (texto branco em
   cima ficaria ilegível) — vira um azul-petróleo um tom acima. */
thead th.col-atual { background: var(--thead-destaque); }
tbody td.col-atual { background: var(--warn-bg); }
tbody tr.fc-linha-entrada td { background: var(--ok-bg); }
tbody tr.fc-linha-entrada td:first-child { color: var(--ok-ink); font-weight: 700; }
tbody tr.fc-linha-saida td { background: var(--bad-bg); }
tbody tr.fc-linha-saida td:first-child { color: var(--bad-ink); font-weight: 700; }
tbody tr.fc-linha-saldo-acumulado td { background: var(--linha-destaque); border-top: 2px solid var(--card-border); border-bottom: 2px solid var(--card-border); font-weight: 700; }
.fc-sub-categoria td:first-child { padding-left: 28px !important; font-weight: 400; color: var(--text-2); }
.fc-seta-alta { color: var(--ok-ink); font-size: 11px; }
.fc-seta-baixa { color: var(--bad-ink); font-size: 11px; }

/* Chips de filtro */
.chips { display: flex; gap: 8px; flex-wrap: wrap; }
.chip {
  padding: 6px 13px; border-radius: 99px; font-size: 12.5px; font-weight: 600;
  border: 1px solid var(--card-border); background: var(--card); color: var(--text-2);
}
.chip:hover { background: var(--hover); }
.chip.active { background: var(--accent-soft); border-color: transparent; color: var(--accent-ink); }
.filters-row { display: flex; align-items: center; gap: 12px; padding: 14px 20px; flex-wrap: wrap; }
.filters-row[hidden] { display: none; }
.filters-row .search {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--card-border); border-radius: 10px; padding: 7px 12px;
  background: var(--input-bg); color: var(--muted); font-size: 13px; min-width: 220px;
}
.filters-row .search input { border: 0; background: none; outline: none; color: var(--text); width: 100%; font: inherit; }

/* ---------- Formulários ----------
   A grade antiga `.form-grid` (2 colunas fixas para tudo) foi REMOVIDA em
   29/07/2026, no fim da Onda 3, depois que o último template saiu dela. Isso
   é a trava: sem a classe no CSS, uma tela nova não tem como reincidir no
   padrão que causava a queixa de campo "jogado" — só existe a grade de 12
   colunas (`.form-grade`, mais abaixo). */
/* min-width:0 é obrigatório: sem ele um <select> com opção comprida trava a
   largura mínima da coluna e a página estoura na horizontal no celular — o
   grid não encolhe um item abaixo do min-content dele por padrão. */
.field { min-width: 0; }
.field label { display: block; font-size: 12.5px; font-weight: 600; margin-bottom: 5px; color: var(--text-2); }
.field input, .field select, .field textarea {
  width: 100%; min-width: 0; padding: 9px 12px; border-radius: var(--radius-sm);
  border: 1px solid var(--card-border); background: var(--input-bg); color: var(--text);
  font: inherit; outline: none;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.field .help { font-size: 11.5px; color: var(--muted); margin-top: 4px; }
.check { display: flex; align-items: center; gap: 8px; font-size: 13px; padding-top: 8px; }
.check input { width: 16px; height: 16px; accent-color: var(--accent); }

/* Checklist de conciliação com soma em tempo real (extrato/index.html,
   08/08/2026, pedido do Felipe) — vários lançamentos marcados juntos
   fecham o valor de uma única transação do extrato. */
.checklist-conciliar {
  display: flex; flex-direction: column; gap: 2px; max-height: 220px; overflow-y: auto;
  border: 1px solid var(--card-border); border-radius: var(--radius-sm); padding: 6px;
}
.checklist-item {
  display: flex; align-items: flex-start; gap: 8px; padding: 7px 8px;
  border-radius: 6px; font-size: 13px; cursor: pointer;
}
.checklist-item:hover { background: var(--hover); }
.checklist-item input { width: 16px; height: 16px; margin-top: 2px; flex-shrink: 0; accent-color: var(--accent); }
.checklist-soma {
  display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 13px; font-weight: 600;
  padding: 7px 12px; border-radius: var(--radius-sm); background: var(--bad-bg); color: var(--bad-ink);
}
.checklist-soma.bate { background: var(--ok-bg); color: var(--ok-ink); }
.checklist-soma-valor { font-variant-numeric: tabular-nums; }

/* .help genérico (21/07/2026) — texto de ajuda fora de um .field (abaixo de
   um .form-secao, por exemplo) usava só a regra `.field .help` acima e
   ficava sem estilo nenhum. Precisa ser <div>, nunca <span>/<small>: a
   margem vertical (margin-top) é ignorada pelo navegador em elemento
   inline. */
.help { font-size: 11.5px; color: var(--muted); margin-top: 4px; }

/* ── Grade de formulário v2: 12 colunas fixas (Onda 3, 29/07/2026) ─────────
   Portada do Level Hub (`.form-grade` lá). Cada linha do formulário é
   DESENHADA: os spans somam 12 (ex.: CEP 3 + Logradouro 6 + Número 3), em vez
   de "2 colunas iguais para tudo" da `.form-grid` antiga — que era a causa da
   queixa "está tudo misturado, como se o campo fosse simplesmente jogado".
   Sem modificador, o campo ocupa a linha inteira.

   Diferença deliberada em relação ao Hub: lá o wrapper de campo é `.campo`,
   aqui é `.field`, que já está em ~300 lugares. Renomear não pagaria; o que
   importa é a grade ser a mesma. */
.form-grade { display: grid; grid-template-columns: repeat(12, 1fr); gap: 14px 18px; align-items: start; }
.form-grade .field { grid-column: span 12; }
.form-grade .field--2  { grid-column: span 2; }
.form-grade .field--3  { grid-column: span 3; }
.form-grade .field--4  { grid-column: span 4; }
.form-grade .field--5  { grid-column: span 5; }
.form-grade .field--6  { grid-column: span 6; }
.form-grade .field--7  { grid-column: span 7; }
.form-grade .field--8  { grid-column: span 8; }
.form-grade .field--9  { grid-column: span 9; }
.form-grade .field--10 { grid-column: span 10; }

/* Cabeçalho de subseção dentro de um formulário/aba (21/07/2026) —
   `.form-secao` para subdivisões dentro do MESMO assunto (sem linha
   divisória, ex.: Configuração Fiscal → "NF-e / NFC-e" → "Reforma
   tributária"); `.form-secao-bloco` para blocos funcionalmente distintos
   dentro da mesma aba (com linha divisória, ex.: Logomarca, Módulos
   contratados, D4Sign, Envio de e-mails).
   A tipografia veio na Onda 3: até então `.form-secao` só tinha margem e o
   título de seção saía do mesmo tamanho de um título de card, competindo com
   ele em vez de organizá-lo. */
.form-secao, .form-secao-bloco {
  font-size: 13px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted);
}
.form-secao { margin: 22px 0 10px; }
.form-secao-bloco {
  margin: 28px 0 10px; padding-top: 20px; border-top: 1px solid var(--card-border);
}
/* A primeira seção do formulário/aba não precisa do respiro de cima.
   `:first-of-type` e não `:first-child`: o primeiro filho de todo `<form>` do
   projeto é o `<input type="hidden" name="csrf_token">`, então `:first-child`
   nunca casava com o `<h3>` e a primeira seção saía com os 22px cheios,
   descolada do título do card. */
.form-secao:first-of-type, .form-secao-bloco:first-of-type { margin-top: 4px; }
.form-secao-bloco:first-of-type { padding-top: 0; border-top: none; }

/* Campo cujo controle é um input + botão colado (CNPJ + "Consultar Receita
   Federal", CEP + "Buscar"). Substitui o trio de style inline
   `display:flex;gap:8px` + `flex:1;min-width:0` + `white-space:nowrap`. */
.field-com-botao { display: flex; gap: 8px; align-items: stretch; }
.field-com-botao input, .field-com-botao select { flex: 1; min-width: 0; }
.field-com-botao .btn { flex-shrink: 0; white-space: nowrap; }

/* Grupo de opções por radio, tipo segmented control (Benefício Municipal na
   Configuração Fiscal). Estava montado à mão com 3 style inline. */
.grupo-opcoes {
  display: flex; flex-wrap: wrap;
  border: 1px solid var(--card-border); border-radius: var(--radius-sm); overflow: hidden;
}
.grupo-opcoes label {
  flex: 1; min-width: 140px; padding: 10px 16px;
  display: flex; align-items: center; gap: 8px;
  font-size: 13.5px; font-weight: 500; color: var(--text);
  cursor: pointer; border-right: 1px solid var(--card-border);
  transition: background .12s;
}
.grupo-opcoes label:last-child { border-right: none; }
.grupo-opcoes label:hover { background: var(--hover); }
.grupo-opcoes input[type="radio"] { width: auto; accent-color: var(--accent); }
.grupo-opcoes label:has(input:checked) {
  background: var(--accent-soft); color: var(--accent-ink); font-weight: 600;
}

/* Moldura de pré-visualização (logomarca da empresa) — era um card inteiro
   reimplementado em atributo style. */
.moldura-preview {
  background: var(--card); border: 1px solid var(--card-border);
  border-radius: var(--radius-sm); padding: 14px; min-width: 140px;
  display: flex; align-items: center; justify-content: center;
}
.moldura-preview img { max-width: 180px; max-height: 80px; }

/* Formulário GET de filtro acima de uma listagem (período, categoria, status).
   Fica solto entre o cabeçalho da página e a tabela; a margem inferior é dele,
   não de um `style` no template. */
.form-filtro { margin-bottom: 14px; }

/* Sub-formulário dentro de uma seção (credenciais do D4Sign, SMTP, upload de
   certificado): coluna estreita própria, para o campo não esticar pela largura
   inteira do painel. Substitui os `style="max-width:420px"` avulsos. */
.form-bloco { max-width: 420px; }
.form-bloco .btn { width: 100%; justify-content: center; }
.form-bloco + .form-bloco { margin-top: 14px; }

/* Rodapé padrão de ações do formulário (21/07/2026) — mesmo bloco que se
   repetia inline em ~13 templates. Ganhou linha divisória em 29/07/2026, como
   no Level Hub. O alinhamento continua à DIREITA, ao contrário do Hub: é a
   convenção já estabelecida nas 19 telas daqui, e trocar o lado dos botões
   agitaria a interface inteira sem corrigir nada.
   flex-wrap: no estreito os botões quebram linha em vez de estourar a página. */
.acoes-form {
  display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end;
  margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--card-border);
}

/* ── Utilitários que substituem style= inline (29/07/2026) ─────────────────
   Cada um destes existe porque o mesmo trecho estava repetido dezenas de
   vezes como atributo `style` nos templates. O design system não admite
   layout inline; ver a skill level-one-ui. */

/* Substitui todo `style="display:none"` de template e todo
   `.style.display = "none"` de JS. */
.oculta { display: none !important; }

/* Largura do painel de formulário travada no CSS. Antes cada tela punha o seu
   `style="max-width:..."` e o projeto acabou com SETE larguras diferentes
   (480/520/560/640/720/760/820). Sem limite, um formulário de 2 colunas se
   estica: num monitor de 1600px cada campo vira o dobro do que foi desenhado
   — o "esparramado". */
.card--form     { max-width: 820px; }
.card--estreito { max-width: 560px; }   /* cadastros de 1 a 4 campos */

/* Card empilhado abaixo de outro na mesma tela — substitui
   `style="margin-top:16px"`. É classe explícita e NÃO a regra automática
   `.card + .card`: essa versão foi tentada e quebrou a faixa de KPIs da DRE,
   onde os cards são irmãos DENTRO de um grid e o espaçamento já vem do
   `gap` — o margin-top empurrava o 2º e o 3º card 16px para baixo. */
.card--espacado { margin-top: 16px; }

/* Card de aviso no topo da tela ("dados fiscais incompletos", "certificado
   vencendo"). Carrega a margem inferior por dentro porque um aviso é sempre
   seguido de conteúdo — substitui os `margin-bottom:16px; border-color:...`
   que apareciam soltos em 5 telas. */
.card--aviso, .card--erro { margin-bottom: 16px; }
.card--aviso { border-color: var(--warn-ink); }
.card--erro  { border-color: var(--bad-ink); }

/* Card que vem ACIMA de outro bloco na mesma tela (o par de `.card--espacado`,
   que é margem em cima). */
.card--espacado-abaixo { margin-bottom: 16px; }

/* Ação secundária no canto direito do cabeçalho de um card ("ver todos →"). */
.card-head > .btn { margin-left: auto; }

/* Legenda de gráfico: linha de bolinhas coloridas + rótulo. As cores vêm das
   mesmas variáveis das séries, para legenda e gráfico nunca divergirem. */
.legenda-grafico { margin: 0 0 10px; font-size: 12.5px; color: var(--muted); }
.legenda-grafico .ponto-entrada { color: var(--ok-ink); }
.legenda-grafico .ponto-saida   { color: var(--bad-ink); }
.legenda-grafico .ponto-saldo   { color: var(--accent); }
.legenda-grafico .projetado     { opacity: .6; }

/* Bloco de XML/retorno cru — quebra em qualquer ponto e rola dentro do card,
   para uma chave de 44 dígitos não esticar a página. */
.pre-xml {
  white-space: pre-wrap; word-break: break-all;
  font-family: var(--font-mono); font-size: 11px;
  max-height: 220px; overflow: auto;
}

/* Texto de ajuda logo abaixo de uma tabela (ex.: nota sobre a tabela de
   permissões) precisa de respiro — o `.help` normal só tem 4px, pensado para
   ficar colado no campo que explica. */
.table-wrap + .help { margin-top: 10px; }

/* Bloco de leitura dentro de um card (o "Como conseguir o token" das
   Configurações): texto corrido, um pouco menor e mais arejado. */
.card-texto { font-size: 13px; color: var(--text-2); line-height: 1.7; }

/* Linha de botões/blocos lado a lado dentro de um formulário — substitui os
   `display:flex; gap:Npx` avulsos. `--largo` para blocos que precisam quebrar
   linha em tela estreita (preview da logo + campo de upload). */
.linha-flex { display: flex; gap: 10px; align-items: center; }
.linha-flex--largo { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.linha-flex--largo > .cresce { flex: 1; min-width: 260px; }
/* Filtro em linha onde os controles alinham pela BASE (campo + checkbox +
   botão na mesma altura) — Fluxo de Caixa. */
.linha-flex--base { display: flex; gap: 20px; align-items: flex-end; flex-wrap: wrap; }
.linha-flex--base > label { display: flex; align-items: center; gap: 6px; padding-bottom: 9px; }

/* Espaço entre linhas de resumo empilhadas no painel lateral (contrato,
   nota) — substitui os `margin-top:14px` avulsos. */
.sumline--espacado { margin-top: 14px; }

/* Campo cuja linha é um botão/checkbox que precisa alinhar pela base da
   linha ao lado — substitui `style="align-self:flex-end|end"`. */
.field--alinhado { align-self: end; }

/* Frase de contexto acima de um formulário ou dentro de um modal —
   substitui o mesmo `margin-bottom:14px; color:...; font-size:13px` repetido. */
.texto-contexto { margin-bottom: 14px; color: var(--muted); font-size: 13px; }

/* Cabeçalho de seção DENTRO de uma aba/painel (06/08/2026) — texto de
   contexto + ação primária no canto (ex.: "+ Novo modelo" em Modelos de
   comunicação). Mesma ideia de `.page-head`, mas sem o respiro de título
   de página — este vive dentro de um `.card-body` já com padding próprio. */
.secao-cabecalho { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 14px; }
.secao-cabecalho .texto-contexto { margin-bottom: 0; }
.secao-cabecalho .btn { flex-shrink: 0; }

/* Ações numa linha de tabela (21/07/2026) — vários botões pequenos numa
   mesma célula. LEGADO desde a Onda 2 (29/07/2026): o padrão único agora é o
   nome clicável na 1ª coluna + menu "⋮" (`.menu-linha`). Fica só enquanto
   houver tela fora da listagem usando. */
.row-acoes { display: flex; gap: 6px; flex-wrap: wrap; }
.row-acoes--fim { justify-content: flex-end; }

/* Nome da entidade na 1ª coluna: é o link que abre o cadastro (padrão do
   Level Hub, adotado na Onda 2 em 29/07/2026). Substituiu a coluna "Abrir"
   que existia em 11 telas gastando uma coluna inteira num clique que o
   próprio nome resolve.
   Azul, e não preto: no Hub o reset é `a { color: var(--primary-dark) }` e o
   nome sai azul em toda listagem. Aqui o reset é `a { color: inherit }`, então
   sem cor própria o link ficaria preto e nada indicaria que dá para clicar —
   que é justamente o trabalho que o botão "Abrir" fazia. */
.link-entidade { font-weight: 600; color: var(--accent-ink); }
.link-entidade:hover { text-decoration: underline; }

/* Coluna do menu "⋮": estreita e encostada à direita, para não roubar
   espaço das colunas de dado. */
th.col-acoes, td.col-acoes { width: 1%; white-space: nowrap; text-align: right; }

/* Setinhas de reordenar (07/08/2026, categorias — trazido do Level Hub).
   2 <form> lado a lado (cada clique é um POST); desabilitada na ponta do
   grupo de irmãs (primeira não sobe, última não desce). */
.reordenar { display: inline-flex; gap: 2px; }
.btn-reordenar {
  border: 1px solid var(--card-border); background: var(--card); color: var(--text-2);
  border-radius: 6px; padding: 3px 5px; cursor: pointer; line-height: 1;
}
.btn-reordenar:hover:not(:disabled) { background: var(--hover); }
.btn-reordenar:disabled { opacity: .3; cursor: default; }

/* Autocomplete de CNAE (Serviços) — mesmo visual do menu do seletor de empresa. */
.autocomplete { position: relative; }
.autocomplete-lista {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: var(--z-menu);
  background: var(--card); border: 1px solid var(--card-border); border-radius: 10px;
  box-shadow: var(--shadow-lift); max-height: 260px; overflow-y: auto; padding: 4px;
}
.autocomplete-lista button {
  display: block; width: 100%; text-align: left; padding: 8px 10px;
  border: 0; background: none; border-radius: 8px; color: var(--text); font: inherit;
}
.autocomplete-lista button:hover { background: var(--hover); }
.autocomplete-lista button small { display: block; color: var(--muted); font-size: 11.5px; }
.autocomplete-lista .vazio { padding: 8px 10px; color: var(--muted); font-size: 12.5px; }

/* ---------- Resumo da nota / linhas de total ---------- */
.sumline { display: flex; justify-content: space-between; padding: 8px 0; font-size: 13.5px;
  border-bottom: 1px dashed var(--row-border); font-variant-numeric: tabular-nums; }
.sumline:last-child { border-bottom: 0; }
.sumline.total { font-weight: 700; font-size: 15px; border-bottom: 0; padding-top: 12px; }
.sumline .lbl { color: var(--text-2); }

/* ---------- Timeline de status da nota ---------- */
.timeline { list-style: none; }
.timeline li { display: flex; gap: 12px; position: relative; padding-bottom: 18px; }
.timeline li::before {
  content: ""; position: absolute; left: 9px; top: 22px; bottom: 0; width: 2px;
  background: var(--row-border);
}
.timeline li:last-child::before { display: none; }
.timeline .dot {
  width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0; z-index: 1;
  background: var(--hover); border: 2px solid var(--card-border);
  display: inline-flex; align-items: center; justify-content: center; font-size: 10px; color: #fff;
}
.timeline li.done .dot { background: var(--ok-ink); border-color: var(--ok-ink); }
.timeline li.now .dot { background: var(--accent); border-color: var(--accent); }
.timeline .t-title { font-weight: 600; font-size: 13px; }
.timeline .t-sub { color: var(--muted); font-size: 11.5px; }

/* ---------- Medidores (cobranças por status) ---------- */
.meter { margin-bottom: 14px; }
.meter .m-head { display: flex; justify-content: space-between; font-size: 12.5px; margin-bottom: 5px; }
.meter .m-head b { font-variant-numeric: tabular-nums; }
.meter .track { height: 8px; border-radius: 99px; background: var(--hover); overflow: hidden; }
.meter .fill { height: 100%; border-radius: 99px; }
.meter .fill.ok { background: var(--ok-ink); }
.meter .fill.info { background: var(--accent); }
.meter .fill.bad { background: var(--bad-ink); }

/* ---------- Lista de avisos ---------- */
.alerts { list-style: none; }
.alerts li { display: flex; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--row-border);
  font-size: 13px; align-items: flex-start; }
.alerts li:last-child { border-bottom: 0; }
.alerts .a-ico { width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px; }
.alerts .a-ico.warn { background: var(--warn-bg); color: var(--warn-ink); }
.alerts .a-ico.bad { background: var(--bad-bg); color: var(--bad-ink); }
.alerts .a-ico.info { background: var(--info-bg); color: var(--info-ink); }
.alerts small { color: var(--muted); display: block; }

/* ---------- Gráfico ---------- */
.chart-svg { width: 100%; height: auto; display: block; }
.chart-svg text { font-family: inherit; font-size: 11px; fill: var(--muted); font-variant-numeric: tabular-nums; }
.chart-svg .grid { stroke: var(--chart-grid); stroke-width: 1; }
.chart-svg .axis { stroke: var(--chart-axis); stroke-width: 1; }
.chart-svg .bar { fill: var(--chart-series); cursor: pointer; }
.chart-svg .bar:hover { filter: brightness(1.12); }
.chart-svg .bar.entrada { fill: var(--ok-ink); }
.chart-svg .bar.saida { fill: var(--bad-ink); }
.chart-svg .bar.projetado { fill-opacity: .45; }
.chart-svg .dlabel { font-weight: 700; fill: var(--text); font-size: 12px; }
/* Fluxo de Caixa — gráfico combinado (Fase 4) */
.chart-svg .linha-saldo-acumulado { stroke: var(--accent); stroke-width: 2.5; fill: none; }
.chart-svg .linha-hoje { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 4 3; }
.chart-svg .rotulo-hoje { fill: var(--muted); font-size: 10px; }
.viz-tip {
  position: fixed; pointer-events: none; z-index: var(--z-menu); display: none;
  background: var(--tip-bg); color: var(--tip-ink);
  border-radius: 8px; padding: 7px 10px; font-size: 12px; font-weight: 600;
  box-shadow: 0 4px 14px rgba(0,0,0,0.25);
}
.viz-tip small { display: block; font-weight: 400; opacity: 0.75; }

/* ---------- Modal ---------- */
.modal-back {
  display: none; position: fixed; inset: 0; z-index: var(--z-flash);
  background: rgba(8, 15, 24, 0.55); backdrop-filter: blur(3px);
  align-items: center; justify-content: center; padding: 20px;
}
.modal-back.open { display: flex; }
.modal {
  background: var(--card); border: 1px solid var(--card-border);
  border-radius: 16px; box-shadow: var(--shadow);
  width: 100%; max-width: 520px; max-height: 90vh; overflow: auto;
}
.modal.modal-lg { max-width: 720px; }
.modal .m-head { display: flex; align-items: center; padding: 18px 22px 0; }
.modal .m-head h3 { font-size: 16px; font-weight: 700; }
.modal .m-head .x { margin-left: auto; border: 0; background: none; color: var(--muted); font-size: 18px; }
.modal .m-body { padding: 16px 22px; }
.modal .m-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 0 22px 20px; }

/* ---------- Telas cheias (login / seleção de empresa) ---------- */
.auth-wrap { min-height: 100vh; display: flex; }
.auth-brand {
  flex: 1.1; display: flex; flex-direction: column; justify-content: center;
  padding: 60px; color: #fff; position: relative; overflow: hidden;
  background: var(--brand-panel);
}
/* Faixa inclinada no ângulo do "1" da marca — assinatura gráfica */
.auth-brand::before {
  content: ''; position: absolute; top: -12%; bottom: -12%; right: 8%;
  width: 130px; transform: skewX(var(--lo-skew));
  background: linear-gradient(180deg, var(--accent), var(--accent-700));
  opacity: .16;
}
.auth-brand::after {
  content: ''; position: absolute; top: -12%; bottom: -12%; right: calc(8% + 160px);
  width: 34px; transform: skewX(var(--lo-skew));
  background: var(--accent-2); opacity: .10;
}
.auth-brand > * { position: relative; }
/* align-self impede o flex de esticar a logo até a largura do painel
   (align-items: stretch é o padrão em coluna) — sem isso a imagem deforma.
   As alturas casam 1:1 com os PNGs pré-gerados (56/42/40px + versão 2x via
   srcset) — o navegador não redimensiona nada, exibe pixel por pixel. */
.auth-brand .lockup { height: 56px; width: auto; align-self: flex-start; margin-bottom: 38px; }
.auth-brand .eyebrow { color: var(--accent-2); margin-bottom: 10px; }
.auth-brand h2 { font-size: 30px; font-weight: 800; letter-spacing: -0.6px; line-height: 1.2; max-width: 420px; }
.auth-brand p { margin-top: 12px; opacity: 0.8; max-width: 400px; font-size: 14.5px; }
.auth-brand ul { list-style: none; margin-top: 30px; display: grid; gap: 13px; }
.auth-brand li { display: flex; gap: 11px; align-items: center; font-size: 14px; font-weight: 500; }
.auth-brand li .b {
  width: 26px; height: 26px; border-radius: 8px; flex-shrink: 0;
  background: rgba(255,255,255,0.14); display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px;
}
.auth-form {
  width: 460px; flex-shrink: 0; display: flex; flex-direction: column; justify-content: center;
  padding: 60px 56px; background: var(--card);
}
.auth-form .lockup { height: 42px; width: auto; align-self: flex-start; margin-bottom: 26px; }
.auth-form h1 { font-size: 22px; font-weight: 700; letter-spacing: -0.3px; }
.auth-form .sub { color: var(--muted); font-size: 13.5px; margin: 6px 0 26px; }
.auth-form .field { margin-bottom: 15px; }
.auth-form .btn-primary { width: 100%; justify-content: center; padding: 12px; font-size: 14.5px; margin-top: 6px; }
.auth-form .foot { margin-top: 18px; font-size: 13px; color: var(--muted); text-align: center; }
.auth-form .foot a { color: var(--accent-ink); font-weight: 600; }
.auth-badges { display: flex; gap: 8px; margin-top: 26px; justify-content: center; flex-wrap: wrap; }
.auth-badges span { font-size: 11px; color: var(--muted); border: 1px solid var(--card-border);
  padding: 4px 10px; border-radius: 99px; }
@media (max-width: 860px) {
  .auth-brand { display: none; }
  .auth-form { width: 100%; }
}

.select-wrap { min-height: 100vh; display: flex; flex-direction: column; align-items: center;
  justify-content: center; padding: 40px 20px; }
.select-wrap .lockup { height: 40px; width: auto; align-self: center; margin-bottom: 30px; }
.select-wrap h1 { font-size: 24px; font-weight: 700; letter-spacing: -0.4px; }
.select-wrap .sub { color: var(--muted); margin: 6px 0 30px; }
.empresa-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 280px)); gap: 16px;
  justify-content: center; width: 100%; max-width: 940px; }
.empresa-card { padding: 22px; text-align: left; cursor: pointer; transition: transform 0.12s ease, box-shadow 0.12s ease; display: block; }
.empresa-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); border-color: var(--accent); }
.empresa-card .e-ini {
  width: 42px; height: 42px; border-radius: 11px; font-weight: 800; font-size: 15px; color: #fff;
  background: var(--accent);
  display: inline-flex; align-items: center; justify-content: center; margin-bottom: 14px;
}
/* Logo da empresa (07/08/2026) — mesmo slot 42x42 do avatar de iniciais,
   pra trocar um pelo outro sem mudar a altura do cabeçalho do card
   (objetivo do Felipe: "os quadros devem ser alinhados... mesmo
   tamanho"). Fundo branco + borda porque logos costumam ter fundo
   transparente e o card pode não ser branco puro; `object-fit: contain`
   nunca corta a marca, só encolhe dentro do quadrado. */
.empresa-card .e-logo {
  width: 42px; height: 42px; border-radius: 11px; background: #fff;
  border: 1px solid var(--card-border); display: inline-flex; align-items: center;
  justify-content: center; margin-bottom: 14px; padding: 4px; overflow: hidden;
}
.empresa-card .e-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
/* Nome sempre em 1 linha (07/08/2026, pedido do Felipe: "se ficou
   desalinhado por conta da razão social, abreviar para caber") — corta
   com reticências em vez de quebrar linha, senão nomes longos empurram
   o resto do card pra baixo de forma desigual entre um card e outro.
   `title` no <h3> (ver template) mostra o nome inteiro ao passar o mouse. */
.empresa-card h3 {
  font-size: 15px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.empresa-card .cnpj { color: var(--muted); font-size: 12.5px; margin: 3px 0 12px; font-variant-numeric: tabular-nums; }
.empresa-card.nova { border-style: dashed; display: flex; flex-direction: column; align-items: center;
  justify-content: center; color: var(--muted); font-weight: 600; min-height: 180px; gap: 8px; }
.empresa-card.nova:hover { color: var(--accent-ink); }
/* O cartão é um <button> quando é troca de empresa (POST) e um <a> quando é
   "Nova empresa" — a largura precisa ser dita, porque <button> não estica
   sozinho na célula do grid como o <a> faz. */
.empresa-card { width: 100%; }
.empresa-mais { font-size: 22px; line-height: 1; }

/* Cards por cliente na Visão Geral do Escritório (07/08/2026, pedido do
   Felipe: "mostrar cards por clientes" com financeiro + alertas). Variante
   do .empresa-card de selecionar_empresa — dentro do card-body, sem o
   max-width centrado da tela de seleção. */
.empresa-grid--painel { max-width: none; justify-content: stretch;
  grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); }
.empresa-card .ec-kpis { margin-top: 4px; border-top: 1px solid var(--row-border); padding-top: 10px; }
.empresa-card .ec-linha { display: flex; justify-content: space-between; gap: 10px;
  font-size: 12.5px; padding: 3px 0; }
.empresa-card .ec-linha .lbl { color: var(--text-2); }
.empresa-card .ec-linha b { font-variant-numeric: tabular-nums; }
.empresa-card .ec-linha.bad b { color: var(--bad-ink); }
.empresa-card .ec-motivos { margin-top: 10px; font-size: 11.5px; color: var(--bad-ink);
  line-height: 1.5; }
.select-wrap .sair { margin-top: 26px; color: var(--muted); font-size: 13px; }
.select-wrap .sair a { color: var(--accent-ink); font-weight: 600; }

/* Kanban de faturamento (23/07/2026, referência Omie/Conexa — Contratos e
   Ordens de Serviço) — SEM drag-and-drop: colunas fixas, cada uma sua
   própria consulta server-side, com ação em lote no rodapé. Padrão 100%
   novo pro Level Emit, sem precedente de board em nenhuma tela anterior. */
.kanban {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(230px, 1fr);
  gap: 12px; overflow-x: auto; align-items: start; padding-bottom: 4px;
}
.kanban-coluna {
  background: var(--card); border: 1px solid var(--card-border); border-radius: var(--radius);
  display: flex; flex-direction: column; min-width: 230px; max-height: 640px;
}
.kanban-coluna-cab { padding: 12px 14px; border-bottom: 1px solid var(--card-border); }
.kanban-coluna-titulo { font-weight: 700; font-size: 13.5px; }
.kanban-coluna-contagem { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.kanban-corpo { padding: 8px; display: flex; flex-direction: column; gap: 8px; overflow-y: auto; flex: 1; }
.kanban-card { background: var(--hover); border-radius: var(--radius-sm); padding: 10px 12px; }
.kanban-card.bad { background: var(--bad-bg); }
.kanban-card.warn { background: var(--warn-bg); }
.kanban-card-titulo { font-weight: 600; font-size: 12.5px; }
.kanban-card-sub { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.kanban-card-alerta { font-size: 11px; font-weight: 600; color: var(--bad-ink); margin-top: 4px; }
.kanban-card-acao { margin-top: 8px; display: flex; gap: 6px; flex-wrap: wrap; }
.kanban-card-acao select { font-size: 11.5px; padding: 3px 6px; }
.kanban-coluna-acao {
  padding: 10px 14px; border-top: 1px solid var(--card-border); background: var(--bg);
  border-radius: 0 0 var(--radius) var(--radius); text-align: center;
}
.kanban-coluna-acao form, .kanban-coluna-acao button, .kanban-coluna-acao a { width: 100%; }
.kanban-vazio { padding: 20px 12px; text-align: center; color: var(--muted); font-size: 12px; }

/* ---------- Responsivo (29/07/2026) ----------------------------------------
   Até a Onda 3 o sistema não tinha NENHUMA media query de formulário: a grade
   antiga era `1fr 1fr` fixo e, em 375px de largura, os 20 formulários
   estouravam na horizontal. */
@media (max-width: 720px) {
  /* A grade de 12 colunas colapsa: um span 3 num celular de 375px daria 80px
     de campo. */
  .form-grade { grid-template-columns: 1fr; }
  .form-grade .field, .form-grade [class*="field--"] { grid-column: 1 / -1 !important; }
  .content { padding: 18px 16px 40px; }
  .topbar { padding: 0 16px; }
}

/* ---------- Utilitários finais da Onda 3 (29/07/2026) ----------------------
   Cada um destes nasceu de um `style=` que se repetia; nenhum é decorativo. */

/* Texto que preserva as quebras de linha digitadas pelo usuário (mensagem de
   ticket, corpo de artigo da Ajuda) sem virar <pre> — que trocaria a fonte. */
.texto-multilinha { white-space: pre-wrap; }

/* Campo de código de verificação: dígitos espaçados e centralizados, para
   conferir o código do e-mail sem contar caractere. */
.campo-codigo { letter-spacing: 6px; font-size: 20px; text-align: center; }

/* QR code de ativação do MFA (01/08/2026) — centralizado, tamanho fixo
   pra ficar legível pela câmera sem depender do tamanho gerado pela lib. */
.qr-mfa { display: flex; justify-content: center; padding: 16px; background: var(--card);
  border: 1px solid var(--card-border); border-radius: var(--radius-sm); }
.qr-mfa img { width: 200px; height: 200px; }

/* Barra de seleção em massa que aparece acima da tabela quando o usuário
   marca linhas (renegociação em Contas a Receber). */
.barra-selecao { margin-top: 10px; }

/* Bloco separado do anterior por um traço, dentro do MESMO card — usado quando
   dois formulários independentes dividem o card e não há título de seção que
   justifique um `form-secao-bloco`. */
.bloco-separado {
  border-top: 1px solid var(--card-border);
  margin-top: 18px; padding-top: 18px;
}

/* Rodapé de ações SEM o traço divisório: para um botão avulso no fim de um
   painel que já tem outro rodapé logo abaixo — dois traços empilhados leem
   como erro de layout. */
.acoes-form--sem-linha { border-top: none; padding-top: 0; margin-top: 12px; }

/* Texto de ajuda que confirma algo já configurado (token salvo, senha
   cadastrada) — verde, mesma tinta do badge de sucesso. */
.help--ok { color: var(--ok-ink); }
