/* Paleta e tokens portados de variados/sist_cobranca.html (mesmo :root),
   pra ficar visualmente parecido com o sistema que os cobradores já usam. */
:root {
  --bg-primary: #04142b;
  --bg-secondary: #0b1f3f;
  --bg-tertiary: #122a52;

  --accent: #2d66c3;
  --accent-hover: #3b7be0;

  --success: #27ae60;
  --danger: #e74c3c;

  --text-primary: #ffffff;
  --text-secondary: #c9d4e5;

  --border-color: #2d66c3;;
  --shadow: rgba(0, 0, 0, 0.5);
}

/* Tema Claro — alternável em /configuracoes, persistido em localStorage
   ('erp_tema') e aplicado via atributo data-theme em <html> (setado o mais
   cedo possível em base.html, antes do <link> do CSS, pra não piscar o tema
   errado no primeiro paint). */
:root[data-theme="light"] {
  --bg-primary: #f4f6fb;
  --bg-secondary: #ffffff;
  --bg-tertiary: #eef1f8;

  --accent: #2d66c3;
  --accent-hover: #1d4f9e;

  --success: #1e8449;
  --danger: #c0392b;

  --text-primary: #12213e;
  --text-secondary: #4b5875;

  --border-color: #2d66c3;
  --shadow: rgba(15, 23, 42, 0.12);
}

/* Fallback genérico pra qualquer botão de submit "solto" — fora de
   .form-card/.auth-card (ex.: direto num <form> com vários cards, ou dentro
   de um .modal-caixa) não herdava nenhum estilo e caía no botão cru do
   navegador. Especificidade igual à de ".form-card button"/".auth-card
   button" (1 classe/atributo + 1 elemento) e definida ANTES delas no arquivo,
   então onde já existe uma regra mais contextual, ela continua vencendo (CSS
   desempata por ordem quando a especificidade é igual); esta regra só entra
   em cena onde não havia nada. */
button[type="submit"] {
  padding: 0.7rem 1.25rem;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--accent);
  color: white;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.15s ease;
  margin-top: 1rem;
}
button[type="submit"]:hover { background: var(--accent-hover); transform: translateY(-1px); }
button[type="submit"]:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  transform: none;
}

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: 'Geist', sans-serif;
  background: var(--bg-primary);
  color: var(--text-primary);
}

.auth-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.auth-card {
  background: var(--bg-secondary);
  padding: 2rem;
  border-radius: 20px;
  border: 1px solid var(--border-color);
  box-shadow: 0 12px 30px var(--shadow);
  width: min(90vw, 340px);
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.auth-card h1 {
  margin: 0 0 0.5rem;
  font-size: 1.25rem;
}

.auth-card label {
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.auth-card input {
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 1rem;
}

.auth-card button {
  margin-top: 0.5rem;
  padding: 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--accent);
  color: white;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.15s ease;
}

.auth-card button:hover { background: var(--accent-hover); transform: translateY(-1px); }

.auth-card .erro { color: var(--danger); font-size: 0.85rem; margin: 0; }
.auth-card .hint { color: var(--text-secondary); font-size: 0.85rem; margin: 0; }

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

.sidebar {
  position: relative;
  width: 240px;
  background: var(--bg-secondary);
  border-right: 1px solid var(--border-color);
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  transition: width 0.15s ease;
  flex-shrink: 0;
}

.sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 0.75rem;
}

.sidebar-header .logout {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--text-secondary);
  font-size: 0.8rem;
  text-decoration: none;
  flex-shrink: 0;
}

.sidebar-saudacao {
  font-size: 1rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

/* Grudada na borda direita da sidebar, no meio da ALTURA DA TELA — position:
   fixed (não absolute) de propósito: .sidebar é esticada pelo flex pai até a
   altura do conteúdo (.layout não tem altura própria), então numa página com
   tabela grande a sidebar fica muito mais alta que a viewport e top:50%
   relativo a ela jogava o botão pra fora da área visível ao rolar. Fixo à
   viewport, sempre visível, e a posição horizontal acompanha a largura atual
   da sidebar (expandida/recolhida) via a mesma regra data-sidebar abaixo. */
.sidebar-toggle {
  position: fixed;
  top: 50vh;
  left: 227px;
  transform: translateY(-50%);
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--border-color);
  border-radius: 0 10px 10px 0;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  cursor: pointer;
  /* mesma duração/easing de ".sidebar { transition: width }" — sem isso o
     "left" pulava direto pro valor final (data-sidebar muda instantaneamente
     via JS) enquanto a sidebar ainda estava animando a largura, e o botão
     parecia "chegar antes" dela. */
  transition: left 0.15s ease;
}
:root[data-sidebar="recolhida"] .sidebar-toggle {
  left: 51px;
}
.sidebar-toggle:hover { background: var(--accent); color: white; }
.sidebar-toggle .sidebar-icone { width: 14px; height: 14px; transition: transform 0.15s ease; }
:root[data-sidebar="recolhida"] .sidebar-toggle .sidebar-icone { transform: rotate(180deg); }

.sidebar-icone {
  width: 19px;
  height: 19px;
  flex-shrink: 0;
}

.sidebar-categoria {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.6rem 0.75rem;
  border-radius: 15px;
  background: var(--bg-tertiary);
  font-size: 0.9rem;
  color: var(--text-primary);
  text-decoration: none;
  margin: 2px;
}

.sidebar-secao-titulo {
  background: none;
  padding: 0.3rem 0.75rem 0.1rem;
  font-size: 0.7rem;
  letter-spacing: 0.5px;
  color: var(--text-secondary);
  text-transform: uppercase;
}

.sidebar-link:hover { background: var(--accent); cursor: pointer; }
.em-breve { color: var(--text-secondary); font-size: 0.75rem; }

/* Sidebar recolhida (padrão — ver base.html/base.js): só ícone, largura
   estreita, texto/saudação escondidos. Tooltip nativo (title=) substitui o
   texto. Fica de fora no mobile (ver @media abaixo). */
:root[data-sidebar="recolhida"] .sidebar {
  width: 64px;
}
:root[data-sidebar="recolhida"] .sidebar-texto,
:root[data-sidebar="recolhida"] .sidebar-saudacao,
:root[data-sidebar="recolhida"] .sidebar-secao-titulo {
  display: none;
}
:root[data-sidebar="recolhida"] .sidebar-categoria {
  justify-content: center;
  padding: 0.6rem;
}
:root[data-sidebar="recolhida"] .sidebar-header { justify-content: center; }
:root[data-sidebar="recolhida"] .sidebar-header .logout { padding: 0.3rem; }

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tabs { display: flex; gap: 0.5rem; margin-bottom: 1rem; }
.tabs a {
  padding: 0.5rem 1rem;
  border-radius: 6px 6px 0 0;
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  text-decoration: none;
  font-size: 0.9rem;
  border: 1px solid var(--border-color);
  border-bottom: none;
}
.tabs a.ativo { background: var(--accent); color: white; }

.filtro-data {
  display: flex;
  gap: 0.5rem;
  /* center (2026-08-28): o título do campo alinha ao CENTRO da linha, junto
     de inputs e botões — com "end" o label caía no rodapé, desalinhado */
  align-items: center;
}
.filtro-data label { display: flex; flex-direction: column; font-size: 0.75rem; color: var(--text-secondary); gap: 0.25rem; }
.filtro-data input,
.filtro-data select {
  padding: 0.4rem 0.5rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: 0.85rem;
}
.filtro-data button {
  padding: 0.45rem 1rem;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--accent);
  color: white;
  font-weight: 600;
  cursor: pointer;
}
.filtro-data button:hover { background: var(--accent-hover); }

/* Hub de categoria (ex.: COMERCIAL) — blocos grandes clicáveis, um por
   funcionalidade da categoria. Grid responsivo: encolhe pra 1 coluna sozinho
   em telas estreitas, sem precisar de media query própria. */
.hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.25rem;
  max-width: 720px;
}
.hub-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-left: 4px solid var(--accent);
  border-radius: 12px;
  box-shadow: 0 12px 35px var(--shadow);
  padding: 1.5rem;
  text-decoration: none;
  color: var(--text-primary);
  transition: all 0.15s ease;
}
.hub-card:hover {
  transform: translateY(-3px);
  border-left-color: var(--accent-hover);
  box-shadow: 0 16px 40px var(--shadow);
}
.hub-card h3 { margin: 0; }
.hub-card p { margin: 0; color: var(--text-secondary); font-size: 0.9rem; }
.hub-card-desabilitado {
  cursor: not-allowed;
  filter: grayscale(1);
  opacity: 0.55;
  border-left-color: var(--border-color);
}
.hub-card-desabilitado:hover { transform: none; box-shadow: 0 12px 35px var(--shadow); }

.btn-novo {
  display: inline-block;
  padding: 0.5rem 1rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--success);
  color: white;
  text-decoration: none;
  font-weight: 600;
  /* <button> não herda a fonte do body (usa a do sistema) e tem line-height
     próprio — sem fixar os dois aqui, um <button class="btn-novo"> sai com
     TAMANHO diferente de um <a class="btn-novo"> na mesma linha. */
  font-family: inherit;
  line-height: 1.4;
  cursor: pointer;
  font-size: 0.9rem;
  transition: all 0.15s ease;
}
.btn-novo:hover { transform: translateY(-1px); }

table.dados {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  background: var(--bg-secondary);
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--border-color);
  box-shadow: 0 8px 25px var(--shadow);
}
table.dados th, table.dados td {
  text-align: left;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--border-color);
}
table.dados th {
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  /* cabeçalho centralizado é padrão da casa (2026-08-25); o dado continua
     à esquerda — não repetir text-align nos templates */
  text-align: center;
}
/* Cabeçalho clicável pra ordenar (ex.: Comercial > Boletos emitidos) — link
   herda a cor/tamanho do th, só ganha cursor de clique e destaque no hover. */
table.dados th a.th-ordenavel {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}

/* Tabelas interativas (base.js, 2026-08-25): ordenação + filtro por coluna
   em toda table.dados — opt-out via class="tabela-simples". A linha
   escondida pelo filtro usa classe (não inline) de propósito: as paginações
   client-side mexem no style.display e não podem "ressuscitar" linha
   filtrada. */
table.dados th.th-interativo { cursor: pointer; user-select: none; }
table.dados tr.linha-filtrada { display: none; }
.th-seta { margin-left: 0.15rem; }
/* Dica sob demanda (2026-08-28): um ⓘ discreto que mostra o texto SÓ no
   hover/foco — pra lista/explicação longa que poluiria a tela sempre
   aberta (ex.: os processos judiciais relevantes na análise de crédito).
   Uso: <span class="dica" tabindex="0" data-dica="texto...">ⓘ</span>
   O tabindex deixa o teclado alcançar (foco também abre). */
.dica {
  display: inline-block;
  position: relative;
  cursor: help;
  color: var(--text-secondary);
  font-size: 0.85rem;
  margin-left: 0.25rem;
  line-height: 1;
}
.dica:hover, .dica:focus { color: var(--accent); outline: none; }
.dica::after {
  content: attr(data-dica);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 0.45rem);
  transform: translateX(-50%);
  width: max-content;
  max-width: 20rem;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 0.5rem 0.7rem;
  font-size: 0.8rem;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  white-space: normal;
  text-transform: none;
  letter-spacing: normal;
  box-shadow: 0 8px 25px var(--shadow);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease;
  z-index: 60;
  pointer-events: none;
}
.dica:hover::after, .dica:focus::after { opacity: 1; visibility: visible; }

/* O ▽ do filtro fica quase invisível até o mouse passar no cabeçalho —
   discrição de propósito (2026-08-28): a coluna continua limpa e quem
   procura acha. Filtro ATIVO fica aceso na cor de destaque sempre. */
.th-filtro {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--text-secondary);
  font-size: 0.65rem;
  padding: 0 0.1rem;
  margin-left: 0.1rem;
  opacity: 0.25;
  vertical-align: middle;
  transition: opacity 0.15s ease, color 0.15s ease;
}
table.dados th:hover .th-filtro { opacity: 0.9; }
.th-filtro:hover { color: var(--accent); opacity: 1; }
.th-filtro.ativo { color: var(--accent); opacity: 1; }
.th-filtro-campo {
  display: block;
  width: 100%;
  min-width: 5rem;
  margin-top: 0.25rem;
  font-size: 0.75rem;
  padding: 0.15rem 0.3rem;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  text-align: left;
}

/* Linha-resumo por contrato com detalhe expansível (Comercial > Boletos SEC
   pendentes) — .oculta esconde as linhas de parcela individuais até o
   usuário clicar na seta; .btn-expandir é só a seta em si, sem moldura de
   botão pra não competir visualmente com os outros .btn-*. */
tr.linha-parcela.oculta { display: none; }
.btn-expandir {
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.9rem;
  padding: 0.2rem 0.4rem;
}
.btn-expandir:hover { color: var(--accent); }
table.dados th a.th-ordenavel:hover { color: var(--accent); }
:root[data-theme="light"] table.dados tr:hover { color: #fff; }
table.dados tr:hover{ background-color: #16386b; }
table.dados tr.linha-esc { background-color: #d35400; }
table.dados tr.linha-esc td { color: #ffffff; }
table.dados tr.linha-esc:hover { background-color: #e67e22; }
table.dados tr.linha-sec { background-color: #8B0000; }
table.dados tr.linha-sec td { color: #ffffff; }
table.dados tr.linha-sec:hover { background-color: #a80000; }
/* Histórico da ficha do cliente PF: boleto emitido no CNPJ da empresa do
   cliente (dono_cpf) — azul fixo, mesmo padrão de cor fixa acima. */
table.dados tr.linha-cnpj { background-color: #1f4e79; }
table.dados tr.linha-cnpj td { color: #ffffff; }
table.dados tr.linha-cnpj:hover { background-color: #2a6299; }

/* Conferência (comercial/conferencia): linha com CONTRATO EMITIDO ganha cor
   pela conta de saída — UY3 laranja, ARTTA cinza (pedido de 2026-08-22).
   Cores fixas + texto branco, mesmo padrão das linhas destacadas. */
table.dados tr.linha-emit-uy3 { background-color: #b45309; }
table.dados tr.linha-emit-uy3 td { color: #ffffff; }
table.dados tr.linha-emit-uy3:hover { background-color: #d97706; }
table.dados tr.linha-emit-artta { background-color: #4b5563; }
table.dados tr.linha-emit-artta td { color: #ffffff; }
table.dados tr.linha-emit-artta:hover { background-color: #6b7280; }

/* Ticker financeiro da home — estilo jornal: passa da direita pra esquerda,
   pausa no hover. O conteúdo é renderizado 2x e a faixa anda -50% em loop
   (largura da faixa = 2× o conteúdo, então o salto é invisível). Em
   prefers-reduced-motion a animação sai e a faixa vira scroll manual. */
.ticker-financeiro {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--bg-secondary);
  border-top: 1px solid var(--border-color);
  overflow: hidden;
  z-index: 5;
}
.ticker-faixa {
  display: inline-flex;
  padding: 0.45rem 0;   /* SEM padding horizontal — quebraria a conta do -50% */
  white-space: nowrap;
  animation: ticker-rolar 45s linear infinite;
  will-change: transform;
}
/* Cada metade é idêntica e autocontida (gap interno + padding-right igual ao
   gap fazem o espaçamento entre o fim de uma e o começo da outra ser o mesmo
   dos itens) — assim o salto de -50% cai EXATAMENTE no início da 2ª cópia e
   a emenda é invisível. */
.ticker-conteudo {
  display: inline-flex;
  gap: 2.5rem;
  padding-right: 2.5rem;
  flex-shrink: 0;
}
.ticker-financeiro:hover .ticker-faixa { animation-play-state: paused; }
.ticker-item { display: inline-flex; gap: 0.4rem; align-items: baseline; font-size: 0.85rem; }
.ticker-sobe { color: var(--success); font-weight: 600; }
.ticker-desce { color: var(--danger); font-weight: 600; }
@keyframes ticker-rolar {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .ticker-faixa { animation: none; }
  .ticker-financeiro { overflow-x: auto; }
}

/* Situação "Adiantado" no histórico de pagamentos da ficha: verde com borda
   DOURADA — selo de mérito (pagou antes do vencimento). Dourado fixo, não
   var(--...), pra não sumir em nenhum tema. */
.situacao-adiantado {
  color: var(--success);
  border: 1px solid #d4a017;
  border-radius: 6px;
  padding: 0.05rem 0.4rem;
  font-weight: 600;
  white-space: nowrap;
}

/* Destaque de linha em Cobrança > Baixas: sacado repetido no período
   filtrado (vermelho, pede atenção) e lançamento já enviado pra planilha
   (verde, resolvido) — enviado tem prioridade sobre duplicado, ver
   cobranca_baixas.html. Mesmo padrão de tr.linha-esc/linha-sec acima
   (cor fixa + texto branco, não var(--bg-*), pra não sumir em nenhum tema). */
table.dados tr.linha-duplicada { background-color: #7a2a20; }
table.dados tr.linha-duplicada td { color: #ffffff; }
table.dados tr.linha-duplicada:hover { background-color: #96382a; }
table.dados tr.linha-enviada { background-color: #1e5c38; }
table.dados tr.linha-enviada td { color: #ffffff; }
table.dados tr.linha-enviada:hover { background-color: #257048; }

/* Renegociação pendente de aprovação do GER. COBRANÇA (Negociações e
   Renegociações): âmbar, cor fixa + texto branco como as demais linha-*. */
table.dados tr.linha-reneg { background-color: #b8860b; }
table.dados tr.linha-reneg td { color: #ffffff; }
table.dados tr.linha-reneg:hover { background-color: #d4a017; }

/* Origem do boleto (Cobrança > Consulta / Distribuição): Bradesco em
   vermelho, Inter em laranja — Sicoob/BTG/legado ficam na cor padrão da
   tabela (sem destaque). Mesmo padrão de cor fixa + texto branco das
   linhas acima, escopo próprio pra não confundir com linha-esc/linha-sec. */
table.dados tr.linha-bradesco { background-color: #8B0000; }
table.dados tr.linha-bradesco td { color: #ffffff; }
table.dados tr.linha-bradesco:hover { background-color: #a11a1a; }
table.dados tr.linha-inter { background-color: #d35400; }
table.dados tr.linha-inter td { color: #ffffff; }
table.dados tr.linha-inter:hover { background-color: #e67e22; }

/* Cobrança > Consulta: boleto "perdido" por idade (Inter 59 dias, demais
   bancos 119) — cinza porque é um estado encerrado sem desfecho positivo,
   diferente do verde de baixado (pago). Prioridade: baixado > perdido >
   cor de origem, ver cobranca_consulta.js. */
table.dados tr.linha-perdido { background-color: #4a4f57; }
table.dados tr.linha-perdido td { color: #ffffff; }
table.dados tr.linha-perdido:hover { background-color: #5c626b; }

/* Financeiro > Caixa Físico: sinal indefinido (tipo fora do mapeamento
   conhecido, não entra no saldo — laranja, pede atenção) tem prioridade
   sobre aprovada (verde, estado resolvido) — diferente da prioridade em
   Cobrança > Baixas (lá o estado resolvido vence), aqui o problema de dado
   é mais urgente que a aprovação, porque compromete o próprio cálculo do
   saldo. Mesmas cores fixas já usadas acima (inter/enviada), reaproveitadas
   por semântica equivalente (laranja=atenção, verde=positivo). */
table.dados tr.linha-aprovada { background-color: #1e5c38; }
table.dados tr.linha-aprovada td { color: #ffffff; }
table.dados tr.linha-aprovada:hover { background-color: #257048; }
table.dados tr.linha-indefinida { background-color: #d35400; }
table.dados tr.linha-indefinida td { color: #ffffff; }
table.dados tr.linha-indefinida:hover { background-color: #e67e22; }
/* Marcação visual de "excluído" (não é exclusão de verdade — ver
   marcar_excluida_movimentacao_caixa) — vermelho, prioridade sobre
   aprovada/indefinida (ver comentário de prioridade no template). */
table.dados tr.linha-excluida { background-color: #8B0000; }
table.dados tr.linha-excluida td { color: #ffffff; }
table.dados tr.linha-excluida:hover { background-color: #a80000; }

.legenda-cores {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin: 0.5rem 0 1rem;
  font-size: 0.8rem;
  color: var(--text-secondary);
}
/* Topo de Cobrança > Distribuição: cards compactos de contagem à esquerda,
   importar dados à direita — cada um ocupa só o espaço que precisa em vez de
   uma linha inteira de cards grandes (cards-grid) seguida de outra linha só
   pra importar. */
.distribuicao-topo {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-bottom: 1rem;
}
.distribuicao-topo .resumo-card-compacto { flex-shrink: 0; }
.distribuicao-importar { flex: 1; min-width: 260px; }
.distribuicao-importar h3 { margin: 0 0 0.5rem; }
.distribuicao-importar .etapas-progresso { margin-bottom: 0; }

.legenda-cores span { display: flex; align-items: center; gap: 0.4rem; }
.legenda-cores .swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.legenda-cores .swatch-duplicada { background-color: #7a2a20; }
.legenda-cores .swatch-enviada { background-color: #1e5c38; }
.legenda-cores .swatch-bradesco { background-color: #8B0000; }
.legenda-cores .swatch-inter { background-color: #d35400; }
.legenda-cores .swatch-perdido { background-color: #4a4f57; }
.legenda-cores .swatch-aprovada { background-color: #1e5c38; }
.legenda-cores .swatch-reneg { background-color: #b8860b; }
.legenda-cores .swatch-indefinida { background-color: #d35400; }
.legenda-cores .swatch-excluida { background-color: #8B0000; }
.legenda-cores .swatch-recebido { background-color: #1e5c38; }
.legenda-cores .swatch-avencer { background-color: #2d66c3; }
.legenda-cores .swatch-vencido { background-color: #8B0000; }
.legenda-cores .swatch-cancelado { background-color: #4a4f57; }

/* Gráfico de barras dos painéis (Financeiro > Securitizadora) — sem
   biblioteca: a largura da barra é a proporção do valor sobre o maior valor
   da série, e as faixas coloridas dentro dela são a composição desse total
   (recebido/vencido/a vencer/cancelado). Cores fixas, não var(--...), pelo
   mesmo motivo das linhas destacadas: não podem sumir em nenhum tema. */
.barra-trilha {
  background: var(--bg-tertiary);
  border-radius: 6px;
  min-width: 80px;
}
.barra-composta {
  display: flex;
  height: 12px;
  border-radius: 6px;
  overflow: hidden;
  min-width: 3px;
}
.barra-composta span { display: block; height: 100%; }
.barra-recebido { background-color: #1e5c38; }
.barra-avencer { background-color: #2d66c3; }
.barra-vencido { background-color: #8B0000; }
.barra-cancelado { background-color: #4a4f57; }
.celula-barra { width: 22%; min-width: 90px; }

/* Barra de progresso das etapas (Cobrança > Distribuição). 4 estados por
   passo: pendente (ainda não rodou), andamento (rodando agora), concluida,
   erro. Sem linha conectando os passos de propósito — mantém simples. */
.etapas-progresso {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.etapa-passo {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.85rem;
  border-radius: 999px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-size: 0.85rem;
  transition: all 0.15s ease;
}
.etapa-numero {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  background: var(--bg-secondary);
  font-size: 0.75rem;
  font-weight: 700;
}
.etapa-passo.andamento {
  border-color: var(--accent);
  color: var(--text-primary);
}
.etapa-passo.andamento .etapa-numero { background: var(--accent); color: #fff; animation: etapa-pulso 1s ease-in-out infinite; }
.etapa-passo.concluida {
  border-color: var(--success);
  color: var(--text-primary);
}
.etapa-passo.concluida .etapa-numero { background: var(--success); color: #fff; }
.etapa-passo.erro {
  border-color: var(--danger);
  color: var(--text-primary);
}
.etapa-passo.erro .etapa-numero { background: var(--danger); color: #fff; }
@keyframes etapa-pulso {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

.contador-pendentes {
  display: inline-block;
  padding: 0.35rem 0.85rem;
  border-radius: 20px;
  background: rgba(241, 196, 15, 0.15);
  color: #f1c40f;
  font-weight: 600;
  font-size: 0.85rem;
  margin-bottom: 0.75rem;
}

/* Linha do filtro com as ações de lote agrupadas à direita — padrão do
   projeto pra qualquer tela de listagem com filtro de data (ver CLAUDE.md,
   seção "Listagens com filtro"). */
.filtro-linha {
  display: flex;
  justify-content: space-between;
  align-items: center;  /* mesmo motivo do .filtro-data: tudo centrado na linha */
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-bottom: 1rem;
}
.acoes-lote { display: flex; gap: 0.5rem; flex-wrap: wrap; }

.badge-conferido { color: var(--success); font-weight: 600; }
.badge-pendente { color: #f1c40f; }
/* Boleto cancelado/baixado no banco (Comercial > Boletos emitidos): estado
   final e "negativo", vermelho — em contraste com "A vencer" (amarelo, ainda
   em aberto) e "Pago" (verde). */
.badge-cancelado { color: var(--danger); font-weight: 600; }
.btn-conferir {
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--bg-tertiary);
  color: white;
  cursor: pointer;
  font-size: 0.8rem;
  font-weight: 600;
  text-decoration: none;
  display: inline-block;
  transition: all 0.15s ease;
  /* mesmo motivo do .btn-novo: <a> herda a fonte do body e <button> usa a do
     sistema — sem fixar, os dois saem com tamanhos diferentes lado a lado. */
  font-family: inherit;
  line-height: 1.4;
  text-align: center;
}

/* Submit com a cara de .btn-conferir (ex.: "Aplicar filtros" nos modais): a
   regra global button[type="submit"] tem especificidade MAIOR que a classe
   (atributo+elemento vs 1 classe) e inflava padding/fonte/margem — o botão
   saía mais alto que o <a> "Limpar" ao lado. Devolve as métricas da classe;
   o background de destaque do submit fica. */
button[type="submit"].btn-conferir {
  padding: 0.3rem 0.7rem;
  font-size: 0.8rem;
  margin-top: 0;
  width: auto;
}
/* o width:100% de submit dentro de form de modal (.modal-caixa form button)
   tem 2 classes + 2 elementos — precisa deste seletor mais forte pra soltar */
.modal-caixa form button[type="submit"].btn-conferir { width: auto; }

/* X de fechar no canto do modal — reutilizável em qualquer .modal-caixa
   (vai como último filho do .topbar do modal, que já é flex space-between). */
.modal-fechar {
  background: none;
  border: none;
  color: var(--text-secondary);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.1rem 0.45rem;
}
.modal-fechar:hover { color: var(--danger); background: none; }

/* Só a cor do texto muda no tema claro — tamanho/borda/etc já vêm da regra
   base acima. Trocar de tema nunca deve mudar o tamanho de nada, só a
   paleta. */
:root[data-theme="light"] .btn-conferir {
  color: #16386b;
}

.btn-conferir:hover { background: var(--accent); }

/* Variantes de cor pra .btn-novo/.btn-conferir que antes eram fixas via
   style="background:#7f1d1d"/"#334155" inline — sempre a mesma cor nos dois
   temas. No tema claro isso ficava especialmente ruim: o texto de
   .btn-conferir vira #16386b (escuro, pensado pro fundo claro padrão), e em
   cima de um fundo vermelho-escuro fixo dava texto escuro sobre fundo
   escuro (ex.: "Solicitar exclusão" quase ilegível). Usam !important porque
   .btn-conferir e a variante têm a mesma especificidade (1 classe) e a regra
   :root[data-theme="light"] .btn-conferir (2 classes) senão venceria. */
.btn-perigo,
:root[data-theme="light"] .btn-perigo {
  background: var(--danger) !important;
  color: white !important;
}
.btn-perigo:hover { filter: brightness(0.88); }

.btn-secundario,
:root[data-theme="light"] .btn-secundario {
  background: var(--bg-tertiary) !important;
  color: var(--text-primary) !important;
  border: 1px solid var(--border-color) !important;
}
.btn-secundario:hover { background: var(--accent) !important; color: white !important; }

.erro-form {
  color: var(--danger);
  background: var(--bg-secondary);
  border: 1px solid var(--danger);
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
  max-width: 480px;
  font-size: 0.9rem;
}

/* .hint/.erro-campo são <p> — sem isso, a margem padrão do navegador pra
   parágrafo soma em cima do gap do flex container, criando espaços bem
   maiores que os outros (ex.: depois da dica do Número do Contrato). */
.hint { color: var(--text-secondary); font-size: 0.85rem; margin: 0; }

.form-card {
  background: var(--bg-secondary);
  padding: 1.5rem;
  margin: 1rem 0;
  border-radius: 12px;
  border: 1px solid var(--border-color);
  box-shadow: 0 12px 35px var(--shadow);
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  border-left: 4px solid transparent;
}
.form-card label { font-size: 0.85rem; color: var(--text-secondary); }
.form-card input, .form-card select {
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 1rem;
  width: 100%;
}
.form-card input:focus, .form-card select:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
}
/* Rádio/checkbox não é campo de texto: SEM width:100% — senão o círculo
   estica a linha, separa do próprio rótulo e espreme o texto até quebrar
   (mordeu no formulário de Análise, 2026-08-28). Tamanho fixo confortável
   (o nativo de 13px ficava espremido) + flex-shrink 0 pra nunca encolher
   dentro de label flex. */
.form-card input[type="radio"], .form-card input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
  padding: 0;
  flex-shrink: 0;
  accent-color: var(--accent);
}
/* Fileira de opções de rádio (formulário de Análise e afins): respiro
   horizontal generoso e rótulo SEM quebra — "Não (-1 pt)" fica numa linha. */
.opcoes-analise {
  display: flex;
  gap: 0.6rem 2.25rem;
  align-items: center;
  flex-wrap: wrap;
  padding: 0.15rem 0 0.35rem;
}
.opcoes-analise label {
  display: flex;
  gap: 0.45rem;
  align-items: center;
  font-weight: 400;
  white-space: nowrap;
  font-size: 0.95rem;
  color: var(--text-primary);
}
.form-card button {
  padding: 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--accent);
  color: white;
  font-weight: 600;
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.15s ease;
}
.form-card button:hover { background: var(--accent-hover); transform: translateY(-1px); }

/* Tons pra distinguir as telas de baixa (vermelho) e abatimento (verde),
   pedido explícito pra não confundir os cobradores em telas parecidas. */
.form-card.tema-baixa {
  background: #2a1420;
  border-left-color: var(--danger);
}
.form-card.tema-baixa button { background: var(--danger); }
.form-card.tema-baixa button:hover { background: #ff5c5c; }

.form-card.tema-abatimento {
  background: #0f2a1f;
  border-left-color: var(--success);
}
.form-card.tema-abatimento button { background: var(--success); }
.form-card.tema-abatimento button:hover { background: #2ecc71; }

/* As duas cores acima são fixas (não usam var(--bg-secondary)) de propósito,
   pra manter o contraste vermelho/verde independente do tema — mas o TOM
   escuro original só funciona no fundo escuro; no tema claro precisa de um
   tingimento bem mais claro pra não virar um bloco escuro isolado na tela. */
:root[data-theme="light"] .form-card.tema-baixa { background: #fdecea; }
:root[data-theme="light"] .form-card.tema-abatimento { background: #e8f6ee; }

.btn-baixa { background: var(--danger); }
.btn-baixa:hover { background: #ff5c5c; }
.btn-abatimento { background: var(--success); }
.btn-abatimento:hover { background: #2ecc71; }

.modal-fundo {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  /* desfoca a tela atrás do modal — o rgba acima segue como fallback pra
     navegador sem suporte a backdrop-filter */
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 1000;
  align-items: center;
  justify-content: center;
}
.modal-fundo.aberto { display: flex; }
.modal-caixa {
  background: var(--bg-secondary);
  border-radius: 12px;
  border: 1px solid var(--border-color);
  box-shadow: 0 12px 35px var(--shadow);
  padding: 1.5rem;
  width: min(90vw, 520px);
  max-height: 80vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
/* Variante larga — modal com tabela dentro (ex.: status de emissão em
   Comercial > Boletos SEC pendentes), onde 520px deixa as colunas apertadas. */
.modal-caixa-larga { width: min(90vw, 720px); }
/* Placeholder de alerta — campo vazio de propósito que PRECISA ser preenchido
   pelo operador (ex.: Número do Contrato quando a origem é SEC, onde o
   placeholder pede o número da CCB). opacity:1 porque o padrão do navegador
   deixa o placeholder translúcido e o vermelho perderia força. */
input.placeholder-alerta::placeholder {
  color: var(--danger);
  opacity: 1;
  font-weight: 600;
}

/* Modal genérico de aviso/confirmação (Modal.avisar/Modal.confirmar, base.js).
   pre-line porque as mensagens herdadas dos antigos alert() usam \n pra
   separar linhas (ex.: lista de erros de um lote). */
.modal-mensagem {
  margin: 0;
  color: var(--text-secondary);
  white-space: pre-line;
  line-height: 1.5;
}
.modal-acoes { display: flex; gap: 0.5rem; justify-content: flex-end; }

/* Visualizador de documento (Modal.visualizar) — precisa de bem mais espaço
   que o modal de aviso: ocupa quase a tela toda e deixa o arquivo caber
   inteiro, sem cortar nem estourar o modal. */
.modal-caixa-visualizador {
  width: min(96vw, 1100px);
  max-height: 92vh;
}
.modal-caixa-visualizador .modal-mensagem {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 55vh;
  background: var(--bg-tertiary);
  border-radius: 8px;
  overflow: auto;
}
.visor-documento {
  max-width: 100%;
  max-height: 78vh;
  border: none;
  border-radius: 6px;
}
iframe.visor-documento {
  width: 100%;
  height: 78vh;
  background: #fff;  /* PDF em fundo escuro fica ilegível enquanto carrega */
}
/* Miniatura clicável — o cursor é o que avisa que dá pra abrir. */
.imagem-container img,
.imagem-container .miniatura-arquivo {
  cursor: zoom-in;
}
.imagem-container .miniatura-arquivo {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  width: 110px;
  height: 110px;
  background: var(--bg-tertiary);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 600;
}
.modal-caixa input {
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 1rem;
}

/* Formulário dentro de modal (ex.: "Novo usuário", "Nova conexão"): sem isso,
   label/input seguem o fluxo inline padrão do navegador — texto e campos se
   espalham lado a lado em vez de empilhar, e os inputs ficam com a largura
   mínima do navegador em vez de ocupar o modal. Mesmo raciocínio de
   .form-card, mas sem repetir o "cartão dentro do cartão" (fundo/sombra/
   borda já vêm do .modal-caixa em volta). */
.modal-caixa form {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}
.modal-caixa form label { font-size: 0.85rem; color: var(--text-secondary); }
.modal-caixa form input:not([type="checkbox"]):not([type="radio"]),
.modal-caixa form select {
  width: 100%;
}
.modal-caixa form select {
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 1rem;
}
.modal-caixa form button[type="submit"] { width: 100%; }

/* Checkbox redondo, igual ao sist_cobranca.html. Tamanho FIXO em qualquer
   contexto (regra da casa 2026-08-29): min/max + flex-shrink 0 blindam
   contra width:100% herdado de campo de texto e contra encolher em label
   flex — checkbox nunca estica nem espreme. */
input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  min-width: 20px;
  max-width: 20px;
  min-height: 20px;
  max-height: 20px;
  padding: 0;
  flex-shrink: 0;
  border: 2px solid var(--text-primary);
  border-radius: 50%;
  background-color: transparent;
  cursor: pointer;
  position: relative;
  vertical-align: middle;
}
input[type="checkbox"]:checked {
  background-color: var(--accent);
  border-color: var(--accent);
}
input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 10px;
  height: 10px;
  background: white;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
input[type="checkbox"]:hover {
  box-shadow: 0 0 5px rgba(255, 255, 255, 0.5);
}

.conteudo {
  flex: 1;
  padding: 2rem;
  min-width: 0; /* deixa o filho encolher e a tabela rolar, em vez de estourar a tela */
}

/* Barra de busca solta no topo de uma listagem (Clientes, Negociações) —
   ficava fora de .form-card/.filter-group/.modal-caixa, então nunca herdava
   nada e caía no input cru do navegador. */
.input-busca {
  display: block;
  width: 100%;
  max-width: 480px;
  margin-bottom: 1rem;
  padding: 0.65rem 1rem;
  border-radius: 10px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 0.95rem;
  box-shadow: 0 8px 20px var(--shadow);
  transition: all 0.15s ease;
}
.input-busca::placeholder { color: var(--text-secondary); }
.input-busca:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent);
}

.tabela-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 10px;
}
.tabela-scroll table.dados {
  min-width: 640px;
}
/* Exceção: a tabelinha de cronograma da Calculadora (Negociação) só tem 3
   colunas estreitas (Parcela/Vencimento/Valor) — herdar o min-width:640px
   genérico (pensado pra tabelas largas tipo Cobrança/Caixa) força ela a ficar
   bem mais larga que a coluna lateral (300-380px) onde mora, sobrando
   scroll horizontal desnecessário e, com a tabela ainda vazia ("Preencha os
   dados acima pra calcular."), um texto cortado. */
.resumo-card .tabela-scroll table.dados {
  min-width: 0;
}

.sidebar-separador {
  height: 1px;
  background: var(--border-color);
  opacity: 0.3;
  margin: 0.5rem 0;
}

/* Cadastro de Clientes — campo com lápis de edição inline */
.campo-cliente {
  margin-bottom: 0.9rem;
}
.campo-cliente label {
  display: block;
  font-size: 0.8rem;
  color: var(--text-secondary);
  margin-bottom: 0.2rem;
}
.campo-valor {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.btn-editar-campo {
  background: none;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 0.95rem;
  padding: 0.1rem 0.3rem;
}
.btn-editar-campo:hover { color: var(--accent-hover); }

.campo-editando {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.3rem;
}
.campo-editando input {
  padding: 0.4rem 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 0.95rem;
}
.campo-editando ._campo-acoes {
  display: flex;
  gap: 0.4rem;
}

.dropdown-banco {
  position: absolute;
  z-index: 50;
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  max-height: 220px;
  overflow-y: auto;
  box-shadow: 0 8px 20px var(--shadow);
  min-width: 220px;
}
.dropdown-banco .dropdown-item {
  padding: 0.5rem 0.75rem;
  cursor: pointer;
  font-size: 0.85rem;
  border-bottom: 1px solid var(--border-color);
}
.dropdown-banco .dropdown-item:hover { background: var(--bg-tertiary); }

.galeria-imagens {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.imagem-container {
  position: relative;
  display: inline-block;
}
.imagem-container img {
  width: 90px;
  height: 90px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border-color);
  cursor: pointer;
}
.imagem-container a {
  display: inline-block;
  padding: 0.4rem 0.7rem;
  background: var(--bg-tertiary);
  border-radius: 6px;
  color: var(--text-primary);
  font-size: 0.8rem;
  text-decoration: none;
}
/* .imagem-container .btn-excluir-documento (2 classes) em vez de só
   .btn-excluir-documento (1 classe) — de propósito: ".form-card button" (1
   classe + 1 elemento) tem especificidade maior que uma classe sozinha e
   vencia aqui dentro (fundo azul do accent em vez do vermelho de danger,
   padding/border-radius/font-size errados), mesmo problema que
   ".form-card.tema-baixa button" já resolve do mesmo jeito. */
.imagem-container .btn-excluir-documento {
  position: absolute;
  top: -6px;
  /* -6px (não -15px): o gap da galeria é 8px — vazando 15px pra fora, o
     botão ficava ATRÁS da miniatura vizinha (container posicionado que vem
     depois no DOM pinta por cima) e sumia quando havia 2+ anexos. O z-index
     garante que ele fica clicável por cima de qualquer vizinho. */
  right: -6px;
  z-index: 2;
  width: 22px;
  height: 22px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-color);
  border-radius: 11px;
  background: var(--danger);
  color: white;
  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
}
.imagem-container .btn-excluir-documento:hover { filter: brightness(0.9); }

/* Cadastro NOVO de Pessoa Física — textarea/file não tinham estilo próprio
   (a regra de .form-card só cobria input/select) e bloco de conexão dinâmica. */
.form-card textarea {
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 1rem;
  font-family: inherit;
  width: 100%;
  resize: vertical;
}
.form-card textarea:focus {
  outline: none;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
}
.form-card input[type="file"] {
  padding: 0.5rem 0;
  border: none;
  background: none;
  color: var(--text-secondary);
  width: 100%;
}

.conexao-bloco {
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

/* Sistema de Caixa (variados/sist-baixa.html) — filtros, resumo, mensagens de
   feedback e destaque de item ativo no autocomplete (reaproveita .dropdown-banco). */
.filters {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.filter-group {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
}
.filter-group label { color: var(--text-secondary); }
.filter-group input, .filter-group select {
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
}
/* .filtro-data (Caixa) já tinha essa regra pro botão de buscar/filtrar —
   .filter-group (Caixa Relatórios, Negociações Extraídas) nunca ganhou a
   equivalente, então "Buscar"/"Visualizar..." caía no botão cru do
   navegador. Mesmo visual de .filtro-data button, por consistência. */
.filter-group button {
  padding: 0.5rem 1rem;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--accent);
  color: white;
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.15s ease;
}
.filter-group button:hover { background: var(--accent-hover); transform: translateY(-1px); }
.filter-group button.btn-conferir { background: var(--bg-tertiary); }
.filter-group button.btn-conferir:hover { background: var(--accent); }

.resumo-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  box-shadow: 0 8px 25px var(--shadow);
  padding: 1rem 1.25rem;
  margin: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  border-left: 4px solid transparent;
}

/* Grid genérico de 2 colunas pra distribuir vários .form-card lado a lado
   em vez de empilhados numa coluna só — evita rolagem longa e cards de
   480px perdidos soltos num container bem mais largo. align-items:start
   faz cada card manter sua própria altura, sem esticar pra igualar o
   vizinho da linha (cards de tamanhos bem diferentes, ex. "Conexões" vazio
   ao lado de "Documentos", ficariam com espaço vazio esquisito se
   esticassem). Usado em telas de cadastro com vários cards curtos (ex.
   Novo Cliente). */
.cards-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  align-items: start;
}
@media (max-width: 760px) {
  .cards-grid { grid-template-columns: 1fr; }
}

/* Tela de Negociação — Calculadora fixa (sticky) do lado, sempre visível
   enquanto rola os outros campos. */
.negociacao-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
  gap: 1rem;
  align-items: start;
}
/* Área principal em 2 colunas fixas pra equilibrar visualmente: "Negociação"
   (card mais longo) sozinho numa coluna, Cliente/Classificação/Abatimento
   empilhados juntos na outra — a soma da altura dos 3 fica parecida com a
   altura do card "Negociação" sozinho. Grid determinístico (não
   column-count/masonry) porque aqui a divisão é fixa por conteúdo, não
   "o que couber": sempre Negociação de um lado, os outros 3 do outro. */
.negociacao-col-principal {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.85rem;
  align-items: start;
  min-width: 0;
}
.negociacao-col-principal > .form-card {
  margin: 0;
}
.negociacao-subcol {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}
.negociacao-subcol > .form-card {
  margin: 0;
}
.negociacao-col-lateral {
  position: sticky;
  top: 1rem;
}
.negociacao-col-lateral > .resumo-card {
  margin: 0;
}
@media (max-width: 900px) {
  .negociacao-grid { grid-template-columns: 1fr; }
  .negociacao-col-lateral { position: static; }
}
@media (max-width: 700px) {
  .negociacao-col-principal { grid-template-columns: 1fr; }
}

.resumo-card h3 { margin: 0; }
.resumo-grid {
  display: flex;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.resumo-item { font-size: 0.85rem; color: var(--text-secondary); }
.resumo-valor { font-size: 1.2rem; font-weight: 700; color: var(--text-primary); }

/* Versão reduzida — indicadores tipo "12 x Sacado(s)" que não precisam do
   destaque/tamanho de um resumo-card cheio, só liberar espaço vertical. */
.resumo-card-compacto { padding: 0.5rem 1rem; margin: 0; gap: 0.25rem; }
.resumo-card-compacto .resumo-grid { gap: 1rem; }
.resumo-card-compacto .resumo-item { font-size: 0.75rem; }
.resumo-card-compacto .resumo-valor { font-size: 0.95rem; }

/* Grade de contagem de cédulas/moedas (Financeiro > Caixa Físico) — 1 label
   com o valor da denominação + 1 input de quantidade por célula, várias
   colunas em telas largas, empilha em 1 coluna no mobile (mesmo breakpoint
   geral do resto do app, ver media query no fim do arquivo). */
.contagem-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 0.75rem;
}
.contagem-grid label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.85rem;
  color: var(--text-secondary);
}

/* Blocos individuais do card "Contrato" (negociacoes_detalhe.html) — cada
   linha (Valor Total, Parcela N, etc.) com seu próprio botão de copiar,
   reaproveitando .resumo-item/.resumo-valor pro texto e só acrescentando o
   ícone ao lado. */
.contrato-bloco-linha { display: flex; align-items: center; gap: 0.4rem; }
.contrato-bloco-valor { font-size: 1rem; word-break: break-word; }
.btn-copiar-bloco {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.1rem 0.25rem;
  font-size: 0.95rem;
  line-height: 1;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.btn-copiar-bloco:hover { color: var(--accent); }

.message {
  padding: 0.6rem 0.9rem;
  border-radius: 8px;
  font-size: 0.9rem;
  margin-top: 0.75rem;
}
.message.success { background: rgba(39, 174, 96, 0.15); border: 1px solid var(--success); color: var(--success); }
.message.error   { background: rgba(231, 76, 60, 0.15); border: 1px solid var(--danger); color: var(--danger); }
.message.warning { background: rgba(241, 196, 15, 0.15); border: 1px solid #f1c40f; color: #f1c40f; }
.message.info    { background: rgba(45, 102, 195, 0.15); border: 1px solid var(--accent); color: var(--accent-hover); }

.dropdown-banco .dropdown-item.autocomplete-active { background: var(--accent); }

.valor-pix-insuficiente { box-shadow: 0 0 0 2px var(--danger) !important; }
.valor-maior { box-shadow: 0 0 0 2px #f1c40f !important; }
.valor-menor { box-shadow: 0 0 0 2px var(--danger) !important; }
.campo-invalido { box-shadow: 0 0 0 2px var(--danger) !important; }

/* Mensagem de validação em tempo real (CPF inválido / telefone repetido),
   sob o campo — vazia e sem altura quando não há erro. */
.erro-campo {
  color: var(--danger);
  font-size: 0.8rem;
  margin: -0.4rem 0 0;
  min-height: 1em;
}

/* Responsivo — sidebar vira barra superior, tabelas rolam na horizontal em
   vez de estourar a tela, formulários/modais ocupam a largura toda. */
@media (max-width: 768px) {
  .layout {
    flex-direction: column;
  }
  .sidebar {
    width: 100%;
    flex-direction: row;
    flex-wrap: wrap;
    border-right: none;
    border-bottom: 1px solid var(--border-color);
    gap: 0.5rem;
    padding: 0.75rem;
  }
  .sidebar-header {
    width: 100%;
  }
  /* Modo recolhido é um recurso de desktop (sidebar lateral) — no mobile a
     sidebar já vira barra horizontal, então ignora data-sidebar e mantém
     tudo visível/expandido como sempre foi. */
  .sidebar, :root[data-sidebar="recolhida"] .sidebar {
    width: 100%;
  }
  :root[data-sidebar="recolhida"] .sidebar-texto {
    display: inline;
  }
  :root[data-sidebar="recolhida"] .sidebar-saudacao {
    display: block;
  }
  :root[data-sidebar="recolhida"] .sidebar-secao-titulo {
    display: flex;
  }
  :root[data-sidebar="recolhida"] .sidebar-categoria {
    justify-content: flex-start;
  }
  :root[data-sidebar="recolhida"] .sidebar-header {
    justify-content: space-between;
  }
  .sidebar-toggle {
    display: none;
  }
  .conteudo {
    padding: 1rem;
  }
  .topbar {
    flex-direction: column;
    align-items: stretch;
  }
  .topbar > div {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  .filtro-data {
    flex-wrap: wrap;
  }
  .form-card, .modal-caixa {
    width: 100%;
    max-width: 100%;
  }
  .modal-caixa {
    max-height: 90vh;
  }
  button, .btn-novo, .btn-conferir {
    font-size: 0.85rem;
  }
  button[type="submit"] {
    width: 100%;
  }
}


/* =====================================================================
   Tabela que vira CARTÃO no celular — opt-in por `class="tabela-cartoes"`
   na table (2026-08-31, Cobrança presencial).

   O `.tabela-scroll` genérico resolve tabela larga fazendo ela rolar na
   horizontal, e isso basta pra uma tela de escritório. Não basta pra quem
   usa o ERP DE PÉ, na porta do devedor: lá a linha tem que caber na tela
   inteira, e o alvo do dedo tem que ser grande.

   Cada `td` vira uma linha "rótulo: valor", com o rótulo saindo do
   `data-rotulo` do próprio td — por isso TODO td precisa do atributo, senão
   a célula aparece sem contexto quando o thead some. O primeiro td é o
   título do cartão.

   Só nesta classe: as demais tabelas seguem rolando na horizontal, que é o
   comportamento certo pra tabela de conferência (comparar coluna entre
   linhas). Não aplicar globalmente. */
@media (max-width: 768px) {
  table.dados.tabela-cartoes,
  table.dados.tabela-cartoes tbody,
  table.dados.tabela-cartoes tr,
  table.dados.tabela-cartoes td {
    display: block;
    width: 100%;
  }
  /* o cabeçalho vira redundante: o rótulo mora em cada célula */
  table.dados.tabela-cartoes thead {
    display: none;
  }
  table.dados.tabela-cartoes tr {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    margin-bottom: 0.75rem;
    padding: 0.5rem 0.75rem;
  }
  table.dados.tabela-cartoes td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    border-bottom: 1px dashed var(--border-color);
    padding: 0.5rem 0;
    /* o alinhamento automático do base.js injeta td:nth-child — aqui o
       cartão manda, senão o valor centraliza dentro da própria linha */
    text-align: right;
  }
  table.dados.tabela-cartoes td:last-child {
    border-bottom: none;
  }
  table.dados.tabela-cartoes td::before {
    content: attr(data-rotulo);
    font-size: 0.7rem;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--text-secondary);
    text-align: left;
    flex: 0 0 auto;
  }
  /* primeiro td = título do cartão: sem rótulo, maior, ocupando a linha */
  table.dados.tabela-cartoes td:first-child {
    justify-content: flex-start;
    text-align: left;
    font-weight: 600;
    font-size: 1rem;
  }
  table.dados.tabela-cartoes td:first-child::before {
    display: none;
  }
  /* alvo de dedo: no celular o cobrador está de pé, com uma mão só */
  table.dados.tabela-cartoes button,
  table.dados.tabela-cartoes .btn-conferir,
  table.dados.tabela-cartoes select,
  table.dados.tabela-cartoes input[type="text"] {
    min-height: 40px;
  }
  table.dados.tabela-cartoes select,
  table.dados.tabela-cartoes input[type="text"] {
    max-width: 60%;
  }
  /* linha vazia ("nenhuma visita") não é cartão: não tem data-rotulo */
  table.dados.tabela-cartoes td[colspan] {
    justify-content: center;
    text-align: center;
    font-weight: normal;
    font-size: inherit;
  }
}

/* Confirmação da visita: checkbox + texto na mesma linha, sem o checkbox
   herdar largura de campo (a regra global de checkbox já trava o tamanho). */
.rotulo-confirmar {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
  cursor: pointer;
}


/* =====================================================================
   Dados dos Clientes (/clientes/painel) — tela dividida PF | PJ.
   Cada metade é um painel independente: cabeçalho com contagem e botão de
   novo cadastro, busca própria e a lista rolando DENTRO do painel (por isso
   o thead sticky funciona aqui: o contêiner rola na vertical, diferente do
   .tabela-scroll genérico, que só rola na horizontal). */
.duplo-painel {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  align-items: start;
}
@media (max-width: 900px) {
  .duplo-painel { grid-template-columns: 1fr; }
}
.painel-lista {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  box-shadow: 0 8px 25px var(--shadow);
  padding: 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.painel-cabecalho {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.painel-cabecalho h3 { margin: 0; display: flex; align-items: center; gap: 0.5rem; }
.badge-contagem {
  background: var(--accent);
  color: #fff;
  border-radius: 999px;
  padding: 0.1rem 0.6rem;
  font-size: 0.75rem;
  font-weight: 600;
}
.painel-lista .input-busca { margin-bottom: 0; max-width: none; }
.painel-scroll {
  max-height: 60vh;
  overflow: auto;
  border-radius: 10px;
  transition: opacity 0.15s ease;
}
.painel-scroll.buscando { opacity: 0.45; }
.painel-scroll table.dados { min-width: 0; }
.painel-scroll thead th { position: sticky; top: 0; z-index: 2; }
.painel-rodape { margin: 0; }

/* Linha inteira clicável (leva ao detalhe) — a seta na última coluna é a
   affordance de que a linha é um link. */
.tabela-clicavel tbody tr[data-href] { cursor: pointer; }
.celula-seta {
  width: 1.5rem;
  text-align: center;
  color: var(--text-secondary);
  font-size: 1rem;
}
.tabela-clicavel tbody tr[data-href]:hover .celula-seta {
  color: #fff;
  transform: translateX(2px);
}
.celula-seta { transition: transform 0.15s ease, color 0.15s ease; }

/* =====================================================================
   Interações globais — movimento sutil pra tela parecer viva sem atrapalhar
   o uso. TUDO aqui respeita prefers-reduced-motion (bloco no fim). */

html { scroll-behavior: smooth; }

/* Entrada suave dos cards quando a tela carrega (e quando um form-card
   escondido vira display:block — a animação roda de novo, virando um reveal).
   Só cards: animar tabela grande (6 mil linhas em Clientes) custaria caro. */
@keyframes surgir {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.hub-card, .form-card, .resumo-card, .painel-lista {
  animation: surgir 0.3s ease both;
}
/* Escadinha nos grids de cards — cada card chega um tiquinho depois. */
.hub-grid > :nth-child(2), .cards-grid > :nth-child(2), .duplo-painel > :nth-child(2) { animation-delay: 0.06s; }
.hub-grid > :nth-child(3), .cards-grid > :nth-child(3) { animation-delay: 0.12s; }
.hub-grid > :nth-child(4), .cards-grid > :nth-child(4) { animation-delay: 0.18s; }
.hub-grid > :nth-child(n+5), .cards-grid > :nth-child(n+5) { animation-delay: 0.24s; }

/* Hover das linhas de tabela com transição (o destaque já existia, era seco). */
table.dados tbody tr { transition: background-color 0.12s ease; }

/* Sidebar: leve deslize no hover, na direção do clique. */
.sidebar-link { transition: background-color 0.15s ease, transform 0.15s ease; }
.sidebar-link:hover { transform: translateX(2px); }

/* Ondulação (ripple) ao clicar em botões — o span é criado pelo base.js no
   ponto do clique e se remove sozinho no fim da animação. position:relative +
   overflow:hidden ficam por classe; regras mais específicas (ex.:
   .sidebar-toggle, que é fixed) continuam valendo. */
button, .btn-novo, .btn-conferir { position: relative; overflow: hidden; }
.ondulacao {
  position: absolute;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.25;
  transform: scale(0);
  pointer-events: none;
  animation: ondular 0.5s ease-out forwards;
}
@keyframes ondular {
  to { transform: scale(1); opacity: 0; }
}

/* Botão flutuante "voltar ao topo" (injetado pelo base.js) — aparece depois
   de rolar uma tela; útil nas listagens longas. */
.btn-topo {
  position: fixed;
  right: 1.25rem;
  bottom: 1.25rem;
  z-index: 30;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--border-color);
  background: var(--accent);
  color: #fff;
  font-size: 1.1rem;
  cursor: pointer;
  box-shadow: 0 8px 25px var(--shadow);
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease, background 0.15s ease;
}
.btn-topo.visivel { opacity: 1; transform: translateY(0); pointer-events: auto; }
.btn-topo:hover { background: var(--accent-hover); }

/* Foco visível consistente pra quem navega por teclado. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Quem pediu menos movimento no sistema operacional recebe tudo parado:
   animações e transições viram instantâneas e a rolagem deixa de ser suave. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Campo de texto do Modal.pedirTexto (motivo obrigatório) — mesmo visual dos
   inputs de formulário, dentro da caixa do modal. */
.modal-campo-texto {
  display: block;
  width: 100%;
  margin-top: 0.75rem;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 0.9rem;
  font-family: inherit;
  resize: vertical;
}

/* Configurações agrupadas por categoria (2026-08-29): título de seção
   discreto + cards lado a lado. O flex zera o margin próprio do .form-card
   (o gap manda) e solta o max-width padrão de 480px até o teto da fileira. */
.config-secao { margin: 1.75rem 0 0; }
.config-secao h2 {
  margin: 0;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--border-color);
  color: var(--text-secondary);
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.config-cards {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  align-items: flex-start;
  margin-top: 0.9rem;
}
.config-cards .form-card {
  flex: 1 1 360px;
  max-width: 560px;
  margin: 0;
}

/* Contas a Pagar/Receber: conta vencida em aberto — cor fixa (não some em
   nenhum tema), mesmo desenho das demais tr.linha-*. */
table.dados tr.linha-conta-vencida { background-color: #8a1f2d; }
table.dados tr.linha-conta-vencida td { color: #fff; }
table.dados tr.linha-conta-vencida:hover { background-color: #a32738; }
.swatch-conta-vencida { background-color: #8a1f2d; }

/* Campos dos modais de Contas (fora de <form> — mesma largura da regra
   .modal-caixa form acima) + rádio com o tamanho fixo do form-card
   (lição de 2026-08-28: rádio nunca herda largura de campo de texto). */
.modal-caixa input:not([type="checkbox"]):not([type="radio"]),
.modal-caixa select,
.modal-caixa textarea {
  width: 100%;
}
.modal-caixa select,
.modal-caixa textarea {
  padding: 0.6rem 0.75rem;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-size: 1rem;
  font-family: inherit;
}
.modal-caixa input[type="radio"] {
  width: 1rem;
  height: 1rem;
  padding: 0;
  flex-shrink: 0;
  accent-color: var(--accent);
}
