/* Inter — vendorizado LOCAL (sem CDN). Origem: @fontsource/inter@5.1.0, subset latin,
   licença OFL-1.1. Servido first-party -> a CSP `default-src 'self'` já cobre font-src,
   sem abrir fonts.googleapis.com/gstatic. Sem local(): usa sempre o arquivo auditado
   (sha256 em assets/vendor/inter/NOTICE), não a fonte instalada na máquina. */
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 300; font-display: swap;
  src: url('../vendor/inter/inter-latin-300-normal.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('../vendor/inter/inter-latin-400-normal.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('../vendor/inter/inter-latin-500-normal.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('../vendor/inter/inter-latin-600-normal.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('../vendor/inter/inter-latin-700-normal.woff2') format('woff2'); }

/* Portal Interno NN — tema (DNA visual: verde-petróleo profundo + terracota).
   Identidade profissional e quente para produto financeiro/contábil executivo.
   Sem CDN, sem build: tokens em CSS variables + componentes do dashboard.
   Denso, executivo, legivel, mobile e TV-friendly.
   Fonte canônica da paleta: blocos :root abaixo (ver Design System NN/Hub). */

:root {
  /* === Marca === */
  --verde:        #002a2b;  /* âncora: header, texto principal, theme-color */
  --verde-medio:  #2e7474;  /* destaque / links / ícones (teal) */
  --terra:        #b2512b;  /* acento secundário (ações, item ativo) */
  --terra-claro:  #d86d42;  /* variação do acento / âmbar (gráficos) */
  --terra-icone:  var(--terra);     /* identidade NN, sem clarear a marca */
  --terra-icone-bg: var(--terra-bg);
  --terra-texto:  var(--terra);     /* texto pequeno, separado do fundo sólido */
  --terra-texto-hover: var(--terra-claro);
  --terra-acao-hover: var(--terra-claro);
  --terra-foco:   var(--terra);
  --areia:        #f3daba;  /* acento quente suave */

  /* === Neutros === */
  --branco:       #ffffff;
  --superficie-2: #f6f4f0;
  --bg:           #f0efec;
  --borda:        #e8e5e5;
  --texto:        #002a2b;
  --texto-2:      #5b595b;
  /* 4,51:1 sobre o fundo da página e 5,19:1 sobre o painel — passa no WCAG AA
     para texto normal. O valor anterior (#8a8789) dava 3,09:1 e 3,55:1, ou
     seja, só era legível a partir de 18,5px, e este token é usado justamente em
     texto pequeno (legenda, meta, "há 3 dias").

     A hierarquia entre título, subtítulo e texto auxiliar NÃO se sustenta só
     nesta escada de cinza — ela vem sobretudo de tamanho e peso. Escurecer aqui
     aproxima este token do --texto-2, e é o preço certo: contraste insuficiente
     é um defeito, hierarquia sutil demais é um ajuste. */
  --texto-fraco:  #6f6c6e;

  /* === Semânticos (financeiro) === */
  --positivo:     #15803d;
  --negativo:     #b91c1c;
  --positivo-bg:  rgba(21, 128, 61, .10);
  --negativo-bg:  rgba(185, 28, 28, .10);
  --verde-bg:     rgba(46, 116, 116, .12);
  --terra-bg:     rgba(178, 81, 43, .12);

  /* === Tipografia === */
  --font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --mono: 'Courier New', monospace;

  /* === Layout === */
  --raio-card: 6px;
  --raio:      4px;
  --sombra:    0 1px 4px rgba(0, 0, 0, .04);
  --gap:       14px;

  /* === Aliases legados (compat com os componentes existentes) === */
  --bg-app:         var(--bg);            /* fundo da página */
  --bg-panel:       var(--branco);        /* cards / painéis */
  --bg-panel-soft:  var(--superficie-2);
  --bg-pill:        var(--superficie-2);  /* inputs / seletores */
  --bg-pill-active: var(--terra);         /* item ativo / ação */
  --accent:         var(--terra);
  --brand:          var(--terra);
  --danger:         var(--negativo);
  --text:           var(--texto);
  --text-muted:     var(--texto-2);
  --border:         var(--borda);
  --grid:           rgba(0, 0, 0, .08);
  --radius:         var(--raio);

  font-synthesis: none;
}

* { box-sizing: border-box; }
/* `hidden` tem que vencer qualquer `display` declarado em classe (um
   `.grid { display: grid }` num elemento [hidden] o deixaria visível). */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden; /* dashboard de tela cheia: sem barra de rolagem */
  background: var(--bg-app);
  color: var(--text);
  font-family: var(--font);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}
body { display: flex; flex-direction: column; }

button { font-family: inherit; cursor: pointer; }

/* ---------- Topbar (marca + abas de departamento) ---------- */
.topbar {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 10px 18px;
  background: var(--verde);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
  flex: 0 0 auto;
  z-index: 20;
}
.brand { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.brand-logo { height: 40px; width: auto; display: block; }
.brand .brand-txt { line-height: 1.05; }
.brand .brand-txt strong { display: block; font-size: 14px; letter-spacing: .2px; color: #fff; }
.brand .brand-txt span { display: block; font-size: 12px; color: rgba(255, 255, 255, .5); }

.dept-tabs {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  flex: 1 1 auto;
  scrollbar-width: thin;
}
.dept-tabs button {
  white-space: nowrap;
  background: transparent;
  color: rgba(255, 255, 255, .55);
  border: 1px solid transparent;
  padding: 7px 14px;
  border-radius: var(--radius);
  font-size: 13px;
  transition: background .15s, color .15s;
}
.dept-tabs button:hover { color: #fff; background: rgba(255, 255, 255, .06); }
.dept-tabs button.active {
  color: #fff;
  background: var(--bg-pill-active);
  font-weight: 600;
}

/* ---------- Subbar (voltar + periodo + abas de ferramenta) ---------- */
.subbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 18px;
  flex-wrap: wrap;
  flex: 0 0 auto;
}
.page-title {
  margin: 0;
  font-size: 26px;
  font-weight: 300;
  letter-spacing: .3px;
}
.period { display: flex; align-items: center; gap: 10px; }
.period-label {
  color: var(--text-muted); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
}
/* Seletor de período (assets/js/periodo.js): setas + botão com o período em
   vigor. O painel vai para o <body> — dentro da .subbar, que rola na
   horizontal, um painel posicionado seria cortado. */
.nnper-ctl {
  display: flex; align-items: stretch;
  background: var(--bg-pill);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.nnper-step {
  background: transparent; border: 0; color: var(--text-muted);
  padding: 0 9px; font-size: 11px;
}
.nnper-step:hover { color: var(--text); background: var(--grid); }
.nnper-trigger {
  display: flex; align-items: center; gap: 8px;
  background: transparent; color: var(--text);
  border: 0; border-left: 1px solid var(--border); border-right: 1px solid var(--border);
  padding: 7px 12px; font-size: 13px; line-height: 1.2;
}
.nnper-trigger:hover { background: var(--grid); }
.nnper-trigger[aria-expanded="true"] { box-shadow: inset 0 -2px 0 var(--terra); }
.nnper-trigger > .fa-calendar { color: var(--terra-icone); font-size: 13px; }
.nnper-preset { color: var(--texto-fraco); font-weight: 500; white-space: nowrap; }
.nnper-preset::after { content: "·"; margin-left: 8px; }
.nnper-texto { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.nnper-chev { font-size: 10px; color: var(--texto-fraco); margin-left: 2px; }

.nnper-scrim { position: fixed; inset: 0; z-index: 94; background: rgba(0, 0, 0, .45); }
.nnper-pop {
  position: fixed; z-index: 95;
  width: 724px; max-width: calc(100vw - 24px);
  display: grid; grid-template-columns: 168px minmax(0, 1fr);
  background: var(--bg-panel); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--raio-card);
  box-shadow: 0 14px 36px rgba(0, 42, 43, .16), 0 2px 6px rgba(0, 42, 43, .06);
  font-size: 13px;
}
.nnper-pop button { font-family: inherit; }
.nnper-pop :focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 1px; }

.nnper-presets {
  display: flex; flex-direction: column; gap: 1px; padding: 10px 8px;
  background: var(--bg-pill); border-right: 1px solid var(--border);
  border-radius: var(--raio-card) 0 0 var(--raio-card);
}
.nnper-presets hr { width: 100%; border: 0; border-top: 1px solid var(--border); margin: 6px 0; }
.nnper-preset-btn {
  text-align: left; background: transparent; border: 0; border-radius: var(--raio);
  color: var(--text-muted); font-size: 13px; padding: 7px 10px; white-space: nowrap;
}
.nnper-preset-btn:hover { background: var(--grid); color: var(--text); }
.nnper-preset-btn.on { background: var(--terra-bg); color: var(--terra-texto); font-weight: 600; }
html.dark .nnper-preset-btn.on { color: var(--terra-texto); }

.nnper-main { display: grid; grid-template-rows: auto 1fr auto; min-width: 0; }
.nnper-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px 0; }
.nnper-seg { display: inline-flex; background: var(--bg-pill); border: 1px solid var(--border); border-radius: var(--raio); padding: 2px; }
.nnper-seg button {
  background: transparent; border: 0; border-radius: 3px;
  color: var(--text-muted); font-size: 12.5px; font-weight: 500; padding: 5px 14px;
}
.nnper-seg button[aria-pressed="true"] {
  background: var(--bg-panel); color: var(--text); font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08);
}
.nnper-hint { color: var(--texto-fraco); font-size: 12px; text-align: right; }

.nnper-vista { padding: 12px 16px 14px; min-height: 304px; }
.nnper-nav-lin { display: flex; align-items: center; justify-content: space-between; height: 28px; margin-bottom: 8px; }
.nnper-nav {
  width: 28px; height: 28px; display: grid; place-items: center;
  background: transparent; border: 0; border-radius: var(--raio);
  color: var(--text-muted); font-size: 11px;
}
.nnper-nav:hover { background: var(--grid); color: var(--text); }
.nnper-oculto, .nnper-so-estreito { visibility: hidden; }
.nnper-titulo { font-weight: 600; font-size: 13px; font-variant-numeric: tabular-nums; }

/* Faixa do intervalo: fundo contínuo entre as pontas, pontas cheias em terracota. */
.nnper-mes, .nnper-dia { background: transparent; border: 0; padding: 0; color: var(--text); }
.nnper-mes span, .nnper-dia span { display: grid; place-items: center; position: relative; }
.nnper-mes:hover span, .nnper-dia:hover span { background: var(--grid); }
.nnper-mes.meio, .nnper-dia.meio { background: var(--terra-bg); }
.nnper-mes.ini, .nnper-dia.ini { background: linear-gradient(90deg, transparent 50%, var(--terra-bg) 50%); }
.nnper-mes.fim, .nnper-dia.fim { background: linear-gradient(90deg, var(--terra-bg) 50%, transparent 50%); }
.nnper-mes.ini.fim, .nnper-dia.ini.fim { background: transparent; }
.nnper-mes.ini span, .nnper-mes.fim span,
.nnper-dia.ini span, .nnper-dia.fim span { background: var(--terra); color: #fff; font-weight: 600; }

.nnper-meses { display: grid; grid-template-columns: repeat(4, 1fr); row-gap: 8px; }
.nnper-mes { height: 52px; font-size: 13.5px; font-weight: 500; }
.nnper-mes span { height: 100%; margin: 0 4px; border-radius: var(--raio); }
.nnper-mes.atual span { box-shadow: inset 0 0 0 1px var(--border); }
.nnper-mes.c0.meio, .nnper-mes.c0.fim { border-radius: var(--raio) 0 0 var(--raio); }
.nnper-mes.c3.meio, .nnper-mes.c3.ini { border-radius: 0 var(--raio) var(--raio) 0; }

.nnper-cals { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.nnper-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); row-gap: 2px; }
.nnper-sem { font-size: 11px; font-weight: 600; color: var(--texto-fraco); text-align: center; padding: 4px 0 6px; }
.nnper-dia { height: 32px; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.nnper-dia span { width: 32px; height: 32px; margin: 0 auto; border-radius: 50%; }
.nnper-dia.fds { color: var(--text-muted); }
.nnper-dia.hoje span::after {
  content: ""; position: absolute; bottom: 4px; left: 50%;
  width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--terra);
}
.nnper-dia.ini.hoje span::after, .nnper-dia.fim.hoje span::after { background: #fff; }
.nnper-dia.c0.meio, .nnper-dia.c0.fim { border-radius: 16px 0 0 16px; }
.nnper-dia.c6.meio, .nnper-dia.c6.ini { border-radius: 0 16px 16px 0; }

.nnper-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 12px 16px; border-top: 1px solid var(--border); }
.nnper-datas { display: flex; align-items: center; gap: 8px; }
.nnper-fld {
  width: 112px; padding: 7px 9px; font-family: inherit; font-size: 13px; font-variant-numeric: tabular-nums;
  color: var(--text); background: var(--bg-pill);
  border: 1px solid var(--border); border-radius: var(--raio);
}
.nnper-fld:focus { outline: none; border-color: var(--terra-foco); }
.nnper-fld[aria-invalid="true"] { border-color: var(--negativo); }
.nnper-ate-txt { color: var(--texto-fraco); font-size: 12px; }
.nnper-erro { color: var(--negativo); font-size: 12px; }
.nnper-erro:empty { display: none; }
.nnper-acoes { margin-left: auto; display: flex; gap: 8px; }
.nnper-acoes button { padding: 7px 14px; font-size: 13px; }
.nnper-aplicar:disabled { opacity: .45; cursor: not-allowed; }

/* Celular: o painel sobe de baixo, atalhos em fileira rolável, um calendário só. */
@media (max-width: 780px) {
  .nnper-preset { display: none; }
  .nnper-pop {
    top: auto; left: 0; right: 0; bottom: 0; width: auto; max-width: none;
    grid-template-columns: minmax(0, 1fr); max-height: 88vh; overflow-y: auto;
    border-radius: 12px 12px 0 0;
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .nnper-presets {
    flex-direction: row; overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--border);
    border-radius: 12px 12px 0 0; padding: 10px 12px;
  }
  .nnper-presets hr { display: none; }
  .nnper-preset-btn { border: 1px solid var(--border); background: var(--bg-panel); }
  .nnper-cals { grid-template-columns: minmax(0, 1fr); }
  .nnper-cal-2 { display: none; }
  .nnper-so-estreito { visibility: visible; }
  .nnper-hint { display: none; }
  .nnper-acoes { margin-left: 0; width: 100%; }
  .nnper-acoes button { flex: 1; }
}
@media (prefers-reduced-motion: no-preference) {
  .nnper-pop:not([hidden]) { animation: nnper-surge .12s ease-out; }
  @keyframes nnper-surge { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
}

/* Voltar ao catálogo de módulos do departamento. Primeiro elemento da subbar:
   é o topo-esquerda da área de conteúdo, onde o olho começa a leitura. */
.subbar-voltar { display: flex; align-items: center; flex: 0 0 auto; }
.subbar-voltar:empty { display: none; }

/* ---------- View (preenche a tela; rola no eixo y só quando a altura mínima
   dos painéis não couber — melhor rolar do que esmagar os gráficos) ---------- */
.view {
  padding: 8px 18px 14px;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-x: hidden;
  overflow-y: auto;
}

/* KPIs */
.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--gap);
  margin-bottom: var(--gap);
  flex: 0 0 auto;
}
.kpi {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--raio-card);
  box-shadow: var(--sombra);
  padding: 12px 16px;
  text-align: center;
}
.kpi .kpi-label { color: var(--text-muted); font-size: 12px; margin-bottom: 6px; min-height: 28px; display: flex; align-items: center; justify-content: center; }
.kpi .kpi-value { font-size: clamp(22px, 3vh, 32px); font-weight: 700; line-height: 1; }
.kpi .kpi-nota { color: var(--text-muted); font-size: 10px; margin-top: 6px; text-transform: uppercase; letter-spacing: .04em; }
.kpi .kpi-value.danger { color: var(--danger); }
.kpi .kpi-value.accent { color: var(--terra); }

/* Resultado financeiro agrupado antes dos indicadores de posição. */
.kpis.kpis-com-resumo { display: flex; flex-direction: column; }
.kpis-indicadores { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--gap); }
.kpis-resumo {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap);
}
.app-shell .kpis-resumo .kpi { min-width: 0; }
.app-shell .kpis-resumo .kpi .kpi-label { min-height: 0; }

/* Grade de paineis (12 colunas) — preenche a altura restante SEM rolar: as linhas
   dividem igualmente a altura disponível (minmax(0,1fr)), então toda sub-aba cabe
   na tela qualquer que seja o nº de linhas de painéis (os gráficos encolhem junto,
   pois são responsivos). Em tela estreita (<=900px) o media query volta a empilhar
   e permitir rolagem. */
.grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: minmax(0, 1fr);
  gap: var(--gap);
  flex: 1 1 auto;
  min-height: 0;
}
.panel {
  background: var(--bg-panel);
  border: 1px solid var(--border);
  border-radius: var(--raio-card);
  box-shadow: var(--sombra);
  padding: 12px 16px;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.panel.span-3 { grid-column: span 3; }
.panel.span-4 { grid-column: span 4; }
.panel.span-6 { grid-column: span 6; }
.panel.span-8 { grid-column: span 8; }
.panel.span-12 { grid-column: span 12; }

.panel-head { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 8px; flex: 0 0 auto; }
/* O ícone do título é o botão de AMPLIAR. Fica com cara de ícone até o hover,
   para não competir com o título — o afeto visual só aparece quando o cursor
   chega nele. `cursor: zoom-in` já anuncia a ação antes do clique. */
.panel-head .panel-zoom {
  background: transparent; border: none; padding: 0; margin: 0;
  font: inherit; color: inherit; line-height: 0; cursor: zoom-in;
  border-radius: var(--raio); transition: transform .12s ease;
}
.panel-head .panel-zoom:hover { transform: scale(1.12); }
.panel-head .panel-zoom:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 3px; }

/* ---------- Painel em tela cheia ---------- */
.panel-zoom-overlay {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(0, 42, 43, .55);
  display: flex; align-items: center; justify-content: center;
  padding: 3vh 3vw;
}
.panel-zoom-box {
  position: relative;
  width: min(1280px, 94vw); height: min(820px, 90vh);
  display: flex; flex-direction: column; min-height: 0;
}
/* O card ocupa a caixa inteira: é isso que dá área ao gráfico. */
.panel-zoom-box .panel {
  flex: 1 1 auto; min-height: 0; margin: 0;
  padding: 18px 22px; border-radius: 10px; box-shadow: 0 12px 40px rgba(0, 0, 0, .28);
}
.panel-zoom-box .panel-head h3 { font-size: 17px; }
.panel-zoom-box .panel-head { margin-bottom: 14px; }
/* Em tela cheia sobra espaço: a tabela e as listas podem respirar. */
.panel-zoom-box .pf-tabela { font-size: 14px; }
.panel-zoom-box .pf-tabela td { padding: 10px 0; }
.panel-zoom-box .pf-prog, .panel-zoom-box .pf-linha { font-size: 14px; padding: 10px 0; }
.panel-zoom-box .pf-mini-valor { font-size: 20px; }
/* Tabela ou lista em tela cheia: o corpo vira coluna para a .pf-scroll receber
   a altura que sobra e rolar DENTRO da caixa. Sem isto a lista crescia até o
   fim, saía da caixa e era cortada, sem barra (medido: 5.885px de lista numa
   caixa de 757px). Só na tela cheia; na grade nada muda. */
.panel-zoom-box .panel-body:has(> .pf-scroll) { display: flex; flex-direction: column; }
/* Cabeçalho das colunas preso no topo enquanto a lista rola. A linha de baixo
   vem da sombra: a borda de célula não acompanha o `sticky`. Só o cabeçalho da
   tabela (`>`): a subtabela de uma linha aberta não gruda no topo. */
.panel-zoom-box .pf-tabela > thead th,
.grid-stack-item-content .pf-tabela > thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-panel); border-bottom: 0; box-shadow: inset 0 -1px 0 var(--border);
}
.panel-zoom-box .pf-mini-nota { font-size: 12px; }
.panel-zoom-box .pf-mini-det { font-size: 12px; }
/* Total da lista preso embaixo também na tela cheia (a Cobrança lista dezenas
   de clientes, e o total de cada faixa é o que fecha com o card). */
.panel-zoom-box .pf-tabela > tfoot td {
  position: sticky; bottom: 0; z-index: 1;
  background: var(--bg-panel); border-top: 0; box-shadow: inset 0 1px 0 var(--border);
}
.panel-zoom-close {
  position: absolute; top: -34px; right: 0;
  background: transparent; border: none; cursor: pointer;
  color: #fff; font-size: 20px; line-height: 1; padding: 4px 6px;
  border-radius: var(--raio);
}
.panel-zoom-close:hover { background: rgba(255, 255, 255, .16); }
.panel-zoom-close:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
@media (max-width: 700px) {
  .panel-zoom-overlay { padding: 0; }
  .panel-zoom-box { width: 100vw; height: 100vh; }
  .panel-zoom-box .panel { border-radius: 0; }
  .panel-zoom-close { top: 8px; right: 8px; color: var(--text); }
  /* O X fica dentro da caixa no celular: o título não passa por baixo dele.
     `.panel >`: a regra do .app-shell (mesmo peso, declarada depois) venceria. */
  .panel-zoom-box .panel > .panel-head { padding-right: 42px; }
  /* Coluna secundária some (ex.: faixas da Cobrança): no celular fica quem,
     quanto e há quanto tempo; o resto abre na linha. */
  .pf-tabela .pf-sec { display: none; }
  .panel-zoom-box .pf-minis-resumo .pf-mini-valor { font-size: 16px; }
}
.panel-head .ic { color: var(--verde-medio); display: inline-flex; }
.panel-head .ic i { font-size: 16px; }
.panel-head h3 { margin: 0; font-size: 15px; font-weight: 600; text-align: center; }
.panel-body { position: relative; flex: 1 1 auto; min-height: 0; }
.panel-body canvas { max-height: 100%; }
/* Painel "aguardando integração": aviso centralizado, discreto, sem dado fictício */
.panel-body .pendente {
  height: 100%; min-height: 120px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px; text-align: center;
  color: var(--text-muted); border: 1px dashed var(--border); border-radius: var(--radius);
  padding: 16px;
}
.panel-body .pendente i { font-size: 22px; opacity: .6; }
.panel-body .pend-msg { font-size: 13px; font-weight: 600; }
.panel-body .pend-fonte { font-size: 11px; opacity: .8; }

/* Callout (numero consolidado + comparativos) */
.callout .big { font-size: 44px; font-weight: 700; color: var(--terra); margin: 6px 0 14px; }
.callout .sub { color: var(--text-muted); font-size: 14px; }
.callout .cmp { margin-top: 10px; }
.callout .cmp .cmp-label { font-weight: 600; }
.callout .cmp .cmp-pct { color: var(--positivo); font-weight: 700; }
.callout .cmp .cmp-detail { color: var(--positivo); font-size: 18px; }
.callout .cmp.neg .cmp-pct, .callout .cmp.neg .cmp-detail { color: var(--danger); }

/* Sidebar de filtros (visao Empresas) */
.filters .fld { margin-bottom: 14px; }
.filters label { display: block; color: var(--text-muted); font-size: 12px; margin-bottom: 5px; }
.filters select, .filters .fake-select {
  width: 100%; background: var(--bg-pill); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 9px 12px; font-size: 13px;
}
.filters .btn-clear {
  width: 100%; margin-top: 6px; background: var(--bg-pill); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 10px; font-size: 13px;
}

/* ===== Seletor de recorte do dashboard (empresa do BI Financeiro) ===== */
.dash-seletor {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: var(--gap); flex: 0 0 auto;
}
.dash-seletor label { color: var(--text-muted); font-size: 12px; font-weight: 600; }
.dash-seletor-sel {
  background: var(--bg-panel); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 7px 12px; font-size: 13px; font-family: var(--font); min-width: 220px;
}
.dash-seletor-sel:focus { border-color: var(--terra-foco); outline: none; }
.dash-seletor-carimbo { margin-left: auto; color: var(--text-muted); font-size: 11px; }

/* Seletor no canto DIREITO da subbar (o `justify-content: space-between` do
   .app-shell .subbar já o empurra para lá). `:empty` some com o host quando o
   dashboard ativo não tem seletor — sem isso um div vazio contaria como terceiro
   item do space-between e jogaria as abas dos outros departamentos para o meio. */
.subbar-seletor { flex: 0 0 auto; margin-left: auto; }
.subbar-seletor:empty { display: none; }
.subbar-seletor .dash-seletor { margin: 0 0 11px; gap: 8px; }
.subbar-seletor .dash-seletor-sel { min-width: 0; padding: 5px 10px; font-size: 12.5px; }
/* Sem `margin-left:auto` aqui: o carimbo fica logo após o seletor, e não empurrado
   para a outra ponta como acontece dentro da view. */
.subbar-seletor .dash-seletor-carimbo { margin-left: 0; }

/* Barra de progresso da sincronização com a Omie (assets/js/sync-progresso.js).
   Uma só para o Admin → Omie e para o botão "Atualizar" do BI Financeiro. */
.sync-prog { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sync-prog-bar {
  position: relative; flex: 0 0 160px; height: 6px; overflow: hidden;
  background: var(--bg-pill); border: 1px solid var(--border); border-radius: 999px;
}
.sync-prog-bar > i { display: block; width: 0; height: 100%; background: var(--terra); transition: width .4s ease; }
/* Sync iniciado fora do portal (CLI): não há etapa para medir — vai e vem, sem %. */
.sync-prog.indeterminado .sync-prog-bar > i { width: 35%; animation: sync-vai-e-vem 1.2s ease-in-out infinite; }
@keyframes sync-vai-e-vem { from { transform: translateX(-100%); } to { transform: translateX(290%); } }
.sync-prog-txt { color: var(--text-muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.sync-prog.ok .sync-prog-txt { color: var(--text); }
.sync-prog.erro .sync-prog-txt { color: var(--negativo); }
.sync-prog.erro .sync-prog-bar > i { background: var(--negativo); }
.omie-sync-prog { margin: -4px 0 14px; }

.dash-seletor-atualizar {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  background: var(--bg-panel); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 5px 10px; font-family: inherit; font-size: 12.5px;
}
.dash-seletor-atualizar:hover { border-color: var(--terra); color: var(--terra-texto); }
.dash-seletor-atualizar:disabled { opacity: .6; cursor: progress; border-color: var(--border); color: var(--text-muted); }
.dash-seletor-atualizar:disabled i { animation: sync-gira 1s linear infinite; }
@keyframes sync-gira { to { transform: rotate(360deg); } }
.dash-seletor-prog .sync-prog-bar { flex-basis: 110px; }
.dash-seletor-prog .sync-prog-txt { max-width: 360px; }
@media (prefers-reduced-motion: reduce) {
  .sync-prog.indeterminado .sync-prog-bar > i { animation: none; width: 100%; opacity: .45; }
  .dash-seletor-atualizar:disabled i { animation: none; }
}

/* Sem voltar, sem período e sem seletor a subbar viraria uma régua vazia sob a
   topbar. Quem decide é o app.js (`syncSubbar`). */
.subbar[hidden] { display: none; }

/* ===== Paineis do BI Financeiro (tabela / progresso / minicards / linhas) =====
   Dados em primeiro plano: bordas minimas, sem zebra, sem sombreado disputando
   atencao. A rolagem acontece DENTRO do card — a pagina nunca rola por causa de
   um painel, e o titulo fica fixo no cabecalho. */
.pf-sub { color: var(--text-muted); font-size: 11.5px; margin-bottom: 8px; flex: 0 0 auto; }
.pf-scroll { overflow-y: auto; overflow-x: auto; min-height: 0; flex: 1 1 auto; }
.pf-rodape {
  color: var(--text-muted); font-size: 10.5px; margin-top: 8px;
  padding-top: 6px; border-top: 1px solid var(--border); flex: 0 0 auto;
}

/* -- tabela de situacao -- */
.pf-tabela { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.pf-tabela th {
  text-align: left; font-weight: 600; font-size: 11px; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em;
  padding: 0 0 6px; border-bottom: 1px solid var(--border);
}
.pf-tabela td { padding: 7px 0; border-bottom: 1px solid var(--border); }
/* FOLGA HORIZONTAL ENTRE COLUNAS.
   Sem isso as celulas so se separam pelo espaco que sobra, e assim que uma
   tabela fica apertada os textos ENCOSTAM: "R$ 8.420,00Maria Souza",
   "VALORMONTOU", "29/08/202660 dias". Aconteceu tres vezes em telas
   diferentes — nao e caso particular de uma tabela, e o padrao.
   A ultima coluna nao recebe: ela encosta na borda do card, e ai a folga so
   comeria largura util. */
.pf-tabela th:not(:last-child),
.pf-tabela td:not(:last-child) { padding-right: 14px; }
.pf-tabela tbody tr:last-child td { border-bottom: none; }
.pf-tabela .dir { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Coluna de AÇÕES de qualquer tabela (.claude/rules/visual.md): a última,
   encostada à direita e do tamanho dos botões — quem lê o registro da esquerda
   para a direita acha o que fazer com ele sempre na mesma borda. Nasceu no Admin
   (`.tbl .acts`); o `table` na frente vence o `text-align: left` do cabeçalho de
   cada tabela (.pf-tabela th, .wf-tabela th, .cs-tabela th…). */
table th.acts, table td.acts { width: 1%; white-space: nowrap; text-align: right; }
.pf-tabela tfoot td {
  padding-top: 9px; border-top: 1px solid var(--border); border-bottom: none;
  font-weight: 700; font-size: 13px;
}
/* Linha de GRUPO (lista longa em blocos, ex.: faixas de atraso da Cobrança).
   Negrito e respiro acima bastam para separar: sem fundo nem borda nova
   disputando atenção com os dados. */
.pf-tabela tr.pf-grupo td { padding-top: 16px; font-weight: 600; }
/* Nota da linha (ex.: quanto do título parcial já entrou): em cinza, na
   largura toda, colada à linha de cima — a borda fica embaixo da nota. */
.pf-tabela tr.pf-com-nota td { border-bottom: none; padding-bottom: 2px; }
.pf-tabela tr.pf-nota td { padding-top: 0; font-size: 11px; color: var(--text-muted); }
.panel-zoom-box .pf-tabela tr.pf-nota td { font-size: 12px; }
/* Nota embaixo de um total do rodapé (a participação da faixa). */
.pf-tot-nota { display: block; margin-top: 2px; font-size: 11px; font-weight: 400; color: var(--text-muted); }
/* -- linha com detalhe (tela cheia da Cobrança: o cliente e os títulos dele) --
   A linha inteira abre e fecha; o chevron da 1ª célula gira e é o botão do
   teclado. O detalhe fica recuado, num fundo suave, para ler como "dentro". */
.pf-tabela tr.pf-com-detalhe { cursor: pointer; }
.pf-tabela tr.pf-com-detalhe:hover > td,
.pf-tabela tr.pf-com-detalhe.aberta > td { background: var(--bg-panel-soft); }
.pf-tabela tr.pf-com-detalhe.aberta > td { border-bottom-color: transparent; }
.pf-abrir {
  border: 0; background: none; padding: 2px; margin: 0 6px 0 -2px; width: 18px;
  color: var(--text-muted); cursor: pointer; line-height: 1; font-size: 10px;
  vertical-align: middle; border-radius: var(--raio);
}
.pf-abrir i { transition: transform .12s ease; }
.pf-abrir[aria-expanded="true"] i { transform: rotate(90deg); }
.pf-abrir:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 1px; }
.pf-tabela tr.pf-detalhe > td { background: var(--bg-panel-soft); padding: 2px 12px 12px 26px; }
/* Subtabela no tamanho do conteúdo: esticada na largura toda, quatro colunas
   ficavam ralas e longe umas das outras. */
.pf-subtabela { width: auto; min-width: min(100%, 460px); border-collapse: collapse; font-size: 12.5px; }
.pf-tabela .pf-subtabela th:not(:last-child),
.pf-tabela .pf-subtabela td:not(:last-child) { padding-right: 32px; }
.panel-zoom-box .pf-subtabela { font-size: 13px; }
.panel-zoom-box .pf-subtabela td { padding: 6px 0; }
.pf-subtabela th { padding-top: 8px; }
@media (prefers-reduced-motion: reduce) { .pf-abrir i { transition: none; } }
/* Celular: DEPOIS das regras-base acima (mesma especificidade — declarado
   antes, o @media perderia e nunca valeria). */
@media (max-width: 700px) {
  .pf-tabela .pf-subtabela th:not(:last-child),
  .pf-tabela .pf-subtabela td:not(:last-child) { padding-right: 14px; }
  .pf-tabela tr.pf-detalhe > td { padding-left: 12px; padding-right: 8px; }
}
/* -- acao por linha (anotar sem abrir a ficha) --
   Coluna estreita na ponta direita. O botao fica CINZA e sem moldura ate o
   ponteiro chegar na linha: a mensagem do painel e a lista, nao o botao. Realce
   permanente em N linhas nao realca nada. */
.pf-tabela th.pf-acao, .pf-tabela td.pf-acao { width: 30px; padding-left: 6px; text-align: right; }
/* A folga horizontal virou regra de TODA .pf-tabela (acima) — foi introduzida
   por causa desta coluna de acao e depois se mostrou necessaria em geral. */
.pf-btn-acao {
  border: 0; background: none; cursor: pointer; padding: 2px 4px; line-height: 1;
  color: var(--text-muted); opacity: 0; font-size: 12px; border-radius: 4px;
  transition: opacity .12s ease, color .12s ease;
}
.pf-tabela tbody tr:hover .pf-btn-acao { opacity: 1; }
/* Teclado nao tem hover: o foco tem de revelar o botao, senao a coluna e
   inalcancavel por Tab. */
.pf-btn-acao:focus-visible { opacity: 1; outline: 2px solid var(--terra-foco); outline-offset: 1px; }
.pf-btn-acao:hover { color: var(--terra-texto); }
/* Rotulo so para leitor de tela (o cabecalho da coluna da acao). */
.pf-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* Ponto de situacao: reforca a linha SEM depender so da cor (o rotulo textual
   continua sendo a informacao primaria — daltonismo). */
.pf-dot {
  display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 7px; vertical-align: middle; background: var(--text-muted);
}
.pf-dot.ok     { background: var(--verde-medio); }
.pf-dot.info   { background: var(--areia); }
.pf-dot.alerta { background: var(--terra-texto-hover); }
.pf-dot.risco  { background: var(--danger); }
/* Parcial: anel na cor do Recebido (ponto vazado) — parte já entrou, o resto não. */
.pf-dot.parcial { background: transparent; box-shadow: inset 0 0 0 2px var(--verde-medio); }

/* -- listas (progresso / linhas) -- */
.pf-lista { list-style: none; margin: 0; padding: 0; }
.pf-prog {
  display: grid; grid-template-columns: minmax(70px, 1.1fr) minmax(40px, 1fr) auto;
  align-items: center; gap: 8px; padding: 6px 0; font-size: 12.5px;
}
.pf-prog-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pf-prog-bar {
  height: 7px; border-radius: 999px; background: var(--bg-pill); overflow: hidden;
}
.pf-prog-bar i { display: block; height: 100%; background: var(--verde-medio); border-radius: 999px; }
.pf-prog-val { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pf-total {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
  font-size: 13px; flex: 0 0 auto;
}
.pf-total span { color: var(--text-muted); }
.pf-total strong { font-size: 14px; }

.pf-linha {
  display: flex; align-items: center; gap: 10px; padding: 8px 0; font-size: 12.5px;
  border-bottom: 1px solid var(--border);
}
.pf-linha:last-child { border-bottom: none; }
.pf-linha-ic { color: var(--verde-medio); display: inline-flex; width: 16px; justify-content: center; }
.pf-linha-label { flex: 1 1 auto; min-width: 0; }
.pf-linha-val { font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pf-linha-val.neg { color: var(--danger); }

/* -- mini cards (cobranca / inadimplencia) -- */
.pf-minis {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px; flex: 1 1 auto; min-height: 0; align-content: start; overflow-y: auto;
}
.pf-mini {
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 9px 10px; text-align: center; min-width: 0;
}
.pf-mini.destaque { border-color: var(--accent); background: var(--terra-bg); }
.pf-mini > span { display: block; }
.pf-mini-label {
  color: var(--text-muted); font-size: 10px; text-transform: uppercase;
  letter-spacing: .04em; margin-bottom: 4px;
}
.pf-mini-valor { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.pf-mini-nota { color: var(--text-muted); font-size: 10px; margin-top: 3px; }
.pf-mini-det { color: var(--text-muted); font-size: 10px; margin-top: 2px; overflow-wrap: anywhere; }
/* Resumo em cima de uma lista (tela cheia da Cobrança): quatro lado a lado, não
   cresce nem rola — quem rola é a lista embaixo. Alinhado à esquerda, como o
   resto do Hub (texto centrado se lê pior e desalinha do começo da tabela). */
.pf-minis.pf-minis-resumo {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  flex: 0 0 auto; overflow: visible; margin-bottom: 12px;
}
.pf-minis-resumo .pf-mini { text-align: left; padding: 12px 14px; }
/* Consulta de cobrança: resumo da carteira, filtros e fila de clientes.
   O detalhe guarda as faixas e os documentos sem alargar a tabela principal. */
.panel-zoom-cobranca .panel-zoom-close { top: 12px; right: 12px; color: var(--text-muted); z-index: 2; }
.panel-zoom-cobranca .panel-zoom-close:hover { background: var(--bg-panel-soft); }
.panel-zoom-cobranca .panel-zoom-close:focus-visible { outline-color: var(--terra-foco); }
.app-shell .panel-zoom-cobranca .panel-head { padding-right: 48px; }
.pf-cobranca .pf-base-carteira { color: var(--text-muted); font-size: 11px; margin: -4px 0 16px; }
.pf-cobranca button.pf-mini { font: inherit; color: var(--text); background: var(--bg-panel); border-color: var(--border); cursor: pointer; }
.pf-cobranca button.pf-mini:hover { border-color: var(--accent); }
.pf-cobranca button.pf-mini[aria-pressed="true"] { border-color: var(--accent); background: var(--terra-bg); }
.pf-cobranca button.pf-mini:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 2px; }
.pf-mini-acao { margin-top: 8px; color: var(--terra-texto); font-size: 11px; }
html.dark .pf-mini-acao { color: var(--terra-texto); }
.pf-mini-acao i { margin-left: 5px; font-size: 9px; }
.pf-consulta { display: flex; align-items: end; gap: 12px; flex: 0 0 auto; }
.pf-consulta label { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; color: var(--text-muted); font-size: 12px; }
.pf-consulta .pf-busca { flex: 1.6; }
.pf-consulta input, .pf-consulta select {
  width: 100%; min-width: 0; height: 36px; box-sizing: border-box; padding: 7px 10px;
  border: 1px solid var(--border); border-radius: var(--raio); background: var(--bg-panel); color: var(--text); font: inherit; font-size: 13px;
}
.pf-consulta input:focus, .pf-consulta select:focus { outline: 2px solid var(--terra-foco); outline-offset: 1px; }
.pf-limpar { height: 36px; padding: 7px 12px; border: 1px solid var(--border); border-radius: var(--raio); background: var(--bg-panel); color: var(--text); font: inherit; font-size: 13px; cursor: pointer; }
.pf-limpar:hover:not(:disabled) { background: var(--bg-panel-soft); }
.pf-limpar:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 2px; }
.pf-limpar:disabled { opacity: .45; cursor: default; }
.pf-consulta-info { display: flex; justify-content: space-between; gap: 16px; margin: 14px 0 10px; font-size: 11px; color: var(--text-muted); }
.pf-consulta-info .pf-contagem { color: var(--text); font-weight: 600; }
.pf-filtro-nota { margin: 0 0 10px; color: var(--text-muted); font-size: 11px; }
.pf-cobranca .pf-tabela > thead th:first-child { width: 55%; }
.pf-cobranca.pf-composicao .pf-tabela > thead th:first-child { width: 40%; }
.pf-composicao .pf-complemento { padding-left: 0; }
.pf-cobranca .pf-tabela > tbody > tr > td { vertical-align: middle; }
.pf-cobranca .pf-tabela > tbody > tr > .pf-destaque { font-weight: 600; }
.pf-cobranca .pf-tabela > tbody > tr > td:first-child { overflow-wrap: anywhere; }
.pf-complemento { display: block; padding-left: 24px; margin-top: 4px; color: var(--text-muted); font-size: 12px; }
.pf-faixas { display: flex; gap: 40px; margin: 12px 0 16px; }
.pf-faixas dt { color: var(--text-muted); font-size: 11px; }
.pf-faixas dd { margin: 4px 0 0; font-size: 13px; font-variant-numeric: tabular-nums; }
.pf-cobranca .pf-vazio td { padding: 28px 12px; text-align: center; color: var(--text-muted); }
/* Em computadores com pouca altura, os cards sobem ao rolar para deixar
   espaço para a fila e para os documentos do cliente expandido. */
@media (min-width: 701px) and (max-height: 800px) {
  .panel-zoom-box .pf-cobranca > .panel-body { overflow-y: auto; padding-top: 0; padding-bottom: 0; border-radius: 0 0 10px 10px; }
  .pf-cobranca .panel-body > .pf-sub { padding-top: 12px; }
  .panel-zoom-box .pf-cobranca > .panel-body > .pf-scroll { flex: 0 0 auto; overflow: visible; }
  .panel-zoom-box .pf-cobranca .pf-tabela > tfoot td { padding-bottom: 14px; }
}
@media (max-width: 700px) {
  .pf-minis.pf-minis-resumo { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* No celular os cards ocupam quase a tela: parados, sobrava uma fresta para
     a lista. Aqui a caixa inteira rola junto (os cards sobem ao descer). */
  .panel-zoom-box .panel-body:has(> .pf-minis-resumo) { overflow-y: auto; }
  .panel-zoom-box .panel-body:has(> .pf-minis-resumo) > .pf-scroll { flex: 0 0 auto; }
}

/* ===== Aba Serviços dos Extras (preço de tabela) =====
   Reusa `.ov-kpi` e `.pf-tabela`. O que e proprio daqui e o estado da LINHA:
   sem preco (o trabalho a fazer), salvo (a confirmacao) e erro. */
.sv-ajuda { max-width: 62ch; line-height: 1.5; margin: 0 0 14px; }
.sv-tabela td { vertical-align: middle; }
.sv-tabela select, .sv-preco {
  font: inherit; font-size: 12.5px; color: var(--text);
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--raio); padding: 4px 6px; max-width: 100%;
}
.sv-preco { width: 92px; text-align: right; font-variant-numeric: tabular-nums; }
.sv-ativo { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-muted); }
/* A fila de trabalho: so o que falta decidir fica marcado. O campo marcado e o
   que espera a decisao — o preco na tela de servicos, a area na de tipos. */
.sv-tabela tr.sv-falta .sv-preco,
.sv-tabela tr.sv-falta [data-tp="departamentoSlug"] {
  border-color: var(--accent); background: var(--terra-bg);
}
.sv-tabela tr.sv-salvo { background: var(--bg-pill); }
.sv-tabela tr.sv-erro .sv-preco { border-color: var(--danger); }
.sv-novo {
  font-size: 10px; background: var(--bg-pill); color: var(--text-muted);
  padding: 1px 7px; border-radius: 999px; margin-left: 7px;
}

/* ===== Aba Overview do admin (travessia do ERP legado) =====
   Mensagem: "o portal esta em dia com o sistema antigo?". Base cinza; a UNICA
   cor do painel e o alerta de atraso (laranja da marca), para que o olho caia
   nele em 3s quando a sincronizacao parar. Sem atraso, nada grita. */
.ov-topo {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px; margin-bottom: 18px;
}
.ov-kpi {
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--raio-card); padding: 14px 16px;
  display: flex; flex-direction: column; gap: 3px;
}
.ov-kpi-val { font-size: 22px; font-weight: 700; line-height: 1.15; }
.ov-kpi-rot { color: var(--text-muted); font-size: 12px; }
.ov-kpi-nota { color: var(--text-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
/* Atraso e a unica tensao que esta tela existe para mostrar. */
.ov-kpi.alerta { border-color: var(--accent); background: var(--terra-bg); }
.ov-kpi.alerta .ov-kpi-val { color: var(--terra); }

.ov-acoes { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 8px; }
.ov-nota { color: var(--text-muted); font-size: 12px; }
.ov-sub { margin: 24px 0 8px; font-size: 15px; font-weight: 600; }
.ov-tabela td, .ov-tabela th { padding: 8px 10px 8px 0; }
.ov-tabela .dir { text-align: right; font-variant-numeric: tabular-nums; }
/* Quem manda no dado: legado e o estado normal (cinza), portal e a excecao. */
.ov-dono { font-size: 10.5px; padding: 1px 8px; border-radius: 999px; background: var(--bg-pill); color: var(--text-muted); }
.ov-dono.portal { background: var(--terra-bg); color: var(--terra-texto); font-weight: 600; }
.ov-desde { color: var(--text-muted); font-size: 10.5px; margin-left: 6px; }
.ov-st { font-size: 10.5px; padding: 1px 8px; border-radius: 999px; background: var(--bg-pill); color: var(--text-muted); }
.ov-st.parcial, .ov-st.erro, .ov-st.alerta { background: var(--terra-bg); color: var(--terra-texto); font-weight: 600; }
.ov-detalhe { color: var(--text-muted); font-size: 11.5px; max-width: 460px; }
.ov-erro { color: var(--danger); font-size: 13px; margin: 0 0 12px; }

/* ===== Aba Omie do admin (empresas + credenciais) ===== */
.omie-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 14px 0; }
.omie-sync-msg { color: var(--text-muted); font-size: 12px; }
.omie-h3 { margin: 26px 0 10px; font-size: 15px; font-weight: 600; }
.omie-card {
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--raio-card); padding: 14px 16px; margin-bottom: 12px;
}
.omie-card-head {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.omie-slug {
  color: var(--text-muted); font-size: 11px; margin-left: 8px;
  font-family: var(--mono);
}
.omie-off {
  font-size: 10px; background: var(--bg-pill); color: var(--text-muted);
  padding: 1px 8px; border-radius: 999px; margin-left: 8px;
}
.omie-chave { color: var(--text-muted); font-size: 11.5px; }
.omie-sem-chave { color: var(--danger); font-weight: 600; }
.omie-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; align-items: start; }
.omie-grid .fld span { display: block; color: var(--text-muted); font-size: 12px; margin-bottom: 5px; }
.omie-grid .fld em, .omie-campo-lbl em { font-style: normal; opacity: .75; }

/* Listas de marcação (contas / categorias vindas do espelho da Omie) */
.omie-campo-top {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 6px;
}
.omie-campo-lbl { display: block; color: var(--text-muted); font-size: 12px; }
/* Atalho discreto: é conveniência, não a ação principal do card (Salvar é). */
.omie-todas {
  flex: 0 0 auto; background: none; border: none; padding: 0;
  color: var(--terra-texto); font: inherit; font-size: 11.5px; cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.omie-todas:hover { color: var(--terra-texto-hover); }
.omie-todas:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 2px; border-radius: 2px; }
.omie-chks {
  border: 1px solid var(--border); border-radius: var(--radius);
  max-height: 190px; overflow-y: auto; background: var(--bg-panel);
}
.omie-chk {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; font-size: 12.5px; cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.omie-chk:last-child { border-bottom: none; }
.omie-chk:hover { background: var(--bg-pill); }
.omie-chk input { margin: 0; flex: 0 0 auto; }
.omie-chk-nome { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.omie-chk-cod { flex: 0 0 auto; color: var(--text-muted); font-size: 11px; font-family: var(--mono); }
/* Valor já configurado que sumiu do espelho: continua marcável para não ser
   perdido no próximo save, mas sinalizado para o admin decidir. */
.omie-chk.orfao .omie-chk-cod { color: var(--danger); font-family: var(--font); }
/* Destino da conta: a linha não é clicável como um todo (é um seletor, não uma
   caixa de marcar), e o seletor fica à direita, alinhado entre as linhas. */
.omie-dest { cursor: default; }
.omie-dest select {
  flex: 0 0 auto; max-width: 150px; margin-left: 4px;
  font: inherit; font-size: 12px; padding: 3px 6px;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--bg-panel); color: inherit;
}
.omie-dest select:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 1px; }
.omie-vazio {
  margin: 0; padding: 12px; border: 1px dashed var(--border); border-radius: var(--radius);
  color: var(--text-muted); font-size: 12px; display: flex; align-items: center; gap: 8px;
}
.omie-card-foot {
  display: flex; align-items: center; gap: 10px; margin-top: 14px;
  padding-top: 12px; border-top: 1px solid var(--border);
}
.omie-msg { color: var(--text-muted); font-size: 12px; }

/* Checklist (tool, nao-dashboard) */
.checklist { max-width: 720px; }
.checklist .progress { color: var(--text-muted); margin-bottom: 14px; }
.checklist .bar { height: 8px; background: var(--bg-pill); border-radius: var(--radius); overflow: hidden; margin: 8px 0 18px; }
.checklist .bar > i { display: block; height: 100%; background: var(--accent); transition: width .25s; }
.checklist ul { list-style: none; margin: 0; padding: 0; }
.checklist li {
  display: flex; align-items: center; gap: 12px;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 12px 14px; margin-bottom: 8px;
}
.checklist li input { width: 18px; height: 18px; accent-color: var(--accent); cursor: pointer; }
.checklist li.done span { color: var(--text-muted); text-decoration: line-through; }

.placeholder { color: var(--text-muted); text-align: center; padding: 60px 20px; font-size: 15px; }

/* Geradores de .docx (Societário e Comercial) — mesma tela, config diferente.
   Layout: coluna estreita com tipo/ajuda + coluna larga com o texto colado.
   Card, input e botão são os componentes de sempre (.panel, .fld, .btn-*). */
.ger-cols { display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: var(--gap); align-items: start; }
.ger-lado { display: flex; flex-direction: column; gap: var(--gap); }
.app-shell .ger-cols .panel { overflow: visible; }
.ger-exemplo { width: 100%; justify-content: center; display: inline-flex; align-items: center; gap: 7px; margin-top: 4px; }
/* Instruções de formato como conteúdo de verdade, não como legenda miúda de campo. */
.ger-ajuda { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 8px; }
.ger-ajuda li { font-size: 12.5px; color: var(--text-muted); line-height: 1.5; }
.ger-ajuda code {
  font-family: var(--mono); font-size: 11.5px; background: var(--bg-pill);
  border: 1px solid var(--border); border-radius: 4px; padding: 1px 5px; color: var(--text);
}
.ger-ajuda strong { color: var(--text); font-weight: 600; }
.ger-texto { margin-bottom: 0; }
/* `.fld.ger-texto` (e não só `.ger-texto`): a regra base `.fld textarea` vem
   depois neste arquivo e venceria por ordem de origem com igual especificidade. */
.fld.ger-texto textarea {
  min-height: 420px; resize: vertical; line-height: 1.55;
  font-family: var(--mono); font-size: 13px;
}
/* Status à ESQUERDA do botão: o retorno aparece onde a ação acontece. */
.ger-acoes { justify-content: space-between; align-items: center; }
.soc-status { font-size: 13px; color: var(--texto-2); }
.soc-status.ok { color: var(--positivo); }
.soc-status.err { color: var(--negativo); }
.badge-sens { font-size: 10px; background: var(--brand); color: #fff; padding: 1px 8px; border-radius: 999px; margin-left: 6px; vertical-align: middle; }

/* Catálogo de módulos do departamento: cabeçalho + cards clicáveis.

   O bloco INTEIRO (cabeçalho + grade) é centrado na área de conteúdo, com a
   largura limitada a 4 colunas de card. Em tela larga isso deixa o catálogo no
   meio, em vez de os cards ficarem encostados à esquerda com um vazio à direita;
   em tela normal o teto não é alcançado e nada muda. O texto dos cards continua
   alinhado à esquerda — quem se centraliza é o bloco, não o conteúdo. */
.hub-scene {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; flex: 1 1 auto;
  min-height: 0; width: 100%;
}
/* Administração e Agenda mantêm o catálogo dentro de uma seção própria. */
.admin-wrap:has(> #tab-hub:not([hidden])), .admin-wrap > #tab-hub:not([hidden]) {
  display: flex; flex-direction: column;
}
.admin-wrap > #tab-hub:not([hidden]) { flex: 1 1 auto; min-height: 0; }
.hub-wrap {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
  width: 100%; margin-inline: auto;
  /* `--hub-cols` = quantas colunas os cards de fato ocupam (o render.js escreve,
     no máximo 4). A grade PREENCHE o bloco e é o BLOCO que se centraliza — assim
     o cabeçalho nunca descola da primeira coluna, que é o que aconteceria se a
     centralização fosse das colunas dentro de um bloco de largura cheia. */
  max-width: calc(var(--hub-cols, 4) * 300px + (var(--hub-cols, 4) - 1) * var(--gap));
}
.tools-hub { flex: 1 1 auto; min-height: 0; }
/* `auto-fit` (e não `auto-fill`): coluna vazia é colapsada. Com `auto-fill` a
   grade reservava lugar para card que não existe, e o conjunto ficava encostado
   à esquerda com um vão à direita. */
.hub-grid {
  display: grid; gap: var(--gap);
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
}
/* Em tela estreita o card ocupa a largura toda: 300px centrados deixariam sobra
   dos dois lados justo onde o espaço é escasso. */
@media (max-width: 700px) {
  .hub-grid { grid-template-columns: minmax(0, 1fr); }
}
.tool-card {
  text-align: left; background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: var(--sombra); padding: 16px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  transition: border-color .15s, box-shadow .15s, transform .05s;
}
.tool-card:hover { border-color: var(--terra); box-shadow: 0 2px 10px rgba(0, 0, 0, .06); }
.tool-card:active { transform: translateY(1px); }
/* Mesmo chip de ícone dos cards de KPI e dos cabeçalhos de painel. */
.tool-card .tc-ic {
  width: 34px; height: 34px; border-radius: 10px; flex: 0 0 auto;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 15px;
}
.tool-card .tc-name { font-size: 15px; font-weight: 600; color: var(--text); }
.tool-card .tc-desc { color: var(--text-muted); font-size: 12.5px; line-height: 1.45; flex: 1 1 auto; }
.tool-card .tc-go {
  margin-top: 4px; font-size: 12.5px; font-weight: 600; color: var(--terra-texto);
  display: inline-flex; align-items: center; gap: 6px;
}
.tool-card .tc-go i { font-size: 11px; transition: transform .15s; }
.tool-card:hover .tc-go i { transform: translateX(3px); }

/* Geometria NN persistente no shell, atrás dos catálogos e das ferramentas.
   O contexto isolado de .app-shell contém o z-index negativo: a arte fica acima
   do fundo da página e abaixo do conteúdo, sem alterar as camadas dos menus.
   Somente a arte é recortada; ela não recebe cliques nem participa da rolagem. */
.hub-art {
  position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none;
  background: radial-gradient(ellipse at 15% 18%, rgba(0, 42, 43, .03), transparent 45%),
    radial-gradient(ellipse at 52% 65%, rgba(178, 81, 43, .024), transparent 46%),
    radial-gradient(ellipse at 88% 92%, rgba(0, 42, 43, .04), transparent 50%);
}
.hub-frame {
  position: absolute; display: block; width: clamp(280px, 29vw, 440px);
  aspect-ratio: 1; border: 1px solid rgba(0, 42, 43, .12);
}
.hub-frame-a { right: 40%; bottom: -230px; }
.hub-frame-b {
  right: -64px; bottom: -115px; border-color: rgba(178, 81, 43, .18);
  background: linear-gradient(135deg, rgba(0, 42, 43, .016), transparent 65%);
}
.hub-frame-b::before {
  content: ''; position: absolute; inset: 30px -30px -30px 30px;
  border: 1px solid rgba(0, 42, 43, .075);
}
.hub-frame-top {
  width: clamp(140px, 14vw, 190px); top: 14%; right: 4%;
  border-color: rgba(0, 42, 43, .095);
}
.hub-frame-top::before {
  content: ''; position: absolute; inset: 24px -24px -24px 24px;
  border: 1px solid rgba(0, 42, 43, .065);
}
.hub-frame-top::after, .hub-frame-b::after {
  content: ''; position: absolute; left: -2px; width: 3px; height: 3px;
  background: var(--terra);
}
.hub-frame-top::after { bottom: -2px; opacity: .32; }
.hub-frame-b::after { top: -2px; opacity: .4; }
.hub-frame-left {
  width: clamp(160px, 17vw, 230px); left: 6%; bottom: 14%;
  border-color: rgba(0, 42, 43, .08);
}
.hub-frame-left::before {
  content: ''; position: absolute; inset: 24px -24px -24px 24px;
  border: 1px solid rgba(178, 81, 43, .095);
}
/* Composição distribuída: posições proporcionais mantêm a geometria presente
   no topo, no meio e na base, inclusive nos espaços entre os painéis. */
.hub-frame-upper {
  width: clamp(104px, 11vw, 160px); left: 22%; top: 8%;
  border-color: rgba(178, 81, 43, .13);
}
.hub-frame-midleft {
  width: clamp(160px, 16vw, 240px); left: 10%; top: 37%;
  border-color: rgba(0, 42, 43, .095);
}
.hub-frame-center {
  width: clamp(160px, 17vw, 250px); left: 44%; top: 31%;
  border-color: rgba(0, 42, 43, .09);
}
.hub-frame-center::before {
  content: ''; position: absolute; inset: 22px -22px -22px 22px;
  border: 1px solid rgba(178, 81, 43, .095);
}
.hub-frame-midright {
  width: clamp(110px, 12vw, 180px); right: 12%; top: 52%;
  border-color: rgba(178, 81, 43, .12);
}
.hub-frame-base {
  width: clamp(90px, 10vw, 150px); left: 36%; bottom: 12%;
  border-color: rgba(0, 42, 43, .08);
}
.hub-frame-upper::after, .hub-frame-center::after, .hub-frame-base::after {
  content: ''; position: absolute; right: -2px; top: -2px; width: 3px; height: 3px;
  background: var(--terra); opacity: .28;
}
.hub-trace { position: absolute; display: block; }
.hub-trace-top {
  top: 28%; left: 34%; width: 34px; height: 34px;
  border-top: 1px solid rgba(178, 81, 43, .20);
  border-left: 1px solid rgba(0, 42, 43, .105);
}
.hub-trace-side {
  top: 64%; right: 35%; width: 62px; height: 1px;
  background: rgba(0, 42, 43, .105);
}
.hub-trace-side::before {
  content: ''; position: absolute; right: 0; top: -11px; width: 1px; height: 23px;
  background: rgba(0, 42, 43, .105);
}
.hub-trace-side::after {
  content: ''; position: absolute; left: -2px; top: -1px; width: 3px; height: 3px;
  background: var(--terra); opacity: .3;
}
.hub-scene .hub-wrap > .admin-head::after {
  content: ''; align-self: center; width: 26px; height: 8px; margin-left: auto;
  border-top: 1px solid rgba(178, 81, 43, .28); border-right: 1px solid rgba(178, 81, 43, .28);
}
.hub-scene .tool-card { position: relative; }
.hub-scene .tool-card::after {
  content: ''; position: absolute; right: 14px; top: 14px; width: 10px; height: 10px;
  border-top: 1px solid transparent; border-right: 1px solid transparent; pointer-events: none;
}
.hub-scene .tool-card:is(:hover, :focus-visible) {
  box-shadow: inset 0 0 0 1px rgba(178, 81, 43, .06), 0 2px 10px rgba(0, 0, 0, .045);
}
.hub-scene .tool-card:is(:hover, :focus-visible)::after { border-color: rgba(178, 81, 43, .42); }
.hub-scene .tool-card:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 3px; }
.hub-scene .tool-card .tc-ic {
  box-shadow: inset 0 0 0 1px rgba(178, 81, 43, .075);
  background: linear-gradient(145deg, rgba(255, 255, 255, .2), transparent 70%), var(--terra-bg);
}
html.dark .hub-art {
  background: radial-gradient(ellipse at 15% 18%, rgba(46, 116, 116, .065), transparent 45%),
    radial-gradient(ellipse at 52% 65%, rgba(178, 81, 43, .035), transparent 46%),
    radial-gradient(ellipse at 88% 92%, rgba(46, 116, 116, .075), transparent 50%);
}
html.dark .hub-frame-a { border-color: rgba(255, 255, 255, .105); }
html.dark .hub-frame-b {
  border-color: rgba(178, 81, 43, .25);
  background: linear-gradient(135deg, rgba(46, 116, 116, .035), transparent 65%);
}
html.dark .hub-frame-b::before { border-color: rgba(255, 255, 255, .065); }
html.dark .hub-frame-top { border-color: rgba(255, 255, 255, .08); }
html.dark .hub-frame-top::before { border-color: rgba(255, 255, 255, .05); }
html.dark .hub-frame-left { border-color: rgba(255, 255, 255, .065); }
html.dark .hub-frame-left::before { border-color: rgba(178, 81, 43, .15); }
html.dark .hub-frame-upper, html.dark .hub-frame-midright { border-color: rgba(178, 81, 43, .18); }
html.dark .hub-frame-midleft, html.dark .hub-frame-center, html.dark .hub-frame-base { border-color: rgba(255, 255, 255, .075); }
html.dark .hub-frame-center::before { border-color: rgba(178, 81, 43, .12); }
html.dark .hub-trace-top { border-top-color: rgba(178, 81, 43, .28); border-left-color: rgba(255, 255, 255, .08); }
html.dark .hub-trace-side, html.dark .hub-trace-side::before { background: rgba(255, 255, 255, .08); }
html.dark .hub-scene .tool-card .tc-ic {
  background: linear-gradient(145deg, rgba(243, 218, 186, .025), transparent 70%), var(--terra-icone-bg);
  color: var(--terra-icone);
}
html.dark .hub-scene .tool-card .tc-go { color: var(--terra-texto); }
@media (max-width: 700px) {
  .hub-art, .hub-scene .hub-wrap > .admin-head::after, .hub-scene .tool-card::after { display: none; }
}
@media print {
  .hub-art, .hub-scene .hub-wrap > .admin-head::after, .hub-scene .tool-card::after { display: none; }
  .hub-scene .tool-card { box-shadow: none; }
}

@media (max-width: 900px) {
  .ger-cols { grid-template-columns: minmax(0, 1fr); }
  .fld.ger-texto textarea { min-height: 300px; }
}

/* Breadcrumb de retorno ao hub (no topo do dashboard-filho) */
.crumb { display: flex; align-items: center; gap: 10px; margin-bottom: var(--gap); flex: 0 0 auto; }
.crumb-back {
  background: var(--bg-pill); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 6px 12px; font-size: 13px;
  display: inline-flex; align-items: center; gap: 7px;
}
.crumb-back:hover { border-color: var(--verde-medio); color: var(--verde-medio); }
.crumb-now { color: var(--text-muted); font-size: 13px; }
.crumb-now::before { content: '/'; margin-right: 10px; color: var(--border); }

/* ============================================================
   LOGIN — tela de acesso em duas áreas. Identidade da marca à esquerda
   (verde-petróleo da sidebar + a geometria de molduras da própria logo) e,
   à direita, uma ÁREA DE CONTEÚDO do portal: mesmo fundo, mesmo cabeçalho
   com chip (.admin-head), mesmo card (.form-panel), mesmos campos (.fld) e
   mesmo botão (.btn-primary) das telas de dentro. Um card só: cabeçalho,
   campos, botão e rodapé de segurança moram dentro dele.
   Só apresentação: o fluxo login > 2FA > troca de senha é do auth.js.
   ============================================================ */
/* A regra responsiva do dashboard solta `html, body { height: auto }` em <=900px
   para o celular poder rolar — e ali o split parava de preencher a tela, sobrando
   uma faixa do fundo cinza embaixo. A altura volta pelo body, em toda largura
   (no desktop `html, body { height: 100% }` já dava o mesmo valor). */
.login-body { min-height: 100vh; min-height: 100dvh; }
.lg-split {
  flex: 1 1 auto; min-height: 0;
  display: grid; grid-template-columns: 58fr 42fr;
}

/* ---------- Lado esquerdo: identidade ---------- */
/* Verde-petróleo da marca (o mesmo --verde da sidebar) com um degradê leve
   para dar profundidade — os hex são variações do --verde, não cores novas. */
.lg-brand {
  position: relative; overflow: hidden; color: #fff;
  display: flex; flex-direction: column; justify-content: center;
  padding: 56px clamp(32px, 5vw, 88px);
  background:
    radial-gradient(110% 80% at 6% 4%, #013b3d 0%, transparent 58%),
    linear-gradient(158deg, #013335 0%, #002a2b 48%, #001c1d 100%);
}
/* Geometria de fundo: as molduras deslocadas que constroem a logo NN.
   Guias horizontais atravessando o painel foram testadas e descartadas: a
   qualquer opacidade elas leem como divisória, não como geometria de marca. */
.lg-art { position: absolute; inset: 0; pointer-events: none; }
.lg-art::before {
  content: ''; position: absolute; left: -22%; bottom: -34%;
  width: 76vmax; height: 76vmax; border-radius: 50%;
  background: radial-gradient(circle, rgba(46, 116, 116, .28), transparent 62%);
}
.lg-frame {
  position: absolute; width: clamp(260px, 26vw, 470px); aspect-ratio: 1;
  border: 1px solid rgba(255, 255, 255, .10);
}
.lg-frame-a { right: -16%; bottom: -35%; }
.lg-frame-b { right: -25%; bottom: -24%; border-color: rgba(178, 81, 43, .28); }
.lg-frame-b::before { /* terceira moldura, aninhada: o mesmo deslocamento da logo */
  content: ''; position: absolute; inset: 26px -26px -26px 26px;
  border: 1px solid rgba(255, 255, 255, .06);
}
.lg-frame-b::after { /* o quadradinho terracota do canto da logo */
  content: ''; position: absolute; left: -4px; bottom: 26%;
  width: 8px; height: 8px; background: var(--terra); opacity: .7;
}

/* Marca no canto superior esquerdo, no mesmo arranjo da .side-brand do portal:
   logo + duas linhas ao lado. Fora do fluxo para o bloco de texto ficar
   centrado no painel INTEIRO, e não no que sobra abaixo da marca. */
.lg-id {
  position: absolute; z-index: 1;
  top: clamp(28px, 4vh, 44px); left: clamp(32px, 5vw, 88px);
  display: flex; align-items: center; gap: 16px; margin: 0;
}
.lg-logo { display: block; width: auto; height: 60px; }
.lg-id-txt { line-height: 1.15; }
.lg-name { margin: 0; color: #fff; font-size: 25px; font-weight: 600; letter-spacing: -.01em; }
/* .55 de branco sobre o verde já passa de 4.5:1; .62 dá margem para a parte
   mais clara do degradê (medido: 5.8:1 sobre #013b3d). */
.lg-sub { margin: 4px 0 0; font-size: 13px; color: rgba(255, 255, 255, .62); }

/* Bloco de texto: centrado na VERTICAL do painel e justificado à esquerda, na
   mesma linha vertical da logo do canto (o `left` da .lg-id e o padding-left
   do painel usam o mesmo clamp de propósito). Centralizar na horizontal foi
   testado e descartado: soltava o bloco da marca. */
.lg-brand-inner { position: relative; z-index: 1; max-width: 560px; }
.lg-claim {
  margin: 0; max-width: 20ch; color: #fff;
  font-size: clamp(27px, 2.6vw, 40px); font-weight: 600;
  line-height: 1.14; letter-spacing: -.025em; text-wrap: balance;
}
.lg-claim-sub {
  margin: 20px 0 0; max-width: 46ch;
  font-size: 15.5px; line-height: 1.65; color: rgba(255, 255, 255, .62);
}

/* ---------- Lado direito: área de conteúdo do portal ---------- */
/* `margin:auto` no .lg-box (em vez de justify-content) para o topo não ser
   cortado quando o passo é alto. O padding de baixo maior que o de cima é o
   que ancora o card ACIMA do centro óptico. */
.lg-side {
  position: relative; z-index: 1; display: flex; flex-direction: column; overflow: auto;
  padding: clamp(28px, 5vh, 60px) clamp(24px, 3vw, 56px) calc(clamp(28px, 5vh, 60px) + 8vh);
  background: var(--bg-app);
  /* `color` explícito: quem NÃO declara cor (ex.: o h1 do cabeçalho) herda a
     cor já COMPUTADA do body — que no html.dark é clara — em vez de resolver
     o --text fixado aqui embaixo. Sem esta linha o título some no escuro. */
  color: var(--text);
  box-shadow: -22px 0 60px rgba(0, 0, 0, .20);

  /* A entrada do portal é SEMPRE clara, inclusive com html.dark: o contraste
     entre o verde da marca e a área clara é o que faz o layout de duas áreas
     existir — no escuro os dois lados viram a mesma mancha. Fixar os tokens
     (e não só o `background`) mantém campo, card, texto, foco e mensagem de
     erro coerentes entre si; o tema escuro volta a valer do index em diante.
     Os aliases (--bg-panel: var(--branco)) já resolvem no :root, então
     redefinir só o token base não teria efeito — os dois nomes vêm junto. */
  color-scheme: light;
  --branco: #ffffff;       --bg-panel: #ffffff;
  --superficie-2: #f6f4f0; --bg-pill: #f6f4f0;
  --bg: #f0efec;           --bg-app: #f0efec;
  --borda: #e8e5e5;        --border: #e8e5e5;
  --texto: #002a2b;        --text: #002a2b;
  --texto-2: #5b595b;      --text-muted: #5b595b;
  --texto-fraco: #8a8789;
  --verde-medio: #2e7474;
  --negativo: #b91c1c;     --danger: #b91c1c;
  --negativo-bg: rgba(185, 28, 28, .10);
  --verde-bg: rgba(46, 116, 116, .12);
  --terra-bg: rgba(178, 81, 43, .12);
  --terra-icone-bg: var(--terra-bg);
  --terra-texto: var(--terra);
  --terra-texto-hover: var(--terra-claro);
  --terra-acao-hover: var(--terra-claro);
  --terra-foco: var(--terra);
}
.lg-box { margin: auto; width: 100%; max-width: 528px; }
/* `.login-body` e não só `.lg-panel`: .form-panel vem depois no arquivo e, com
   a mesma especificidade, venceria o padding/margin desta tela. */
.login-body .lg-panel { padding: 26px 30px 22px; margin-bottom: 0; }

/* Cabeçalho DENTRO do card, separado por divisória — o mesmo par chip + título
   do portal, no lugar do .form-head (que não tem chip). */
.login-body .lg-cardhead {
  margin-bottom: 0; padding-bottom: 16px; border-bottom: 1px solid var(--border);
}
.login-body .admin-head h1 { margin: 0; font-size: 19px; font-weight: 600; line-height: 1.25; }

/* Altura reservada para o erro: aparecer/sumir não pode empurrar o formulário.
   Vazio, o bloco vira o respiro entre a divisória do cabeçalho e o 1º campo —
   por isso o cabeçalho não tem margem embaixo. Medido: 48px = a mensagem de
   uma linha + a margem dela, então o campo não se move. Erro de DUAS linhas
   ainda empurra ~18px; as mensagens do backend cabem em uma. */
.auth-msg-slot { min-height: 48px; display: flex; align-items: center; }
.login-body .auth-msg {
  width: 100%; margin: 0 0 12px; padding: 8px 12px; font-size: 12.5px; line-height: 1.4;
}

/* Campos: o .fld do portal, na escala de uma tela de foco (o resto do sistema
   tem densidade de dashboard; aqui há dois campos e a tela inteira para eles). */
.login-body .fld + .fld { margin-top: 16px; }
.login-body .fld label { font-size: 12.5px; margin-bottom: 6px; }
.login-body .fld input { padding: 15px 14px; font-size: 14.5px; }
/* --texto-fraco (#8a8789) dá só 3.2:1 sobre o campo; #6f6d6f mede 4.7:1. */
.login-body .fld input::placeholder { color: #6f6d6f; }
.login-body .fld input:focus { box-shadow: 0 0 0 3px var(--terra-bg); }
/* Autofill do Chrome pinta o campo de amarelo por cima do estilo. */
.login-body .fld input:-webkit-autofill,
.login-body .fld input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--texto);
  -webkit-box-shadow: 0 0 0 40px var(--bg-pill) inset;
  caret-color: var(--texto);
}
/* Código TOTP: mesmo campo, tratado como número — some a diferença entre 6
   dígitos e um endereço de e-mail digitado ali por engano. */
.login-body .fld input.lg-otp {
  font-size: 22px; letter-spacing: .34em; text-align: center;
  font-variant-numeric: tabular-nums; padding-left: 8px; padding-right: 8px;
}
.login-body .fld input.lg-otp::placeholder { letter-spacing: .34em; }

/* Link de texto (esqueci a senha / voltar): <button> porque nenhum dos dois
   navega — um abre a orientação ali mesmo, o outro troca de passo. */
.lg-link {
  display: inline-flex; align-items: center; gap: 7px;
  margin-top: 10px; padding: 2px 0;
  background: none; border: none; font-family: inherit; font-size: 13px;
  color: var(--terra-texto); font-weight: 500; text-decoration: underline;
  text-underline-offset: 3px;
}
.lg-link:hover { color: var(--terra-texto-hover); }
.lg-link:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 3px; border-radius: 2px; }
.lg-link-centro { display: flex; margin: 14px auto 0; }
.lg-link-msg { margin: 8px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }

/* Campo de senha com botao "mostrar senha" (olho) — .pw-wrap vem do auth.js */
.pw-wrap { position: relative; }
.pw-wrap input { padding-right: 42px; }
.pw-toggle {
  position: absolute; top: 0; right: 0; height: 100%; width: 40px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none; color: var(--text-muted);
  cursor: pointer; border-radius: var(--radius); font-size: 14px;
}
.pw-toggle:hover { color: var(--terra-icone); }
.pw-toggle:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 2px; }

/* .btn-primary do portal, em largura cheia — é a única ação da tela. */
.lg-panel .btn-primary {
  width: 100%; margin-top: 22px; padding: 13px 16px;
  justify-content: center; font-size: 15px;
  box-shadow: 0 6px 18px rgba(178, 81, 43, .20);
  transition: background .15s, box-shadow .15s, transform .06s;
}
.lg-panel .btn-primary:hover:not(:disabled) { background: var(--terra-acao-hover); box-shadow: 0 8px 22px rgba(178, 81, 43, .28); }
.lg-panel .btn-primary:active:not(:disabled) { transform: translateY(1px); }
.lg-panel .btn-primary:focus-visible { outline: 2px solid var(--verde-medio); outline-offset: 2px; }
/* Em carregamento o botão continua legível: só perde o clique, não o contraste
   (o `filter: grayscale` do estado desabilitado padrão deixaria o spinner sujo). */
.lg-panel .btn-primary[aria-busy="true"] { opacity: 1; filter: none; cursor: progress; box-shadow: none; }

/* Em produção este bloco fica vazio (só o mock escreve nele): sem :empty ele
   deixaria espaço morto entre o botão e o rodapé do card. */
.lg-panel .hint { margin-top: 16px; font-size: 12px; line-height: 1.5; text-align: center; color: var(--text-muted); }
.lg-panel .hint:empty { display: none; }

/* Rodapé de segurança: dentro do card, abaixo do botão. */
.lg-foot {
  margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 6px;
}
.lg-foot p {
  margin: 0; display: flex; align-items: center; justify-content: center; gap: 7px;
  font-size: 12px; color: var(--text-muted);
}
.lg-foot i { font-size: 10px; opacity: .75; }

/* .auth-* e .qr-box são compartilhados com os modais do portal: aqui só o
   respiro da tela de login, sem tocar na regra global. */
.login-body .auth-info { padding: 10px 12px; margin-bottom: 16px; }
/* "Entre com suas credenciais" só vale no 1o passo; nos seguintes (2FA, troca
   de senha) quem explica é o .auth-info do próprio passo. Só CSS: sem :has()
   o subtítulo apenas continua visível, como era antes. */
.lg-panel:has(.auth-step[data-step="login"][hidden]) .ah-sub { display: none; }

/* Tela baixa (notebook 768/900p): o bloco de texto desce e encostaria na
   moldura — empurra a geometria mais para fora. */
@media (min-width: 768px) and (max-height: 820px) {
  .lg-frame-a { bottom: -46%; }
  .lg-frame-b { bottom: -34%; }
}

/* 768–1023px: os 58% da marca deixariam o card com menos de 330px. Nesta faixa
   a proporção se inverte — a tarefa (entrar) vale mais que a vitrine. */
@media (min-width: 768px) and (max-width: 1023px) {
  .lg-split { grid-template-columns: 46fr 54fr; }
  .lg-brand { padding: 40px 28px; }
  .lg-id { top: 28px; left: 28px; gap: 13px; }
  .lg-logo { height: 50px; }
  .lg-name { font-size: 21px; }
  .lg-sub { font-size: 12px; }
  .lg-claim { font-size: 21px; max-width: 18ch; }
  .lg-claim-sub { font-size: 14px; margin-top: 16px; }
  .lg-side { padding-left: 24px; padding-right: 24px; }
  .login-body .lg-panel { padding: 22px 22px 20px; }
}

/* < 768px: o painel de identidade sai inteiro. Fica a marca no topo sobre o
   verde sólido e o card ocupando o resto da tela. */
@media (max-width: 767px) {
  .lg-split { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }

  .lg-brand {
    justify-content: flex-start; padding: 22px 20px 14px;
    background: var(--verde);            /* verde sólido: sem degradê nem geometria */
  }
  .lg-art, .lg-brand-inner { display: none; }
  /* A marca do canto é a única coisa que sobra: volta ao fluxo como faixa. */
  .lg-id { position: static; gap: 13px; }
  .lg-logo { height: 44px; }
  .lg-name { font-size: 19px; }
  .lg-sub { display: none; }

  /* O card ocupa o restante da tela, com folga lateral confortável. */
  .lg-side {
    padding: 12px 18px 20px; background: var(--verde);
    box-shadow: none; color: var(--text);
  }
  .lg-box { margin: 0; max-width: none; display: flex; flex-direction: column; flex: 1 1 auto; }
  .login-body .lg-panel {
    flex: 1 1 auto; padding: 22px 20px 20px;
    display: flex; flex-direction: column;   /* para o rodapé descer */
  }
  .lg-foot { margin-top: auto; }
}

/* ---------- Ações do header (usuário / admin / sair) ---------- */
.top-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; margin-left: auto; }
.top-actions .user { color: rgba(255, 255, 255, .6); font-size: 13px; white-space: nowrap; }
.ta-btn {
  background: rgba(255, 255, 255, .08); color: #fff; border: 1px solid rgba(255, 255, 255, .16);
  border-radius: var(--radius); padding: 7px 12px; font-size: 13px; text-decoration: none;
  display: inline-flex; align-items: center; gap: 6px;
}
.ta-btn:hover { background: var(--bg-pill-active); border-color: transparent; }

/* ---------- Fluxo de autenticação ---------- */
.auth-step label:first-child { margin-top: 0; }
.auth-msg { background: var(--negativo-bg); border: 1px solid var(--negativo); color: var(--negativo);
  border-radius: var(--radius); padding: 9px 12px; font-size: 13px; margin-bottom: 12px; }
.auth-info {
  color: var(--text); font-size: 13px; line-height: 1.45; margin: 0 0 12px;
  background: var(--verde-bg); border-radius: var(--radius); padding: 10px 12px;
}
.auth-info i { color: var(--terra-icone); margin-right: 4px; }
.auth-hint { color: var(--texto-fraco); font-size: 12px; margin: 8px 0 0; }
.auth-hint code {
  font-family: var(--mono); color: var(--texto); font-size: 12px; word-break: break-all;
  background: var(--superficie-2); border: 1px solid var(--borda); border-radius: 4px; padding: 1px 6px;
}
/* QR do cadastro 2FA (imgSrc da CSP já permite data: para o data-URL do QR) */
.qr-box { display: flex; justify-content: center; margin: 6px 0 12px; }
.qr-box img {
  width: 184px; height: 184px; background: #fff;
  border: 1px solid var(--borda); border-radius: var(--radius); padding: 8px;
}

/* ---------- Modal (reconfiguração de 2FA sob demanda) ---------- */
.nn-modal {
  position: fixed; inset: 0; z-index: 100; padding: 18px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 22, 22, .55);
}
.nn-modal-card {
  position: relative; width: 100%; max-width: 360px;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--raio-card); padding: 22px;
  box-shadow: 0 16px 48px rgba(0, 0, 0, .28);
}
.nn-modal-card h3 { margin: 0 0 14px; font-size: 17px; font-weight: 700; }
.nn-modal-card h3 i { color: var(--terra-icone); margin-right: 6px; }
.nn-modal-card label { display: block; color: var(--text-muted); font-size: 13px; margin: 12px 0 6px; }
.nn-modal-card input {
  width: 100%; background: var(--bg-pill); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 12px; font-size: 14px;
}
.nn-modal-card input:focus {
  outline: none; background: var(--branco);
  border-color: var(--verde-medio); box-shadow: 0 0 0 3px rgba(46, 116, 116, .16);
}
.nn-modal-card .btn {
  width: 100%; margin-top: 18px; background: var(--accent); color: #fff;
  border: none; border-radius: var(--radius); padding: 11px; font-size: 15px; font-weight: 600;
}
.nn-modal-card .btn:hover { background: var(--terra-acao-hover); }
.nn-modal-x {
  position: absolute; top: 12px; right: 12px; background: transparent; border: none;
  color: var(--texto-fraco); font-size: 16px; line-height: 1;
}
.nn-modal-x:hover { color: var(--text); }
.nn-modal-msg {
  background: var(--negativo-bg); border: 1px solid var(--negativo); color: var(--negativo);
  border-radius: var(--radius); padding: 9px 12px; font-size: 13px; margin-bottom: 12px;
}

/* ---------- Caixa de anotar (atalho de qualquer tela · fase 4.4) ----------
   Reusa .nn-modal/.nn-modal-card. Um pouco mais larga que o padrao de 360px
   porque o campo principal e um texto de 4 linhas, nao um codigo de 6 digitos. */
.an-card { max-width: 460px; }
/* O nome do cliente e a ancora da caixa: confirma SOBRE QUEM se esta
   escrevendo antes de escrever. Sem isso, um clique na linha errada de uma
   tabela de 30 vira anotacao no cliente errado. */
.an-cliente {
  margin: -6px 0 4px; font-size: 13.5px; font-weight: 600; color: var(--text);
}
.an-sel, .an-texto {
  width: 100%; background: var(--bg-pill); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 10px 12px; font-size: 14px; font-family: inherit;
}
.an-texto { resize: vertical; min-height: 92px; line-height: 1.45; }
.an-sel:focus, .an-texto:focus {
  outline: none; background: var(--branco);
  border-color: var(--verde-medio); box-shadow: 0 0 0 3px rgba(46, 116, 116, .16);
}
/* `.nn-modal-card .btn` e 100% de largura (modais de um botao so) — aqui sao
   dois, entao a largura volta a ser do conteudo. */
.an-acoes { display: flex; gap: 10px; margin-top: 18px; }
.an-acoes .btn { margin-top: 0; flex: 1 1 auto; width: auto; }
.an-acoes .btn.ghost { flex: 0 0 auto; }

/* ---------- Cartão de perfil (classes .pp-*) ----------
   Capa + foto sobreposta + identidade. Usado em DOIS lugares: no popover do
   rodapé da sidebar (.perfil-pop) e na ficha do funcionário no Admin. Por isso
   as .pp-* não são escopadas — só o "envelope" (posição, largura, sombra) muda
   entre os dois.

   .perfil-pop: `position: fixed` com left/bottom calculados por shell.js, para
   escapar do overflow da sidebar e continuar correto com a barra recolhida. */
.perfil-pop {
  position: fixed; z-index: 90; width: 268px;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--raio-card); overflow: hidden;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .26);
}
/* Capa: 3:1, a mesma proporção do recorte. Sem banner, fica o verde da marca —
   um bloco de cor é melhor que um buraco cinza. */
.pp-capa {
  position: relative; width: 100%; aspect-ratio: 3 / 1;
  background: var(--verde);
}
.pp-capa-img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Avatar sobreposto à borda da capa, como em qualquer perfil. A borda da cor do
   painel é o que separa a foto da imagem de fundo.
   `position: relative` é obrigatório: a capa é posicionada e, sem isto, pintaria
   POR CIMA do avatar (elementos posicionados vêm depois na ordem de pintura) —
   o círculo aparecia cortado ao meio. */
.pp-avatar { position: relative; z-index: 1; margin: -30px 0 0 16px; }
/* Escopado em `.app-shell` para desempatar com `.app-shell .side-avatar` (34px),
   que tem a MESMA especificidade e vem depois no arquivo — sem isto o avatar do
   cartão saía do tamanho da miniatura da sidebar. */
.app-shell .pp-avatar .side-avatar {
  width: 60px; height: 60px; font-size: 19px;
  border: 3px solid var(--bg-panel);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
.pp-avatar .side-avatar-img { object-fit: cover; }

.pp-corpo { display: flex; flex-direction: column; padding: 8px 16px 14px; }
.pp-nome { font-size: 15.5px; font-weight: 700; line-height: 1.3; color: var(--text); }
/* Nome de cadastro: aparece só quando há apelido — é ele que consta na agenda
   e nos registros, e omiti-lo confundiria quem procura a pessoa. */
.pp-real { margin-top: 1px; font-size: 11.5px; color: var(--texto-fraco); }
.pp-cargo { margin-top: 3px; font-size: 12.5px; color: var(--text-muted); }
.pp-login {
  margin-top: 2px; font-size: 11.5px; color: var(--texto-fraco);
  display: inline-flex; align-items: center; gap: 5px;
}
.pp-login i { font-size: 10px; }
/* Recado: bloco citado, separado dos dados de identidade por uma régua. */
.pp-recado {
  margin: 10px 0 0; padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 12.5px; font-style: italic; line-height: 1.45; color: var(--text-muted);
}
.pp-editar {
  margin-top: 12px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 8px 12px; font-family: inherit; font-size: 13px;
}
.pp-editar:hover { background: var(--bg-pill); color: var(--text); border-color: var(--texto-fraco); }

/* ---------- Admin › ficha do funcionário ----------
   A tabela vira índice (foto + nome + login numa célula só) e as ações moram na
   ficha. Sem isto, cada linha carregava cinco botões e a leitura da lista
   competia com a operação. */
.fn-pessoa { display: flex; align-items: center; gap: 10px; min-width: 0; cursor: pointer; }
.fn-pessoa:hover .fn-txt strong { text-decoration: underline; }
.fn-pessoa .fn-foto {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%;
  background: var(--terra); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; overflow: hidden;
}
.fn-pessoa img.fn-foto { object-fit: cover; }
.fn-pessoa .fn-txt { min-width: 0; line-height: 1.25; }
.fn-pessoa .fn-txt strong { display: block; font-weight: 600; }
.fn-pessoa .fn-txt span { display: block; font-size: 11.5px; color: var(--texto-fraco); }

/* A ficha reusa o cartão .pp-* dentro de um modal, então o card perde o padding
   padrão — a capa precisa encostar nas bordas. */
.fperfil-card { max-width: 420px; padding: 0; overflow: hidden; }
/* A ficha é bem mais larga que o popover da sidebar (420px contra 268px): a foto
   acompanha, senão fica perdida ao lado da capa. A margem negativa vale metade
   do lado, para manter a sobreposição na borda da capa. */
.app-shell .fperfil-card .pp-avatar { margin: -44px 0 0 18px; }
.app-shell .fperfil-card .pp-avatar .side-avatar { width: 88px; height: 88px; font-size: 27px; }
.fperfil-card .nn-modal-x { color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .5); z-index: 2; }
.fperfil-meta {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border);
}
.fperfil-linha { margin-top: 10px; font-size: 12.5px; color: var(--text-muted); }
.fperfil-linha b { color: var(--text); font-weight: 600; }
/* Ações em grade: pares lado a lado, e a de desativar isolada embaixo — ela é
   a única destrutiva e não deve ficar a um clique errado das outras. */
.fperfil-acoes {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border);
}
/* Escopadas em `.app-shell` porque `.app-shell .ta-btn` (borda transparente)
   tem a MESMA especificidade e vem depois no arquivo — sem isto os botões da
   ficha saem sem borda nenhuma. */
.app-shell .fperfil-acoes .ta-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border: 1px solid var(--border); padding: 9px 10px; font-size: 13px;
  color: var(--text-muted);
}
.app-shell .fperfil-acoes .ta-btn:hover {
  background: var(--bg-pill); color: var(--text); border-color: var(--texto-fraco);
}
.app-shell .fperfil-acoes .fp-larga { grid-column: 1 / -1; }
/* Desativar é a única destrutiva: cor de alerta e isolada na linha de baixo,
   para não ficar a um clique errado de "Sessões". */
.app-shell .fperfil-acoes .fp-perigo { color: var(--negativo); border-color: var(--negativo-bg); }
.app-shell .fperfil-acoes .fp-perigo:hover {
  background: var(--negativo-bg); color: var(--negativo); border-color: var(--negativo);
}

/* ---------- Modal "Meu perfil" ---------- */
.perfil-card { max-width: 420px; max-height: 90vh; overflow-y: auto; }
.perfil-foto { display: flex; align-items: center; gap: 16px; margin-bottom: 4px; }
/* O recorte é quadrado, mas o portal mostra o avatar em círculo — a máscara
   redonda aqui é o que faz o usuário enquadrar o que vai realmente aparecer. */
.perfil-preview {
  position: relative; flex: 0 0 auto;
  width: 104px; height: 104px; border-radius: 50%; overflow: hidden;
  background: var(--terra);
  display: flex; align-items: center; justify-content: center;
}
.perfil-preview canvas,
.perfil-preview img { display: block; width: 100%; height: 100%; object-fit: cover; }
.perfil-preview canvas { cursor: grab; touch-action: none; }
.perfil-preview canvas:active { cursor: grabbing; }
.perfil-iniciais { color: #fff; font-size: 30px; font-weight: 700; letter-spacing: .5px; }

.perfil-foto-acoes { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.perfil-foto-acoes .btn-ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 8px 12px; font-size: 13px;
}
.perfil-remover { color: var(--negativo); border-color: var(--negativo-bg); }
.perfil-zoom {
  display: flex; align-items: center; gap: 8px;
  margin: 0 !important; font-size: 12px; color: var(--text-muted);
}
.perfil-zoom input[type="range"] { width: auto; flex: 1 1 auto; padding: 0; accent-color: var(--terra); }
.perfil-dica { margin: 0; font-size: 11.5px; color: var(--texto-fraco); }
.perfil-hint { margin: 6px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--texto-fraco); }

/* ---------- Banner (faixa 3:1, capa do cartão de perfil) ----------
   O preview mostra a imagem limpa, na mesma proporção da capa do .perfil-pop —
   é exatamente como ela vai aparecer. */
.perfil-banner { display: flex; flex-direction: column; gap: 8px; }
.perfil-banner-preview {
  position: relative; width: 100%; aspect-ratio: 3 / 1;
  border-radius: var(--raio-card); overflow: hidden;
  background: var(--verde);
  display: flex; align-items: center; justify-content: center;
}
.perfil-banner-preview canvas,
.perfil-banner-preview img { display: block; width: 100%; height: 100%; object-fit: cover; }
.perfil-banner-preview canvas { cursor: grab; touch-action: none; }
.perfil-banner-preview canvas:active { cursor: grabbing; }
.perfil-banner-vazio { color: rgba(255, 255, 255, .5); font-size: 12.5px; }
/* Nota logo abaixo do rótulo, antes do preview (a .perfil-hint padrão fica
   depois do campo que explica). */
.perfil-hint-topo { margin: 0 0 8px; }
.perfil-banner-acoes { display: flex; flex-direction: column; gap: 8px; }
.perfil-banner-acoes .btn-ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 8px 12px; font-size: 13px;
}

/* Cancelar/Salvar lado a lado: `.nn-modal-card .btn` é 100% de largura por
   padrão (modais de um botão só), o que aqui empilharia os dois. */
.perfil-acoes { display: flex; gap: 10px; margin-top: 20px; }
.perfil-acoes .btn-ghost { flex: 0 0 auto; }
.perfil-acoes .btn { flex: 1 1 auto; width: auto; margin-top: 0; }

/* Segurança no perfil: o 2FA saiu do topo da tela e mora aqui. Uma linha com
   chip, texto e a ação — o mesmo desenho dos cabeçalhos de card do portal. */
.perfil-seg {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border: 1px solid var(--border); border-radius: var(--raio-card);
}
.perfil-seg-ic {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px;
}
.perfil-seg-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.perfil-seg-txt strong { font-size: 13px; color: var(--text); }
.perfil-seg-txt span { font-size: 11.5px; line-height: 1.4; color: var(--texto-fraco); }
.perfil-seg .btn-ghost { flex: 0 0 auto; padding: 7px 12px; font-size: 12.5px; }

/* ---------- Tela de administração ---------- */
.admin-wrap { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 18px; }
.admin-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; gap: 12px; }
.admin-head h2 { margin: 0; font-size: 20px; font-weight: 600; }
.admin-head h2 i { color: var(--terra-icone); margin-right: 6px; }
.btn-primary {
  background: var(--accent); color: #fff; border: none; border-radius: var(--radius);
  padding: 9px 16px; font-size: 14px; font-weight: 600; display: inline-flex; align-items: center; gap: 7px;
}
.btn-ghost {
  background: transparent; color: var(--text-muted); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 9px 16px; font-size: 14px;
}
/* Estado desabilitado precisa ser VISÍVEL: sem isto um botão bloqueado parece
   clicável e o usuário fica clicando sem entender por que nada acontece. */
.btn-primary:disabled, .btn-ghost:disabled, .ta-btn:disabled,
.vid-novo-acoes .btn:disabled {
  opacity: .45; cursor: not-allowed; filter: grayscale(.35);
}

.form-panel { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; margin-bottom: 16px; }
.form-head { display: flex; align-items: center; gap: 8px; margin: -2px 0 14px; padding-bottom: 10px; border-bottom: 1px solid var(--border); }
.form-head h3 { margin: 0; font-size: 16px; font-weight: 600; }
.form-head h3 i { color: var(--terra-icone); margin-right: 8px; }
.fld-hint { display: block; color: var(--text-muted); font-size: 11px; margin-top: 5px; }
.form-panel input:focus, .form-panel select:focus { border-color: var(--terra-foco); outline: none; }
.form-msg { background: var(--negativo-bg); border: 1px solid var(--negativo); color: var(--negativo); border-radius: var(--radius); padding: 8px 12px; font-size: 13px; margin-bottom: 12px; }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; margin-bottom: 8px; }
.form-cols { display: grid; grid-template-columns: 280px 1fr; gap: 20px; margin-top: 10px; }
.form-cols h4 { margin: 8px 0; font-size: 13px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.fld label { display: block; color: var(--text-muted); font-size: 12px; margin-bottom: 5px; }
/* select e textarea seguem o MESMO campo do input — antes só `input` estava
   coberto, e cada tela acabava reestilizando o seu por fora. */
.fld input, .fld select, .fld textarea, .form-panel input {
  width: 100%; background: var(--bg-pill); color: var(--text); font-family: inherit;
  border: 1px solid var(--border); border-radius: var(--radius); padding: 9px 12px; font-size: 14px;
}
.fld textarea { min-height: 84px; resize: vertical; line-height: 1.45; }
/* Espaço para a seta nativa: sem isso o texto de uma opção longa corre por baixo dela. */
.fld select { padding-right: 30px; }
.fld input:focus, .fld select:focus, .fld textarea:focus { border-color: var(--terra-foco); outline: none; }
.chk-list { display: flex; flex-direction: column; gap: 8px; }
/* Departamentos em grade de 2+ colunas: menos rolagem vertical no cadastro. */
.chk-list.deptos { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 8px; }
.chk { display: flex; align-items: center; gap: 8px; color: var(--text); font-size: 14px; }
.chk input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); }
/* Nome do departamento junto do checkbox (proximidade); seletor de papel à direita. */
.chk.dep { justify-content: flex-start; background: var(--bg-pill); border: 1px solid var(--border); border-radius: var(--radius); padding: 7px 10px; cursor: pointer; }
.chk.dep .dep-papel { margin-left: auto; background: var(--bg-app); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); padding: 4px 8px; }
.form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 16px; }

/* overflow-x: em janela estreita a tabela rola na horizontal em vez de
   espremer as células (que fazia status/ações quebrarem linha). */
.table-wrap { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); overflow-x: auto; overflow-y: hidden; }
.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.tbl th, .tbl td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.tbl th { color: var(--text-muted); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; background: var(--superficie-2); }
.tbl tr:last-child td { border-bottom: none; }
/* Ações SEMPRE numa linha só: célula encolhe pro conteúdo e alinha à direita. */
.tbl .acts { white-space: nowrap; width: 1%; text-align: right; }
.tbl td.acts .ta-btn { display: inline-flex; align-items: center; gap: 6px; vertical-align: middle; }
.tbl td.acts .ta-btn + .ta-btn { margin-left: 6px; }
/* Status numa linha só; pills nunca quebram internamente ("troca pendente"). */
.tbl td.status { white-space: nowrap; }
.tbl td.vazio { text-align: center; color: var(--text-muted); font-size: 13px; padding: 18px; }
.pill-ok, .pill-off, .pill-warn, .pill-info { display: inline-block; white-space: nowrap; }
/* .ta-btn nasceu na barra escura do topo (branco translúcido + texto branco);
   na tabela clara isso fica branco-no-branco (invisível). Reveste para o fundo claro. */
.tbl .acts .ta-btn { background: var(--bg-pill); color: var(--text); border-color: var(--border); cursor: pointer; }
.tbl .acts .ta-btn:hover { background: var(--bg-pill-active); color: #fff; border-color: transparent; }
.pill-ok { background: var(--positivo); color: #fff; padding: 2px 9px; border-radius: 999px; font-size: 12px; }
.pill-off { background: var(--texto-2); color: #fff; padding: 2px 9px; border-radius: 999px; font-size: 12px; }
.pill-warn { background: var(--accent); color: #fff; padding: 2px 9px; border-radius: 999px; font-size: 11px; }
.pill-info { background: var(--verde-medio); color: #fff; padding: 2px 9px; border-radius: 999px; font-size: 11px; }

/* ============================================================================
   Modo de edição do layout (GridStack) — cards móveis/redimensionáveis
   ========================================================================== */
.dash-wrap { flex: 1 1 auto; min-height: 0; }
/* Barra do modo de edição (gruda no topo da view enquanto rola) */
.layout-editbar {
  position: sticky; top: 0; z-index: 60;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 14px; margin-bottom: 12px;
  background: var(--bg-panel); border: 1.5px dashed var(--accent);
  border-radius: var(--raio-card); box-shadow: var(--sombra);
}
.layout-editbar .leb-badge {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--accent); color: #fff; padding: 4px 12px;
  border-radius: 999px; font-size: 12.5px; font-weight: 600; white-space: nowrap;
}
.layout-editbar .leb-hint { color: var(--text-muted); font-size: 12.5px; flex: 1 1 auto; min-width: 220px; }
.layout-editbar .leb-actions { display: flex; gap: 8px; margin-left: auto; }
/* Cards em edição: borda tracejada + cursor de arraste; charts não capturam o mouse */
.layout-editing .grid-stack-item > .panel { border: 1.5px dashed var(--accent); cursor: grab; }
.layout-editing .grid-stack-item.ui-draggable-dragging > .panel {
  cursor: grabbing; border-style: solid; box-shadow: 0 14px 30px rgba(0, 0, 0, 0.28);
}
.layout-editing .grid-stack-item.ui-draggable-dragging,
.layout-editing .grid-stack-item.ui-resizable-resizing { z-index: 70; }
.layout-editing .panel-body canvas { pointer-events: none; }
/* Linhas-guia das 12 colunas enquanto edita */
.layout-editing .dash-grid {
  background-image: linear-gradient(to right, var(--border) 1px, transparent 1px);
  background-size: calc(100% / 12) 100%;
}
/* Prévia (placeholder) do destino durante arraste/redimensionamento */
.grid-stack-placeholder > .placeholder-content {
  border: 2px dashed var(--accent) !important;
  background: rgba(178, 81, 43, 0.08) !important;
  border-radius: var(--raio-card);
}
.layout-editing .ui-resizable-handle { opacity: 0.85; }
/* Toast de confirmação (salvar/restaurar layout) */
.nn-toast {
  position: fixed; right: 18px; bottom: 18px; z-index: 1000;
  background: var(--bg-pill-active); color: #fff; padding: 10px 16px;
  border-radius: 8px; font-size: 13px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}
.nn-toast.err { background: var(--danger); }

/* ---- Lembrete de reunião ("começa em X min") -------------------------------
   Card fixo, canto inferior direito, EMPILHADO ACIMA do toast (bottom maior):
   o toast some sozinho em 2,8s e o lembrete fica — se dividissem a mesma
   posição, um cobriria o outro no momento em que os dois importam.
   Aparece em qualquer tela do portal, porque o shell é o mesmo em todas. */
.nn-lembretes {
  position: fixed; right: 18px; bottom: 66px; z-index: 999;
  display: flex; flex-direction: column; gap: 8px;
  width: min(360px, calc(100vw - 36px));
}
.nn-lem {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-panel); color: var(--texto);
  border: 1px solid var(--borda); border-left: 3px solid var(--verde-medio);
  border-radius: var(--raio-card); padding: 11px 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .16);
}
/* Reunião em andamento é a única que muda de cor: o atraso é a informação
   nova, e é o único momento em que o aviso pede ação imediata. */
.nn-lem.agora { border-left-color: var(--terra); }
.nn-lem-ic { color: var(--verde-medio); font-size: 15px; flex: none; }
.nn-lem.agora .nn-lem-ic { color: var(--terra-icone); }
.nn-lem-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.nn-lem-txt strong {
  font-size: 13px; font-weight: 600; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nn-lem-com { font-size: 11.5px; color: var(--texto-2); }
.nn-lem-quando { font-size: 11.5px; color: var(--texto-fraco); }
.nn-lem.agora .nn-lem-quando { color: var(--terra-texto); font-weight: 600; }
.nn-lem-btn {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  background: var(--bg-pill-active); color: #fff; border: 0;
  padding: 7px 11px; border-radius: var(--raio);
  font-size: 12px; font-weight: 600; cursor: pointer; text-decoration: none;
}
.nn-lem-btn:hover { filter: brightness(1.08); }
.nn-lem-btn.ghost {
  background: transparent; color: var(--texto-2); border: 1px solid var(--borda);
}
.nn-lem-x {
  position: absolute; top: 3px; right: 5px;
  background: none; border: 0; cursor: pointer; line-height: 1;
  font-size: 15px; color: var(--texto-fraco); padding: 2px 4px;
}
.nn-lem-x:hover { color: var(--texto); }
@media (max-width: 900px) {
  .nn-lembretes { right: 12px; left: 12px; width: auto; bottom: 60px; }
}

/* Rolagem interna do gráfico (muitas categorias): SÓ a área de plotagem rola;
   título do card fixo; a página não rola por causa do gráfico. */
.chart-scroll {
  position: absolute; inset: 0;
  overflow-y: auto; overflow-x: hidden;
}
.chart-fit { position: relative; min-height: 100%; width: 100%; }
/* Gráfico com subtítulo (os cards do BI Financeiro que eram tabela ou lista):
   o corpo vira coluna — o subtítulo parado em cima e o gráfico na altura que
   sobra, numa área só dele. O Chart.js se mede pelo pai, e a .chart-scroll da
   barra horizontal se prende a essa área em vez de cobrir o subtítulo. */
.panel-body:has(> .chart-area) { display: flex; flex-direction: column; }
.chart-area { position: relative; flex: 1 1 auto; min-height: 0; }

/* Rolagem dentro dos cards do dashboard (o card, o corpo, as listas, os mini
   cards e a barra horizontal com muitas categorias): pílula de 6px com pontas
   redondas sobre um trilho clarinho, que mostra o caminho inteiro e onde se
   está. Sai do --texto-fraco, definido nos dois temas, então o modo escuro vem
   junto. Nunca some: é ela que avisa que a lista continua. Borda transparente +
   `padding-box` afinam a pílula sem estreitar a faixa de 12px do mouse. Padrão
   e webkit separados por `@supports` (ver .side-nav). */
:is(.grid-stack-item-content, .grid-stack-item-content > .panel-body, .pf-scroll, .pf-minis, .chart-scroll)::-webkit-scrollbar {
  -webkit-appearance: none; width: 12px; height: 12px;
}
:is(.grid-stack-item-content, .grid-stack-item-content > .panel-body, .pf-scroll, .pf-minis, .chart-scroll)::-webkit-scrollbar-track {
  background: color-mix(in srgb, var(--texto-fraco) 12%, transparent);
  border-radius: 999px; border: 3px solid transparent; background-clip: padding-box;
}
:is(.grid-stack-item-content, .grid-stack-item-content > .panel-body, .pf-scroll, .pf-minis, .chart-scroll)::-webkit-scrollbar-corner { background: transparent; }
:is(.grid-stack-item-content, .grid-stack-item-content > .panel-body, .pf-scroll, .pf-minis, .chart-scroll)::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--texto-fraco) 45%, transparent);
  border-radius: 999px; border: 3px solid transparent; background-clip: padding-box;
}
:is(.grid-stack-item-content, .grid-stack-item-content > .panel-body, .pf-scroll, .pf-minis, .chart-scroll)::-webkit-scrollbar-thumb:hover,
:is(.grid-stack-item-content, .grid-stack-item-content > .panel-body, .pf-scroll, .pf-minis, .chart-scroll)::-webkit-scrollbar-thumb:active {
  background: var(--texto-fraco); background-clip: padding-box;
}
/* Longe dos cantos arredondados do card: colada neles, a barra parecia cortada.
   O corpo e a .chart-scroll encostam na borda do card (o painel do shell não
   tem padding), por isso a folga embaixo, onde está o canto. */
.grid-stack-item-content::-webkit-scrollbar-track { margin: 12px 0; }
:is(.grid-stack-item-content > .panel-body, .grid-stack-item-content .chart-scroll)::-webkit-scrollbar-track { margin: 4px 0 10px; }
@supports not selector(::-webkit-scrollbar) {
  .grid-stack-item-content, .grid-stack-item-content > .panel-body, .pf-scroll, .pf-minis, .chart-scroll {
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--texto-fraco) 45%, transparent) color-mix(in srgb, var(--texto-fraco) 12%, transparent);
  }
}

/* Na grade, o card fica PARADO e o título sempre à vista: quem rola é o
   conteúdo. Em tabela, listas e mini cards rola só a lista — subtítulo,
   cabeçalho das colunas, total e rodapé ficam parados, como na tela cheia
   (.panel-zoom-box). Só acima de 900px: no celular a grade vira coluna e o card
   rola inteiro, como antes. */
@media (min-width: 901px) {
  .grid-stack > .grid-stack-item > .grid-stack-item-content { overflow-y: hidden; }
  .grid-stack-item-content > .panel-body { overflow-y: auto; overflow-x: hidden; }
  /* Gráfico cabe no corpo por construção (o Chart.js se mede por ele): corpo sem
     rolagem, para uma sobra de subpixel não acender barra à toa. A barra
     horizontal com muitas categorias rola na própria .chart-scroll. */
  .grid-stack-item-content > .panel-body:has(> canvas, > .chart-scroll, > .chart-area) { overflow: hidden; }
  .grid-stack-item-content > .panel-body:has(> .pf-scroll, > .pf-minis) {
    display: flex; flex-direction: column; overflow: hidden;
  }
  /* Total preso embaixo. A linha de cima vem da sombra (a borda de célula não
     acompanha o `sticky`), e a sombra larga esmaece a linha que passa por trás,
     avisando que tem mais. */
  .grid-stack-item-content .pf-tabela tfoot td {
    position: sticky; bottom: 0; z-index: 1;
    background: var(--bg-panel); border-top: 0;
    box-shadow: inset 0 1px 0 var(--border), 0 -10px 10px -4px var(--bg-panel);
  }
  /* A pílula corre só ao lado das linhas, não do cabeçalho nem do total. */
  .grid-stack-item-content .pf-scroll:has(> .pf-tabela > thead)::-webkit-scrollbar-track { margin-top: 26px; }
  .grid-stack-item-content .pf-scroll:has(> .pf-tabela > tfoot)::-webkit-scrollbar-track { margin-bottom: 34px; }
}

/* Responsivo: em telas estreitas, empilha e volta a permitir rolagem
   (tela cheia sem scroll vale para monitor/TV; no celular seria espremido). */
@media (max-width: 900px) {
  #btnLayout { display: none; } /* edição de layout só em telas largas */
  html, body { height: auto; overflow: auto; }
  .view { overflow: visible; }
  .grid { grid-auto-rows: auto; }
  .panel { overflow: visible; }
  .panel-body { min-height: 220px; }
  .panel.span-3, .panel.span-4, .panel.span-6, .panel.span-8 { grid-column: span 12; }
  .filters { grid-row: auto !important; }
  .form-cols { grid-template-columns: 1fr; }
  .subbar { gap: 10px; }
  .page-title { font-size: 22px; }
}

/* Altura curta (notebooks/TV deitada): encolhe um pouco os KPIs */
@media (max-height: 760px) {
  .kpi { padding: 9px 14px; }
  .kpi .kpi-label { min-height: 24px; margin-bottom: 4px; font-size: 11px; }
}

/* ============================================================================
   Auxílio Ac Docs — visão COMPLETA de Entregas (port do preview no tema do portal).
   Tudo escopado em `.ac-wrap` para não colidir com o resto do portal.
   ============================================================================ */
.ac-wrap { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; padding-right: 4px; }

/* Tira de FONTES: frescor do espelho da Acessórias, sempre à vista, logo abaixo
   do cabeçalho. Uma linha só — é contexto para os números, não um painel: com
   altura de card empurraria o dado para fora da primeira tela.

   `ok` e `velho` mudam ÍCONE e cor; cor sozinha excluiria quem não distingue
   verde/vermelho. Terracota (a cor de ação da marca) marca o que pede atenção. */
.ac-fontes {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px;
  margin: 0 0 14px; padding: 9px 12px;
  background: var(--bg-pill); border: 1px solid var(--borda); border-radius: var(--radius);
  font-size: 12.5px;
}
.ac-fontes[hidden] { display: none; }
.acf-rot {
  color: var(--texto-fraco); font-size: 10.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
}
.acf-item { display: inline-flex; align-items: center; gap: 6px; color: var(--text-muted); }
.acf-item b { color: var(--text); font-weight: 600; }
.acf-item.ok > i { color: var(--positivo); }
.acf-item.velho > i, .acf-item.velho b { color: var(--terra-texto); }
/* Botão e mensagem fecham a linha à direita: o estado se lê da esquerda para a
   direita, a AÇÃO vem depois do diagnóstico. */
.ac-fontes .ac-sync-btn { margin-left: auto; padding: 6px 12px; font-size: 12.5px; }
.acf-msg { color: var(--text-muted); }
.acf-msg.erro { color: var(--terra-texto); font-weight: 600; }
.acf-msg[hidden] { display: none; }
.ac-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* Faixa de avisos que MUDAM a leitura dos números (truncamento, espelho velho,
   entregas sem prazo). Terracota da marca: chama atenção sem virar erro. */
.ac-aviso {
  display: flex; gap: 10px; align-items: flex-start;
  margin: 0 0 14px; padding: 11px 14px;
  background: var(--terra-bg); border: 1px solid var(--terra);
  border-radius: var(--raio-card); color: var(--texto); font-size: 12.5px;
}
.ac-aviso[hidden] { display: none; }
.ac-aviso > i { color: var(--terra-icone); margin-top: 1px; flex: 0 0 auto; }
.ac-aviso p { margin: 0; }
.ac-aviso p + p { margin-top: 6px; }
/* Coluna informativa (não entra na taxa de falha) — em segundo plano. */
.ac-wrap td.col-neutra { color: var(--texto-fraco); }
.ac-btn { font: inherit; cursor: pointer; background: var(--bg-pill); color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); padding: 9px 14px; font-size: 13px; display: inline-flex; align-items: center; gap: 7px; }
.ac-btn:hover { border-color: var(--verde-medio); }
.ac-btn-primary { background: var(--accent); color: #fff; border-color: transparent; font-weight: 600; }
.ac-btn-primary:hover { background: var(--terra-acao-hover); }

/* Abas internas (Visão geral / Entregas / Boletos / Solicitações) */
.ac-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: var(--gap); border-bottom: 1px solid var(--border); }
.ac-tab { font: inherit; cursor: pointer; background: transparent; color: var(--text-muted); border: 1px solid transparent; border-bottom: none; border-radius: var(--radius) var(--radius) 0 0; padding: 9px 16px; font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 7px; margin-bottom: -1px; }
.ac-tab:hover { color: var(--text); background: var(--superficie-2); }
.ac-tab.active { color: var(--terra-texto); background: var(--bg-panel); border-color: var(--border); border-bottom-color: var(--bg-panel); }
.ac-tab .ac-tab-count { font-size: 11px; font-weight: 700; opacity: .75; }
.ac-panel { display: none; }
.ac-panel.active { display: block; }

/* Leitura das tabelas: zebra sutil + um pouco mais de respiro vertical */
.ac-wrap tbody tr:nth-child(even) { background: rgba(15, 23, 42, .025); }
.ac-wrap tbody td { padding-top: 9px; padding-bottom: 9px; }

/* cards de métrica (faixa de acento à esquerda) */
.ac-metrics { display: grid; gap: var(--gap); grid-template-columns: repeat(4, minmax(0, 1fr)); margin-bottom: var(--gap); }
.ac-wrap .metric { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--raio-card); box-shadow: var(--sombra); padding: 13px 15px; position: relative; overflow: hidden; }
.ac-wrap .metric::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--accent-bar, #cbd5e1); }
.ac-wrap .metric .label { font-size: 12px; color: var(--text-muted); font-weight: 600; }
.ac-wrap .metric .value { font-size: 26px; font-weight: 800; margin-top: 4px; letter-spacing: -1px; line-height: 1; }
.ac-wrap .metric .sub { font-size: 11px; color: var(--texto-fraco); margin-top: 3px; }
.ac-wrap .metric.red { --accent-bar: #c0392b; }
.ac-wrap .metric.orange { --accent-bar: #d86d42; }
.ac-wrap .metric.green { --accent-bar: #2f9e6f; }
.ac-wrap .metric.blue { --accent-bar: #b2512b; }
.ac-wrap .metric.yellow { --accent-bar: #d9a441; }
.ac-wrap .metric.teal { --accent-bar: #2e7474; }
.ac-wrap .metric.violet { --accent-bar: #002a2b; }
.ac-wrap .metric.slate { --accent-bar: #5b595b; }

/* cards/seções */
.ac-card { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--raio-card); box-shadow: var(--sombra); padding: 16px 18px; margin-bottom: var(--gap); }
.ac-wrap .section-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.ac-wrap .section-head h3 { margin: 0; font-size: 15px; font-weight: 600; }
.ac-wrap .hint { font-size: 12px; color: var(--text-muted); }

/* filtros */
.ac-filters { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
.ac-wrap .field { display: flex; flex-direction: column; gap: 5px; }
.ac-wrap .field label { font-size: 11.5px; font-weight: 600; color: var(--text-muted); }
.ac-wrap .field input, .ac-wrap .field select { font: inherit; font-size: 13px; color: var(--text); border: 1px solid var(--border); border-radius: var(--radius); padding: 8px 10px; background: var(--branco); outline: none; }
.ac-wrap .field input:focus, .ac-wrap .field select:focus { border-color: var(--verde-medio); box-shadow: 0 0 0 3px rgba(46, 116, 116, .16); }
.ac-wrap .filters-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border); }

/* gráficos (HTML/CSS) */
.ac-wrap .charts { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ac-wrap .chart-box { background: var(--superficie-2); border: 1px solid var(--border); border-radius: var(--raio); padding: 14px; min-width: 0; }
.ac-wrap .chart-box.chart-wide { grid-column: 1 / -1; } /* "recebidos por dia" ocupa a linha toda */
.ac-wrap .chart-box h4 { font-size: 13px; margin: 0 0 12px; color: var(--text-muted); font-weight: 600; }
.ac-wrap .chart-note { font-size: 10.5px; color: var(--texto-fraco); margin: 10px 0 0; }
.ac-wrap .bars-v { display: flex; align-items: flex-end; gap: 8px; height: 180px; padding-top: 24px; }
.ac-wrap .bar-v { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
.ac-wrap .bar-v .col { width: 100%; max-width: 34px; background: linear-gradient(180deg, #2e7474, #002a2b); border-radius: 5px 5px 2px 2px; min-height: 3px; position: relative; }
.ac-wrap .bar-v .col .n { position: absolute; top: -17px; left: 50%; transform: translateX(-50%); font-size: 11px; font-weight: 700; color: var(--text-muted); }
.ac-wrap .bar-v .x { font-size: 10.5px; color: var(--texto-fraco); white-space: nowrap; }
.ac-wrap .bar-v .x-mes { color: var(--text-muted); font-weight: 600; } /* rótulo de início de mês: âncora visual */
.ac-wrap .bars-h { display: flex; flex-direction: column; gap: 9px; }
.ac-wrap .bar-h { display: grid; grid-template-columns: 130px 1fr 34px; align-items: center; gap: 8px; }
.ac-wrap .bar-h .lbl { font-size: 11.5px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-wrap .bar-h .track { display: block; background: var(--border); border-radius: 999px; height: 14px; overflow: hidden; }
.ac-wrap .bar-h .fill { display: block; height: 100%; border-radius: 999px; min-width: 3px; }
.ac-wrap .bar-h .num { font-size: 11.5px; font-weight: 700; text-align: right; color: var(--text-muted); }
.ac-wrap .fill.red { background: #c0392b; } .ac-wrap .fill.orange { background: #d86d42; } .ac-wrap .fill.yellow { background: #d9a441; }
.ac-wrap .fill.green { background: #2f9e6f; } .ac-wrap .fill.blue { background: #2e7474; } .ac-wrap .fill.gray { background: #908e90; }

/* tabelas */
.ac-wrap .table-scroll { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--raio); }
.ac-wrap table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.ac-wrap thead th { background: var(--superficie-2); color: var(--text-muted); text-align: left; padding: 9px 11px; font-weight: 700; font-size: 11px; white-space: nowrap; border-bottom: 1px solid var(--border); text-transform: uppercase; letter-spacing: .03em; }
.ac-wrap tbody td { padding: 8px 11px; border-bottom: 1px solid var(--border); white-space: nowrap; }
.ac-wrap tbody tr:hover { background: var(--superficie-2); }
.ac-wrap tbody tr:last-child td { border-bottom: none; }
.ac-wrap .cli-name { font-weight: 600; color: var(--text); }
.ac-wrap .cli-cnpj { font-size: 11px; color: var(--texto-fraco); font-family: var(--mono); }

/* badges de status (paleta da marca) */
.ac-wrap .badge { display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 700; white-space: nowrap; }
.ac-wrap .b-red { background: #f6ddd6; color: #b03222; }
.ac-wrap .b-orange { background: #f7e3d3; color: #b2512b; }
.ac-wrap .b-yellow { background: #f3e7c6; color: #946f22; }
.ac-wrap .b-green { background: #d8ece1; color: #1f7a52; }
.ac-wrap .b-blue { background: #d4e4e4; color: #1f5e5e; }
.ac-wrap .b-gray { background: #e8e5e5; color: #5b595b; }

/* progress / risco / layout / vazio */
.ac-wrap .progress { background: var(--border); border-radius: 999px; height: 9px; width: 90px; overflow: hidden; display: inline-block; vertical-align: middle; }
.ac-wrap .progress > span { display: block; height: 100%; background: linear-gradient(90deg, #2f9e6f, #1f7a52); border-radius: 999px; }
.ac-wrap .progress.mid > span { background: linear-gradient(90deg, #d9a441, #c0892f); }
.ac-wrap .progress.low > span { background: linear-gradient(90deg, #d86d42, #b2512b); }
.ac-wrap .pct { font-weight: 700; font-size: 11.5px; margin-left: 8px; }
.ac-wrap .risk-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
.ac-wrap .two-col { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }
.ac-wrap .empty { padding: 22px; text-align: center; color: var(--text-muted); font-size: 13px; }

/* ---------- Tela cheia por seção (botão ao lado do título) ---------- */
/* margin-right:auto cola o botão no título e empurra o hint p/ a direita (como na ref.) */
.ac-wrap .ac-fs {
  margin-right: auto; flex: 0 0 auto; width: 30px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius); font-size: 13px;
}
.ac-wrap .ac-fs:hover { color: var(--terra-texto); border-color: var(--accent); }
.ac-wrap .ac-fs:focus-visible { outline: 2px solid var(--verde-medio); outline-offset: 2px; }

/* card maximizado: cobre a viewport, rola por dentro, cabeçalho/título fixos no topo */
.ac-card.ac-fs-active {
  position: fixed; inset: 0; z-index: 90; margin: 0;
  border: none; border-radius: 0; box-shadow: none;
  padding: 16px 22px 18px; background: var(--bg-panel);
  display: flex; flex-direction: column; overflow: hidden;
}
.ac-card.ac-fs-active .section-head {
  flex: 0 0 auto; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.ac-card.ac-fs-active .section-head h3 { font-size: 17px; }
/* tabelas: ocupam toda a altura disponível, rolam dentro, thead grudado no topo */
.ac-card.ac-fs-active .table-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; }
/* fit-to-viewport: layout fixo divide a largura disponível entre as colunas (em vez
   de esticar com o conteúdo) -> o texto QUEBRA em linha em vez de estourar a tela.
   overflow-wrap quebra tokens longos (CNPJ, nomes sem espaço). Só em tela cheia;
   na view normal a tabela segue com scroll horizontal. */
.ac-card.ac-fs-active table { table-layout: fixed; width: 100%; font-size: 13px; }
.ac-card.ac-fs-active th,
.ac-card.ac-fs-active td { white-space: normal; overflow-wrap: anywhere; vertical-align: top; }
.ac-card.ac-fs-active tbody td { padding: 9px 12px; }
.ac-card.ac-fs-active thead th { position: sticky; top: 0; z-index: 1; }
/* a coluna identificadora (cliente/dia) ganha mais largura; as demais dividem o resto */
.ac-card.ac-fs-active thead th:first-child { width: 18%; }
/* gráficos: mais espaço, barras mais altas */
.ac-card.ac-fs-active .charts { flex: 1 1 auto; min-height: 0; overflow: auto; align-content: start; }
.ac-card.ac-fs-active .bars-v { height: 42vh; }
.ac-card.ac-fs-active .bar-v .col { max-width: 46px; }
@media (max-width: 900px) {
  .ac-card.ac-fs-active .charts { grid-template-columns: 1fr; }
}

@media (max-width: 1200px) {
  .ac-wrap .charts { grid-template-columns: 1fr; }
  .ac-wrap .two-col { grid-template-columns: 1fr; }
  .ac-filters { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 820px) {
  .ac-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ac-filters { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================
   TEMA ESCURO — Paleta NN Hub (ekontroll). Ativado por html.dark
   (classe em <html>), persistido em localStorage['ekontroll-theme'].
   Acentos por função: ícones na cor da marca, texto legível, superfícies discretas
   e preenchimento de ação separado para preservar o contraste com branco.
   ============================================================ */
html { color-scheme: light; }

html.dark {
  color-scheme: dark;

  /* Estrutura / superfícies */
  --branco:       #0f2627;             /* cards / superfícies / linha de tabela */
  --superficie-2: #0a1d1e;             /* cabeçalho de tabela, pills, inputs */
  --bg:           #081819;             /* fundo da página */
  --borda:        rgba(255,255,255,.1);

  /* Texto (escala slate) */
  --texto:        #e2e8f0;             /* slate-700 (base) */
  --texto-2:      #cbd5e1;             /* slate-600/300 */
  --texto-fraco:  #94a3b8;             /* slate-500/400 */

  /* Marca exata nos ícones; variação oficial clara só no texto pequeno. */
  --terra-icone-bg: var(--superficie-2);
  --terra-texto:  var(--terra-claro);
  --terra-texto-hover: var(--terra-texto);
  --terra-acao-hover: #a84d2a;
  --terra-foco:   var(--terra-texto);

  /* Foreground de marca: teal claro p/ links/ícones */
  --verde-medio:  #5eead4;             /* teal */

  /* Semânticos — cor de TEXTO; bg = mesma cor a 10% (pills/badges tratadas abaixo) */
  --positivo:     #86efac;             /* green */
  --negativo:     #fca5a5;             /* red */
  --positivo-bg:  rgba(134,239,172,.10);
  --negativo-bg:  rgba(252,165,165,.10);
  --verde-bg:     rgba(94,234,212,.10);
  --terra-bg:     rgba(178,81,43,.02);

  --grid:         rgba(255,255,255,.07);
  --sombra:       0 1px 3px rgba(0,0,0,.5);
}

/* Header é verde-petróleo nos dois temas; reforça a borda inferior no escuro. */
html.dark .topbar { border-bottom-color: rgba(255,255,255,.1); }

/* Linha de tabela — hover (NN Hub): base sutil + escuro #153536 */
.tbl tbody tr:hover td { background: var(--superficie-2); }
html.dark .tbl tbody tr:hover td { background: #153536; }

/* Pills de status: viram chips (texto semântico + fundo a ~10%). */
html.dark .pill-ok   { background: rgba(134,239,172,.12); color: #86efac; }
html.dark .pill-off  { background: rgba(255,255,255,.08); color: #94a3b8; }
html.dark .pill-warn { background: rgba(253,186,116,.12); color: #fdba74; }
html.dark .pill-info { background: rgba(94,234,212,.12);  color: #5eead4; }

/* Badges do Auxílio Ac Docs (pastéis claros -> chips com a paleta NN Hub) */
html.dark .ac-wrap .b-red    { background: rgba(252,165,165,.10); color: #fca5a5; }
html.dark .ac-wrap .b-orange { background: rgba(253,186,116,.10); color: #fdba74; }
html.dark .ac-wrap .b-yellow { background: rgba(251,191,36,.10);  color: #fbbf24; }
html.dark .ac-wrap .b-green  { background: rgba(134,239,172,.10); color: #86efac; }
html.dark .ac-wrap .b-blue   { background: rgba(147,197,253,.10); color: #93c5fd; }
html.dark .ac-wrap .b-gray   { background: rgba(255,255,255,.08); color: #94a3b8; }

/* Barras verticais: gradiente teal visível sobre o card escuro. */
html.dark .ac-wrap .bar-v .col { background: linear-gradient(180deg, #4aa3a3, #2e7474); }

/* Accent-bars de métrica escuras demais p/ o card escuro. */
html.dark .ac-wrap .metric.violet { --accent-bar: #5eead4; }
html.dark .ac-wrap .metric.slate  { --accent-bar: #94a3b8; }

/* Valores grandes preservam a terracota original da NN. */
html.dark .kpi .kpi-value.accent,
html.dark .callout .big { color: var(--terra); }


/* Transição suave ao alternar tema (sutil; não roda no load inicial). */
body, .topbar, .subbar, .panel, .ac-card, .nn-modal-card,
.tbl, .tbl td, .tbl th, .ac-wrap .metric, .kpi, input, select, textarea {
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}

/* Botão flutuante de tema na tela de login (que não tem barra superior). */
.theme-fab { position: fixed; top: 14px; right: 14px; z-index: 20; cursor: pointer; }

/* ============================================================
   Pesquisa Mensal de Uso (modal de formulário) — reusa .nn-modal*
   ============================================================ */
.pq-card { max-width: 560px; max-height: 88vh; overflow-y: auto; text-align: left; }
.pq-card .auth-info { margin: 0 0 6px; }
.pq { display: flex; flex-direction: column; gap: 16px; margin-top: 12px; }
.pq-q { display: flex; flex-direction: column; gap: 8px; }
.pq-label { display: block; color: var(--text); font-size: 14px; font-weight: 600; margin: 0; }
.pq-label.pq-sub { font-weight: 500; color: var(--text-muted); font-size: 13px; }
.pq-hint { color: var(--texto-fraco); font-size: 12px; }
.pq-opts { display: flex; flex-direction: column; gap: 6px; }
.pq-opt { display: flex; align-items: center; gap: 9px; cursor: pointer; color: var(--text);
  font-size: 14px; padding: 8px 11px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-panel); }
.pq-opt:hover { border-color: var(--verde-medio); }
.pq-opt input { width: auto; accent-color: var(--accent); margin: 0; }
.pq-text { width: 100%; background: var(--bg-pill); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 9px 12px; font-size: 14px; font-family: inherit; resize: vertical; }
.pq-text:focus { outline: none; background: var(--branco); border-color: var(--verde-medio); box-shadow: 0 0 0 3px rgba(46,116,116,.16); }
.pq-stars { display: flex; gap: 6px; }
.pq-star { background: transparent; border: none; cursor: pointer; font-size: 22px; line-height: 1; color: var(--border); padding: 2px; }
.pq-star:hover, .pq-star.on { color: var(--terra-icone); }
.pq-scale { display: flex; flex-wrap: wrap; gap: 6px; }
.pq-num { min-width: 34px; height: 34px; padding: 0 8px; cursor: pointer; font-size: 14px; font-weight: 600;
  background: var(--bg-pill); color: var(--text-muted); border: 1px solid var(--border); border-radius: var(--radius); }
.pq-num:hover { border-color: var(--verde-medio); color: var(--text); }
.pq-num.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.pq-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; position: sticky; bottom: -22px;
  background: var(--bg-panel); padding: 14px 0 2px; }
.pq-foot .btn { width: auto; margin: 0; background: var(--accent); color: #fff; border: none;
  border-radius: var(--radius); padding: 10px 18px; font-size: 14px; font-weight: 600; cursor: pointer; }
.pq-foot .btn:hover { background: var(--terra-acao-hover); }
.pq-foot .btn-ghost { cursor: pointer; }
.pq-thanks { text-align: center; padding: 30px 10px; color: var(--text); }
.pq-thanks i { color: var(--positivo); font-size: 38px; }
.pq-thanks p { margin: 12px 0 0; font-size: 16px; font-weight: 600; }

/* ============================================================
   Admin — abas (Funcionários / Indicadores de Uso)
   ============================================================ */
.admin-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 16px; }
.admin-tabs button { background: transparent; border: none; cursor: pointer; color: var(--text-muted);
  font-size: 14px; font-weight: 600; padding: 10px 14px; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.admin-tabs button:hover { color: var(--text); }
.admin-tabs button.active { color: var(--terra-texto); border-bottom-color: var(--accent); }
.admin-tabs button i { margin-right: 6px; }
.ind-period { display: inline-flex; align-items: center; gap: 8px; color: var(--text-muted); font-size: 13px; }
.ind-period select { background: var(--bg-pill); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 7px 10px; font-size: 14px; }

/* Indicadores: KPI cards (número grande), distribuições e ranking */
.ind-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: var(--gap); margin-bottom: 18px; }
.ind-kpi { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--raio-card);
  padding: 14px 16px; box-shadow: var(--sombra); }
.ind-kpi-label { color: var(--text-muted); font-size: 12px; margin-bottom: 8px; }
.ind-kpi-val { font-size: clamp(24px, 3vh, 32px); font-weight: 700; line-height: 1; color: var(--text); }
.ind-kpi.accent .ind-kpi-val { color: var(--terra); }
.ind-kpi.danger .ind-kpi-val { color: var(--danger); }
.ind-kpi-sub { color: var(--texto-fraco); font-size: 12px; margin-top: 6px; }
.ind-cols { display: grid; grid-template-columns: 1fr 2fr; gap: var(--gap); align-items: start; }
.ind-panel { background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--raio-card);
  padding: 16px 18px; box-shadow: var(--sombra); margin-bottom: 18px; }
.ind-panel h3 { margin: 0; font-size: 15px; font-weight: 700; color: var(--text); }
.ind-cap { margin: 4px 0 14px; color: var(--text-muted); font-size: 12.5px; }
.ind-dist { display: flex; flex-direction: column; gap: 10px; }
.ind-dist-row { display: grid; grid-template-columns: 120px 1fr 80px; align-items: center; gap: 10px; font-size: 13px; }
.ind-dist-lbl { color: var(--text-muted); }
.ind-dist-bar { background: var(--bg-pill); border-radius: 999px; height: 9px; overflow: hidden; }
.ind-dist-bar i { display: block; height: 100%; background: var(--verde-medio); border-radius: 999px; }
.ind-dist-val { text-align: right; color: var(--text); font-variant-numeric: tabular-nums; }
.ind-tbl td.num, .ind-tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
.ind-nps { font-weight: 700; }
.ind-nps.neg { color: var(--danger); }
.ind-empty { text-align: center; color: var(--text-muted); }
.ind-sug { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.ind-sug li { font-size: 13.5px; color: var(--text); line-height: 1.45; }
.ind-sug-tag { display: inline-block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  padding: 2px 7px; border-radius: 999px; margin-right: 7px; }
.ind-sug-tag.nova { background: var(--verde-bg); color: var(--verde-medio); }
.ind-sug-tag.melh { background: var(--terra-bg); color: var(--terra-texto); }
@media (max-width: 860px) {
  .ind-cols { grid-template-columns: 1fr; }
  .ind-dist-row { grid-template-columns: 110px 1fr 70px; }
}

/* ============================================================
   Modo TV — apresentação em tela cheia (some só a barra verde;
   subbar fica para dar contexto de departamento/aba na TV)
   ============================================================ */
body.tv-mode .topbar { display: none; }
/* Modo TV no portal: só o dashboard na tela — some a sidebar e todo o chrome. */
body.app-shell.tv-mode .sidebar,
body.app-shell.tv-mode .side-scrim,
body.app-shell.tv-mode .subbar { display: none; }
/* Modo TV não tem quem clique: o seletor de empresa sai junto com a subbar, e a
   tela exibe o recorte padrão (consolidado). */
body.app-shell.tv-mode .subbar-seletor { display: none; }

/* Mídia de transição (imagem ou vídeo) entre as trocas de aba (cobre o carregamento) */
.tv-splash {
  position: fixed; inset: 0; z-index: 260; background: #000;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity .45s ease; /* manter em sincronia com FADE_MS do tv.js */
}
.tv-splash.on { opacity: 1; pointer-events: auto; }
/* Imagem e vídeo preenchem a tela toda (cover corta as bordas quando a
   proporção do arquivo difere da tela — sem barras pretas). */
.tv-splash img, .tv-splash video { width: 100%; height: 100%; object-fit: cover; }

/* Botão discreto para encerrar (além do Esc) */
.tv-exit {
  position: fixed; right: 16px; bottom: 16px; z-index: 270;
  display: inline-flex; align-items: center; gap: 7px;
  background: rgba(0, 0, 0, .55); color: #fff;
  border: 1px solid rgba(255, 255, 255, .25); border-radius: 999px;
  padding: 9px 16px; font-size: 13px;
  opacity: .18; transition: opacity .2s;
}
.tv-exit:hover, .tv-exit:focus-visible { opacity: 1; }

/* Tela de configuração (reusa .nn-modal) */
.tv-config-card { max-width: 430px; }
.tv-row { display: flex; gap: 12px; }
.tv-row > div { flex: 1 1 0; }
.tv-img-prev {
  margin-top: 8px; min-height: 96px; max-height: 180px; padding: 6px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  background: var(--bg-pill); border: 1px dashed var(--border); border-radius: var(--radius);
  color: var(--texto-fraco); font-size: 12px; text-align: center;
}
.tv-img-prev img, .tv-img-prev video { max-width: 100%; max-height: 168px; object-fit: contain; display: block; }
.tv-actions { display: flex; gap: 10px; margin-top: 18px; }
.tv-actions .btn { margin-top: 0; }
.nn-modal-card .btn.ghost {
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); font-weight: 500;
}
.nn-modal-card .btn.ghost:hover { background: var(--bg-pill-active); color: #fff; border-color: transparent; }
.nn-modal-card .btn.tv-remover { width: auto; margin-top: 10px; padding: 8px 14px; font-size: 13px; }
.nn-modal-msg.ok { background: var(--positivo-bg); border-color: var(--positivo); color: var(--positivo); }

/* ============================== Calendário NN ==============================
   O calendário em si virou aplicativo de página inteira (calendario.html +
   calendario.css). Aqui ficam APENAS os estilos reutilizados por ele:
   configuração (.cal-cfg*), detalhe (.cal-det/.cal-hist/.cal-anexos) e
   remarcação (.cal-resched). */

/* Config: ocupa a largura toda (como as visões mês/semana). Conta Google em
   card único no topo; donos (Fábio/Nadia) lado a lado em telas largas, empilham
   no estreito. */
.cal-cfg-card { margin-bottom: 16px; }
.cal-cfg-donos { display: grid; grid-template-columns: repeat(auto-fit, minmax(440px, 1fr)); gap: 16px; align-items: start; }
.cal-cfg-donos .cal-cfg-card { margin-bottom: 0; }
.cal-cfg-head {
  display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  padding-bottom: 12px; margin-bottom: 2px; border-bottom: 1px solid var(--border);
}
.cal-cfg-head h3 { margin: 0; }
.cal-cfg-hint { color: var(--text-muted); font-size: 13px; margin: 12px 0; }
/* Rótulo de sub-seção (Identificação / Regras / Janelas): agrupa e dá hierarquia. */
.cal-cfg-sub {
  font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--texto-fraco); margin: 18px 0 10px;
}
.cal-cfg-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px; }
.cal-cfg-grid.tres { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cal-cfg-grid.um { grid-template-columns: minmax(0, 420px); }
/* Número com unidade encostada (60 [min], 24 [horas]) — legível de relance. */
.cal-cfg-num { display: flex; align-items: center; gap: 8px; }
.cal-cfg-num input { flex: 1 1 auto; min-width: 0; }
.cal-cfg-num > span { color: var(--text-muted); font-size: 13px; white-space: nowrap; }
.cal-cfg-actions, .cal-cfg-footer { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 16px; }
.cal-cfg-footer { border-top: 1px solid var(--border); padding-top: 14px; margin-top: 18px; }
.cal-cfg-footer .form-msg { margin: 0 auto 0 0; } /* mensagem à esquerda, botão à direita */
.cal-cfg-addj { margin-top: 4px; }
.cal-cfg-empty { color: var(--text-muted); font-size: 13px; font-style: italic; margin: 2px 0 6px; }

/* Switch "Aceita agendamentos" — controle booleano em destaque no cabeçalho. */
.cal-switch { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; font-size: 13px; color: var(--texto); user-select: none; }
.cal-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.cal-switch-track { position: relative; width: 40px; height: 22px; border-radius: 999px; background: var(--texto-fraco); transition: background .15s; flex: 0 0 auto; }
.cal-switch-track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform .15s; }
.cal-switch input:checked + .cal-switch-track { background: var(--accent); }
.cal-switch input:checked + .cal-switch-track::after { transform: translateX(18px); }
.cal-switch input:focus-visible + .cal-switch-track { outline: 2px solid var(--verde-medio); outline-offset: 2px; }

/* Janelas: linhas alinhadas (dia · início às fim · remover). */
.cal-janela-row { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; flex-wrap: wrap; }
.cal-janela-row select { flex: 0 0 auto; min-width: 132px; }
.cal-janela-row select, .cal-janela-row input[type="time"] {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg-panel); color: var(--texto); font: inherit; font-size: 13px; padding: 6px 8px;
}
.cal-janela-row .cal-jr-ate { color: var(--text-muted); font-size: 13px; }
.cal-janela-row .rm {
  border: 0; background: transparent; color: var(--negativo); cursor: pointer; font-size: 14px; margin-left: 4px;
}
.cal-google-status { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 8px 0 12px; }

@media (max-width: 640px) {
  .cal-cfg-grid, .cal-cfg-grid.tres { grid-template-columns: 1fr; }
}

/* Detalhe (modal) */
.cal-det { display: grid; gap: 6px; margin: 4px 0 10px; }
.cal-det div { display: flex; justify-content: space-between; gap: 14px; font-size: 13.5px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.cal-det div:last-child { border-bottom: 0; }
.cal-det span { color: var(--text-muted); flex: 0 0 auto; }
.cal-det strong { text-align: right; overflow-wrap: anywhere; }
.cal-hist { margin: 8px 0 0; padding-left: 18px; font-size: 12.5px; color: var(--text-muted); }
.cal-hist li { margin-bottom: 4px; }
.cal-anexos { list-style: none; margin: 8px 0 0; padding: 0; }
.cal-anexos li { margin-bottom: 6px; font-size: 13px; }
.cal-anexos a { color: var(--verde-medio); }
.cal-resched { border-top: 1px solid var(--border); margin-top: 14px; padding-top: 12px; }
.cal-resched .slots { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.cal-resched .slots button {
  border: 1px solid var(--border); background: var(--bg-panel); color: var(--texto);
  border-radius: var(--radius); padding: 7px 12px; font: inherit; font-size: 13px; cursor: pointer;
}
.cal-resched .slots button.sel { background: var(--verde); border-color: var(--verde); color: #fff; }

/* ============================================================================
   SHELL DO PORTAL — sidebar + coluna principal (index.html)
   ----------------------------------------------------------------------------
   TUDO escopado em `body.app-shell`: admin.html, agenda-interna.html e
   calendario.html reusam .topbar/.ta-btn/.view/.panel e NÃO podem herdar isto.
   A marca continua a mesma: sidebar em --verde, ativo/acento em --terra.
   ============================================================================ */
.app-shell { flex-direction: row; isolation: isolate; }

/* ---------- Sidebar ---------- */
.app-shell .sidebar {
  flex: 0 0 232px;
  width: 232px;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--verde);
  border-right: 1px solid rgba(255, 255, 255, .08);
  z-index: 30;
  /* Recolher/expandir anima só a largura. O `transform` fica para o off-canvas
     do mobile (<=900px), que é outra mecânica. */
  transition: flex-basis .18s ease, width .18s ease;
}
/* Aplicada por shell.js só no carregamento, quando ele restaura a preferência
   de sidebar recolhida: sem isto a página abre com um deslize de 232px -> 64px. */
.app-shell.no-anim .sidebar { transition: none; }
.app-shell .side-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  flex: 0 0 auto;
}
/* .brand-logo (40px) é o mesmo do header antigo — logo da NN inalterada. */
.app-shell .side-brand .brand-txt { line-height: 1.05; }
.app-shell .side-brand .brand-txt strong { display: block; font-size: 13px; letter-spacing: .2px; color: #fff; }
.app-shell .side-brand .brand-txt span { display: block; font-size: 11.5px; color: rgba(255, 255, 255, .5); }

.app-shell .side-nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 12px 10px; }
/* Rolagem da sidebar: fina, no branco translúcido da própria barra (mesma
   escala dos hovers e filetes acima), sem trilho. Discreta parada, mais firme
   com o mouse na sidebar. Padrão e webkit separados por `@supports`: juntos, o
   Chrome ignora os pseudo-elementos (ver workflow.css, .wf-board). */
.app-shell .side-nav::-webkit-scrollbar { -webkit-appearance: none; width: 8px; }
.app-shell .side-nav::-webkit-scrollbar-track { background: transparent; }
.app-shell .side-nav::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .14);
  border-radius: 999px;
  /* Polegar de 4px visível numa faixa de 8px para o mouse. */
  border: 2px solid transparent;
  background-clip: content-box;
}
.app-shell .side-nav:hover::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .28); background-clip: content-box; }
.app-shell .side-nav::-webkit-scrollbar-thumb:hover,
.app-shell .side-nav::-webkit-scrollbar-thumb:active { background: rgba(255, 255, 255, .45); background-clip: content-box; }
@supports not selector(::-webkit-scrollbar) {
  .app-shell .side-nav { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .28) transparent; }
}
/* Coluna única de navegação: sem rótulo de grupo e sem separador — o agrupamento
   "Departamentos"/"Ferramentas" saiu (ver shell.js). O que organiza a lista agora
   é a ORDEM (fixos no topo, alfabética no meio), não uma divisória. */
.app-shell .side-group { display: flex; flex-direction: column; gap: 2px; }
.app-shell .side-group a,
.app-shell .side-group button {
  display: flex; align-items: center; gap: 11px;
  width: 100%; text-align: left;
  background: transparent; border: 1px solid transparent;
  color: rgba(255, 255, 255, .62);
  padding: 9px 11px; border-radius: var(--raio-card);
  font-family: inherit; font-size: 13.5px; text-decoration: none;
  transition: background .15s, color .15s;
}
.app-shell .side-group a:hover,
.app-shell .side-group button:hover { color: #fff; background: rgba(255, 255, 255, .07); }
/* Vale para <button> (departamentos no portal) E <a> (ferramentas, e os
   departamentos fora do portal, que viram link para index.html#slug). */
.app-shell .side-group button.active,
.app-shell .side-group a.active { color: #fff; background: var(--terra); font-weight: 600; }
.app-shell .side-group .ic { flex: 0 0 auto; width: 17px; text-align: center; opacity: .9; }
.app-shell .side-group .badge-sens { margin-left: auto; }

/* Rodapé: avatar + identidade (clicável, abre o popover de perfil) + sair.
   Sem imagem de fundo: o banner atrás do texto disputava com o nome. Ele vive
   no popover (.perfil-pop), onde tem espaço próprio. */
.app-shell .side-user {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 4px;
  padding: 10px 10px 12px;
  border-top: 1px solid rgba(255, 255, 255, .08);
}
/* O card de identidade é um botão; "sair" fica fora dele. Um alvo de clique só
   para dois destinos diferentes é como se perde uma sessão sem querer. */
.app-shell .side-perfil {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 10px; text-align: left;
  background: transparent; border: none; color: inherit;
  padding: 4px; border-radius: var(--raio-card);
  font-family: inherit;
  transition: background .15s;
}
.app-shell .side-perfil:hover { background: rgba(255, 255, 255, .07); }
.app-shell .side-avatar {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  background: var(--terra); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
}
/* A foto vem recortada em quadrado pelo modal; `cover` é rede de segurança
   para uma imagem antiga que tenha entrado com outra proporção. */
.app-shell .side-avatar-img { object-fit: cover; background: var(--terra); }
.app-shell .side-user-txt { flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.app-shell .side-user-txt strong,
.app-shell .side-user-txt span {
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Recado: terceira linha, só quando existe. Mais apagado que o cargo — é
   contexto ("volto dia 20"), não identidade. */
.app-shell .side-recado {
  margin-top: 2px;
  font-size: 11px; font-style: italic; color: rgba(255, 255, 255, .38);
}
.app-shell .side-user-txt strong { font-size: 13px; font-weight: 600; color: #fff; }
.app-shell .side-user-txt span { font-size: 11px; color: rgba(255, 255, 255, .45); }
.app-shell .side-logout {
  flex: 0 0 auto; background: transparent; border: none;
  color: rgba(255, 255, 255, .5); padding: 7px; border-radius: var(--raio); font-size: 14px;
}
.app-shell .side-logout:hover { color: #fff; background: rgba(255, 255, 255, .09); }

/* ---------- Coluna principal ---------- */
.app-shell .app-main {
  position: relative;
  flex: 1 1 auto; min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}

/* Topbar clara (a escura continua valendo em admin/agenda) */
.app-shell .topbar {
  gap: 14px;
  padding: 11px 22px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--border);
}
.app-shell .page-title { flex: 0 0 auto; font-size: 21px; font-weight: 600; letter-spacing: .2px; }

.app-shell .topsearch {
  position: relative; display: flex; align-items: center;
  flex: 1 1 auto; max-width: 520px;
}
/* `> i`: só a lupa do campo. O dropdown de resultados é filho de .topsearch,
   e sem o `>` esta regra prendia TODO ícone dele em position:absolute left:13px
   — os ícones saíam de dentro do próprio chip. */
.app-shell .topsearch > i {
  position: absolute; left: 13px; pointer-events: none;
  color: var(--texto-fraco); font-size: 13px;
}
.app-shell .topsearch input {
  width: 100%; font-family: inherit; font-size: 13.5px; color: var(--text);
  background: var(--bg-pill); border: 1px solid var(--border);
  border-radius: 999px; padding: 9px 14px 9px 36px;
}
.app-shell .topsearch input::placeholder { color: var(--texto-fraco); }
.app-shell .topsearch input:disabled { cursor: not-allowed; opacity: .7; }

.app-shell .ta-btn {
  background: transparent; color: var(--text-muted);
  border: 1px solid transparent; padding: 7px 11px;
}
.app-shell .ta-btn:hover { background: var(--bg-pill); border-color: var(--border); color: var(--text); }
/* Alternador de tema só com o ícone. O rótulo ("Escuro"/"Claro") é um nó de texto
   solto criado por theme.js — compartilhado com admin/agenda, onde ele DEVE
   aparecer. Zeramos a fonte do botão (some o texto) e devolvemos tamanho ao <i>,
   em vez de mexer no JS comum. O nome continua acessível: theme.js mantém
   `title` e `aria-label` no botão. */
.app-shell .ta-btn[data-theme-toggle] { font-size: 0; padding: 7px 9px; }
.app-shell .ta-btn[data-theme-toggle] i { font-size: 14px; }

/* Botão de menu + scrim do off-canvas. O botão vale nas duas larguras, com
   significados diferentes: <=900px abre/fecha a sidebar por cima do conteúdo;
   acima disso recolhe/expande o trilho de ícones (ver bloco abaixo). */
.app-shell .side-toggle {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  background: transparent; border: 1px solid var(--border); color: var(--text);
  border-radius: var(--raio); padding: 7px 10px; font-size: 14px;
}
.app-shell .side-toggle:hover { background: var(--bg-pill); color: var(--text); }
.app-shell .side-scrim { display: none; }

/* ---------- Sidebar recolhida: trilho de ícones (só no desktop) ----------
   Recolher não é esconder: os departamentos continuam a UM clique, o que evita
   o vai-e-vem de reabrir o menu a cada troca de aba. Só o texto sai; o `title`
   de cada item (posto por shell.js) mantém o nome acessível no hover.
   Escopado em min-width: no mobile a sidebar já é off-canvas — lá o mesmo botão
   abre/fecha a versão completa e o trilho não deve valer. */
@media (min-width: 901px) {
  .app-shell.side-rail .sidebar { flex-basis: 64px; width: 64px; }
  .app-shell.side-rail .side-brand { justify-content: center; padding: 14px 0; }
  .app-shell.side-rail .side-brand .brand-txt { display: none; }

  .app-shell.side-rail .side-nav { padding: 12px 8px; }
  .app-shell.side-rail .side-group a,
  .app-shell.side-rail .side-group button { justify-content: center; gap: 0; padding: 10px 0; }
  /* `:not(.ic)` preserva o chip do ícone — some só o rótulo e o selo "sensível". */
  .app-shell.side-rail .side-group a > span:not(.ic),
  .app-shell.side-rail .side-group button > span:not(.ic) { display: none; }

  .app-shell.side-rail .side-user { flex-direction: column; gap: 6px; padding: 12px 8px; }
  .app-shell.side-rail .side-perfil { flex: 0 0 auto; justify-content: center; }
  .app-shell.side-rail .side-user-txt { display: none; }
}

/* ---------- Subbar: voltar + período à esquerda, seletor de empresa à direita --
   Tudo na MESMA linha, encostado à esquerda: o "← Departamento" e o período são
   lidos em sequência, e separá-los pelas pontas da tela faria o olho atravessar
   a régua inteira à toa. Quem vai para a direita é só o seletor de empresa, pelo
   `margin-left: auto` dele. */
.app-shell .subbar {
  align-items: flex-end;
  justify-content: flex-start;
  flex-wrap: nowrap;          /* mesma linha: quem falta espaço é quem rola */
  gap: 18px;
  padding: 13px 22px 0;
  border-bottom: 1px solid var(--border);
  /* O `nowrap` acima só promete a linha única; sem isto o excesso era cortado
     em vez de rolar — e o seletor de empresa saía da tela em monitor menor
     quando o período ganhou os campos de data. */
  overflow-x: auto;
  scrollbar-width: thin;
}
/* O período não encolhe: o botão mostra o período inteiro por extenso. */
.app-shell .subbar .period { flex: 0 0 auto; padding-bottom: 11px; }
/* Mesmo recuo do período: com `align-items: flex-end` na subbar, sem este
   padding o "voltar" desceria 11px e ficaria desalinhado do seletor de meses. */
.app-shell .subbar-voltar { padding-bottom: 11px; }
.app-shell .nnper-trigger { padding: 6px 11px; font-size: 12.5px; }
.app-shell .period-label { font-size: 10px; }
.app-shell .view { padding: 16px 22px 18px; }

/* ---------- KPI card: rótulo + ícone no topo, valor grande, fonte no rodapé ---------- */
.app-shell .kpi {
  display: flex; flex-direction: column;
  text-align: left; padding: 14px 16px; border-radius: 10px;
}
.app-shell .kpi-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.app-shell .kpi .kpi-label {
  display: block; text-align: left; margin: 0; min-height: 0;
  font-size: 12.5px; line-height: 1.3;
}
.app-shell .kpi .kpi-ic {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px;
}
.app-shell .kpi .kpi-value { margin-top: 10px; font-size: clamp(22px, 2.6vh, 30px); }
.app-shell .kpi .kpi-nota {
  display: flex; align-items: center; gap: 6px;
  margin-top: auto; padding-top: 10px; font-size: 10px;
}
.app-shell .kpi .kpi-nota::before {
  content: ''; flex: 0 0 auto;
  width: 6px; height: 6px; border-radius: 50%; background: var(--terra-texto-hover);
}
.app-shell .kpi .kpi-nota span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Painel: cabeçalho à esquerda com ícone em chip + divisória ---------- */
.app-shell .panel { padding: 0; border-radius: 10px; }
.app-shell .panel-head {
  justify-content: flex-start; gap: 10px;
  margin: 0; padding: 11px 15px;
  border-bottom: 1px solid var(--border);
}
.app-shell .panel-head .ic {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center;
}
.app-shell .panel-head .ic i { font-size: 13px; }
.app-shell .panel-head h3 { text-align: left; font-size: 14.5px; }
/* Slot de ações à direita do título do card (navegação, filtro do card…). */
.app-shell .panel-head .panel-acoes {
  margin-left: auto; display: flex; align-items: center; gap: 6px; flex: 0 0 auto;
}
.app-shell .panel-body { padding: 12px 15px 14px; }

/* "Aguardando integração" + atalho para configurar a fonte (só admin) */
.app-shell .panel-body .pendente { gap: 10px; border-radius: 10px; }
.app-shell .panel-body .pendente .pend-ic {
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--bg-pill); color: var(--texto-fraco);
  display: inline-flex; align-items: center; justify-content: center;
}
.app-shell .panel-body .pendente .pend-ic i { font-size: 17px; opacity: 1; }
.app-shell .pend-cfg {
  margin-top: 4px; display: inline-flex; align-items: center; gap: 7px;
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 7px 15px; font-family: inherit; font-size: 12.5px; text-decoration: none;
}
.app-shell .pend-cfg:hover { color: var(--terra-texto); border-color: var(--terra); background: var(--terra-bg); }

/* Voltar + período + seletor de empresa na mesma linha. Em tela mais estreita o
   rótulo "Período" é o primeiro (e único) a cair: é o elemento mais dispensável
   do conjunto — o ícone de calendário e o texto do botão já dizem o que aquilo é. */
@media (max-width: 1500px) {
  .app-shell .period-label { display: none; }
}

/* ---------- Responsivo: sidebar vira off-canvas ---------- */
@media (max-width: 900px) {
  .app-shell .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0;
    transform: translateX(-100%);
    transition: transform .22s ease;
  }
  .app-shell .sidebar.open { transform: none; }
  .app-shell .side-scrim {
    display: block; position: fixed; inset: 0;
    background: rgba(0, 0, 0, .45); z-index: 25;
  }
  .app-shell .app-main { overflow: visible; }
  .app-shell .topbar { position: sticky; top: 0; z-index: 20; }
  .app-shell .topsearch { display: none; }
  .app-shell .subbar, .app-shell .view { padding-left: 14px; padding-right: 14px; }
  /* Sem espaço horizontal: as abas quebram para a linha de baixo, à esquerda. */
  .app-shell .subbar { flex-wrap: wrap; gap: 0 14px; }
}

/* ---------- Admin dentro do shell (admin.html tem body.app-shell) ---------- */
/* Abas da administração ganham o mesmo ritmo das abas de ferramenta do portal:
   régua inferior de ponta a ponta e respiro lateral igual ao do conteúdo. */
.app-shell .admin-tabs {
  flex: 0 0 auto;
  margin: 0; padding: 0 22px; gap: 2px;
  flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin;
}
.app-shell .admin-tabs button { padding: 11px 14px; font-size: 13.5px; white-space: nowrap; }

/* Sub-abas do módulo (hoje: os painéis de BI dentro do card KPIs; app.js
   `pintarSubabas`). É a régua sublinhada do `.admin-tabs`, logo abaixo da
   subbar; rola na horizontal quando falta largura. */
/* `.admin-tabs` declara display:flex, que venceria o atributo hidden. */
.app-shell .subabas[hidden] { display: none; }
/* Com a régua à vista, o filete da subbar sairia duplicado logo acima do dela. */
.app-shell .subbar:has(+ .subabas:not([hidden])) { border-bottom: 0; }
.app-shell .subabas button i.subaba-sens { margin: 0 0 0 2px; font-size: 11px; opacity: .7; }
.app-shell .admin-wrap { padding: 18px 22px 22px; }

/* Cabeçalho de seção: chip do ícone + título + subtítulo, ação à direita. */
.app-shell .admin-head { align-items: flex-start; gap: 12px; margin-bottom: 16px; }
.app-shell .admin-head .ah-ic,
.login-body .admin-head .ah-ic {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 10px;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 15px;
}
.app-shell .admin-head .ah-txt,
.login-body .admin-head .ah-txt { flex: 1 1 auto; min-width: 0; }
.app-shell .admin-head h2 { font-size: 19px; line-height: 1.25; }
.app-shell .admin-head .ah-sub,
.login-body .admin-head .ah-sub { margin: 2px 0 0; color: var(--text-muted); font-size: 12.5px; }
/* O ícone agora vive no chip — o <i> herdado de `.admin-head h2 i` sai de cena. */
.app-shell .admin-head h2 i { display: none; }

/* Cartões de KPI e painéis do admin acompanham o raio dos cards do portal. */
.app-shell .ind-kpi, .app-shell .ind-panel,
.app-shell .table-wrap, .app-shell .form-panel,
.login-body .form-panel { border-radius: 10px; }
.app-shell .ind-panel h3 { display: flex; align-items: center; gap: 9px; }
.app-shell .ind-panel h3 i {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px;
}
/* Card de importação: título e selo de status na MESMA linha. */
.app-shell .ek-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.app-shell .ek-head h3 { margin: 0; }
.app-shell .ek-head .ek-status { margin: 0; }

/* Importar e-Kontroll: sub-abas por DEPARTAMENTO. São ~45 indicadores no total,
   então mostrar tudo de uma vez viraria rolagem longa — a pessoa escolhe o
   departamento e vê só os cards dele.
   Estilo de PÍLULA e não o sublinhado do `.admin-tabs`: as abas do admin ficam
   logo acima, e duas barras sublinhadas iguais empilhadas não deixariam clara a
   hierarquia. */
.app-shell .ek-nav {
  display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 16px;
}
.app-shell .ek-nav button {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--bg-pill); color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 8px 14px; font-size: 13px; cursor: pointer;
}
.app-shell .ek-nav button:hover { color: var(--text); }
.app-shell .ek-nav button.active {
  color: #fff; background: var(--bg-pill-active); border-color: transparent; font-weight: 600;
}
.app-shell .ek-nav button .ic { opacity: .85; }
/* Contagem de indicadores do departamento, discreta dentro da pílula. */
.app-shell .ek-nav-qtd {
  background: rgba(0, 0, 0, .12); border-radius: 999px;
  padding: 1px 7px; font-size: 11px; font-weight: 600;
}
.app-shell .ek-nav button.active .ek-nav-qtd { background: rgba(255, 255, 255, .22); }
/* No tema escuro a pílula inativa já é escura: o contraste tem que vir do claro. */
html.dark .app-shell .ek-nav-qtd { background: rgba(255, 255, 255, .12); }
.app-shell .ek-card { margin-bottom: 12px; }
/* Aba esperada dentro da Pasta Geral — referência, fica em segundo plano. */
.app-shell .ek-abas { margin: 2px 0 0; color: var(--text-muted); font-size: 11.5px; }
.app-shell .ek-abas code {
  background: var(--bg-suave, rgba(0,0,0,.04)); border-radius: 4px; padding: 1px 5px; font-size: 11px;
}
/* Ambiguidade que o time da NN precisa resolver antes de confiar no número. */
.app-shell .ek-nota {
  margin: 8px 0 0; padding: 7px 10px; border-radius: 8px;
  background: var(--terra-bg); color: var(--terra-texto); font-size: 12px; line-height: 1.45;
}
.app-shell .ek-selo {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; white-space: nowrap;
}
.app-shell .ek-selo-cli  { background: var(--terra-bg); color: var(--terra-texto); }
.app-shell .ek-selo-sens { background: rgba(46,116,116,.12); color: var(--verde-medio); }
/* KPI de Indicadores: rótulo + chip do ícone no topo (igual aos KPIs do portal). */
.app-shell .ind-kpi-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.app-shell .ind-kpi-top .ind-kpi-label { margin: 0; }
.app-shell .ind-kpi-ic {
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 13px;
}
.app-shell .ind-kpi .ind-kpi-val { margin-top: 8px; }

/* ---------- Busca de navegação (Ctrl/Cmd+K) ---------- */
.app-shell .topsearch input:not(:disabled) { cursor: text; }
.app-shell .topsearch input:not(:disabled):focus { border-color: var(--terra-foco); outline: none; }
/* Atalho impresso no campo: descobre a tecla sem precisar de tour. */
.app-shell .gs-kbd {
  position: absolute; right: 10px; pointer-events: none;
  font-family: var(--font); font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
  color: var(--texto-fraco); background: var(--bg-panel);
  border: 1px solid var(--border); border-radius: 5px; padding: 2px 6px;
}
.app-shell .topsearch input:disabled ~ .gs-kbd { display: none; }

.app-shell .gs-pop {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 60;
  max-height: 60vh; overflow-y: auto;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 8px 28px rgba(0, 0, 0, .14); padding: 6px;
}
html.dark .app-shell .gs-pop { box-shadow: 0 8px 28px rgba(0, 0, 0, .5); }
.app-shell .gs-grupo + .gs-grupo { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--border); }
.app-shell .gs-grupo h4 {
  margin: 0; padding: 7px 10px 5px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--texto-fraco);
}
.app-shell .gs-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: transparent; border: 0; border-radius: 7px;
  padding: 8px 10px; font: inherit; cursor: pointer;
}
/* `.on` (teclado) e hover compartilham o realce: navegar por seta e por mouse
   dá exatamente o mesmo retorno visual. */
.app-shell .gs-item.on, .app-shell .gs-item:hover { background: var(--bg-pill); }
.app-shell .gs-item .gs-ic {
  width: 28px; height: 28px; border-radius: 8px; flex: 0 0 auto;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 12px;
}
.app-shell .gs-txt { flex: 1 1 auto; min-width: 0; }
.app-shell .gs-txt strong {
  display: block; font-size: 13.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* O caminho é o que responde "onde isso fica" — some junto com o resultado. */
.app-shell .gs-path {
  display: block; font-size: 11.5px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.app-shell .gs-item > i { flex: 0 0 auto; font-size: 11px; color: var(--texto-fraco); opacity: 0; }
.app-shell .gs-item.on > i { opacity: 1; color: var(--terra-icone); }
.app-shell .gs-vazio { margin: 0; padding: 16px 12px; font-size: 13px; color: var(--text-muted); text-align: center; }

@media (max-width: 900px) {
  /* A busca reaparece no celular: é o caminho mais curto para qualquer tela. */
  .app-shell .topsearch { display: flex; }
  .app-shell .gs-kbd { display: none; }
  .app-shell .page-title { display: none; }
}

/* ---------- Caixa de notificações (sino do topo) ---------- */
.app-shell .nt-wrap { position: relative; display: inline-flex; }
.app-shell .nt-btn { position: relative; padding: 7px 10px; }
/* Contador só existe quando há não-lida: ponto vermelho permanente vira ruído
   que o time aprende a ignorar. */
.app-shell .nt-badge {
  position: absolute; top: 1px; right: 2px; min-width: 15px; height: 15px;
  padding: 0 4px; border-radius: 999px;
  background: var(--negativo); color: #fff;
  font-size: 9.5px; font-weight: 700; line-height: 15px; text-align: center;
}
.app-shell .nt-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  width: 340px; max-height: 62vh; overflow-y: auto;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 8px 28px rgba(0, 0, 0, .14);
}
html.dark .app-shell .nt-pop { box-shadow: 0 8px 28px rgba(0, 0, 0, .5); }
.app-shell .nt-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px; border-bottom: 1px solid var(--border);
}
.app-shell .nt-head h4 { margin: 0; font-size: 13.5px; font-weight: 600; color: var(--text); }
.app-shell .nt-todas {
  background: transparent; border: 0; cursor: pointer;
  color: var(--terra-texto); font: inherit; font-size: 11.5px; font-weight: 600; padding: 0;
}
.app-shell .nt-todas:hover { text-decoration: underline; }
.app-shell .nt-item {
  display: flex; align-items: flex-start; gap: 10px; width: 100%; text-align: left;
  background: transparent; border: 0; border-bottom: 1px solid var(--border);
  padding: 11px 14px; font: inherit; cursor: pointer;
}
.app-shell .nt-lista .nt-item:last-child { border-bottom: 0; }
.app-shell .nt-item:hover { background: var(--bg-pill); }
/* Não-lida: fundo tênue + barra na borda — legível também para quem não
   distingue bem a diferença de tom. */
.app-shell .nt-item.nova { background: var(--terra-bg); box-shadow: inset 3px 0 0 var(--terra); }
.app-shell .nt-item.nova:hover { filter: brightness(.98); }
.app-shell .nt-item .nt-ic {
  width: 28px; height: 28px; border-radius: 8px; flex: 0 0 auto; margin-top: 1px;
  background: var(--bg-pill); color: var(--text-muted);
  display: inline-flex; align-items: center; justify-content: center; font-size: 12px;
}
.app-shell .nt-item.nova .nt-ic { background: var(--branco); color: var(--terra-icone); }
.app-shell .nt-txt { flex: 1 1 auto; min-width: 0; }
.app-shell .nt-txt strong { display: block; font-size: 13px; font-weight: 600; color: var(--text); line-height: 1.35; }
.app-shell .nt-corpo { display: block; font-size: 12px; color: var(--text-muted); line-height: 1.4; margin-top: 2px; }
.app-shell .nt-meta { display: block; font-size: 11px; color: var(--texto-fraco); margin-top: 3px; }
.app-shell .nt-vazio { margin: 0; padding: 26px 14px; text-align: center; font-size: 13px; color: var(--text-muted); }
/* Lembrete de reunião fixado no topo da caixa. NÃO é notificação: não conta
   como não-lida, não sai com "marcar todas como lidas" e não é clicável como
   as outras — daí o cursor normal e o hover que não muda nada. */
.app-shell .nt-item.nt-lem { cursor: default; align-items: center; background: var(--verde-bg); }
.app-shell .nt-item.nt-lem:hover { background: var(--verde-bg); }
.app-shell .nt-item.nt-lem .nt-ic { background: var(--branco); color: var(--verde-medio); }
.app-shell .nt-lem-btn {
  flex: 0 0 auto; align-self: center;
  background: var(--bg-pill-active); color: #fff;
  padding: 5px 10px; border-radius: var(--raio);
  font-size: 11.5px; font-weight: 600; text-decoration: none; white-space: nowrap;
}
.app-shell .nt-lem-btn:hover { filter: brightness(1.08); }
/* Topo da caixa: título + alternador ficam à vista enquanto a lista rola —
   quem desce trinta avisos não pode perder o caminho para a outra vista. */
.app-shell .nt-topo {
  position: sticky; top: 0; z-index: 1;
  background: var(--bg-panel); border-bottom: 1px solid var(--border);
}
.app-shell .nt-topo .nt-head { border-bottom: 0; padding-bottom: 8px; }
/* "Para você | No portal": o mesmo desenho do alternador de visão do Workflow
   (.wf-views), que mora num CSS que o admin e a agenda não carregam. */
.app-shell .nt-vistas {
  display: flex; gap: 2px; margin: 0 14px 10px; padding: 2px;
  background: var(--bg-app); border-radius: var(--raio);
}
.app-shell .nt-vistas button {
  flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 0; background: none; padding: 6px 10px; border-radius: 3px; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--text-muted);
}
.app-shell .nt-vistas button.on { background: var(--bg-panel); color: var(--text); font-weight: 600; box-shadow: var(--sombra); }
/* Não-lidas no alternador: terracota, a mesma cor da não-lida na lista. */
.app-shell .nt-conta {
  min-width: 16px; padding: 0 5px; border-radius: 999px;
  background: var(--terra-bg); color: var(--terra-texto);
  font-size: 10.5px; font-weight: 700; line-height: 16px; text-align: center;
}
.app-shell .nt-filtro {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  font-size: 12px; color: var(--text-muted);
}
.app-shell .nt-filtro select {
  flex: 1 1 auto; min-width: 0; padding: 5px 8px;
  background: var(--bg-pill); color: var(--text); font: inherit; font-size: 12.5px;
  border: 1px solid var(--border); border-radius: var(--radius);
}
.app-shell .nt-filtro select:focus { border-color: var(--terra-foco); outline: none; }
/* Mudança no portal é contexto, não chamado: não abre nada, então não finge
   ser clicável (sem cursor de mão, sem hover). */
.app-shell .nt-item.nt-mud { cursor: default; }
.app-shell .nt-item.nt-mud:hover { background: transparent; }
.app-shell .nt-mais {
  display: block; width: calc(100% - 28px); margin: 8px 14px 12px; padding: 7px 10px;
  background: transparent; border: 1px solid var(--border); border-radius: var(--raio);
  color: var(--text); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.app-shell .nt-mais:hover { background: var(--bg-pill); }
.app-shell .nt-mais[aria-busy="true"] { color: var(--text-muted); cursor: progress; }

@media (max-width: 900px) {
  .app-shell .nt-pop { width: min(340px, calc(100vw - 24px)); right: -8px; }
}
/* Lista de avisos publicados (admin) */
.app-shell .av-item {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 11px 2px; border-bottom: 1px solid var(--border);
}
.app-shell #avLista .av-item:last-child { border-bottom: 0; }
.app-shell .av-txt { flex: 1 1 auto; min-width: 0; }
.app-shell .av-txt strong { display: block; font-size: 13.5px; color: var(--text); }
.app-shell .av-corpo { display: block; font-size: 12.5px; color: var(--text-muted); margin-top: 2px; }
.app-shell .av-meta { display: block; font-size: 11px; color: var(--texto-fraco); margin-top: 4px; }
.app-shell .av-rm { flex: 0 0 auto; }

/* ============================================================================
   RELATÓRIO EM PDF
   O PDF é montado em assets/js/relatorio.js (jsPDF), a partir do descritor do
   dashboard — não é impressão da tela, então não depende de CSS. Aqui fica só
   a escolha das empresas que entram no relatório.
   ========================================================================= */

/* Escolha do que entra no relatório (abre no botão Relatório da topbar). */
.rel-pop {
  position: fixed; z-index: 95;
  width: 300px; max-width: calc(100vw - 24px);
  background: var(--bg-panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .14);
  font-size: 13px;
}
html.dark .rel-pop { box-shadow: 0 8px 28px rgba(0, 0, 0, .5); }
.rel-pop-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px; border-bottom: 1px solid var(--border);
}
.rel-pop-head strong { font-size: 13.5px; font-weight: 600; }
.rel-pop-todas {
  background: transparent; border: 0; padding: 0; cursor: pointer;
  color: var(--terra-texto); font: inherit; font-size: 11.5px; font-weight: 600;
}
.rel-pop-todas:hover { text-decoration: underline; }
.rel-pop-lista { display: flex; flex-direction: column; padding: 6px; max-height: 50vh; overflow-y: auto; }
.rel-pop-op {
  display: flex; align-items: center; gap: 10px;
  padding: 8px; border-radius: var(--radius); cursor: pointer;
}
.rel-pop-op:hover { background: var(--bg-pill); }
.rel-pop-op input { width: 16px; height: 16px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.rel-pop-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 14px; border-top: 1px solid var(--border);
}
.rel-pop-conta { color: var(--text-muted); font-size: 12px; }
.rel-pop-gerar { padding: 7px 14px; font-size: 13px; }
.rel-pop-gerar:disabled { opacity: .45; cursor: not-allowed; }
/* Aviso do Cadastro (relatório pedido sem cliente): texto e uma ação à direita. */
.rel-pop-texto { margin: 0; padding: 12px 14px; color: var(--text); font-size: 12.5px; line-height: 1.5; }
.rel-pop-foot-fim { justify-content: flex-end; }

/* Impressão da TELA pelo navegador (Ctrl+P): o relatório de verdade é o PDF do
   botão Relatório; isto só evita que a navegação vá para o papel. */
@media print {
  .sidebar, .side-scrim, .side-toggle, .topbar, .subbar, .crumb,
  .panel-zoom-overlay, .pend-cfg, .layout-bar, .nia-panel, .rel-pop { display: none !important; }
  .panel-head .panel-zoom { cursor: default; }

  html, body { background: #fff !important; }
  body.app-shell { display: block !important; }
  .app-main { display: block !important; height: auto !important; overflow: visible !important; }

  @page { size: A4 landscape; margin: 12mm 10mm; }
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
}

/* ============================================================================
   COBRANÇA (sub-abas do Financeiro)
   Port do modelo de referência para o DNA do portal: nada de paleta própria —
   tudo sai das variáveis do tema, então claro/escuro funcionam de graça.
   ========================================================================= */
.cb-wrap { display: flex; flex-direction: column; gap: 14px; }

/* ---- filtros ---- */
.cb-filtros { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.cb-fl { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-muted); }
.cb-fl select { font-size: 13px; padding: 6px 10px; }
.cb-busca { position: relative; }
.cb-busca i { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-muted); font-size: 12px; }
.cb-busca input {
  padding: 7px 10px 7px 30px; width: 260px; font-size: 13px;
  background: var(--bg-panel); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text);
}
.cb-busca input:focus { border-color: var(--terra-foco); outline: none; }
.cb-resumo { margin-left: auto; display: flex; align-items: center; gap: 10px; font-size: 12.5px; color: var(--text-muted); }
.cb-resumo strong { color: var(--text); }
.cb-sep { width: 1px; height: 12px; background: var(--border); }
.cb-alerta strong { color: var(--danger); }

/* ---- tabela ---- */
.cb-tabela-card { background: var(--bg-panel); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.cb-scroll { overflow-x: auto; }
.cb-tabela { width: 100%; border-collapse: collapse; min-width: 860px; }
.cb-tabela thead tr { background: var(--bg-pill); border-bottom: 1px solid var(--border); }
.cb-tabela th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-muted); font-weight: 600; padding: 10px 12px; white-space: nowrap;
}
.cb-tabela td { padding: 11px 12px; border-bottom: 1px solid var(--border); vertical-align: top; font-size: 13px; }
.cb-tabela tbody tr:last-child td { border-bottom: none; }
.cb-tabela tbody tr { cursor: pointer; transition: background .12s; }
.cb-tabela tbody tr:hover { background: var(--bg-pill); }
.cb-tabela tbody tr:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: -2px; }
.cb-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cb-tabela th.cb-num { text-align: right; }
.cb-val { font-weight: 600; }
.cb-cli { font-weight: 500; }
.cb-sub { font-size: 11.5px; color: var(--text-muted); }
.cb-forte { color: var(--text); }
.cb-vazio { color: var(--text-muted); }
.cb-atraso { font-size: 11px; color: var(--danger); margin-top: 2px; }
.cb-trunc { max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-chev { color: var(--text-muted); width: 24px; }
.cb-empty { padding: 40px; text-align: center; color: var(--text-muted); }

/* ---- fila por cliente: linha do cliente + vencidos abertos logo abaixo ---- */
.cb-grupo td { vertical-align: middle; }
.cb-grupo .cb-chev i { transition: transform .15s; }
.cb-tabela tbody tr.cb-grupo[aria-expanded="true"] { background: var(--bg-pill); }
.cb-grupo[aria-expanded="true"] > td { border-bottom-color: transparent; }
.cb-grupo[aria-expanded="true"] .cb-chev i { transform: rotate(180deg); }
/* A linha que embrulha os títulos não é clicável: quem abre o detalhe são as
   linhas de dentro. `>` de propósito — a tabela interna também tem tr/td. */
.cb-tabela > tbody > tr.cb-subgrupo,
.cb-tabela > tbody > tr.cb-subgrupo:hover { cursor: default; background: var(--bg-pill); }
.cb-tabela > tbody > tr.cb-subgrupo > td { padding: 0 12px 12px 26px; }
.cb-sub-card { background: var(--bg-panel); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.cb-tabela.cb-tabela-sub { min-width: 0; }
.cb-tabela-sub thead tr { background: transparent; }

/* Situação: cor + PALAVRA (a cor nunca é o único sinal — daltonismo). */
.cb-badge {
  display: inline-block; border-radius: 999px; padding: 2px 10px;
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.cb-vencido { background: rgba(192, 57, 43, .12); color: var(--danger); }
.cb-hoje { background: var(--terra-bg); color: var(--terra-texto); }
.cb-avencer { background: var(--bg-pill); color: var(--text-muted); }
.cb-pago { background: rgba(47, 138, 91, .12); color: var(--positivo); }

/* ---- painel lateral de detalhe ---- */
.cb-overlay {
  position: fixed; inset: 0; z-index: 80;
  background: rgba(0, 42, 43, .45); display: flex; justify-content: flex-end;
}
.cb-painel {
  background: var(--bg); width: min(580px, 100%); height: 100%;
  overflow-y: auto; box-shadow: -8px 0 30px rgba(0, 0, 0, .22);
  display: flex; flex-direction: column;
}
.cb-painel-carregando { padding: 40px; text-align: center; color: var(--text-muted); }
.cb-painel-topo {
  position: sticky; top: 0; z-index: 2;
  background: var(--verde-escuro, #002a2b); color: #fff;
  padding: 16px 20px; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
}
.cb-painel-topo h2 { margin: 0; font-size: 17px; font-weight: 600; }
.cb-painel-topo .cb-sub { color: rgba(255, 255, 255, .72); }
.cb-fechar {
  background: none; border: none; color: #fff; cursor: pointer;
  padding: 5px 7px; border-radius: var(--radius); font-size: 17px; line-height: 1;
}
.cb-fechar:hover { background: rgba(255, 255, 255, .14); }
.cb-painel-corpo { padding: 18px 20px 28px; display: flex; flex-direction: column; gap: 22px; }

.cb-boxes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.cb-box {
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 10px 12px; display: flex; flex-direction: column; gap: 3px;
}
.cb-box strong { font-size: 14px; }
.cb-sec { margin: 0; font-size: 13.5px; font-weight: 600; }
.cb-sec-nota { margin: 2px 0 9px; }

.cb-dl { margin: 0; display: grid; gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.cb-dl > div { background: var(--bg-panel); display: flex; justify-content: space-between; padding: 9px 12px; font-size: 13px; }
.cb-dl dt { color: var(--text-muted); }
.cb-dl dd { margin: 0; font-weight: 500; }

/* histórico */
.cb-hist-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.cb-nada { padding: 4px 0; }
.cb-hist { display: flex; gap: 10px; }
.cb-hist-ic {
  width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0; margin-top: 2px;
  display: flex; align-items: center; justify-content: center;
  background: var(--terra-icone-bg); color: var(--terra-icone); font-size: 12px;
}
.cb-hist-card { flex: 1; background: var(--bg-panel); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
.cb-hist-top { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 12.5px; }
.cb-hist-nota { margin: 5px 0 0; font-size: 13px; white-space: pre-wrap; }
.cb-hist-pe { margin-top: 7px; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.cb-tag { font-size: 11.5px; background: var(--bg-pill); border-radius: 4px; padding: 2px 8px; }
.cb-autor { margin-left: auto; }

/* formulário */
.cb-form { display: flex; flex-direction: column; gap: 11px; background: var(--bg-panel); border: 1px solid var(--border); border-radius: 8px; padding: 14px; }
.cb-form label { display: block; font-size: 12px; color: var(--text-muted); }
.cb-form input, .cb-form select, .cb-form textarea {
  width: 100%; margin-top: 4px; font-size: 13px; padding: 7px 10px;
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); color: var(--text);
}
.cb-form textarea { resize: vertical; line-height: 1.45; }
.cb-form input:focus, .cb-form select:focus, .cb-form textarea:focus { border-color: var(--terra-foco); outline: none; }
.cb-form-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cb-form-msg { font-size: 12px; color: var(--text-muted); }
.cb-btn {
  background: var(--accent); color: #fff; border: none; border-radius: var(--radius);
  padding: 10px; font-size: 13.5px; font-weight: 600; cursor: pointer; font-family: inherit;
}
.cb-btn:hover { background: var(--terra-acao-hover); }
.cb-btn:disabled { opacity: .6; cursor: default; }

@media (max-width: 720px) {
  .cb-boxes, .cb-form-2 { grid-template-columns: 1fr; }
  .cb-busca input { width: 100%; }
  .cb-resumo { margin-left: 0; }
}
/* O painel lateral não vai para o relatório impresso. */
@media print { .cb-overlay { display: none !important; } }

/* ===================== NIA (aba do assistente) =====================
   Chat + coluna de apoio. Duas colunas no desktop (conversa dominante, apoio
   estreito); empilha no estreito. A conversa tem altura própria e rola por
   dentro — a `.view` do portal não rola, então a lista precisa ser o container
   de scroll, senão a caixa de envio sairia da tela. */
.cp-cols {
  display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--gap);
  /* `.view` é um flex column: sem o flex/min-height a grade encolheria para a
     altura do conteúdo e a caixa de envio subiria para o meio da tela. */
  flex: 1 1 auto; min-height: 0;
}
.cp-chat { padding: 0; min-height: 380px; }
.cp-lado { display: flex; flex-direction: column; gap: var(--gap); align-content: start; min-height: 0; overflow-y: auto; }

.cp-lista { flex: 1 1 auto; overflow-y: auto; padding: 18px 18px 6px; display: flex; flex-direction: column; gap: 16px; }

/* Estado vazio: convite, não erro. */
.cp-vazio { margin: auto; text-align: center; max-width: 380px; padding: 20px; }
.cp-vazio .nia-logo { --nia-logo: 64px; }
.cp-vazio-t { margin: 12px 0 4px; font-size: 16px; font-weight: 600; }
.cp-vazio-s { margin: 0; font-size: 13px; color: var(--text-muted); line-height: 1.5; }

/* Perguntas frequentes do estado vazio. Texto alinhado à esquerda (a lista é
   lida, não admirada); o chip escolhido é o único elemento em cor. */
.cp-faq { margin-top: 18px; text-align: left; }
.cp-faq-t {
  margin: 0 0 8px; font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-muted);
}
.cp-mods { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.cp-mod {
  border: 1px solid var(--border); background: var(--bg-panel); color: var(--text-muted);
  border-radius: 999px; padding: 4px 11px; font: inherit; font-size: 12px; cursor: pointer;
}
.cp-mod:hover { color: var(--text); border-color: var(--text-muted); }
.cp-mod.on { background: var(--terra-bg); border-color: transparent; color: var(--terra-texto); font-weight: 600; }
.cp-faq-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.cp-faq-lista .cp-sug-btn { width: 100%; }
.cp-faq-dica { margin: 9px 0 0; font-size: 11.5px; color: var(--text-muted); }

/* Dia da conversa: rótulo à esquerda e um filete até a borda. */
.cp-dia {
  display: flex; align-items: center; gap: 10px; margin: 2px 0 -4px;
  font-size: 11px; font-weight: 600; color: var(--text-muted);
}
.cp-dia::after { content: ''; flex: 1; border-top: 1px solid var(--border); }

/* Falha de um envio: dita na conversa, junto da pergunta que falhou. */
.cp-sistema {
  margin: -6px 0 0 38px; font-size: 12px; line-height: 1.45; color: var(--terra-texto);
}
.cp-sistema i { margin-right: 4px; }

/* Bolhas. A do assistente vem em superfície neutra e a do usuário no teal da
   marca: uma cor por papel, consistente com o resto do portal. */
.cp-msg { display: flex; gap: 10px; align-items: flex-start; }
.cp-user { flex-direction: row-reverse; }
.cp-ava {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; margin-top: 2px;
  display: flex; align-items: center; justify-content: center; font-size: 12px;
  background: var(--verde-bg); color: var(--verde-medio);
}
.cp-user .cp-ava { background: var(--terra-bg); color: var(--terra-texto); }
/* Foto de perfil no lugar do ícone: mesmo círculo de 28px, imagem recortada. */
.cp-ava-img { object-fit: cover; }
.cp-ava-txt { font-size: 10px; font-weight: 600; letter-spacing: .3px; }
.cp-balao {
  max-width: min(85%, 640px);
  background: var(--bg-panel-soft); border: 1px solid var(--border);
  border-radius: 10px; padding: 9px 13px;
}
.cp-user .cp-balao { background: var(--verde); border-color: var(--verde); color: #fff; }
.cp-quem { display: block; font-size: 11px; font-weight: 600; opacity: .7; margin-bottom: 3px; }
.cp-txt { font-size: 13.5px; line-height: 1.55; }
.cp-txt p { margin: 0 0 8px; }
.cp-txt p:last-child { margin-bottom: 0; }
.cp-txt ul, .cp-txt ol { margin: 0 0 8px; padding-left: 20px; }
.cp-txt li { margin-bottom: 3px; }
.cp-txt strong { font-weight: 600; }

/* "pensando": três pontos, sem spinner girando — o resto do portal não anima. */
.cp-dots { display: inline-flex; gap: 4px; padding: 3px 0; }
.cp-dots i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--text-muted);
  animation: cp-pulso 1.1s infinite ease-in-out;
}
.cp-dots i:nth-child(2) { animation-delay: .18s; }
.cp-dots i:nth-child(3) { animation-delay: .36s; }
@keyframes cp-pulso { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .cp-dots i { animation: none; opacity: .6; } }

.cp-alerta {
  margin: 9px 0 0; font-size: 12px; line-height: 1.45;
  color: var(--terra-texto); background: var(--terra-bg);
  border-radius: var(--radius); padding: 6px 9px;
}

/* Atalhos da resposta: cards de navegação. O filete de acento é o "olhe aqui"
   da bolha; o caminho (Departamento › card) vem antes do nome, como breadcrumb. */
.cp-atalhos { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.cp-atalho {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-left: 3px solid var(--terra); border-radius: var(--radius);
  padding: 7px 11px; color: var(--text); text-align: left; cursor: pointer; font: inherit;
}
.cp-atalho:hover { border-color: var(--terra); }
.cp-atalho-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cp-atalho-cam { font-size: 11px; color: var(--text-muted); }
.cp-atalho strong { font-size: 13px; font-weight: 600; }
.cp-atalho i { font-size: 12px; color: var(--terra-icone); }

.cp-acoes { margin-top: 6px; display: flex; gap: 4px; }
.cp-acao {
  display: inline-flex; align-items: center; gap: 5px; border: none; background: transparent;
  color: var(--text-muted); font: inherit; font-size: 11.5px; padding: 3px 6px;
  border-radius: var(--radius); cursor: pointer;
}
.cp-acao:hover { color: var(--text); background: var(--bg-pill); }
.cp-acao i { font-size: 11px; }

/* Caixa de envio */
.cp-entrada { border-top: 1px solid var(--border); padding: 12px 16px 14px; background: var(--bg-panel); }
.cp-off {
  margin: 0 0 10px; font-size: 12.5px; line-height: 1.45;
  color: var(--text-muted); background: var(--bg-panel-soft);
  border: 1px solid var(--border); border-radius: var(--radius); padding: 9px 11px;
}
/* O campo é a caixa inteira (com o botão de envio dentro); o textarea não tem
   borda própria e cresce com o texto até o max-height (copilot.js, ajustarCampo). */
.cp-campo {
  display: flex; gap: 6px; align-items: flex-end;
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px;
  padding: 5px 5px 5px 12px;
}
.cp-campo:focus-within { border-color: var(--terra-foco); }
.cp-campo textarea {
  flex: 1; min-width: 0; resize: none; font-family: inherit; font-size: 13.5px; line-height: 1.5;
  padding: 6px 0; max-height: 160px; overflow-y: auto;
  background: transparent; border: none; color: var(--text);
}
.cp-campo textarea:focus { outline: none; }
.cp-campo textarea:disabled { opacity: .6; }
.cp-enviar {
  background: var(--accent); color: #fff; border: none; border-radius: 8px;
  width: 34px; height: 34px; font-size: 13px; flex-shrink: 0;
}
.cp-enviar:hover { background: var(--terra-acao-hover); }
.cp-enviar:disabled { opacity: .5; cursor: default; }

/* Uma linha discreta sob o campo: a disclosure de privacidade à esquerda (fica
   visível onde se digita, de propósito) e a cota à direita. */
.cp-rodape {
  display: flex; align-items: flex-start; gap: 12px; margin-top: 7px;
  font-size: 11px; line-height: 1.45; color: var(--text-muted);
}
.cp-aviso { margin: 0; flex: 1; min-width: 0; }
.cp-aviso i { color: var(--verde-medio); margin-right: 3px; }
.cp-quota { white-space: nowrap; }

/* Status da NIA, no cabeçalho de quem hospeda o chat. O ponto é reforço; o que
   informa é o texto (cor sozinha não pode ser o único sinal). */
.cp-estado { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 400; color: var(--text-muted); white-space: nowrap; }
.cp-estado:empty { display: none; }
.cp-estado::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: var(--border); }
.cp-estado[data-estado="on"]::before { background: var(--verde-medio); }
.cp-estado[data-estado="ocupada"]::before,
.cp-estado[data-estado="esgotada"]::before { background: var(--terra); }

/* Barra do próprio chat, só quando ninguém hospeda o cabeçalho (página inteira). */
.cp-barra {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 16px; border-bottom: 1px solid var(--border);
}
.cp-barra #cpConversas { margin-left: auto; }

/* Faixa da conversa aberta: título (a primeira pergunta) e Salvar. */
.cp-conversa-topo { display: none; }
.cp-conversa-topo.on {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border-bottom: 1px solid var(--border);
}
.cp-conversa-titulo {
  flex: 1; min-width: 0; font-size: 12.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cp-salvar {
  display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
  border: none; background: transparent; cursor: pointer; border-radius: var(--radius);
  font: inherit; font-size: 12px; color: var(--text-muted); padding: 4px 7px;
}
.cp-salvar:hover { color: var(--terra-texto); background: var(--terra-bg); }
.cp-salvar.on { color: var(--terra-texto); font-weight: 600; }

/* Lista de conversas: ocupa o lugar da conversa no mesmo card. */
.cp-hist { display: none; }
.cp-chat.cp-vendo-hist > .cp-conversa-topo,
.cp-chat.cp-vendo-hist > .cp-lista,
.cp-chat.cp-vendo-hist > .cp-entrada { display: none; }
.cp-chat.cp-vendo-hist > .cp-hist {
  display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
  padding: 12px 14px; gap: 10px;
}
.cp-hist-busca {
  display: flex; align-items: center; gap: 8px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 10px; padding: 0 12px;
}
.cp-hist-busca:focus-within { border-color: var(--terra-foco); }
.cp-hist-busca i { font-size: 12px; color: var(--text-muted); }
.cp-hist-busca input {
  flex: 1; min-width: 0; border: none; background: transparent; outline: none;
  font: inherit; font-size: 13px; color: var(--text); padding: 9px 0;
}
.cp-hist-aviso { margin: 0; font-size: 12px; color: var(--terra-texto); }
.cp-hist-aviso:empty { display: none; }
.cp-hist-lista { flex: 1 1 auto; min-height: 0; overflow-y: auto; margin: 0 -4px; padding: 0 4px; }
.cp-hist-vazio { margin: 12px 0; font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }
.cp-hist-grupo + .cp-hist-grupo { margin-top: 12px; }
.cp-hist-grupo h4 {
  margin: 0 0 4px; font-size: 11px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-muted);
}
.cp-hist-grupo ul { list-style: none; margin: 0; padding: 0; }
.cp-hist-item { display: flex; align-items: center; gap: 2px; border-radius: var(--radius); }
.cp-hist-item:hover { background: var(--bg-panel-soft); }
.cp-hist-item.aberta { background: var(--terra-bg); }
.cp-hist-abrir {
  flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 10px;
  border: none; background: transparent; cursor: pointer; text-align: left;
  font: inherit; padding: 8px 8px; color: var(--text);
}
.cp-hist-abrir:disabled { cursor: default; opacity: .6; }
.cp-hist-titulo { flex: 1; min-width: 0; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-hist-item.aberta .cp-hist-titulo { font-weight: 600; }
.cp-hist-quando { flex-shrink: 0; font-size: 11px; color: var(--text-muted); }
.cp-hist-acao {
  flex-shrink: 0; width: 28px; height: 28px; border: none; background: transparent; cursor: pointer;
  border-radius: var(--radius); color: var(--text-muted); font-size: 12px;
}
.cp-hist-acao:hover { color: var(--terra-texto); background: var(--bg-pill); }
.cp-hist-acao.on { color: var(--terra-texto); }
.cp-hist-nota { margin: 0; font-size: 11px; line-height: 1.45; color: var(--text-muted); }
.cp-hist-nota i { margin-right: 3px; }

/* Coluna de apoio */
.cp-sug { display: flex; flex-direction: column; gap: 7px; }
.cp-sug-btn {
  text-align: left; background: var(--bg-panel-soft); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 8px 11px; font-size: 12.5px;
  color: var(--text); line-height: 1.4;
}
.cp-sug-btn:hover { border-color: var(--accent); color: var(--terra-texto); }
.cp-sug-btn:disabled { opacity: .5; cursor: default; }
.cp-regras { margin: 0; padding-left: 17px; font-size: 12.5px; line-height: 1.55; color: var(--text-muted); }
.cp-regras li { margin-bottom: 8px; }
.cp-regras li:last-child { margin-bottom: 0; }
.cp-regras strong { color: var(--text); }

/* Limite diário atingido: tom de acento (não é erro, é uma regra da casa). */
.cp-esgotado { color: var(--terra-texto); background: var(--terra-bg); border-color: transparent; }

/* No tema escuro o verde da marca (#002a2b) fica quase indistinguível do fundo
   (#081819) e a bolha do usuário desaparecia. Troca para um teal mais claro —
   mesma família de cor, mesmo papel: "esta fala é sua". */
html.dark .cp-user .cp-balao { background: #14494a; border-color: #1c6364; color: #eaf5f4; }

@media (max-width: 1100px) {
  .cp-cols { grid-template-columns: 1fr; grid-auto-rows: min-content; overflow-y: auto; }
  .cp-chat { height: 62vh; }
  .cp-lado { overflow: visible; }
}

/* ===================== Início (tela de entrada do portal) ==================
   Escopo `.app-shell` como todo o resto do shell: `.panel`, `.crumb` e `.view`
   são compartilhados com admin/agenda/calendário e não podem herdar isto.

   A tela é de NAVEGAÇÃO, não um dashboard: a hierarquia visual é
   saudação → pergunta à NIA → módulos → histórico. Por isso o único destaque
   em cor da marca é o "resolver hoje?" e a estrela do card fixado; todo o
   resto vive em cinza para não disputar com eles.                            */

.app-shell .ini-wrap {
  /* A coluna centralizada é o que segura a leitura no monitor largo do
     escritório — texto de ponta a ponta em 1900px cansa. */
  width: 100%; max-width: 1180px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 22px;
  padding: 10px 0 26px;
}

/* ---------- Herói: saudação + pergunta à NIA ---------- */

.app-shell .ini-hero { text-align: center; display: flex; flex-direction: column; align-items: center; }

.app-shell .ini-saud {
  display: inline-block; padding: 5px 14px; border-radius: 999px;
  background: var(--areia); color: #7a3a1e;
  font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
}
html.dark .app-shell .ini-saud { background: rgba(243, 218, 186, .16); color: var(--areia); }

.app-shell .ini-titulo {
  margin: 16px 0 0; font-size: clamp(26px, 3.4vw, 40px); line-height: 1.15;
  font-weight: 700; letter-spacing: -.02em; color: var(--texto);
}
/* O acento da marca cai numa metade só da frase — é o "olhe aqui" da tela. */
.app-shell .ini-titulo em { font-style: normal; color: var(--terra-texto); }
/* O título grande usa a terracota exata da NN. */
html.dark .app-shell .ini-titulo em { color: var(--terra); }

/* Máquina de escrever (inicio.js): as frases ficam empilhadas na MESMA célula
   da grade, as de molde invisíveis. A caixa tem sempre a largura da maior, e
   o texto vivo cresce da esquerda dentro dela — nada em volta se mexe.
   `inline-grid` também é atômico: no celular o trecho quebra de linha inteiro,
   nunca no meio da frase que está sendo digitada. */
.app-shell .ini-tw { display: inline-grid; text-align: left; white-space: nowrap; }
.app-shell .ini-tw > span { grid-area: 1 / 1; }
.app-shell .ini-tw-molde { visibility: hidden; }
/* O cursor vai também nos moldes (escondido) para a largura reservada já
   contar com ele quando a maior frase estiver completa. */
.app-shell .ini-tw > span::after {
  content: ''; display: inline-block; width: .06em; height: .92em;
  margin-left: .06em; vertical-align: -.1em; background: currentColor;
}
.app-shell .ini-tw-vivo::after { animation: ini-tw-cursor 1s steps(1) infinite; }
@keyframes ini-tw-cursor { 50% { opacity: 0; } }
/* Movimento reduzido: o JS não digita, e o cursor parado só confundiria. */
@media (prefers-reduced-motion: reduce) {
  .app-shell .ini-tw-vivo::after { visibility: hidden; }
}
/* Texto para o leitor de tela: a frase fixa, sem o loop. */
.app-shell .ini-tw-leitor {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.app-shell .ini-sub {
  margin: 10px 0 0; font-size: 14.5px; color: var(--text-muted); max-width: 640px;
}

.app-shell .ini-ask {
  margin-top: 22px; width: min(720px, 100%);
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: 14px; padding: 12px 14px; box-shadow: var(--sombra);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.app-shell .ini-ask:focus-within {
  border-color: var(--terra-foco); box-shadow: 0 2px 14px rgba(178, 81, 43, .13);
}
.app-shell .ini-ask .nia-logo { --nia-logo: 30px; }
.app-shell .ini-ask input {
  flex: 1 1 auto; min-width: 0; border: none; background: transparent;
  font: inherit; font-size: 15px; color: var(--texto); outline: none;
}
.app-shell .ini-ask input::placeholder { color: var(--texto-fraco); }
.app-shell .ini-ask-kbd {
  flex: 0 0 auto; font: inherit; font-size: 11px; color: var(--texto-fraco);
  background: var(--bg-pill); border: 1px solid var(--border);
  border-radius: 6px; padding: 3px 7px;
}
.app-shell .ini-ask-dica { margin: 9px 0 0; font-size: 12.5px; color: var(--texto-fraco); }
.app-shell .ini-ask-dica strong { color: var(--text-muted); }

/* "Continuar conversa": porta de volta para a thread que já existe. Discreto de
   propósito — é retomada, não a ação principal da tela (que é perguntar). */
.app-shell .ini-retomar {
  margin-top: 10px; display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--border); background: var(--bg-panel);
  border-radius: 999px; padding: 6px 14px; cursor: pointer;
  font: inherit; font-size: 12.5px; color: var(--text-muted);
}
.app-shell .ini-retomar:hover { color: var(--terra-texto); border-color: var(--terra); }
.app-shell .ini-retomar i { font-size: 11px; }
.app-shell .ini-retomar span { color: var(--texto-fraco); }

.app-shell .ini-chips {
  margin-top: 18px; display: flex; flex-wrap: wrap; justify-content: center; gap: 9px;
}
.app-shell .ini-chip {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--bg-panel); border: 1px solid var(--border); border-radius: 999px;
  padding: 8px 15px; font: inherit; font-size: 13px; font-weight: 500;
  color: var(--texto); cursor: pointer; transition: border-color .15s ease, color .15s ease;
}
.app-shell .ini-chip i { font-size: 12px; color: var(--terra-icone); }
.app-shell .ini-chip:hover { border-color: var(--terra); color: var(--terra-texto); }

/* ---------- Módulos ---------- */

.app-shell .ini-mods-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 12px;
}
.app-shell .ini-mods-head h3 { margin: 0; font-size: 15.5px; font-weight: 600; color: var(--texto); }

.app-shell .ini-seg {
  display: inline-flex; gap: 2px; background: var(--bg-pill);
  border: 1px solid var(--border); border-radius: 999px; padding: 3px;
}
.app-shell .ini-seg-btn {
  border: none; background: transparent; font: inherit; font-size: 12.5px;
  color: var(--text-muted); padding: 6px 15px; border-radius: 999px; cursor: pointer;
}
.app-shell .ini-seg-btn:hover { color: var(--texto); }
.app-shell .ini-seg-btn.on { background: var(--bg-panel); color: var(--texto); font-weight: 600; box-shadow: var(--sombra); }

.app-shell .ini-grid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.app-shell .ini-card {
  position: relative; background: var(--bg-panel);
  border: 1px solid var(--border); border-radius: var(--raio-card);
  box-shadow: var(--sombra); transition: border-color .15s ease, transform .15s ease;
}
.app-shell .ini-card:hover { border-color: var(--terra); transform: translateY(-2px); }
.app-shell .ini-card-btn {
  display: flex; flex-direction: column; gap: 14px; align-items: flex-start;
  width: 100%; border: none; background: transparent; font: inherit;
  padding: 18px 16px; cursor: pointer; text-align: left; color: var(--texto);
  border-radius: var(--raio-card);
}
.app-shell .ini-card-ic {
  width: 42px; height: 42px; border-radius: 11px;
  background: var(--areia); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 16px;
}
html.dark .app-shell .ini-card-ic { background: var(--terra-icone-bg); }
/* Navegação secundária discreta; o foco de teclado continua explícito. */
html.dark .app-shell :is(.ini-card, .ini-chip, .ini-retomar, .ini-voltar):hover {
  border-color: rgba(255,255,255,.24);
}
html.dark .app-shell :is(.ini-chip, .ini-retomar, .ini-voltar):hover {
  background: var(--superficie-2); color: var(--texto);
}
html.dark .app-shell :is(.ini-card-btn, .ini-chip, .ini-retomar, .ini-voltar, .ini-dica-btn):focus-visible {
  outline: 2px solid var(--terra-foco); outline-offset: 3px;
}
html.dark .app-shell .ini-ask:focus-within { box-shadow: none; }
.app-shell .ini-card-btn strong { font-size: 14.5px; font-weight: 600; }

/* A estrela fica apagada até ser usada: fixar é uma ação secundária e não pode
   competir com o nome do módulo, que é o motivo do card existir. */
.app-shell .ini-card-fix {
  position: absolute; top: 10px; right: 10px; z-index: 1;
  border: none; background: transparent; cursor: pointer;
  padding: 5px; line-height: 1; border-radius: 6px;
  color: var(--borda); font-size: 13px; transition: color .15s ease;
}
.app-shell .ini-card-fix:hover { color: var(--texto-fraco); }
.app-shell .ini-card-fix.on { color: var(--terra-icone); }
.app-shell .ini-card-fix:focus-visible { outline: 2px solid var(--terra-foco); outline-offset: 1px; }

/* ---------- Onde você parou / Sugestões ---------- */

.app-shell .ini-cols { display: grid; gap: 14px; grid-template-columns: 1fr 1fr; }
.app-shell .ini-cols .panel { min-height: 170px; }
/* Os dois cards têm a mesma altura (grid), mas conteúdos de tamanhos bem
   diferentes. Quem se centraliza é SÓ o estado vazio, pela margem automática —
   assim ele não fica pendurado no topo de um card alto, e a lista (que tem
   ordem: mais recente primeiro) continua começando de cima, como se lê. */
.app-shell .ini-cols .panel-body { display: flex; flex-direction: column; }
.app-shell .ini-cols .ini-vazio { margin: auto 0; }
.app-shell .ini-cols .ini-parou, .app-shell .ini-cols .ini-dicas { width: 100%; }

.app-shell .ini-vazio {
  margin: 0; font-size: 13px; line-height: 1.6; color: var(--texto-fraco);
  padding: 14px 0;
}

.app-shell .ini-parou { list-style: none; margin: 0; padding: 0; }
.app-shell .ini-parou li + li { border-top: 1px solid var(--border); }
.app-shell .ini-parou button {
  display: flex; align-items: center; gap: 11px; width: 100%;
  border: none; background: transparent; font: inherit; cursor: pointer;
  padding: 11px 4px; text-align: left; color: var(--texto); border-radius: var(--raio);
}
.app-shell .ini-parou button:hover { background: var(--bg-pill); }
.app-shell .ini-parou-ic {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px;
  background: var(--verde-bg); color: var(--verde-medio);
  display: inline-flex; align-items: center; justify-content: center; font-size: 12px;
}
.app-shell .ini-parou-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.app-shell .ini-parou-txt strong { font-size: 13.5px; font-weight: 600; }
.app-shell .ini-parou-txt span { font-size: 11.5px; color: var(--texto-fraco); }
.app-shell .ini-parou-quando { flex: 0 0 auto; font-size: 11.5px; color: var(--texto-fraco); }

/* Dicas curadas (vêm do backend por regra, sem IA). Lista vertical: cada dica
   é um bloco de leitura, não um card — três cards pequenos lado a lado
   truncariam o texto justamente onde ele explica o atalho. */
.app-shell .ini-dicas { list-style: none; margin: 0; padding: 0; }
.app-shell .ini-dicas li { display: flex; gap: 11px; padding: 11px 0; }
.app-shell .ini-dicas li + li { border-top: 1px solid var(--border); }
.app-shell .ini-dica-ic {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px;
  background: var(--terra-icone-bg); color: var(--terra-icone);
  display: inline-flex; align-items: center; justify-content: center; font-size: 12px;
}
.app-shell .ini-dica-txt { flex: 1 1 auto; min-width: 0; }
.app-shell .ini-dica-txt strong { display: block; font-size: 13.5px; font-weight: 600; color: var(--texto); }
.app-shell .ini-dica-txt p { margin: 3px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--text-muted); }
.app-shell .ini-dica-btn {
  margin-top: 7px; display: inline-flex; align-items: center; gap: 6px;
  border: none; background: transparent; padding: 0; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--terra-texto);
}
.app-shell .ini-dica-btn i { font-size: 10px; transition: transform .15s ease; }
.app-shell .ini-dica-btn:hover i { transform: translateX(3px); }

/* ---------- Início → conversa com a NIA ----------
   Duas fases. (1) O Início recolhe: tudo sobe e some, MENOS a caixa de
   perguntas, que fica parada — é ela que ancora o olho e faz a conversa parecer
   ter nascido dali. (2) A thread entra crescendo a partir de baixo.
   Movimento curto de propósito (220ms): transição de tela que se faz notar
   incomoda a partir da terceira vez. */
/* A transição fica no elemento BASE, não na classe de estado: a IDA anima ao
   ganhar `.saindo` e a VOLTA anima ao PERDER `.voltando` — o segundo caso só
   funciona se a regra já estiver no elemento. */
.app-shell .ini-wrap .ini-saud,
.app-shell .ini-wrap .ini-titulo,
.app-shell .ini-wrap .ini-sub,
.app-shell .ini-wrap .ini-ask-dica,
.app-shell .ini-wrap .ini-retomar,
.app-shell .ini-wrap .ini-chips,
.app-shell .ini-wrap .ini-mods,
.app-shell .ini-wrap .ini-cols {
  transition: opacity .19s ease, transform .22s cubic-bezier(.4, 0, .2, 1);
}
.app-shell .ini-wrap .ini-ask {
  transition: transform .22s cubic-bezier(.4, 0, .2, 1), border-color .19s ease,
              box-shadow .15s ease;
}

/* IDA: tudo sai por cima; a caixa fica e cresce um tico (o "aumentando"). */
.app-shell .ini-wrap.saindo .ini-saud,
.app-shell .ini-wrap.saindo .ini-titulo,
.app-shell .ini-wrap.saindo .ini-sub,
.app-shell .ini-wrap.saindo .ini-ask-dica,
.app-shell .ini-wrap.saindo .ini-retomar,
.app-shell .ini-wrap.saindo .ini-chips,
.app-shell .ini-wrap.saindo .ini-mods,
.app-shell .ini-wrap.saindo .ini-cols {
  opacity: 0;
  transform: translateY(-10px);
}
.app-shell .ini-wrap.saindo .ini-ask { transform: scale(1.02); border-color: var(--terra); }

/* VOLTA: espelho da ida, em @keyframes. Animação e não transição de propósito —
   transição exige tirar a classe no quadro seguinte, e se esse quadro atrasar o
   conteúdo fica preso no estado inicial (invisível). O keyframe roda sozinho e
   PARA no estado natural, então não há nada a desfazer. */
.app-shell .ini-wrap.voltando .ini-saud,
.app-shell .ini-wrap.voltando .ini-titulo,
.app-shell .ini-wrap.voltando .ini-sub,
.app-shell .ini-wrap.voltando .ini-ask-dica,
.app-shell .ini-wrap.voltando .ini-retomar,
.app-shell .ini-wrap.voltando .ini-chips,
.app-shell .ini-wrap.voltando .ini-mods,
.app-shell .ini-wrap.voltando .ini-cols {
  animation: iniVolta .24s cubic-bezier(.4, 0, .2, 1) both;
}
.app-shell .ini-wrap.voltando .ini-ask { animation: iniVoltaCaixa .24s cubic-bezier(.4, 0, .2, 1) both; }

@keyframes iniVolta {
  from { opacity: 0; transform: translateY(-10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes iniVoltaCaixa {
  from { transform: scale(1.02); border-color: var(--terra); }
  to   { transform: none; }
}

.app-shell .ini-conversa {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  width: 100%; max-width: 1180px; margin: 0 auto; padding: 10px 0 0;
}
/* A entrada roda ao ser criada (mesma razão do keyframe da volta). Não há
   estado de saída: no caminho de volta a conversa cede o lugar de uma vez e quem
   anima é o Início entrando — senão sobra um quadro em branco entre as duas. */
.app-shell .ini-conversa { animation: iniConversaEntra .26s cubic-bezier(.4, 0, .2, 1) both; }
@keyframes iniConversaEntra {
  from { opacity: 0; transform: translateY(18px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

.app-shell .ini-conversa-topo { flex: 0 0 auto; margin-bottom: 8px; display: flex; align-items: center; gap: 12px; }
.app-shell .ini-conversas { margin-left: auto; }
.app-shell .ini-voltar {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--border); background: var(--bg-panel);
  border-radius: 999px; padding: 7px 15px; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 500; color: var(--text-muted);
}
.app-shell .ini-voltar:hover { color: var(--terra-texto); border-color: var(--terra); }
.app-shell .ini-voltar i { font-size: 11px; }

/* O chat ocupa o resto da tela e ganha a moldura de card (no painel lateral ele
   é liso, porque lá o painel inteiro já é a moldura). */
.app-shell .ini-conversa-chat {
  flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
  background: var(--bg-panel); border: 1px solid var(--border);
  border-radius: var(--raio-card); box-shadow: var(--sombra); overflow: hidden;
}
/* Conversa em tela cheia tem espaço: o texto pode respirar mais que no painel. */
.app-shell .ini-conversa-chat .cp-lista { padding: 18px 22px; }
.app-shell .ini-conversa-chat .cp-txt { font-size: 14.5px; line-height: 1.6; }
.app-shell .ini-conversa-chat .cp-entrada { padding: 12px 22px; }

/* Em <=900px o portal troca para rolagem do DOCUMENTO (`html,body{height:auto}`),
   então tudo passa a ser dimensionado pelo conteúdo — e a conversa ficava um
   card curto com fundo sobrando embaixo. Aqui ela volta a ocupar a tela.
   `dvh` cobre a barra do navegador móvel; o `vh` acima fica de reserva para
   quem não suporta a unidade. */
@media (max-width: 900px) {
  .app-shell .ini-conversa { min-height: calc(100vh - 84px); }
  .app-shell .ini-conversa { min-height: calc(100dvh - 84px); }
}

/* Quem pediu menos movimento recebe a troca seca — sem transição nenhuma. */
@media (prefers-reduced-motion: reduce) {
  .app-shell .ini-wrap.saindo .ini-saud,
  .app-shell .ini-wrap.saindo .ini-titulo,
  .app-shell .ini-wrap.saindo .ini-sub,
  .app-shell .ini-wrap.saindo .ini-ask-dica,
  .app-shell .ini-wrap.saindo .ini-chips,
  .app-shell .ini-wrap.saindo .ini-mods,
  .app-shell .ini-wrap.saindo .ini-cols,
  .app-shell .ini-wrap .ini-saud,
  .app-shell .ini-wrap .ini-titulo,
  .app-shell .ini-wrap .ini-sub,
  .app-shell .ini-wrap .ini-ask-dica,
  .app-shell .ini-wrap .ini-retomar,
  .app-shell .ini-wrap .ini-chips,
  .app-shell .ini-wrap .ini-mods,
  .app-shell .ini-wrap .ini-cols,
  .app-shell .ini-wrap.saindo .ini-ask,
  .app-shell .ini-wrap .ini-ask,
  .app-shell .ini-conversa { transition: none; }
  .app-shell .ini-conversa,
  .app-shell .ini-wrap.voltando .ini-saud,
  .app-shell .ini-wrap.voltando .ini-titulo,
  .app-shell .ini-wrap.voltando .ini-sub,
  .app-shell .ini-wrap.voltando .ini-ask-dica,
  .app-shell .ini-wrap.voltando .ini-retomar,
  .app-shell .ini-wrap.voltando .ini-chips,
  .app-shell .ini-wrap.voltando .ini-mods,
  .app-shell .ini-wrap.voltando .ini-cols,
  .app-shell .ini-wrap.voltando .ini-ask { animation: none; }
}

/* ===================== Painel lateral da NIA =====================
   `body.app-shell` é flex-row, então o painel entra como IRMÃO da coluna
   principal e a empurra — o dashboard continua legível ao lado da resposta, que
   é o motivo de ser painel e não aba. Em telas estreitas não há o que dividir:
   vira sobreposição de tela cheia.                                          */
:is(.app-shell, .calapp) .nia-panel {
  flex: 0 0 400px; width: 400px; min-height: 0; z-index: 40;
  display: flex; flex-direction: column;
  background: var(--bg-panel); border-left: 1px solid var(--border);
  box-shadow: -6px 0 20px rgba(0, 0, 0, .06);
  transition: transform .26s cubic-bezier(.2, .8, .2, 1), margin-right .26s cubic-bezier(.2, .8, .2, 1);
}

/* Abrir e fechar DESLIZAM pela borda direita (shell.js põe e tira a classe).
   Encaixado ao lado do conteúdo, a margem negativa devolve a largura ao portal
   junto com o deslize — o conteúdo cede espaço enquanto o painel entra, sem
   pulo no fim. Nos modos sobrepostos (Calendário NN, tela cheia, celular) é só
   o deslize. A entrada desacelera e a saída acelera: o movimento termina macio
   onde a pessoa vai ler, e sai do caminho rápido. */
:is(.app-shell, .calapp) .nia-panel.nia-recolhida {
  transform: translateX(100%);
  transition-duration: .2s; transition-timing-function: cubic-bezier(.4, 0, 1, 1);
}
@media (min-width: 901px) {
  .app-shell .nia-panel.nia-recolhida:not(.nia-cheia) { transform: none; margin-right: -400px; }
}
@media (prefers-reduced-motion: reduce) {
  :is(.app-shell, .calapp) .nia-panel { transition: none; }
}
:is(.app-shell, .calapp) .nia-head {
  flex: 0 0 auto; display: flex; align-items: center; gap: 9px;
  padding: 12px 14px; border-bottom: 1px solid var(--border);
}
:is(.app-shell, .calapp) .nia-head-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; line-height: 1.2; }
:is(.app-shell, .calapp) .nia-head strong { font-size: 14.5px; font-weight: 600; letter-spacing: .01em; }
:is(.app-shell, .calapp) .nia-head-btn {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  border: none; background: transparent; cursor: pointer; font: inherit;
  color: var(--texto-fraco); font-size: 14px; line-height: 1; padding: 6px 7px;
  border-radius: var(--raio);
}
:is(.app-shell, .calapp) .nia-head-btn:hover { color: var(--texto); background: var(--bg-pill); }
:is(.app-shell, .calapp) .nia-head-btn:disabled { opacity: .45; cursor: default; background: transparent; color: var(--texto-fraco); }
/* Conversas e Nova conversa agem sobre a CONVERSA (pílulas, como o "← Início");
   expandir e fechar agem sobre a janela (ícones soltos). */
:is(.app-shell, .calapp) .nia-conversas { margin-left: auto; }
:is(.app-shell, .calapp) .nia-head { gap: 6px; }
:is(.app-shell, .calapp) .nia-head .nia-pill { padding: 6px 11px; }

/* Pílula das ações da NIA — mesma família do "← Início" (fundo de card, borda
   fina, cantos redondos). Texto em cor cheia e ícone em terracota: é ação à
   mão, não item apagado. Marcada (lista aberta), ganha o fundo de acento. */
:is(.app-shell, .calapp) .nia-pill {
  display: inline-flex; align-items: center; gap: 7px; flex-shrink: 0;
  border: 1px solid var(--border); background: var(--bg-panel); color: var(--text);
  border-radius: 999px; padding: 7px 14px; cursor: pointer;
  font: inherit; font-size: 12.5px; font-weight: 500; line-height: 1.1; white-space: nowrap;
}
:is(.app-shell, .calapp) .nia-pill i { font-size: 11px; color: var(--terra-icone); }
:is(.app-shell, .calapp) .nia-pill:hover { border-color: var(--terra); color: var(--terra-texto); }
:is(.app-shell, .calapp) .nia-pill[aria-pressed="true"] {
  background: var(--terra-bg); border-color: transparent; color: var(--terra-texto);
}
:is(.app-shell, .calapp) .nia-pill:disabled { opacity: .55; cursor: default; }
:is(.app-shell, .calapp) .nia-pill:disabled:hover { border-color: var(--border); color: var(--text); }
:is(.app-shell, .calapp) .nia-corpo { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }

/* Chat em modo compacto: sem cabeçalho de página e sem a coluna lateral — o
   painel já dá o título, e as perguntas de partida migraram para o estado
   vazio. O card perde a borda porque o painel inteiro já é o card. */
:is(.app-shell, .calapp) .cp-compacto { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
:is(.app-shell, .calapp) .cp-compacto .cp-chat {
  flex: 1 1 auto; min-height: 0; border: none; box-shadow: none;
  border-radius: 0; padding: 0;
}
:is(.app-shell, .calapp) .cp-compacto .cp-lista { padding: 12px 14px; }
:is(.app-shell, .calapp) .cp-compacto .cp-entrada { padding: 10px 14px; }

/* Tela cheia: o painel cobre o portal (como já faz em <=900px) e a conversa fica
   numa coluna de leitura, em vez de linhas de 1.400px. */
:is(.app-shell, .calapp) .nia-panel.nia-cheia {
  position: fixed; inset: 0; width: auto; flex: none; z-index: 120;
  border-left: none; box-shadow: none;
}
:is(.app-shell, .calapp) .nia-cheia .cp-compacto { width: 100%; max-width: 860px; margin: 0 auto; }
:is(.app-shell, .calapp) .nia-cheia .cp-txt { font-size: 14.5px; line-height: 1.6; }

/* Logo da NIA — sistema de marca com TRÊS espessuras de traço (ver
   assets/img/README.md). O traço certo depende do tamanho E da densidade da tela:
   num monitor comum (1x) os tamanhos pequenos precisam de traço reforçado para
   não sumir; numa tela retina (2x) o mesmo reforço empasta (medido em folha de
   teste nas duas densidades). O navegador escolhe pela densidade (image-set):

     tamanho            1x                 2x
     18–20px (padrão)   icone (+4px)       media (+2px)
     24–34px            media (+2px)       marca (original)
     48px ou mais       marca (original)   marca

   Mínimo de 18px: abaixo disso a logo vira mancha. Ela aparece SOZINHA, no
   espaço inteiro que o chip ocupava — dentro do chip ficava com metade do
   tamanho e não era vista. O tamanho de cada lugar vem de --nia-logo.
   O image-set vai escrito por extenso (sem var()): navegador que não o entende
   descarta só aquela linha e fica com a imagem da linha anterior. */
.nia-logo {
  --nia-logo: 20px;
  display: inline-block; flex-shrink: 0; vertical-align: middle;
  width: var(--nia-logo); height: var(--nia-logo);
  background: url(../img/logo-nia-icone.png) center / contain no-repeat;
  background-image: -webkit-image-set(url(../img/logo-nia-icone.png) 1x, url(../img/logo-nia-media.png) 2x);
  background-image: image-set(url(../img/logo-nia-icone.png) 1x, url(../img/logo-nia-media.png) 2x);
}
/* 24–34px: onde a logo ocupa o lugar de um chip (o chip perde o fundo). */
.cp-ava.cp-ava-nia,
.app-shell .gs-item .gs-ic.gs-ic-nia,
.app-shell .panel-head .ic.ic-nia,
.app-shell .admin-head .ah-ic.ah-ic-nia { background: none; }
.cp-ava-nia .nia-logo,
.app-shell .gs-ic-nia .nia-logo,
.app-shell .panel-head .ic-nia .nia-logo { --nia-logo: 28px; }
.app-shell .ah-ic-nia .nia-logo { --nia-logo: 34px; }
.cp-ava-nia .nia-logo,
.app-shell .gs-ic-nia .nia-logo,
.app-shell .panel-head .ic-nia .nia-logo,
.app-shell .ah-ic-nia .nia-logo,
.app-shell .ini-ask .nia-logo,
.bib-nia .nia-logo {
  background-image: url(../img/logo-nia-media.png);
  background-image: -webkit-image-set(url(../img/logo-nia-media.png) 1x, url(../img/logo-nia-marca.png) 2x);
  background-image: image-set(url(../img/logo-nia-media.png) 1x, url(../img/logo-nia-marca.png) 2x);
}
/* 48px ou mais: o traço da arte, em qualquer tela. */
.nia-logo.nia-logo-marca { background-image: url(../img/logo-nia-marca.png); }

/* Nos botões "NIA" (topo, Calendário NN) ela divide o espaço com o texto. A
   margem negativa segura a altura do botão (18px de logo numa linha de texto de
   16px o faria 2px mais alto que os vizinhos da barra). */
.app-shell .ta-nia .nia-logo,
.calapp .ca-btn .nia-logo { --nia-logo: 18px; margin-block: -1px; }
/* Sobre fundo terracota (botão da NIA aberto, botão primário) o laranja da logo
   sumiria: ali ela é desenhada na cor do texto (branco), usando a própria imagem
   como máscara. `.nia-logo-mono` pede isso em qualquer lugar. */
html.dark .nia-logo,
.nia-logo.nia-logo-mono,
.app-shell .ta-nia[aria-expanded="true"] .nia-logo {
  background: currentColor;
  -webkit-mask: url(../img/logo-nia-icone.png) center / contain no-repeat;
  mask: url(../img/logo-nia-icone.png) center / contain no-repeat;
  -webkit-mask-image: -webkit-image-set(url(../img/logo-nia-icone.png) 1x, url(../img/logo-nia-media.png) 2x);
  mask-image: image-set(url(../img/logo-nia-icone.png) 1x, url(../img/logo-nia-media.png) 2x);
}

html.dark .nia-logo.nia-logo,
html.dark .app-shell .panel-head .ic-nia .nia-logo { background: var(--nia-tinta, var(--terra-icone)); }
html.dark .nia-logo.nia-logo-mono,
html.dark .app-shell .ta-nia[aria-expanded="true"] .nia-logo { --nia-tinta: currentColor; background: currentColor; }

/* O botão da NIA é a única ação em cor de marca na topbar: é a que abre uma
   capacidade nova, as outras operam a tela que já está aberta. */
.app-shell .ta-nia { color: var(--terra-texto); border-color: var(--terra-bg); }
.app-shell .ta-nia:hover { background: var(--terra-bg); }
.app-shell .ta-nia[aria-expanded="true"] { background: var(--terra); border-color: var(--terra); color: #fff; }

/* Escalonamento da busca: a linha da NIA fecha o dropdown, então ganha uma
   divisória. O caminho vira o custo ("usa 1 consulta"), que é a informação que
   evita a pessoa gastar cota sem querer. */
.app-shell .gs-grupo:last-child h4 { color: var(--terra-texto); }

@media (max-width: 900px) {
  /* Sem largura para dividir: cobre a tela. */
  .app-shell .nia-panel {
    position: fixed; inset: 0; width: auto; flex: none; z-index: 120;
    border-left: none;
  }
  /* Já é tela cheia: expandir não tem o que fazer. */
  .app-shell .nia-expandir { display: none; }
}
@media (max-width: 420px) {
  .app-shell .nia-nova span { display: none; }
}

@media (max-width: 900px) {
  .app-shell .ini-cols { grid-template-columns: 1fr; }
  .app-shell .ini-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .app-shell .ini-mods-head { justify-content: flex-start; }
}

/* ============================================================================
   HUB POR EMPRESA (empresa ativa, estilo Domínio) · 28/09/2026
   ----------------------------------------------------------------------------
   Filetes da barra lateral, marcação de escopo nos cards do catálogo e a faixa
   de contexto dos módulos filtrados. O botão da empresa no topo mora em
   cadastro-contexto.css: é o MESMO componente do card do Cadastro.
   ============================================================================ */
/* Filete entre os blocos da barra (Início+Cadastro │ departamentos │ demais). */
.app-shell .side-sep { flex: 0 0 auto; height: 1px; margin: 8px 11px; background: rgba(255, 255, 255, .1); }
@media (min-width: 901px) {
  .app-shell.side-rail .side-sep { margin: 8px 10px; }
}

/* Catálogo com empresa ativa: cada card diz como se comporta com ela. */
.tool-card .tc-escopo {
  display: inline-block; margin-left: 6px; vertical-align: middle;
  padding: 1px 6px; border-radius: var(--raio);
  background: var(--bg-panel); border: 1px solid var(--border); color: var(--text-muted);
  font-size: 10px; font-weight: 600; letter-spacing: .02em; line-height: 1.5;
}
.tool-card .tc-emp {
  display: flex; align-items: baseline; gap: 6px; width: 100%;
  padding-top: 8px; border-top: 1px solid var(--border);
  font-size: 12.5px; font-weight: 500; line-height: 1.4; color: var(--text);
}
.tool-card .tc-emp > i { flex: 0 0 auto; font-size: 10px; color: var(--terra-icone); }
html.dark .tool-card .tc-emp > i { color: var(--terra-icone); }
.tool-card .tc-emp.fora { color: var(--texto-fraco); font-weight: 400; }
.tool-card .tc-emp.fora > i { color: var(--texto-fraco); }
/* Card que não muda com a empresa vai para o fundo: tom de superfície, sem
   sombra. O clique continua valendo — ele abre como hoje. */
.tool-card.tc-fora { background: var(--bg-panel-soft); box-shadow: none; }
.hub-scene .tool-card.tc-fora .tc-ic,
html.dark .hub-scene .tool-card.tc-fora .tc-ic { background: var(--bg-panel); color: var(--texto-2); box-shadow: none; }
.hub-wrap > .cc-contexto-aviso { margin: 0 0 14px; }

/* Faixa dos módulos filtrados: qual empresa a tela mostra e como voltar à
   carteira. Aviso de INFORMAÇÃO (visual.md): borda de 3px em --verde-medio. */
.emp-faixa {
  display: flex; align-items: baseline; gap: 8px; margin: 0;
  padding: 8px 14px; border-left: 3px solid var(--verde-medio); border-radius: var(--raio);
  background: linear-gradient(var(--verde-bg), var(--verde-bg)), var(--bg-panel);
  color: var(--text); font-size: 12.5px; line-height: 1.5;
}
.emp-faixa > i { flex: 0 0 auto; font-size: 11px; color: var(--verde-medio); }
.emp-faixa strong { font-weight: 600; }
.emp-faixa + .cc-contexto-aviso { margin-top: -6px; }
/* A barra de ações encolhe (o nome da empresa corta com reticências) antes de
   empurrar a busca para fora. */
.app-shell .top-actions { flex: 0 1 auto; min-width: 0; }
.app-shell .ta-empresa { flex: 0 1 auto; min-width: 0; }
/* Linha que pede atenção (ocorrência aberta, vencimento, pendência): a única
   cor de destaque do card. O resto fica no tom do texto. */
.tool-card .tc-emp.atencao { color: var(--terra-texto); font-weight: 600; }
.tool-card .tc-emp.atencao > i { color: var(--terra-icone); }
html.dark .tool-card .tc-emp.atencao, html.dark .tool-card .tc-emp.atencao > i { color: var(--terra-texto); }
/* Início com empresa ativa: o que o módulo tem dela, sob o nome. */
.app-shell .ini-card-emp {
  margin-top: -8px; font-size: 12px; line-height: 1.35; color: var(--text-muted);
}
.app-shell .ini-card-emp.atencao { color: var(--terra-texto); font-weight: 600; }
html.dark .app-shell .ini-card-emp.atencao { color: var(--terra-texto); }
.app-shell .ini-hero .cc-contexto-aviso { margin: 10px 0 0; }
/* Régua do KPIs com empresa ativa: quais painéis saíram e por quê. */
.app-shell .subabas-nota {
  margin-left: auto; align-self: center; padding: 0 4px;
  font-size: 11.5px; color: var(--texto-fraco); white-space: nowrap;
}
.app-shell .subabas-nota i { margin-right: 4px; font-size: 10.5px; }
@media (max-width: 900px) { .app-shell .subabas-nota { display: none; } }
/* Faixa da empresa no topo de um dashboard (renderDashboard `faixa`). */
.dash-faixa { display: flex; flex-direction: column; gap: 6px; margin: 0 0 12px; }
.dash-faixa .cc-contexto-aviso { margin: 0; }
/* Aviso do dashboard vindo do backend (ex.: carga do Domínio atrasada). */
.dash-aviso { margin: 0 0 12px; }
/* Com a empresa ativa no topo, os botões dos dashboards (Vídeo, Relatório,
   Editar Layout) viram só ícone até 1600px — senão a busca vira um toco e o
   nome da empresa corta. O rótulo segue no nome acessível (clip, não
   display:none) e o `title` de cada botão explica no hover. */
@media (max-width: 1600px) {
  .app-shell .topbar:has(.ta-empresa:not([hidden])) .ta-rotulo {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}
/* Como o backend recortou uma fonte externa (Acessórias, Omie pelo CNPJ). */
.emp-faixa .emp-faixa-nota { display: block; margin-top: 2px; font-size: 11.5px; color: var(--text-muted); }
/* Telas com renderer próprio: a faixa ganha o respiro que a grade não dá. */
.ac-wrap > .emp-faixa, .ac-wrap > .emp-faixa + .cc-contexto-aviso { margin-bottom: 12px; }
.view > .emp-faixa, .view > .emp-faixa + .cc-contexto-aviso { margin-bottom: 12px; }
