:root {
  /* marca / ação primária */
  --asj-blue: #0c4cae;
  --asj-blue-dark: #08367c;
  --asj-blue-soft: #eaf2ff;

  /* base (shell, textos, bordas) */
  --bg: #f4f7fb;
  --card: #ffffff;
  --text: #0f172a;
  --muted: #5b6475;
  --line: #dbe4f0;
  --danger: #dc2626;
  --success: #059669;
  --warning: #d97706;
  --warning-soft: #fff7ed;

  /* sidebar */
  --sidebar-bg: #081a3d;
  --sidebar-line: rgba(255, 255, 255, 0.12);
  --sidebar-accent: #1e3a70;
  --sidebar-accent-hover: #2c4f8f;

  /* superfícies de cadastro/tabelas/ações (ex-bloco solto "ERP INDUSTRIAL") */
  --erp-bg: #f3f5f7;
  --erp-surface: #ffffff;
  --erp-surface-2: #f8fafc;
  --erp-border: #d9e0e7;
  --erp-border-soft: #e8edf2;
  --erp-text: #1f2a37;
  --erp-text-soft: #5b6875;
  --erp-primary: #0c4cae;
  --erp-primary-soft: #eaf2ff;
  --erp-primary-soft-2: #dce9ff;
  --erp-hover: #f4f8fc;
  --erp-danger-soft: #f3f5f7;
  --erp-danger-text: #51606f;
  --erp-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: Arial, Helvetica, sans-serif;
}

/* Trava o scroll da página inteira: só .sidebar e .content rolam,
   cada um dentro da própria caixa. Sem isso, quando o scroll interno
   de .content chega ao fim, o navegador "encadeia" o scroll pro body
   inteiro — e a sidebar (com o menu) rola junto e some do topo. */
html, body {
  height: 100%;
  overflow: hidden;
}

body {
  background: var(--erp-bg);
  color: var(--erp-text);
}

.app {
  display: flex;
  height: 100vh;
}

/* SIDEBAR */
.sidebar {
  width: 300px;
  background: var(--sidebar-bg);
  color: #fff;
  padding: 20px;
  border-right: 4px solid var(--sidebar-accent);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.sidebar-brand {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 12px;
}

.sidebar-logo {
  width: 110px;
  height: 110px;
  object-fit: contain;
  background: transparent;
  border-radius: 12px;
  display: block;
  flex-shrink: 0;
}

.sidebar-company-info {
  text-align: center;
  padding-bottom: 18px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--sidebar-line);
}

.sidebar-company-info h2 {
  font-size: 15px;
  line-height: 1.35;
  color: #ffffff;
  font-weight: 800;
  text-transform: uppercase;
  margin-bottom: 10px;
}

.sidebar-company-lines {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sidebar-company-lines span {
  font-size: 12px;
  color: #dbeafe;
  line-height: 1.35;
}

/* MENU */
.menu {
  list-style: none;
  padding: 0;
  margin: 0;
}

.menu-item {
  padding: 12px 14px;
  cursor: pointer;
  font-weight: 800;
  font-size: 16px;
  color: #ffffff;
  border-radius: 8px;
  transition: 0.2s;
  text-transform: uppercase;
  margin-bottom: 6px;
}

.menu-item:hover {
  background: rgba(12, 76, 174, 0.25);
}

.hidden {
  display: none;
}

/* MAIN */
.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.page-title-hidden {
  display: none;
}

/* CONTENT */
.content {
  padding: 20px;
  overflow-y: auto;
  height: 100vh;
  overscroll-behavior: contain;
}

/* CARDS */
.form-card {
  background: #fff;
  border-radius: 14px;
  padding: 18px;
  margin-top: 15px;
  border: 1px solid var(--line);
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.04);
}

.section-title {
  font-size: 18px;
  font-weight: 800;
  margin-bottom: 14px;
  color: var(--asj-blue-dark);
  text-transform: uppercase;
}

.summary-box {
  background: #eef5ff;
  border: 1px solid #bfd6ff;
  border-radius: 10px;
  padding: 12px;
  color: var(--asj-blue-dark);
  margin-top: 10px;
  font-weight: 700;
  line-height: 1.5;
}

/* TOOLBAR / BUTTONS */
.form-toolbar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.btn {
  padding: 10px 14px;
  border: none;
  border-radius: 8px;
  background: var(--asj-blue);
  color: #fff;
  cursor: pointer;
  white-space: nowrap;
  font-weight: 700;
  transition: 0.2s;
}

.btn:hover {
  background: var(--asj-blue-dark);
}

.btn-edit {
  background: var(--success);
}

.btn-edit:hover {
  filter: brightness(0.95);
}

.btn-delete {
  background: var(--danger);
}

.btn-delete:hover {
  filter: brightness(0.95);
}

.btn-secondary {
  background: #64748b;
}

.btn-secondary:hover {
  background: #475569;
}

/* FORM */
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-bottom: 14px;
}

.form-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-bottom: 14px;
}

.form-field {
  display: flex;
  flex-direction: column;
}

.form-field label {
  font-size: 12px;
  color: var(--asj-blue-dark);
  margin-bottom: 6px;
  font-weight: 800;
  text-transform: uppercase;
}

.form-field input,
.form-field select,
.form-field textarea,
.login-box input,
.login-box select {
  width: 100%;
  padding: 12px;
  border: 1px solid #cfd8e3;
  border-radius: 8px;
  background: #fff;
  color: var(--text);
  outline: none;
  font-size: 15px;
}

.login-box select {
  margin-bottom: 12px;
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus,
.login-box input:focus,
.login-box select:focus {
  border-color: var(--asj-blue);
  box-shadow: 0 0 0 3px rgba(12, 76, 174, 0.1);
}

.form-field textarea {
  resize: vertical;
  min-height: 100px;
}

.form-note {
  font-size: 12px;
  color: var(--muted);
  margin-top: 4px;
}

.info-box {
  background: #f8fbff;
  border: 1px solid #dbe4f0;
  border-radius: 10px;
  padding: 12px;
  color: var(--asj-blue-dark);
  margin: 10px 0 14px;
  font-size: 14px;
  line-height: 1.5;
}

/* TABLE */
.table {
  width: 100%;
  background: #fff;
  margin-top: 20px;
  border-collapse: collapse;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.04);
}

.table th,
.table td {
  padding: 12px 10px;
  border-bottom: 1px solid #edf2f7;
  text-align: left;
  vertical-align: middle;
  word-break: break-word;
  font-size: 14px;
}

.table th {
  background: #f8fbff;
  color: var(--asj-blue-dark);
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
}

/* SEARCH / PILLS */
.search-pill,
.rule-chip {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
  background: #dbeafe;
  color: var(--asj-blue-dark);
}

.search-highlight {
  background: #fde68a;
  padding: 1px 2px;
  border-radius: 4px;
}

/* LOGIN — tela dividida: barra de marca no topo, formulário à esquerda,
   foto à direita (some em telas estreitas, ver media query no final). */
.login-screen {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

.login-topbar {
  flex-shrink: 0;
  height: 64px;
  display: flex;
  align-items: center;
  padding: 0 28px;
  background: var(--sidebar-bg);
}

.login-topbar-logo {
  height: 40px;
  width: auto;
  /* logo tem fundo branco sólido — um leve destaque atrás pra não "sumir"
     em cima do azul-marinho da barra */
  background: #fff;
  border-radius: 6px;
  padding: 3px 8px;
}

.login-content {
  flex: 1;
  display: flex;
  min-height: 0;
}

.login-form-pane {
  width: 440px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  background: #fff;
  overflow-y: auto;
}

.login-photo-pane {
  flex: 1;
  background-image: url("./img/login-foto.jpg");
  background-size: cover;
  background-position: center;
}

.login-box {
  width: 100%;
  max-width: 340px;
}

.login-box .form-field {
  margin-bottom: 16px;
}

.login-logo-main {
  display: block;
  width: 180px;
  height: auto;
  margin: 0 auto 26px;
}

.login-logo-secondary {
  display: block;
  width: 130px;
  height: auto;
  margin: 20px auto 0;
  opacity: 0.85;
}

.login-box button {
  width: 100%;
  padding: 14px;
  border: none;
  border-radius: 8px;
  background: var(--success);
  color: white;
  font-weight: 800;
  font-size: 16px;
  cursor: pointer;
  transition: 0.2s;
}

.login-box button:hover {
  filter: brightness(0.92);
}

.login-error {
  margin-top: 14px;
  color: var(--danger);
  font-size: 14px;
  font-weight: 700;
  white-space: pre-wrap;
}

/* Telas estreitas: a foto não cabe bem, esconde e deixa o formulário
   ocupar a largura toda. */
@media (max-width: 900px) {
  .login-photo-pane {
    display: none;
  }
  .login-form-pane {
    width: 100%;
  }
}

.login-link-plataforma {
  display: block;
  margin-top: 18px;
  font-size: 12px;
  color: var(--text-secondary, #9aa5b1);
  text-decoration: none;
  text-align: center;
}

.login-link-plataforma:hover {
  text-decoration: underline;
}

/* Modo administração da plataforma (ASS Sistemas) — esconde o menu inteiro
   do ERP, mantém só marca/usuário/sair. Ver Main.startPlatformApp(). */
.app.platform-mode .menu,
.app.platform-mode #sidebar-empresa-endereco {
  display: none;
}

.logout-btn {
  width: 100%;
  margin-top: 20px;
  padding: 10px 12px;
  border: none;
  border-radius: 8px;
  background: #64748b;
  color: #fff;
  font-weight: 800;
  cursor: pointer;
}

.logout-btn:hover {
  background: #475569;
}

.btn-change-password-link {
  display: block;
  width: 100%;
  margin-top: 10px;
  padding: 6px 0;
  border: none;
  background: none;
  color: #dbeafe;
  font-size: 12px;
  font-weight: 700;
  text-align: center;
  cursor: pointer;
  text-decoration: underline;
}

.btn-change-password-link:hover {
  color: #fff;
}

/* RESPONSIVO */
@media (max-width: 1100px) {
  .sidebar {
    width: 280px;
  }

  .form-grid,
  .form-grid-3 {
    grid-template-columns: 1fr;
  }
}

.tabs {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.tab {
  padding: 10px 14px;
  background: #e8eef8;
  cursor: pointer;
  border-radius: 8px;
  font-weight: 800;
  color: var(--asj-blue-dark);
  transition: 0.2s;
}

.tab.active {
  background: var(--asj-blue);
  color: #fff;
}

.foto-drop-zone {
  border: 2px dashed #cbd5e1;
  border-radius: 8px;
  padding: 10px 12px;
  cursor: pointer;
  transition: border-color .2s, background .2s;
  display: flex;
  align-items: center;
  gap: 8px;
  background: #f8fafc;
}
.foto-drop-zone:hover, .foto-drop-zone.drag-over {
  border-color: #3b82f6;
  background: #eff6ff;
}
.foto-drop-hint {
  font-size: 12px;
  color: #64748b;
  pointer-events: none;
}
.foto-drop-zone input[type="file"] {
  opacity: 0;
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0; left: 0;
  cursor: pointer;
}
.foto-drop-zone { position: relative; overflow: hidden; }

.preview-img {
  width: 100%;
  max-width: 260px;
  height: 180px;
  object-fit: contain;
  background: #f3f4f6;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  margin-top: 8px;
}

.kit-card {
  background: #fff;
  padding: 15px;
  border-radius: 12px;
  margin-top: 15px;
  border: 1px solid var(--line);
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.04);
}

.kit-values {
  display: flex;
  gap: 10px;
  margin-top: 10px;
}

.kit-box {
  flex: 1;
  background: var(--asj-blue-soft);
  padding: 10px;
  text-align: center;
  border-radius: 8px;
  color: var(--asj-blue-dark);
  font-weight: 700;
}

.search-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #cfd8e3;
  border-radius: 8px;
  outline: none;
  margin-bottom: 14px;
  background: #fff;
}

.search-input:focus {
  border-color: var(--asj-blue);
  box-shadow: 0 0 0 3px rgba(12,76,174,0.10);
}

.search-pill {
  display: inline-block;
  padding: 4px 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
  background: #dbeafe;
  color: var(--asj-blue-dark);
}

.search-highlight {
  background: #fde68a;
  padding: 1px 2px;
  border-radius: 4px;
}

.stock-tabs {
  display: flex;
  gap: 10px;
  margin-bottom: 15px;
}

.stock-tabs button {
  padding: 8px 12px;
  background: #1f2937;
  color: white;
  border: none;
  cursor: pointer;
}

.stock-tabs button:hover {
  background: #374151;
}

.stock-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}

.stock-cards .card {
  padding: 15px;
  background: #111827;
  color: white;
  border-radius: 6px;
}

.stock-cards .danger {
  background: #7f1d1d;
}

.submenu {
  list-style: none;
  padding-left: 10px;
  margin-bottom: 10px;
}

.submenu-title {
  font-size: 12px;
  font-weight: 800;
  color: #93c5fd;
  margin: 8px 0 4px;
  text-transform: uppercase;
}

.submenu-item {
  padding: 8px 10px;
  font-size: 14px;
  cursor: pointer;
  border-radius: 6px;
  color: #e0e7ff;
  transition: 0.2s;
}

.submenu-item:hover {
  background: rgba(255,255,255,0.1);
}

/* ── Botão abrir em nova aba ↗ ─────────────────────────── */
.menu-item,
.submenu-item {
  position: relative;
}

.btn-nova-aba {
  display: none;
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,0.2);
  border-radius: 5px;
  color: #c7d7ff;
  font-size: 11px;
  line-height: 1;
  padding: 3px 5px;
  cursor: pointer;
  transition: background .15s;
  z-index: 10;
  white-space: nowrap;
}

.btn-nova-aba:hover {
  background: rgba(79,140,255,0.4);
  color: #fff;
  border-color: rgba(79,140,255,0.6);
}

.menu-item:hover .btn-nova-aba,
.submenu-item:hover .btn-nova-aba {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.submenu-divider {
  height: 1px;
  background: rgba(255,255,255,0.2);
  margin: 8px 0;
}

/* ===== ESTOQUE ===== */

.stock-module-header {
  margin-bottom: 14px;
}

.stock-module-header h2 {
  margin: 0 0 4px 0;
  font-size: 32px;
  font-weight: 800;
  color: #0b3b82;
}

.stock-module-header p {
  margin: 0;
  font-size: 18px;
  color: #4b5563;
}

.stock-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 18px 0 20px;
}

.stock-tab-btn {
  border: none;
  background: #1f2937;
  color: #fff;
  padding: 12px 18px;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: 0.2s ease;
}

.stock-tab-btn:hover {
  background: #111827;
  transform: translateY(-1px);
}

.stock-tab-btn.active {
  background: #0b4db3;
}

.stock-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
}

.stock-card {
  background: #ffffff;
  border: 1px solid #d9e2f1;
  border-radius: 14px;
  padding: 18px;
  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.06);
}

.stock-card-label {
  font-size: 13px;
  font-weight: 700;
  color: #6b7280;
  text-transform: uppercase;
  margin-bottom: 8px;
}

.stock-card-value {
  font-size: 30px;
  font-weight: 800;
  color: #0b3b82;
}

.stock-card-alert {
  border-color: #f5c56b;
  background: #fff8eb;
}

.stock-card-danger {
  border-color: #f0a5a5;
  background: #fff1f1;
}

.stock-table-card {
  background: #ffffff;
  border: 1px solid #d9e2f1;
  border-radius: 16px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06);
  overflow: hidden;
}

.stock-table-header {
  padding: 18px 20px;
  border-bottom: 1px solid #e5e7eb;
  background: #f8fbff;
}

.stock-table-header h3 {
  margin: 0 0 4px 0;
  font-size: 20px;
  color: #0f172a;
}

.stock-table-header p {
  margin: 0;
  font-size: 14px;
  color: #6b7280;
}

.stock-table-wrap {
  width: 100%;
  overflow-x: auto;
}

.stock-table {
  width: 100%;
  min-width: 1180px;
  border-collapse: collapse;
  table-layout: fixed;
}

.stock-table thead th {
  background: #0b3b82;
  color: #ffffff;
  font-size: 13px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  padding: 14px 12px;
  border-bottom: 1px solid #d9e2f1;
  white-space: nowrap;
}

.stock-table tbody td {
  padding: 14px 12px;
  border-bottom: 1px solid #edf2f7;
  color: #111827;
  vertical-align: middle;
  background: #ffffff;
}

.stock-table tbody tr:nth-child(even) td {
  background: #f9fbfd;
}

.stock-table tbody tr:hover td {
  background: #eef5ff;
}

.stock-col-code {
  width: 120px;
  font-weight: 700;
  white-space: nowrap;
}

.stock-col-desc {
  width: 340px;
  white-space: normal;
  word-break: break-word;
  line-height: 1.35;
}

.stock-col-type {
  width: 120px;
  white-space: nowrap;
}

.stock-col-num {
  width: 95px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.stock-col-total {
  font-weight: 800;
}

.stock-col-status {
  width: 150px;
  text-align: center;
  white-space: nowrap;
}

.stock-status-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 110px;
  padding: 7px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.stock-status-normal {
  background: #e8f7ec;
  color: #18794e;
}

.stock-status-cambam {
  background: #fff4db;
  color: #a16207;
}

.stock-status-rotativo {
  background: #ffe9d8;
  color: #c2410c;
}

.stock-status-critico {
  background: #ffe1e1;
  color: #b91c1c;
}

.stock-status-badges {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.stock-status-badge-sm {
  min-width: auto;
  padding: 3px 9px;
  font-size: 10px;
}

.stock-status-bar {
  display: flex;
  height: 30px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #e2e8f0;
}

.stock-status-bar-seg {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 1;
  flex-basis: 0;
  min-width: 44px;
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity 0.15s ease;
}

.stock-status-bar-seg:hover {
  opacity: 0.85;
}

.stock-status-bar-seg.active {
  outline: 2px solid #1e293b;
  outline-offset: -2px;
}

@media (max-width: 900px) {
  .stock-module-header h2 {
    font-size: 26px;
  }

  .stock-module-header p {
    font-size: 15px;
  }

  .stock-tab-btn {
    width: 100%;
  }

  .stock-table {
    min-width: 1000px;
  }
}

.fluxo-chart-wrap {
  position: relative;
  width: 100%;
  min-height: 380px;
}

.fluxo-suggestions {
  position: relative;
}

.fluxo-suggestions-list {
  position: absolute;
  top: 6px;
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid #d9e2ef;
  border-radius: 10px;
  box-shadow: 0 8px 18px rgba(0,0,0,0.08);
  z-index: 20;
  max-height: 260px;
  overflow-y: auto;
}

.fluxo-suggestion-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  border: 0;
  background: #fff;
  cursor: pointer;
}

.fluxo-suggestion-item:hover {
  background: #f3f7fc;
}

.fluxo-chart-wrap {
  position: relative;
  width: 100%;
  min-height: 420px;
}

#fluxo_chart {
  width: 100% !important;
  height: 420px !important;
  display: block;
}

/* ===== PERMISSÕES USUÁRIO ===== */

.permission-group {
  border: 1px solid #dbe4f0;
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 14px;
  background: #f9fbff;
}

.permission-group-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
  flex-wrap: wrap;
  gap: 10px;
}

.permission-group-title {
  font-weight: 800;
  text-transform: uppercase;
  font-size: 13px;
  color: var(--asj-blue-dark);
}

.permission-group-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.permission-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}

.permission-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  transition: 0.2s;
}

.permission-item:hover {
  background: #eef5ff;
  border-color: #c7dcff;
}

.permission-item input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--asj-blue);
  cursor: pointer;
  flex-shrink: 0;
}

.permission-item span {
  font-size: 13px;
  font-weight: 600;
  color: #1e293b;
  line-height: 1.35;
}

.permission-item input[type="checkbox"]:checked + span {
  color: var(--asj-blue-dark);
  font-weight: 700;
}

/* ================= TABELA MAIS LEVE ================= */

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.table th {
  text-align: left;
  padding: 8px 10px;
  background: #f5f7fa;
  font-weight: 600;
  border-bottom: 1px solid #e3e6ea;
}

.table td {
  padding: 6px 10px;
  border-bottom: 1px solid #eef1f4;
  color: #2c3e50;
}

.table tr:hover {
  background-color: #f9fbfd;
}

/* ================= BOTÕES MAIS SUAVES ================= */

.btn {
  padding: 5px 10px;
  font-size: 12px;
  border-radius: 4px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 0.15s ease;
}

/* BOTÃO EDITAR - azul suave */
.btn-edit {
  background-color: #eaf3ff;
  color: #0c4cae;
  border: 1px solid #c7dbf7;
}

.btn-edit:hover {
  background-color: #d8e9ff;
  border-color: #9fc3f3;
}

/* BOTÃO EXCLUIR - neutro elegante (não agressivo) */
.btn-delete {
  background-color: #f5f6f8;
  color: #5c6670;
  border: 1px solid #d6dbe1;
}

.btn-delete:hover {
  background-color: #eceff3;
  color: #2f3942;
}

/* ================= TOOLBAR E BOTÕES GERAIS ================= */

.btn-secondary {
  background-color: #f0f4fa;
  color: #0c4cae;
  border: 1px solid #d2e0f5;
}

.btn-secondary:hover {
  background-color: #e2ecfb;
}

/* ================= VISUAL MAIS LIMPO ================= */

.form-card {
  background: #ffffff;
  border: 1px solid #e5e9ef;
  border-radius: 6px;
  padding: 14px;
}

.section-title {
  font-size: 14px;
  font-weight: 600;
  color: #2c3e50;
  margin-bottom: 10px;
}

/* ================= INPUT MAIS CLEAN ================= */

input, select, textarea {
  border: 1px solid #dfe4ea;
  padding: 6px 8px;
  border-radius: 4px;
  font-size: 13px;
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: #0c4cae;
  box-shadow: 0 0 0 1px rgba(12, 76, 174, 0.1);
}

/* =========================================================
   ERP INDUSTRIAL / SAP-LIKE
   Ajuste visual para cadastro, tabelas e ações
   (tokens --erp-* unificados no :root do topo do arquivo)
========================================================= */

/* Cards / containers */
.form-card,
.summary-box,
.info-box {
  background: var(--erp-surface);
  border: 1px solid var(--erp-border);
  border-radius: 4px;
  box-shadow: var(--erp-shadow);
}

.form-card {
  padding: 14px;
  margin-bottom: 12px;
}

.summary-box,
.info-box {
  padding: 10px 12px;
  color: var(--erp-text-soft);
  font-size: 12px;
}

/* Títulos */
.section-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--erp-text);
  text-transform: uppercase;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--erp-border-soft);
}

/* Grid */
.form-grid,
.form-grid-3 {
  gap: 10px;
  margin-bottom: 10px;
}

/* Campos */
.form-field label {
  display: block;
  margin-bottom: 4px;
  font-size: 11px;
  font-weight: 700;
  color: var(--erp-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.form-note {
  margin-top: 4px;
  font-size: 11px;
  color: var(--erp-text-soft);
}

input,
select,
textarea {
  width: 100%;
  min-height: 34px;
  padding: 6px 9px;
  border: 1px solid var(--erp-border);
  border-radius: 3px;
  background: #fff;
  color: var(--erp-text);
  font-size: 13px;
  line-height: 1.3;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
  box-sizing: border-box;
}

textarea {
  min-height: 84px;
  resize: vertical;
}

input[readonly],
textarea[readonly] {
  background: #f6f8fa;
  color: var(--erp-text-soft);
}

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--erp-primary);
  box-shadow: 0 0 0 2px rgba(12, 76, 174, 0.08);
}

/* Toolbar */
.form-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
  flex-wrap: wrap;
}

/* Tabs */
.tabs {
  display: flex;
  gap: 2px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--erp-border);
}

.tab {
  padding: 9px 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--erp-text-soft);
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.tab:hover {
  background: #f7f9fb;
  color: var(--erp-text);
}

.tab.active {
  background: var(--erp-surface);
  color: var(--erp-primary);
  border-color: var(--erp-border);
  position: relative;
  top: 1px;
}

/* Tabela estilo ERP */
.table {
  width: 100%;
  border-collapse: collapse;
  background: var(--erp-surface);
  font-size: 12px;
  table-layout: auto;
}

.table th {
  background: #eef2f6;
  color: #334155;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  text-align: left;
  padding: 8px 10px;
  border: 1px solid var(--erp-border);
  white-space: nowrap;
}

.table td {
  padding: 7px 10px;
  border: 1px solid var(--erp-border-soft);
  color: var(--erp-text);
  vertical-align: middle;
}

.table tr:nth-child(even) td {
  background: #fcfdff;
}

.table tr:hover td {
  background: var(--erp-hover);
}

/* Ações */
.btn {
  min-height: 30px;
  padding: 5px 10px;
  border-radius: 3px;
  border: 1px solid var(--erp-border);
  background: #fff;
  color: var(--erp-text);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: all 0.15s ease;
  box-shadow: none;
}

.btn:hover {
  background: #f7f9fb;
  border-color: #c8d2dc;
}

.btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn-secondary {
  background: var(--erp-primary-soft);
  color: var(--erp-primary);
  border-color: #bfd5fb;
}

.btn-secondary:hover {
  background: var(--erp-primary-soft-2);
  border-color: #9fc0f7;
}

.btn-edit {
  background: #edf4ff;
  color: var(--erp-primary);
  border-color: #c8daf8;
}

.btn-edit:hover {
  background: #dfebff;
  border-color: #aecaef;
}

.btn-delete {
  background: #f6f8fa;
  color: var(--erp-danger-text);
  border-color: #d7dee6;
}

.btn-delete:hover {
  background: #eceff3;
  color: #334155;
  border-color: #c4ced8;
}

/* Busca */
#cad_search_input {
  background: #fff;
  border: 1px solid var(--erp-border);
}

/* Preview */
.preview-img {
  margin-top: 10px;
  max-width: 180px;
  max-height: 180px;
  object-fit: contain;
  border: 1px solid var(--erp-border);
  border-radius: 4px;
  background: #fff;
  padding: 4px;
}

/* Tabela mais compacta em telas menores */
@media (max-width: 1200px) {
  .table {
    font-size: 11px;
  }

  .table th,
  .table td {
    padding: 6px 8px;
  }

  .btn {
    padding: 4px 8px;
    font-size: 11px;
  }
}

.toggle-sidebar {
  position: absolute;
  top: 10px;
  right: -12px;
  width: 24px;
  height: 24px;
  background: var(--sidebar-accent);
  color: white;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  z-index: 10;
  font-size: 14px;
}

/* expandir área principal */
.app.collapsed .main {
  margin-left: 70px;
}
.sidebar {
  position: relative;
}

.toggle-sidebar {
  position: fixed;
  top: 10px;
  left: 10px;
  width: 34px;
  height: 34px;
  background: var(--sidebar-accent);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 8px;
  cursor: pointer;
  z-index: 1000;
  font-size: 18px;
  font-weight: 800;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.18);
}

.toggle-sidebar:hover {
  background: var(--sidebar-accent-hover);
}

.sidebar-brand {
  margin-top: 28px;
}

/* estado recolhido */
.sidebar.collapsed {
  width: 70px;
  padding: 20px 10px;
  overflow: visible;
}

/* recolhido: o painel fica visível (não display:none) para que os
   ÍCONES do menu continuem aparecendo na trilha — só o texto, dados da
   empresa e o botão Sair somem. Ao passar o mouse (:hover), tudo volta
   ao normal automaticamente, então as regras abaixo só valem quando
   NÃO está em hover — não precisamos "desfazer" nada no hover. */
.sidebar.collapsed .sidebar-flyout {
  display: block;
}

.sidebar.collapsed:not(:hover) .sidebar-company-info,
.sidebar.collapsed:not(:hover) .logout-btn,
.sidebar.collapsed:not(:hover) .menu-label {
  display: none;
}

.sidebar.collapsed:not(:hover) .submenu {
  display: none !important;
}

.sidebar.collapsed:not(:hover) .menu-item {
  justify-content: center;
  padding: 12px 0;
}

.sidebar.collapsed .sidebar-brand {
  margin-top: 36px;
  margin-bottom: 0;
  padding-bottom: 0;
}

.sidebar.collapsed .sidebar-logo {
  width: 42px;
  height: 42px;
}

/* ícone do item de menu: sempre visível, chama atenção mesmo recolhido */
.menu-item,
.submenu-item {
  display: flex;
  align-items: center;
  gap: 12px;
}

.menu-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.menu-label {
  flex: 1;
  min-width: 0;
}

/* menu "fantasma": ao passar o mouse sobre a trilha recolhida, o próprio
   sidebar assume exatamente o mesmo tamanho/aparência do modo fixo
   (expandido) — mesma largura, padding, logo e rolagem — só que como uma
   camada flutuante por cima do conteúdo (sem empurrar o layout) e que
   volta ao estado recolhido ao tirar o mouse. */
.sidebar.collapsed:hover {
  position: fixed;
  top: 0;
  left: 0;
  width: 300px;
  height: 100vh;
  padding: 20px;
  overflow-y: auto;
  z-index: 1500;
  box-shadow: 8px 0 28px rgba(0, 0, 0, 0.35);
  animation: sidebar-flyout-in 0.18s ease-out;
}

.sidebar.collapsed:hover .sidebar-brand {
  margin-top: 28px;
  margin-bottom: 16px;
  padding-bottom: 12px;
}

.sidebar.collapsed:hover .sidebar-logo {
  width: 110px;
  height: 110px;
}

@keyframes sidebar-flyout-in {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* área principal */
.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.app.collapsed .main {
  margin-left: 0;
}

/* ============================================================
   ADICIONAR AO FINAL DE: public/style.css
   Estilos do módulo financeiro
   ============================================================ */

/* ── Layout base ── */
.fin-wrapper        { display: flex; flex-direction: column; gap: 0; height: 100%; min-height: 0; }
.fin-content        { flex: 1; min-height: 0; padding: 1.5rem; overflow-y: auto; overscroll-behavior: contain; }
.fin-loading, .erp-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 2rem;
  text-align: center;
  color: var(--erp-text-soft, #64748b);
  font-size: 13.5px;
}
.fin-loading::before, .erp-loading::before {
  content: "";
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 2px solid var(--erp-border, #d9e0e7);
  border-top-color: var(--erp-primary, #0c4cae);
  animation: erp-spin .7s linear infinite;
}
@keyframes erp-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .fin-loading::before, .erp-loading::before { animation-duration: 2.4s; }
}

/* ── Toast (notificação não bloqueante — substitui alert()) ── */
.erp-toast-container {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: min(360px, calc(100vw - 36px));
}
.erp-toast {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--erp-surface, #fff);
  color: var(--erp-text, #1f2a37);
  border: 1px solid var(--erp-border, #d9e0e7);
  border-left: 4px solid var(--asj-blue, #0c4cae);
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(16, 24, 40, 0.12);
  padding: 10px 12px;
  font-size: 13.5px;
  line-height: 1.4;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .18s ease, transform .18s ease;
}
.erp-toast--visible { opacity: 1; transform: translateY(0); }
.erp-toast--success  { border-left-color: var(--success, #059669); }
.erp-toast--warning  { border-left-color: var(--warning, #d97706); }
.erp-toast--danger   { border-left-color: var(--danger, #dc2626); }
.erp-toast-msg   { flex: 1; }
.erp-toast-close {
  border: none;
  background: transparent;
  color: var(--erp-text-soft, #5b6875);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
.erp-toast-close:hover { color: var(--erp-text, #1f2a37); }
@media (prefers-reduced-motion: reduce) {
  .erp-toast { transition: opacity .18s linear; transform: none; }
}
.fin-error          { padding: 1rem; background: #fee2e2; color: #dc2626; border-radius: 6px; }
.fin-empty          { color: #94a3b8; font-style: italic; padding: 1rem 0; }
.fin-section        { display: flex; flex-direction: column; gap: 1rem; }
.fin-section-title  { font-size: 1.25rem; font-weight: 600; color: #1e293b; margin: 0; }

/* ── Tabs ── */
.fin-tabs           { display: flex; gap: 2px; background: #e2e8f0; padding: 4px; border-radius: 8px;
                      flex-wrap: wrap; margin-bottom: 0; row-gap: 2px;
                      position: sticky; top: 0; z-index: 5; flex-shrink: 0; }
.fin-tab            { flex: 0 0 auto; padding: 8px 14px; border: none; background: transparent;
                      border-radius: 6px; cursor: pointer; font-size: 0.8rem; font-weight: 500; color: #475569;
                      transition: all .15s; white-space: nowrap; }
.fin-tab:hover      { background: #fff; color: #1e293b; }
.fin-tab.active     { background: #fff; color: #0f172a; font-weight: 700; box-shadow: 0 1px 3px rgba(0,0,0,.1); }

/* ── Toolbar ── */
.fin-toolbar        { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: .75rem; }
.fin-toolbar-actions{ display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }

/* ── Botões ── */
.fin-btn            { padding: 7px 16px; border: none; border-radius: 6px; cursor: pointer; font-size: .85rem; font-weight: 500; transition: opacity .15s; }
.fin-btn:hover      { opacity: .85; }
.fin-btn-primary    { background: #2563eb; color: #fff; }
.fin-btn-secondary  { background: #e2e8f0; color: #1e293b; }
.fin-btn-success    { background: #16a34a; color: #fff; }
.fin-btn-danger     { background: #dc2626; color: #fff; }
.fin-btn-info       { background: #0891b2; color: #fff; }
.fin-btn-warning    { background: #d97706; color: #fff; }
.fin-btn-sm         { padding: 4px 10px; font-size: .78rem; border: none; border-radius: 5px; cursor: pointer; transition: opacity .15s; }
.fin-btn-sm:hover   { opacity: .8; }

/* ── Dropdown de ações nos boletos ── */
.bol-menu-wrap { position: relative; display: inline-block; }

.bol-menu-btn {
  padding: 5px 12px;
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .03em;
  background: #fff;
  color: #1a3a5c;
  border: 1.5px dashed #1a3a5c;
  border-radius: 5px;
  cursor: pointer;
  white-space: nowrap;
  transition: background .15s, color .15s;
}
.bol-menu-btn:hover, .bol-menu-btn.active { background: #1a3a5c; color: #fff; }

.bol-menu-drop {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  min-width: 170px;
  background: #fff;
  border: 1.5px solid #1a3a5c;
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0,0,0,.12);
  z-index: 9999;
  overflow: hidden;
}
.bol-menu-drop.open { display: block; }

.bol-menu-item {
  display: block;
  width: 100%;
  padding: 9px 14px;
  font-size: .8rem;
  text-align: left;
  background: #fff;
  color: #1a3a5c;
  border: none;
  border-bottom: 1px solid #e8eef4;
  cursor: pointer;
  transition: background .12s;
}
.bol-menu-item:last-child { border-bottom: none; }
.bol-menu-item:hover { background: #1a3a5c; color: #fff; }
.bol-menu-item--alt  { color: #1a6a3c; }
.bol-menu-item--alt:hover { background: #1a6a3c; color: #fff; }
.bol-menu-item--danger { color: #b91c1c; }
.bol-menu-item--danger:hover { background: #b91c1c; color: #fff; }
.fin-btn-sm.fin-btn-info    { background: #0891b2; color: #fff; }
.fin-btn-sm.fin-btn-danger  { background: #dc2626; color: #fff; }
.fin-btn-sm.fin-btn-success { background: #16a34a; color: #fff; }
.fin-btn-sm.fin-btn-primary { background: #2563eb; color: #fff; }

/* ── Inputs ── */
.fin-input          { padding: 7px 10px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: .85rem;
                      outline: none; transition: border-color .15s; width: 100%; box-sizing: border-box; }
.fin-input:focus    { border-color: #2563eb; }
.fin-select         { padding: 7px 10px; border: 1px solid #cbd5e1; border-radius: 6px; font-size: .85rem;
                      background: #fff; cursor: pointer; outline: none; }
.fin-select:focus   { border-color: #2563eb; }

/* ── Tabela ── */
.fin-table          { width: 100%; border-collapse: collapse; font-size: .85rem; }
.fin-table th       { background: #f1f5f9; padding: 10px 12px; text-align: left; font-weight: 600;
                      color: #475569; border-bottom: 2px solid #e2e8f0; }
.fin-table td       { padding: 9px 12px; border-bottom: 1px solid #f1f5f9; vertical-align: middle; }
.fin-table tr:hover td  { background: #f8fafc; }
.fin-table .fin-actions { display: flex; gap: 4px; }
.row-vencido        { background: #fff7ed !important; }
.row-vencido:hover td { background: #fef3c7 !important; }

/* ── Cards Dashboard ── */
.fin-cards          { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
.fin-card           { border-radius: 10px; padding: 1.25rem; display: flex; gap: 1rem; align-items: flex-start;
                      box-shadow: 0 1px 4px rgba(0,0,0,.08); }
.fin-card-icon      { font-size: 1.8rem; }
.fin-card-body      { display: flex; flex-direction: column; gap: 2px; }
.fin-card-label     { font-size: .75rem; font-weight: 600; text-transform: uppercase; opacity: .75; }
.fin-card-value     { font-size: 1.3rem; font-weight: 700; }
.fin-card-sub       { font-size: .75rem; opacity: .7; }
.fin-card-success   { background: #dcfce7; color: #14532d; }
.fin-card-danger    { background: #fee2e2; color: #7f1d1d; }
.fin-card-warning   { background: #fef9c3; color: #713f12; }
.fin-card-info      { background: #dbeafe; color: #1e3a8a; }

/* ── Alertas ── */
.fin-alert          { padding: .75rem 1rem; border-radius: 6px; font-size: .85rem; margin-bottom: .75rem; }
.fin-alert-danger   { background: #fee2e2; color: #991b1b; border-left: 4px solid #dc2626; }
.fin-alert-warning  { background: #fef9c3; color: #92400e; border-left: 4px solid #f59e0b; }
.fin-alert-info     { background: #dbeafe; color: #1e40af; border-left: 4px solid #3b82f6; }
.fin-dash-vencidos  { display: flex; flex-direction: column; gap: .5rem; }

/* ══════════════════════════════════════════════════════════════
   DASHBOARD EXECUTIVO (dex-*)
══════════════════════════════════════════════════════════════ */
.dex-wrap { display:flex; flex-direction:column; gap:1.1rem; padding:.2rem 0 2rem; }

/* Barra de ações rápidas */
.dex-quickbar { display:flex; flex-wrap:wrap; gap:.5rem; background:#0F2747; border-radius:10px; padding:.7rem 1rem; }
.dex-quick-btn { padding:6px 14px; font-size:.78rem; font-weight:600; background:rgba(255,255,255,.1); color:#fff; border:1px solid rgba(255,255,255,.2); border-radius:6px; cursor:pointer; transition:background .15s; }
.dex-quick-btn:hover { background:rgba(255,255,255,.22); }

/* Alertas */
.dex-alertas { display:flex; flex-direction:column; gap:.4rem; }
.dex-alerta { padding:.55rem 1rem; border-radius:7px; font-size:.82rem; font-weight:500; }
.dex-alerta-danger  { background:#fee2e2; color:#991b1b; border-left:4px solid #dc2626; }
.dex-alerta-warning { background:#fef9c3; color:#92400e; border-left:4px solid #f59e0b; }
.dex-alerta-info    { background:#dcfce7; color:#166534; border-left:4px solid #22c55e; }

/* Título de seção */
.dex-section-title { display:flex; align-items:center; justify-content:space-between; font-size:.72rem; font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:#94a3b8; padding:.2rem 0; border-bottom:2px solid #e2e8f0; margin-top:.4rem; }

/* Grid 4 colunas */
.dex-row-4 { display:grid; grid-template-columns:repeat(4,1fr); gap:.9rem; }
.dex-row-2 { display:grid; grid-template-columns:repeat(2,1fr); gap:.9rem; }
.dex-row-5 { display:grid; grid-template-columns:repeat(5,1fr); gap:.9rem; }
@media(max-width:1100px){ .dex-row-4{ grid-template-columns:repeat(2,1fr); } .dex-row-5{ grid-template-columns:repeat(3,1fr); } }
@media(max-width:700px){ .dex-row-4,.dex-row-2,.dex-row-5{ grid-template-columns:1fr; } }

/* KPI grande */
.dex-kpi { background:#fff; border-radius:10px; padding:1.1rem 1.3rem; box-shadow:0 1px 4px rgba(0,0,0,.07); border-left:4px solid #1D4E89; }
.dex-kpi-blue  { border-left-color:#1D4E89; }
.dex-kpi-green { border-left-color:#22c55e; }
.dex-kpi-red   { border-left-color:#ef4444; }
.dex-kpi-label { font-size:.72rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:#94a3b8; margin-bottom:.3rem; }
.dex-kpi-value { font-size:1.45rem; font-weight:800; color:#0F2747; line-height:1.2; }
.dex-kpi-sub   { font-size:.73rem; color:#94a3b8; margin-top:.25rem; }

/* KPI pequeno (boletos) */
.dex-kpi-sm { background:#fff; border-radius:10px; padding:.9rem 1rem; box-shadow:0 1px 4px rgba(0,0,0,.07); text-align:center; }
.dex-kpi-sm-label { font-size:.68rem; font-weight:700; text-transform:uppercase; color:#94a3b8; }
.dex-kpi-sm-val   { font-size:1.6rem; font-weight:800; color:#0F2747; margin:.2rem 0; }
.dex-kpi-sm-sub   { font-size:.72rem; color:#64748b; }
.dex-c-blue  { color:#1D4E89!important; }
.dex-c-green { color:#16a34a!important; }
.dex-c-gray  { color:#64748b!important; }
.dex-c-red   { color:#dc2626!important; }

/* Card genérico */
.dex-card { background:#fff; border-radius:10px; padding:1.1rem 1.3rem; box-shadow:0 1px 4px rgba(0,0,0,.07); }
.dex-card-full { width:100%; }
.dex-card-title { font-size:.8rem; font-weight:700; color:#0F2747; margin-bottom:.9rem; padding-bottom:.5rem; border-bottom:1px solid #f1f5f9; }

/* Mini grid CR/CP */
.dex-mini-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:.5rem .8rem; }
.dex-mini-item { padding:.5rem .6rem; border-radius:6px; background:#f8fafc; }
.dex-mini-label { font-size:.68rem; color:#64748b; font-weight:600; text-transform:uppercase; letter-spacing:.04em; display:block; margin-bottom:2px; }
.dex-mini-val   { font-size:.92rem; font-weight:700; color:#0F2747; }
.dex-mini-warn    .dex-mini-val { color:#d97706; }
.dex-mini-danger  .dex-mini-val { color:#dc2626; }
.dex-mini-ok      .dex-mini-val { color:#16a34a; }

/* Bancos */
.dex-bancos-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:.9rem; }
.dex-banco-card { background:#fff; border-radius:10px; padding:1rem 1.2rem; box-shadow:0 1px 4px rgba(0,0,0,.07); border-top:3px solid #1D4E89; }
.dex-banco-total { border-top-color:#0F2747; background:#f0f4ff; }
.dex-banco-nome  { font-size:.75rem; font-weight:700; text-transform:uppercase; color:#64748b; margin-bottom:.3rem; }
.dex-banco-saldo { font-size:1.2rem; font-weight:800; }
.dex-banco-info  { font-size:.72rem; color:#94a3b8; margin-top:.2rem; }
.dex-banco-alerta { font-size:.72rem; color:#d97706; margin-top:.35rem; font-weight:600; }
.dex-banco-ok     { font-size:.72rem; color:#16a34a; margin-top:.35rem; font-weight:600; }

/* Tabelas de ranking */
.dex-rank-table { width:100%; border-collapse:collapse; font-size:.8rem; }
.dex-rank-table th { text-align:left; font-size:.68rem; font-weight:700; color:#94a3b8; text-transform:uppercase; letter-spacing:.04em; padding:.4rem .5rem; border-bottom:1px solid #e2e8f0; }
.dex-rank-table td { padding:.5rem .5rem; border-bottom:1px solid #f1f5f9; color:#334155; }
.dex-rank-table tr:last-child td { border-bottom:none; }
.dex-rank-table tr:hover td { background:#f8fafc; }
.dex-rank-pos { font-weight:800; color:#1D4E89; width:22px; }

/* KPI indicadores */
.dex-kpi-ind { background:#fff; border-radius:10px; padding:1rem 1.2rem; box-shadow:0 1px 4px rgba(0,0,0,.07); border-top:3px solid #1D4E89; }
.dex-kpi-ind-label { font-size:.68rem; font-weight:700; color:#64748b; text-transform:uppercase; letter-spacing:.05em; margin-bottom:.4rem; }
.dex-kpi-ind-val   { font-size:1.4rem; font-weight:800; color:#0F2747; }
.dex-kpi-ind-sub   { font-size:.7rem; color:#94a3b8; margin-top:.2rem; }

/* Tabs fluxo */
.dex-chart-tabs { display:flex; gap:.3rem; }
.dex-chart-tab  { padding:3px 10px; font-size:.72rem; font-weight:600; border:1px solid #cbd5e1; border-radius:5px; background:#fff; color:#64748b; cursor:pointer; }
.dex-chart-tab.active { background:#1D4E89; color:#fff; border-color:#1D4E89; }

/* ── Badges ── */
.badge              { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: .75rem; font-weight: 600; }
.badge-success      { background: #dcfce7; color: #166534; }
.badge-danger       { background: #fee2e2; color: #991b1b; }
.badge-warning      { background: #fef9c3; color: #854d0e; }
.badge-info         { background: #dbeafe; color: #1e40af; }
.badge-primary      { background: #ede9fe; color: #4c1d95; }
.badge-secondary    { background: #f1f5f9; color: #475569; }

/* ── Ficha do item (view modal) ── */
.view-section        { margin-bottom: 24px; }
.view-section-title  { font-size: 11px; font-weight: 700; text-transform: uppercase;
                       letter-spacing: .08em; color: #64748b; border-bottom: 1px solid #e2e8f0;
                       padding-bottom: 5px; margin-bottom: 12px; }
.view-grid           { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 28px; }
.view-row            { display: flex; flex-direction: column; min-width: 0; }
.view-row--full      { grid-column: 1 / -1; }
.view-label          { font-size: 10px; font-weight: 700; color: #94a3b8;
                       text-transform: uppercase; letter-spacing: .06em; margin-bottom: 3px; }
.view-value          { font-size: 13px; color: #1e293b; line-height: 1.45;
                       word-break: break-word; overflow-wrap: anywhere; }

/* ── Banco cards ── */
.fin-banco-card     { display: flex; justify-content: space-between; align-items: center;
                      padding: 1rem 1.25rem; border: 1px solid #e2e8f0; border-radius: 8px;
                      margin-bottom: .75rem; background: #fafafa; }
.fin-banco-info     { display: flex; flex-direction: column; gap: 2px; font-size: .85rem; }
.fin-banco-info strong { font-size: 1rem; color: #1e293b; }
.fin-banco-info span  { color: #64748b; }

/* ── Formulários (modal) ── */
.fin-form           { display: flex; flex-direction: column; gap: 1rem; }
.fin-form-row       { display: flex; flex-direction: column; gap: 4px; }
.fin-form-row label { font-size: .8rem; font-weight: 600; color: #475569; }
.fin-form-2col      { display: grid !important; grid-template-columns: 1fr 1fr; gap: 1rem; }

/* ── Modal ── */
.fin-modal-overlay  { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 9999;
                      display: flex; align-items: center; justify-content: center; }
.fin-modal          { background: #fff; border-radius: 10px; width: 100%; max-width: 520px;
                      max-height: 90vh; overflow-y: auto; box-shadow: 0 10px 40px rgba(0,0,0,.2); }
.fin-modal-header   { display: flex; justify-content: space-between; align-items: center;
                      padding: 1rem 1.25rem; border-bottom: 1px solid #e2e8f0; }
.fin-modal-header h3 { margin: 0; font-size: 1rem; font-weight: 700; color: #1e293b; }
.fin-modal-close    { background: none; border: none; font-size: 1.1rem; cursor: pointer; color: #94a3b8; }
.fin-modal-close:hover { color: #1e293b; }
.fin-modal-body     { padding: 1.25rem; }
.fin-modal-footer   { display: flex; justify-content: flex-end; gap: .5rem;
                      padding: 1rem 1.25rem; border-top: 1px solid #e2e8f0; }

/* ============================================================
   ADICIONAR AO FINAL DE: public/style.css
   CSS adicional — impressão em lote de boletos
   ============================================================ */

.fin-lote-toolbar {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .75rem 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  margin-bottom: .5rem;
}

/* ============================================================
   ADICIONAR AO FINAL DE: public/style.css
   CSS adicional — impressão em lote de boletos
   ============================================================ */

.fin-lote-toolbar {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .75rem 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  margin-bottom: .5rem;
}

/* ── Filtros avançados de boletos ── */
.bol-filtros-card {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: .75rem;
}
.bol-filtros-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr auto;
  gap: .75rem;
  align-items: end;
}
@media (max-width: 900px) {
  .bol-filtros-grid { grid-template-columns: 1fr 1fr; }
}
.bol-label {
  display: block;
  font-size: .78rem;
  font-weight: 600;
  color: #475569;
  margin-bottom: 3px;
  text-transform: uppercase;
}

/* ── Barra de ações em lote ── */
.bol-acoes-lote {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .6rem 1rem;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  margin-bottom: .5rem;
  flex-wrap: wrap;
}
.bol-sel-count {
  font-size: .85rem;
  font-weight: 700;
  color: #1d4ed8;
}

/* ── Resumo total ── */
.bol-resumo {
  padding: .6rem 1rem;
  background: #f1f5f9;
  border-top: 1px solid #e2e8f0;
  font-size: .82rem;
  color: #475569;
  text-align: right;
}

/* ── Linha clicável ── */
.bol-row { cursor: pointer; }
.bol-row:hover td { background: #eff6ff !important; }

/* ── Modal ERP global ── */
.erp-modal-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.52);
  z-index: 8000;
  display: flex; align-items: flex-start; justify-content: center;
  padding: 24px 16px;
  overflow-y: auto;
}
.erp-modal {
  background: #fff;
  border-radius: 10px;
  width: 100%; max-width: 940px;
  box-shadow: 0 10px 40px rgba(0,0,0,.28);
  padding: 28px 32px;
  position: relative;
}

/* ── Staging area seleção de item no kit ── */
.kit-staged-area {
  background: #eff6ff;
  border: 1.5px solid #bfdbfe;
  border-radius: 8px;
  padding: 12px 16px 14px;
  margin: 10px 0;
}
.kit-staged-area .staged-label {
  font-size: 11px;
  color: #64748b;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .5px;
  margin-bottom: 4px;
}
.kit-staged-area .staged-name {
  font-weight: 700;
  color: #1d4ed8;
  font-size: 14px;
  margin-bottom: 10px;
}

/* ── Modal fullscreen (kits) ── */
.erp-modal--fullscreen {
  max-width: calc(100vw - 32px);
  min-height: calc(100vh - 48px);
}
.erp-modal-overlay:has(.erp-modal--fullscreen) {
  align-items: flex-start;
}

/* ── Busca de itens no kit ── */
.kit-search-results {
  border: 1px solid var(--line);
  border-radius: 6px;
  max-height: 260px;
  overflow-y: auto;
  background: #fff;
}
.kit-search-hint {
  padding: 10px 12px;
  color: var(--muted);
  font-size: 13px;
}
.kit-result-item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 12px;
  cursor: pointer;
  border-bottom: 1px solid #f1f5f9;
  transition: background 0.1s;
}
.kit-result-item:last-child { border-bottom: none; }
.kit-result-item:hover { background: #eff6ff; }
.kit-result-item--selected { background: #dbeafe; }
.kit-result-code {
  font-family: monospace;
  font-weight: 700;
  font-size: 13px;
  white-space: nowrap;
  color: #1e40af;
  min-width: 90px;
}
.kit-result-desc {
  font-size: 13px;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kit-result-tipo {
  font-size: 11px;
  color: #64748b;
  white-space: nowrap;
  background: #f1f5f9;
  border-radius: 4px;
  padding: 1px 6px;
}

// ============================================================
// SALVAR EM: public/js/financeiro.js
// ============================================================

window.Financeiro = (() => {
  // ── Estado local ────────────────────────────────────────────
  let _currentTab   = "dashboard";
  let _bancos       = [];
  let _entities     = [];

  // ── Utilitários ─────────────────────────────────────────────
  const fmt = {
    moeda: v => Number(v || 0).toLocaleString("pt-BR", { style: "currency", currency: "BRL" }),
    data:  v => v ? v.slice(0, 10).split("-").reverse().join("/") : "—",
    status: (s, tipo) => {
      const map = {
        aberto:     { label: "Aberto",     cls: "badge-warning" },
        pago:       { label: "Pago",       cls: "badge-success" },
        recebido:   { label: "Recebido",   cls: "badge-success" },
        vencido:    { label: "Vencido",    cls: "badge-danger"  },
        cancelado:  { label: "Cancelado",  cls: "badge-secondary"},
        gerado:     { label: "Gerado",     cls: "badge-info"    },
        registrado: { label: "Registrado", cls: "badge-primary" },
        pendente:   { label: "Pendente",   cls: "badge-warning" },
        conciliado: { label: "Conciliado", cls: "badge-success" },
      };
      const item = map[s] || { label: s, cls: "badge-secondary" };
      return `<span class="badge ${item.cls}">${item.label}</span>`;
    }
  };

  async function api(method, path, body) {
    const token = (window.AppState && AppState.authToken)
      ? AppState.authToken
      : localStorage.getItem("token");
    const opts = {
      method,
      headers: {
        "Content-Type": "application/json",
        ...(token ? { "Authorization": "Bearer " + token } : {})
      }
    };
    if (body) opts.body = JSON.stringify(body);
    const res = await fetch("/api" + path, opts);
    const data = await res.json();
    if (!res.ok) throw new Error(data.error || "Erro na requisição");
    return data;
  }

  async function loadEntities() {
    try {
      // Usa rota própria do financeiro que faz comparação case-insensitive
      const todos = await api("GET", "/financeiro/entities");
      _entities = Array.isArray(todos) ? todos : [];
    } catch { _entities = []; }
  }

  async function loadBancos() {
    try {
      _bancos = await api("GET", "/financeiro/bancos");
    } catch { _bancos = []; }
  }

  function entityNome(id) {
    const e = _entities.find(x => x.id === id);
    if (!e) return "—";
    const d = e.data_json || e;
    return d.razaoSocial || d.nomeFantasia || d.cnpjCpf || String(id);
  }

  function bancoNome(id) {
    const b = _bancos.find(x => x.id === id);
    return b ? b.nome : id || "—";
  }

  // ── Estrutura principal ──────────────────────────────────────
  function renderShell() {
    const tabs = [
      { id: "dashboard",       label: "Dashboard",         icon: "📊" },
      { id: "contas_pagar",    label: "Contas a Pagar",    icon: "📤" },
      { id: "contas_receber",  label: "Contas a Receber",  icon: "📥" },
      { id: "boletos",         label: "Boletos",           icon: "🧾" },
      { id: "gerar_lote",      label: "Gerar em Lote",     icon: "⚡" },
      { id: "banco",           label: "Banco / CNAB",      icon: "🏦" },
      { id: "conciliacao",     label: "Conciliação",       icon: "🔗" },
      { id: "fluxo_caixa",     label: "Fluxo de Caixa",   icon: "💰" },
    ];

    return `
      <div class="fin-wrapper">
        <div class="fin-tabs">
          ${tabs.map(t => `
            <button class="fin-tab ${_currentTab === t.id ? "active" : ""}"
                    data-tab="${t.id}">
              ${t.icon} ${t.label}
            </button>
          `).join("")}
        </div>
        <div id="fin-content" class="fin-content">
          <div class="fin-loading">Carregando...</div>
        </div>
      </div>
    `;
  }

  function bindTabs() {
    document.querySelectorAll(".fin-tab").forEach(btn => {
      btn.addEventListener("click", () => {
        _currentTab = btn.dataset.tab;
        document.querySelectorAll(".fin-tab").forEach(b => b.classList.remove("active"));
        btn.classList.add("active");
        renderTab(_currentTab);
      });
    });
  }

  async function renderTab(tab) {
    const el = document.getElementById("fin-content");
    if (!el) return;
    el.innerHTML = `<div class="fin-loading">Carregando...</div>`;
    try {
      switch (tab) {
        case "dashboard":      await renderDashboard(el);      break;
        case "contas_pagar":   await renderContasPagar(el);    break;
        case "contas_receber": await renderContasReceber(el);  break;
        case "boletos":        await renderBoletos(el);        break;
        case "banco":          await renderBanco(el);          break;
        case "conciliacao":    await renderConciliacao(el);    break;
        case "fluxo_caixa":    await renderFluxoCaixa(el);     break;
        case "gerar_lote":     await renderGerarLote(el);      break;
        default: el.innerHTML = `<p>Módulo em construção.</p>`;
      }
    } catch (err) {
      el.innerHTML = `<div class="fin-error">Erro: ${err.message}</div>`;
    }
  }

  // ── DASHBOARD ────────────────────────────────────────────────
  async function renderDashboard(el) {
    const d = await api("GET", "/financeiro/dashboard");

    el.innerHTML = `
      <div class="fin-dashboard">
        <h2 class="fin-section-title">Dashboard Financeiro</h2>

        <div class="fin-cards">
          <div class="fin-card fin-card-danger">
            <div class="fin-card-icon">📤</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Contas a Pagar</span>
              <span class="fin-card-value">${fmt.moeda(d.contas_pagar.aberto.total)}</span>
              <span class="fin-card-sub">${d.contas_pagar.aberto.n} título(s) em aberto</span>
            </div>
          </div>

          <div class="fin-card fin-card-warning">
            <div class="fin-card-icon">⚠️</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Pagar Vencido</span>
              <span class="fin-card-value">${fmt.moeda(d.contas_pagar.vencido.total)}</span>
              <span class="fin-card-sub">${d.contas_pagar.vencido.n} título(s) vencido(s)</span>
            </div>
          </div>

          <div class="fin-card fin-card-success">
            <div class="fin-card-icon">📥</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Contas a Receber</span>
              <span class="fin-card-value">${fmt.moeda(d.contas_receber.aberto.total)}</span>
              <span class="fin-card-sub">${d.contas_receber.aberto.n} título(s) em aberto</span>
            </div>
          </div>

          <div class="fin-card fin-card-info">
            <div class="fin-card-icon">🧾</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Boletos Ativos</span>
              <span class="fin-card-value">${d.boletos_ativos}</span>
              <span class="fin-card-sub">aguardando pagamento</span>
            </div>
          </div>
        </div>

        <div class="fin-dash-vencidos">
          ${d.contas_pagar.vencido.n > 0
            ? `<div class="fin-alert fin-alert-danger">
                ⚠️ Você tem <strong>${d.contas_pagar.vencido.n}</strong> conta(s) a pagar vencida(s)
                totalizando <strong>${fmt.moeda(d.contas_pagar.vencido.total)}</strong>.
               </div>`
            : ""}
          ${d.contas_receber.vencido.n > 0
            ? `<div class="fin-alert fin-alert-warning">
                ⚠️ Você tem <strong>${d.contas_receber.vencido.n}</strong> conta(s) a receber vencida(s)
                totalizando <strong>${fmt.moeda(d.contas_receber.vencido.total)}</strong>.
               </div>`
            : ""}
        </div>
      </div>
    `;
  }

  // ── CONTAS A PAGAR ───────────────────────────────────────────
  async function renderContasPagar(el) {
    await loadEntities();

    el.innerHTML = `
      <div class="fin-section">
        <div class="fin-toolbar">
          <h2 class="fin-section-title">Contas a Pagar</h2>
          <div class="fin-toolbar-actions">
            <select id="cp-filtro-status" class="fin-select">
              <option value="">Todos os status</option>
              <option value="aberto">Aberto</option>
              <option value="pago">Pago</option>
              <option value="cancelado">Cancelado</option>
            </select>
            <input type="date" id="cp-filtro-de"  class="fin-input" placeholder="De">
            <input type="date" id="cp-filtro-ate" class="fin-input" placeholder="Até">
            <button id="cp-filtrar-btn" class="fin-btn fin-btn-secondary">🔍 Filtrar</button>
            <button id="cp-novo-btn" class="fin-btn fin-btn-primary">+ Nova conta</button>
          </div>
        </div>
        <div id="cp-table-wrap"></div>
      </div>
    `;

    async function load() {
      const status = document.getElementById("cp-filtro-status").value;
      const de     = document.getElementById("cp-filtro-de").value;
      const ate    = document.getElementById("cp-filtro-ate").value;
      let qs = "?";
      if (status) qs += `status=${status}&`;
      if (de)     qs += `vencimento_de=${de}&`;
      if (ate)    qs += `vencimento_ate=${ate}&`;

      const rows = await api("GET", `/financeiro/contas-pagar${qs}`);
      const hoje = new Date().toISOString().slice(0, 10);

      const wrap = document.getElementById("cp-table-wrap");
      if (!rows.length) {
        wrap.innerHTML = `<p class="fin-empty">Nenhuma conta encontrada.</p>`;
        return;
      }

      wrap.innerHTML = `
        <table class="fin-table">
          <thead>
            <tr>
              <th>#</th>
              <th>Fornecedor</th>
              <th>Descrição</th>
              <th>Vencimento</th>
              <th>Valor</th>
              <th>Status</th>
              <th>Ações</th>
            </tr>
          </thead>
          <tbody>
            ${rows.map(r => {
              const vencido = r.status === "aberto" && r.vencimento < hoje;
              return `
                <tr class="${vencido ? "row-vencido" : ""}">
                  <td>${r.id}</td>
                  <td>${r.fornecedor ? (() => { const d = r.fornecedor.data_json || r.fornecedor; return d.razaoSocial || d.nomeFantasia || d.cnpjCpf || "—"; })() : "—"}</td>
                  <td>${r.descricao || "—"}</td>
                  <td>${fmt.data(r.vencimento)} ${vencido ? "⚠️" : ""}</td>
                  <td>${fmt.moeda(r.valor)}</td>
                  <td>${fmt.status(vencido ? "vencido" : r.status)}</td>
                  <td class="fin-actions">
                    <button class="fin-btn-sm fin-btn-info"    data-cp-edit="${r.id}">✏️</button>
                    ${r.status === "aberto"
                      ? `<button class="fin-btn-sm fin-btn-success" data-cp-baixar="${r.id}">✅ Pagar</button>`
                      : ""}
                  </td>
                </tr>
              `;
            }).join("")}
          </tbody>
        </table>
      `;

      wrap.querySelectorAll("[data-cp-edit]").forEach(btn =>
        btn.addEventListener("click", () => modalContaPagar(btn.dataset.cpEdit))
      );
      wrap.querySelectorAll("[data-cp-baixar]").forEach(btn =>
        btn.addEventListener("click", () => modalBaixarPagar(btn.dataset.cpBaixar))
      );
    }

    document.getElementById("cp-filtrar-btn").addEventListener("click", load);
    document.getElementById("cp-novo-btn").addEventListener("click", () => modalContaPagar(null, load));
    load();
  }

  function modalContaPagar(id, onSave) {
    // Modal de criação/edição de conta a pagar
    const isEdit = !!id;
    const title  = isEdit ? "Editar Conta a Pagar" : "Nova Conta a Pagar";

    const fornecedores = _entities.filter(e => String(e.kind || "").toLowerCase() === "fornecedor");

    showModal(title, `
      <div class="fin-form">
        <div class="fin-form-row">
          <label>Fornecedor</label>
          <select id="modal-cp-fornecedor" class="fin-select">
            <option value="">— Selecione —</option>
            ${fornecedores.map(e => {
              const d = e.data_json || e;
              const nome = d.razaoSocial || d.nomeFantasia || d.cnpjCpf || String(e.id);
              return `<option value="${e.id}">${nome}</option>`;
            }).join("")}
          </select>
        </div>
        <div class="fin-form-row">
          <label>Descrição</label>
          <input id="modal-cp-descricao" class="fin-input" type="text" placeholder="Descrição">
        </div>
        <div class="fin-form-row fin-form-2col">
          <div>
            <label>Valor (R$)</label>
            <input id="modal-cp-valor" class="fin-input" type="number" step="0.01" min="0">
          </div>
          <div>
            <label>Vencimento</label>
            <input id="modal-cp-vencimento" class="fin-input" type="date">
          </div>
        </div>
        <div class="fin-form-row">
          <label>Número de parcelas <small style="color:#64748b;font-weight:400">(1 = à vista)</small></label>
          <input id="modal-cp-total-parcelas" class="fin-input" type="number" value="1" min="1" max="60">
          <input id="modal-cp-parcela" type="hidden" value="1">
        </div>
        <div class="fin-form-row">
          <label>Nº Documento</label>
          <input id="modal-cp-numero-doc" class="fin-input" type="text">
        </div>
        <div class="fin-form-row">
          <label>Observações</label>
          <textarea id="modal-cp-obs" class="fin-input" rows="2"></textarea>
        </div>
      </div>
    `, async () => {
      const fornecedor_id  = document.getElementById("modal-cp-fornecedor").value || null;
      const descricao      = document.getElementById("modal-cp-descricao").value;
      const valorTotal     = parseFloat(document.getElementById("modal-cp-valor").value);
      const vencimento1    = document.getElementById("modal-cp-vencimento").value;
      const total_parcelas = parseInt(document.getElementById("modal-cp-total-parcelas").value) || 1;
      const numero_doc     = document.getElementById("modal-cp-numero-doc").value;
      const observacoes    = document.getElementById("modal-cp-obs").value;
      const valorParcela   = Math.round((valorTotal / total_parcelas) * 100) / 100;

      if (isEdit) {
        await api("PUT", `/financeiro/contas-pagar/${id}`, {
          fornecedor_id, descricao, valor: valorTotal, vencimento: vencimento1,
          parcela: 1, total_parcelas, numero_doc, observacoes
        });
      } else {
        const dataBase = new Date(vencimento1 + "T12:00:00");
        for (let i = 0; i < total_parcelas; i++) {
          const dataVenc = new Date(dataBase);
          dataVenc.setMonth(dataVenc.getMonth() + i);
          const vencStr = dataVenc.toISOString().slice(0, 10);
          await api("POST", "/financeiro/contas-pagar", {
            fornecedor_id,
            descricao: total_parcelas > 1 ? `${descricao} (${i + 1}/${total_parcelas})` : descricao,
            valor: valorParcela,
            vencimento: vencStr,
            parcela: i + 1,
            total_parcelas,
            numero_doc,
            observacoes
          });
        }
      }
      closeModal();
      if (onSave) onSave();
      else renderTab("contas_pagar");
    });
  }

  function modalBaixarPagar(id) {
    const hoje = new Date().toISOString().slice(0, 10);
    showModal("Registrar Pagamento", `
      <div class="fin-form">
        <div class="fin-form-row">
          <label>Data do Pagamento</label>
          <input id="modal-baixar-data" class="fin-input" type="date" value="${hoje}">
        </div>
        <div class="fin-form-row">
          <label>Valor Pago (R$)</label>
          <input id="modal-baixar-valor" class="fin-input" type="number" step="0.01" min="0">
        </div>
        <div class="fin-form-row">
          <label>Observações</label>
          <input id="modal-baixar-obs" class="fin-input" type="text">
        </div>
      </div>
    `, async () => {
      await api("POST", `/financeiro/contas-pagar/${id}/baixar`, {
        data_pagamento: document.getElementById("modal-baixar-data").value,
        valor_pago:     parseFloat(document.getElementById("modal-baixar-valor").value),
        observacoes:    document.getElementById("modal-baixar-obs").value,
      });
      closeModal();
      renderTab("contas_pagar");
    });
  }

  // ── CONTAS A RECEBER ─────────────────────────────────────────
  async function renderContasReceber(el) {
    await loadEntities();

    el.innerHTML = `
      <div class="fin-section">
        <div class="fin-toolbar">
          <h2 class="fin-section-title">Contas a Receber</h2>
          <div class="fin-toolbar-actions">
            <select id="cr-filtro-status" class="fin-select">
              <option value="">Todos os status</option>
              <option value="aberto">Aberto</option>
              <option value="recebido">Recebido</option>
              <option value="cancelado">Cancelado</option>
            </select>
            <input type="date" id="cr-filtro-de"  class="fin-input">
            <input type="date" id="cr-filtro-ate" class="fin-input">
            <button id="cr-filtrar-btn" class="fin-btn fin-btn-secondary">🔍 Filtrar</button>
            <button id="cr-novo-btn" class="fin-btn fin-btn-primary">+ Nova conta</button>
          </div>
        </div>
        <div id="cr-table-wrap"></div>
      </div>
    `;

    async function load() {
      const status = document.getElementById("cr-filtro-status").value;
      const de     = document.getElementById("cr-filtro-de").value;
      const ate    = document.getElementById("cr-filtro-ate").value;
      let qs = "?";
      if (status) qs += `status=${status}&`;
      if (de)     qs += `vencimento_de=${de}&`;
      if (ate)    qs += `vencimento_ate=${ate}&`;

      const rows = await api("GET", `/financeiro/contas-receber${qs}`);
      const hoje = new Date().toISOString().slice(0, 10);
      const wrap = document.getElementById("cr-table-wrap");

      if (!rows.length) {
        wrap.innerHTML = `<p class="fin-empty">Nenhuma conta encontrada.</p>`;
        return;
      }

      wrap.innerHTML = `
        <table class="fin-table">
          <thead>
            <tr>
              <th>#</th>
              <th>Cliente</th>
              <th>Descrição</th>
              <th>Vencimento</th>
              <th>Valor</th>
              <th>Status</th>
              <th>Ações</th>
            </tr>
          </thead>
          <tbody>
            ${rows.map(r => {
              const vencido = r.status === "aberto" && r.vencimento < hoje;
              return `
                <tr class="${vencido ? "row-vencido" : ""}">
                  <td>${r.id}</td>
                  <td>${r.cliente ? (() => { const d = r.cliente.data_json || r.cliente; return d.razaoSocial || d.nomeFantasia || d.cnpjCpf || "—"; })() : "—"}</td>
                  <td>${r.descricao || "—"}</td>
                  <td>${fmt.data(r.vencimento)} ${vencido ? "⚠️" : ""}</td>
                  <td>${fmt.moeda(r.valor)}</td>
                  <td>${fmt.status(vencido ? "vencido" : r.status)}</td>
                  <td class="fin-actions">
                    <button class="fin-btn-sm fin-btn-info"    data-cr-edit="${r.id}">✏️</button>
                    ${r.status === "aberto"
                      ? `<button class="fin-btn-sm fin-btn-primary" data-cr-boleto="${r.id}" title="Gerar boleto">🧾 Boleto</button>
                         <button class="fin-btn-sm fin-btn-success" data-cr-baixar="${r.id}">✅ Receber</button>`
                      : ""}
                  </td>
                </tr>
              `;
            }).join("")}
          </tbody>
        </table>
      `;

      wrap.querySelectorAll("[data-cr-edit]").forEach(btn =>
        btn.addEventListener("click", () => modalContaReceber(btn.dataset.crEdit, load))
      );
      wrap.querySelectorAll("[data-cr-baixar]").forEach(btn =>
        btn.addEventListener("click", () => modalBaixarReceber(btn.dataset.crBaixar))
      );
      wrap.querySelectorAll("[data-cr-boleto]").forEach(btn =>
        btn.addEventListener("click", () => modalGerarBoleto(btn.dataset.crBoleto))
      );
    }

    document.getElementById("cr-filtrar-btn").addEventListener("click", load);
    document.getElementById("cr-novo-btn").addEventListener("click", () => modalContaReceber(null, load));
    load();
  }

  function modalContaReceber(id, onSave) {
    const isEdit = !!id;
    const clientes = _entities.filter(e => ["cliente","CLIENTE"].includes(String(e.kind || "")));

    showModal(isEdit ? "Editar Conta a Receber" : "Nova Conta a Receber", `
      <div class="fin-form">
        <div class="fin-form-row">
          <label>Cliente</label>
          <select id="modal-cr-cliente" class="fin-select">
            <option value="">— Selecione —</option>
            ${clientes.map(e => {
              const d = e.data_json || e;
              const nome = d.razaoSocial || d.nomeFantasia || d.cnpjCpf || String(e.id);
              return `<option value="${e.id}">${nome}</option>`;
            }).join("")}
          </select>
        </div>
        <div class="fin-form-row">
          <label>Descrição</label>
          <input id="modal-cr-descricao" class="fin-input" type="text">
        </div>
        <div class="fin-form-row fin-form-2col">
          <div>
            <label>Valor (R$)</label>
            <input id="modal-cr-valor" class="fin-input" type="number" step="0.01" min="0">
          </div>
          <div>
            <label>Vencimento</label>
            <input id="modal-cr-vencimento" class="fin-input" type="date">
          </div>
        </div>
        <div class="fin-form-row">
          <label>Número de parcelas <small style="color:#64748b;font-weight:400">(1 = à vista)</small></label>
          <input id="modal-cr-total-parcelas" class="fin-input" type="number" value="1" min="1" max="60">
          <input id="modal-cr-parcela" type="hidden" value="1">
        </div>
        <div class="fin-form-row">
          <label>Forma de Recebimento</label>
          <select id="modal-cr-forma" class="fin-select">
            <option value="boleto">Boleto</option>
            <option value="pix">PIX</option>
            <option value="transferencia">Transferência</option>
            <option value="dinheiro">Dinheiro</option>
            <option value="cheque">Cheque</option>
          </select>
        </div>
        <div class="fin-form-row">
          <label>Nº Documento</label>
          <input id="modal-cr-numero-doc" class="fin-input" type="text">
        </div>
        <div class="fin-form-row">
          <label>Observações</label>
          <textarea id="modal-cr-obs" class="fin-input" rows="2"></textarea>
        </div>
      </div>
    `, async () => {
      const cliente_id     = document.getElementById("modal-cr-cliente").value || null;
      const descricao      = document.getElementById("modal-cr-descricao").value;
      const valorTotal     = parseFloat(document.getElementById("modal-cr-valor").value);
      const vencimento1    = document.getElementById("modal-cr-vencimento").value;
      const total_parcelas = parseInt(document.getElementById("modal-cr-total-parcelas").value) || 1;
      const forma_recebimento = document.getElementById("modal-cr-forma").value;
      const numero_doc     = document.getElementById("modal-cr-numero-doc").value;
      const observacoes    = document.getElementById("modal-cr-obs").value;
      const valorParcela   = Math.round((valorTotal / total_parcelas) * 100) / 100;

      if (isEdit) {
        await api("PUT", `/financeiro/contas-receber/${id}`, {
          cliente_id, descricao, valor: valorTotal, vencimento: vencimento1,
          parcela: 1, total_parcelas, forma_recebimento, numero_doc, observacoes
        });
      } else {
        const dataBase = new Date(vencimento1 + "T12:00:00");
        for (let i = 0; i < total_parcelas; i++) {
          const dataVenc = new Date(dataBase);
          dataVenc.setMonth(dataVenc.getMonth() + i);
          const vencStr = dataVenc.toISOString().slice(0, 10);
          await api("POST", "/financeiro/contas-receber", {
            cliente_id,
            descricao: total_parcelas > 1 ? `${descricao} (${i + 1}/${total_parcelas})` : descricao,
            valor: valorParcela,
            vencimento: vencStr,
            parcela: i + 1,
            total_parcelas,
            forma_recebimento,
            numero_doc,
            observacoes
          });
        }
      }
      closeModal();
      if (onSave) onSave();
      else renderTab("contas_receber");
    });
  }

  // ── GERAR BOLETO a partir de conta a receber ─────────────────
  async function modalGerarBoleto(contaId) {
    await loadBancos();

    if (!_bancos.length) {
      alert("Nenhum banco cadastrado. Configure em Banco / CNAB antes de emitir boletos.");
      return;
    }

    showModal("Gerar Boleto", `
      <div class="fin-form">
        <div class="fin-alert fin-alert-info">
          🧾 O boleto será gerado e registrado automaticamente no Sicoob
          se as credenciais estiverem configuradas.
        </div>
        <div class="fin-form-row">
          <label>Banco para emissão</label>
          <select id="modal-boleto-banco" class="fin-select">
            <option value="">— Selecione o banco —</option>
            ${_bancos.map(b => `<option value="${b.id}">${b.nome}</option>`).join("")}
          </select>
        </div>
      </div>
    `, async () => {
      const banco_id = document.getElementById("modal-boleto-banco").value;
      if (!banco_id) throw new Error("Selecione um banco.");

      const btn = document.getElementById("fin-modal-confirm");
      btn.textContent = "Emitindo...";

      const result = await api("POST", `/financeiro/contas-receber/${contaId}/gerar-boleto`, { banco_id });

      closeModal();

      if (result.registrado_sicoob) {
        modalVisualizarBoleto(result);
      } else {
        const msg = result.aviso
          ? `⚠️ ${result.aviso}`
          : `✅ Boleto criado (ID: ${result.boleto_id}). Configure o Sicoob para registro automático.`;
        alert(msg);
        renderTab("boletos");
      }
    });
  }

  // ── VISUALIZAR boleto emitido ─────────────────────────────────
  function modalVisualizarBoleto(dados) {
    showModal("Boleto Emitido ✅", `
      <div class="fin-form">
        <div class="fin-alert fin-alert-info" style="background:#dcfce7;border-color:#16a34a;color:#14532d">
          ✅ Boleto registrado com sucesso no Sicoob!
        </div>
        <div class="fin-form-row">
          <label>Nosso Número</label>
          <input class="fin-input" readonly value="${dados.nosso_numero || '—'}">
        </div>
        <div class="fin-form-row">
          <label>Linha Digitável</label>
          <input class="fin-input" readonly id="linha-digitavel-copy"
                 value="${dados.linha_digitavel || '—'}"
                 style="font-family:monospace;font-size:.8rem">
        </div>
        <div class="fin-form-row">
          <label>Código de Barras</label>
          <input class="fin-input" readonly
                 value="${dados.codigo_barras || '—'}"
                 style="font-family:monospace;font-size:.75rem">
        </div>
        <div style="display:flex;gap:.5rem;margin-top:.5rem">
          <button class="fin-btn fin-btn-secondary" onclick="
            const el = document.getElementById('linha-digitavel-copy');
            el.select(); document.execCommand('copy');
            this.textContent = '✅ Copiado!';
            setTimeout(() => this.textContent = '📋 Copiar linha digitável', 2000);
          ">📋 Copiar linha digitável</button>
        </div>
      </div>
    `, async () => {
      closeModal();
      renderTab("boletos");
    });

    // Mudar texto do botão confirmar
    setTimeout(() => {
      const btn = document.getElementById("fin-modal-confirm");
      if (btn) btn.textContent = "Ver Boletos";
    }, 100);
  }

  function modalBaixarReceber(id) {
    const hoje = new Date().toISOString().slice(0, 10);
    showModal("Registrar Recebimento", `
      <div class="fin-form">
        <div class="fin-form-row">
          <label>Data do Recebimento</label>
          <input id="modal-recv-data" class="fin-input" type="date" value="${hoje}">
        </div>
        <div class="fin-form-row">
          <label>Valor Recebido (R$)</label>
          <input id="modal-recv-valor" class="fin-input" type="number" step="0.01" min="0">
        </div>
        <div class="fin-form-row">
          <label>Observações</label>
          <input id="modal-recv-obs" class="fin-input" type="text">
        </div>
      </div>
    `, async () => {
      await api("POST", `/financeiro/contas-receber/${id}/baixar`, {
        data_recebimento: document.getElementById("modal-recv-data").value,
        valor_recebido:   parseFloat(document.getElementById("modal-recv-valor").value),
        observacoes:      document.getElementById("modal-recv-obs").value,
      });
      closeModal();
      renderTab("contas_receber");
    });
  }

  // ── BOLETOS ──────────────────────────────────────────────────
  async function renderBoletos(el) {
    await loadBancos();
    await loadEntities();

    el.innerHTML = `
      <div class="fin-section">
        <h2 class="fin-section-title">Boletos</h2>

        <!-- Filtros avançados -->
        <div class="bol-filtros-card">
          <div class="bol-filtros-grid">
            <div>
              <label class="bol-label">Cliente / Sacado</label>
              <input id="bol-filtro-cliente" class="fin-input" type="text" placeholder="Nome ou CNPJ...">
            </div>
            <div>
              <label class="bol-label">Status</label>
              <select id="bol-filtro-status" class="fin-select">
                <option value="">Todos</option>
                <option value="gerado">Gerado</option>
                <option value="registrado">Registrado</option>
                <option value="pago">Pago</option>
                <option value="cancelado">Cancelado</option>
              </select>
            </div>
            <div>
              <label class="bol-label">Banco</label>
              <select id="bol-filtro-banco" class="fin-select">
                <option value="">Todos os bancos</option>
                ${_bancos.map(b => `<option value="${b.id}">${b.nome}</option>`).join("")}
              </select>
            </div>
            <div>
              <label class="bol-label">Vencimento de</label>
              <input id="bol-filtro-de" class="fin-input" type="date">
            </div>
            <div>
              <label class="bol-label">Vencimento até</label>
              <input id="bol-filtro-ate" class="fin-input" type="date">
            </div>
            <div style="display:flex;align-items:flex-end;gap:.5rem">
              <button id="bol-filtrar-btn" class="fin-btn fin-btn-primary" style="flex:1">🔍 Buscar</button>
              <button id="bol-limpar-btn" class="fin-btn fin-btn-secondary">✕</button>
            </div>
          </div>
        </div>

        <!-- Barra de ações em lote -->
        <div class="bol-acoes-lote" id="bol-acoes-lote" style="display:none">
          <span id="bol-sel-count" class="bol-sel-count">0 selecionado(s)</span>
          <button id="bol-imprimir-sel-btn" class="fin-btn fin-btn-info">🖨️ Imprimir selecionados</button>
          <button id="bol-deselect-btn" class="fin-btn fin-btn-secondary">✕ Desmarcar todos</button>
        </div>

        <!-- Toolbar global -->
        <div class="fin-toolbar" style="margin-top:.5rem">
          <div style="display:flex;gap:.5rem;align-items:center">
            <input type="checkbox" id="bol-check-all" title="Selecionar todos visíveis" style="width:16px;height:16px;cursor:pointer">
            <label for="bol-check-all" style="font-size:.82rem;color:#475569;cursor:pointer">Selecionar todos</label>
          </div>
          <div style="display:flex;gap:.5rem">
            <button id="bol-imprimir-todos-btn" class="fin-btn fin-btn-secondary">🖨️ Imprimir todos visíveis</button>
            <button id="bol-novo-btn" class="fin-btn fin-btn-primary">+ Novo boleto</button>
          </div>
        </div>

        <div id="bol-table-wrap"></div>
      </div>
    `;

    let _boletosFiltrados = [];

    function atualizarBarraLote() {
      const checks = document.querySelectorAll(".bol-check-item:checked");
      const barra  = document.getElementById("bol-acoes-lote");
      const count  = document.getElementById("bol-sel-count");
      if (!barra || !count) return;
      if (checks.length > 0) {
        barra.style.display = "flex";
        count.textContent = `${checks.length} boleto(s) selecionado(s)`;
      } else {
        barra.style.display = "none";
      }
    }

    function imprimirIds(ids) {
      if (!ids.length) { alert("Nenhum boleto selecionado."); return; }
      // Abre impressão individual para cada um em sequência
      // Para lote, passa os IDs como query string
      const token = (window.AppState && AppState.authToken)
        ? AppState.authToken
        : localStorage.getItem("token");
      const qs = ids.map(id => `ids=${id}`).join("&");
      // Abre nova aba com token no header via form POST
      const form = document.createElement("form");
      form.method = "GET";
      form.action = `/api/financeiro/boletos/lote/imprimir`;
      form.target = "_blank";
      ids.forEach(id => {
        const input = document.createElement("input");
        input.type = "hidden"; input.name = "ids"; input.value = id;
        form.appendChild(input);
      });
      // Adiciona token como parâmetro (rota vai aceitar token via query)
      const tkInput = document.createElement("input");
      tkInput.type = "hidden"; tkInput.name = "token"; tkInput.value = token || "";
      form.appendChild(tkInput);
      document.body.appendChild(form);
      form.submit();
      document.body.removeChild(form);
    }

    async function load() {
      const cliente    = document.getElementById("bol-filtro-cliente").value.toLowerCase().trim();
      const status     = document.getElementById("bol-filtro-status").value;
      const banco_id   = document.getElementById("bol-filtro-banco").value;
      const de         = document.getElementById("bol-filtro-de").value;
      const ate        = document.getElementById("bol-filtro-ate").value;

      let qs = "?";
      if (status)   qs += `status=${status}&`;
      if (de)       qs += `vencimento_de=${de}&`;
      if (ate)      qs += `vencimento_ate=${ate}&`;

      const rows = await api("GET", `/financeiro/boletos${qs}`);
      const wrap = document.getElementById("bol-table-wrap");

      // Filtro por cliente (frontend, pois sacado_nome já vem no retorno)
      _boletosFiltrados = cliente
        ? rows.filter(r => {
            const nome = (r.sacado_nome || r.banco_nome || "").toLowerCase();
            return nome.includes(cliente);
          })
        : rows;

      // Filtro por banco
      if (banco_id) {
        _boletosFiltrados = _boletosFiltrados.filter(r => String(r.banco_id) === String(banco_id));
      }

      if (!_boletosFiltrados.length) {
        wrap.innerHTML = `<p class="fin-empty">Nenhum boleto encontrado para os filtros aplicados.</p>`;
        return;
      }

      wrap.innerHTML = `
        <table class="fin-table">
          <thead>
            <tr>
              <th style="width:36px"></th>
              <th>#</th>
              <th>Banco</th>
              <th>Cliente / Sacado</th>
              <th>Vencimento</th>
              <th>Valor</th>
              <th>Nosso Nº</th>
              <th>Status</th>
              <th>Ações</th>
            </tr>
          </thead>
          <tbody>
            ${_boletosFiltrados.map(r => `
              <tr class="bol-row" data-id="${r.id}">
                <td style="text-align:center">
                  <input type="checkbox" class="bol-check-item" value="${r.id}"
                         style="width:15px;height:15px;cursor:pointer">
                </td>
                <td>${r.id}</td>
                <td>${r.banco_nome || bancoNome(r.banco_id)}</td>
                <td>${r.sacado_nome || "—"}</td>
                <td>${fmt.data(r.vencimento)}</td>
                <td>${fmt.moeda(r.valor)}</td>
                <td style="font-family:monospace;font-size:.78rem">${r.nosso_numero || "—"}</td>
                <td>${fmt.status(r.status)}</td>
                <td class="fin-actions">
                  <button class="fin-btn-sm fin-btn-info" data-bol-imprimir="${r.id}" title="Imprimir este boleto">🖨️</button>
                  ${r.status !== "cancelado" && r.status !== "pago"
                    ? `<button class="fin-btn-sm fin-btn-danger" data-bol-cancelar="${r.id}" title="Cancelar">🚫</button>`
                    : ""}
                </td>
              </tr>
            `).join("")}
          </tbody>
        </table>
        <div class="bol-resumo">
          Total: <strong>${_boletosFiltrados.length}</strong> boleto(s) |
          Valor total: <strong>${fmt.moeda(_boletosFiltrados.reduce((s,r) => s + (r.valor||0), 0))}</strong>
        </div>
      `;

      // Bind checkboxes
      wrap.querySelectorAll(".bol-check-item").forEach(cb =>
        cb.addEventListener("change", atualizarBarraLote)
      );

      // Click na linha seleciona o checkbox
      wrap.querySelectorAll(".bol-row").forEach(row => {
        row.addEventListener("click", (e) => {
          if (e.target.tagName === "BUTTON" || e.target.tagName === "INPUT") return;
          const cb = row.querySelector(".bol-check-item");
          if (cb) { cb.checked = !cb.checked; atualizarBarraLote(); }
        });
      });

      wrap.querySelectorAll("[data-bol-cancelar]").forEach(btn =>
        btn.addEventListener("click", async (e) => {
          e.stopPropagation();
          if (!confirm("Cancelar este boleto?")) return;
          await api("POST", `/financeiro/boletos/${btn.dataset.bolCancelar}/cancelar`);
          load();
        })
      );

      wrap.querySelectorAll("[data-bol-imprimir]").forEach(btn =>
        btn.addEventListener("click", (e) => {
          e.stopPropagation();
          imprimirIds([btn.dataset.bolImprimir]);
        })
      );
    }

    // Bind filtros
    document.getElementById("bol-filtrar-btn").addEventListener("click", load);
    document.getElementById("bol-filtro-cliente").addEventListener("keydown", e => { if (e.key === "Enter") load(); });
    document.getElementById("bol-limpar-btn").addEventListener("click", () => {
      document.getElementById("bol-filtro-cliente").value = "";
      document.getElementById("bol-filtro-status").value  = "";
      document.getElementById("bol-filtro-banco").value   = "";
      document.getElementById("bol-filtro-de").value      = "";
      document.getElementById("bol-filtro-ate").value     = "";
      load();
    });

    // Selecionar todos
    document.getElementById("bol-check-all").addEventListener("change", (e) => {
      document.querySelectorAll(".bol-check-item").forEach(cb => cb.checked = e.target.checked);
      atualizarBarraLote();
    });

    // Imprimir selecionados
    document.getElementById("bol-imprimir-sel-btn").addEventListener("click", () => {
      const ids = [...document.querySelectorAll(".bol-check-item:checked")].map(cb => cb.value);
      imprimirIds(ids);
    });

    // Desmarcar todos
    document.getElementById("bol-deselect-btn").addEventListener("click", () => {
      document.querySelectorAll(".bol-check-item").forEach(cb => cb.checked = false);
      document.getElementById("bol-check-all").checked = false;
      atualizarBarraLote();
    });

    // Imprimir todos visíveis
    document.getElementById("bol-imprimir-todos-btn").addEventListener("click", () => {
      const ids = _boletosFiltrados.map(r => String(r.id));
      imprimirIds(ids);
    });

    document.getElementById("bol-novo-btn").addEventListener("click", () => modalNovoBoleto(load));

    load();
  }

  function modalNovoBoleto(onSave) {
    showModal("Novo Boleto", `
      <div class="fin-form">
        <div class="fin-alert fin-alert-info">
          ℹ️ A emissão automática via Sicoob estará disponível após configuração do banco.
          Aqui você pode registrar boletos manualmente.
        </div>
        <div class="fin-form-row">
          <label>Banco</label>
          <select id="modal-bol-banco" class="fin-select">
            <option value="">— Selecione —</option>
            ${_bancos.map(b => `<option value="${b.id}">${b.nome}</option>`).join("")}
          </select>
        </div>
        <div class="fin-form-row fin-form-2col">
          <div>
            <label>Valor (R$)</label>
            <input id="modal-bol-valor" class="fin-input" type="number" step="0.01" min="0">
          </div>
          <div>
            <label>Vencimento</label>
            <input id="modal-bol-vencimento" class="fin-input" type="date">
          </div>
        </div>
        <div class="fin-form-row">
          <label>Nosso Número</label>
          <input id="modal-bol-nosso-numero" class="fin-input" type="text">
        </div>
        <div class="fin-form-row">
          <label>Sacado (Nome)</label>
          <input id="modal-bol-sacado-nome" class="fin-input" type="text">
        </div>
        <div class="fin-form-row">
          <label>Sacado (CNPJ/CPF)</label>
          <input id="modal-bol-sacado-doc" class="fin-input" type="text">
        </div>
        <div class="fin-form-row">
          <label>Instruções</label>
          <textarea id="modal-bol-instrucoes" class="fin-input" rows="2"></textarea>
        </div>
      </div>
    `, async () => {
      await api("POST", "/financeiro/boletos", {
        banco_id:        document.getElementById("modal-bol-banco").value,
        valor:           parseFloat(document.getElementById("modal-bol-valor").value),
        vencimento:      document.getElementById("modal-bol-vencimento").value,
        nosso_numero:    document.getElementById("modal-bol-nosso-numero").value,
        sacado_nome:     document.getElementById("modal-bol-sacado-nome").value,
        sacado_documento: document.getElementById("modal-bol-sacado-doc").value,
        instrucoes:      document.getElementById("modal-bol-instrucoes").value,
      });
      closeModal();
      if (onSave) onSave();
    });
  }

  // ── BANCO / CNAB ─────────────────────────────────────────────
  async function renderBanco(el) {
    await loadBancos();

    el.innerHTML = `
      <div class="fin-section">
        <div class="fin-toolbar">
          <h2 class="fin-section-title">Banco / CNAB</h2>
          <button id="banco-novo-btn" class="fin-btn fin-btn-primary">+ Novo banco</button>
        </div>
        <div id="banco-list">
          ${!_bancos.length
            ? `<p class="fin-empty">Nenhum banco cadastrado.</p>`
            : _bancos.map(b => `
                <div class="fin-banco-card">
                  <div class="fin-banco-info">
                    <strong>${b.nome}</strong>
                    <span>Cód: ${b.codigo} | Ag: ${b.agencia || "—"} | Cc: ${b.conta || "—"}</span>
                    <span>Convênio: ${b.convenio || "—"} | Carteira: ${b.carteira || "—"}</span>
                    <span class="badge ${b.ativo ? "badge-success" : "badge-secondary"}">
                      ${b.ativo ? "Ativo" : "Inativo"}
                    </span>
                  </div>
                  <div class="fin-actions">
                    <button class="fin-btn-sm fin-btn-info"    data-banco-edit="${b.id}">✏️ Editar</button>
                    <button class="fin-btn-sm fin-btn-primary" data-banco-sicoob="${b.id}">⚙️ Config Sicoob</button>
                    <button class="fin-btn-sm fin-btn-secondary" data-banco-testar="${b.id}">🔌 Testar</button>
                  </div>
                </div>
              `).join("")}
        </div>
      </div>
    `;

    document.getElementById("banco-novo-btn").addEventListener("click", () => modalBanco(null));

    document.querySelectorAll("[data-banco-edit]").forEach(btn =>
      btn.addEventListener("click", () => modalBanco(btn.dataset.bancoEdit))
    );
    document.querySelectorAll("[data-banco-sicoob]").forEach(btn =>
      btn.addEventListener("click", () => modalSicoobConfig(btn.dataset.bancoSicoob))
    );
    document.querySelectorAll("[data-banco-testar]").forEach(btn =>
      btn.addEventListener("click", async () => {
        btn.textContent = "🔄 Testando...";
        btn.disabled = true;
        try {
          const r = await api("POST", `/financeiro/bancos/${btn.dataset.bancoTestar}/sicoob/testar`);
          alert(r.ok ? "✅ Conexão Sicoob OK! Token obtido com sucesso." : `❌ Falha: ${r.erro}`);
        } catch(e) {
          alert("❌ Erro: " + e.message);
        }
        btn.textContent = "🔌 Testar";
        btn.disabled = false;
      })
    );
  }

  function modalBanco(id) {
    const banco  = id ? _bancos.find(b => String(b.id) === String(id)) : null;
    const isEdit = !!banco;

    showModal(isEdit ? "Editar Banco" : "Novo Banco", `
      <div class="fin-form">
        <div class="fin-form-row">
          <label>Nome do banco</label>
          <input id="modal-banco-nome"     class="fin-input" type="text" value="${banco?.nome || ""}">
        </div>
        <div class="fin-form-row fin-form-2col">
          <div>
            <label>Código bancário</label>
            <input id="modal-banco-codigo"   class="fin-input" type="text" value="${banco?.codigo || ""}">
          </div>
          <div>
            <label>Agência</label>
            <input id="modal-banco-agencia"  class="fin-input" type="text" value="${banco?.agencia || ""}">
          </div>
        </div>
        <div class="fin-form-row fin-form-2col">
          <div>
            <label>Conta corrente</label>
            <input id="modal-banco-conta"    class="fin-input" type="text" value="${banco?.conta || ""}">
          </div>
          <div>
            <label>Convênio</label>
            <input id="modal-banco-convenio" class="fin-input" type="text" value="${banco?.convenio || ""}">
          </div>
        </div>
        <div class="fin-form-row">
          <label>Carteira</label>
          <input id="modal-banco-carteira"  class="fin-input" type="text" value="${banco?.carteira || ""}">
        </div>
      </div>
    `, async () => {
      const body = {
        nome:     document.getElementById("modal-banco-nome").value,
        codigo:   document.getElementById("modal-banco-codigo").value,
        agencia:  document.getElementById("modal-banco-agencia").value,
        conta:    document.getElementById("modal-banco-conta").value,
        convenio: document.getElementById("modal-banco-convenio").value,
        carteira: document.getElementById("modal-banco-carteira").value,
      };
      if (isEdit) {
        await api("PUT", `/financeiro/bancos/${id}`, body);
      } else {
        await api("POST", "/financeiro/bancos", body);
      }
      closeModal();
      await loadBancos();
      renderTab("banco");
    });
  }

  function modalSicoobConfig(bancoId) {
    showModal("Configuração Sicoob", `
      <div class="fin-form">
        <div class="fin-alert fin-alert-info">
          🔐 As credenciais Sicoob são armazenadas localmente no servidor.
          O certificado digital (.p12) deve estar no servidor.
        </div>
        <div class="fin-form-row">
          <label>Client ID</label>
          <input id="modal-sc-client-id" class="fin-input" type="text" placeholder="Client ID do Sicoob">
        </div>
        <div class="fin-form-row">
          <label>Client Secret</label>
          <input id="modal-sc-client-secret" class="fin-input" type="password" placeholder="Client Secret">
        </div>
        <div class="fin-form-row">
          <label>Caminho do certificado (.p12)</label>
          <input id="modal-sc-cert-path" class="fin-input" type="text" placeholder="Ex: /certs/sicoob.p12">
        </div>
        <div class="fin-form-row">
          <label>Caminho da chave (.key)</label>
          <input id="modal-sc-key-path" class="fin-input" type="text" placeholder="Ex: /certs/sicoob.key">
        </div>
        <div class="fin-form-row">
          <label>Ambiente</label>
          <select id="modal-sc-ambiente" class="fin-select">
            <option value="homologacao">Homologação</option>
            <option value="producao">Produção</option>
          </select>
        </div>
        <div class="fin-form-row fin-form-2col">
          <div>
            <label>Número da Conta</label>
            <input id="modal-sc-conta" class="fin-input" type="text">
          </div>
          <div>
            <label>Código do Beneficiário</label>
            <input id="modal-sc-beneficiario" class="fin-input" type="text">
          </div>
        </div>
      </div>
    `, async () => {
      await api("POST", `/financeiro/bancos/${bancoId}/sicoob`, {
        client_id:           document.getElementById("modal-sc-client-id").value,
        client_secret:       document.getElementById("modal-sc-client-secret").value,
        cert_path:           document.getElementById("modal-sc-cert-path").value,
        key_path:            document.getElementById("modal-sc-key-path").value,
        ambiente:            document.getElementById("modal-sc-ambiente").value,
        numero_conta:        document.getElementById("modal-sc-conta").value,
        codigo_beneficiario: document.getElementById("modal-sc-beneficiario").value,
      });
      closeModal();
      alert("✅ Configuração Sicoob salva com sucesso!");
    });
  }

  // ── CONCILIAÇÃO ──────────────────────────────────────────────
  async function renderConciliacao(el) {
    await loadBancos();

    el.innerHTML = `
      <div class="fin-section">
        <div class="fin-toolbar">
          <h2 class="fin-section-title">Conciliação Bancária</h2>
          <div class="fin-toolbar-actions">
            <select id="conc-banco" class="fin-select">
              <option value="">Todos os bancos</option>
              ${_bancos.map(b => `<option value="${b.id}">${b.nome}</option>`).join("")}
            </select>
            <select id="conc-status" class="fin-select">
              <option value="pendente">Pendentes</option>
              <option value="conciliado">Conciliados</option>
              <option value="">Todos</option>
            </select>
            <button id="conc-filtrar-btn" class="fin-btn fin-btn-secondary">🔍 Filtrar</button>
          </div>
        </div>
        <div id="conc-table-wrap">
          <p class="fin-empty">Selecione um banco e clique em Filtrar para ver os lançamentos.</p>
        </div>
      </div>
    `;

    document.getElementById("conc-filtrar-btn").addEventListener("click", async () => {
      const banco_id = document.getElementById("conc-banco").value;
      const status   = document.getElementById("conc-status").value;
      let qs = "?status=pendente";
      if (banco_id) qs += `&banco_id=${banco_id}`;
      if (status)   qs = `?${banco_id ? `banco_id=${banco_id}&` : ""}status=${status}`;

      const rows = await api("GET", `/financeiro/extrato${qs}`);
      const wrap = document.getElementById("conc-table-wrap");

      if (!rows.length) {
        wrap.innerHTML = `<p class="fin-empty">Nenhum lançamento encontrado.</p>`;
        return;
      }

      wrap.innerHTML = `
        <table class="fin-table">
          <thead>
            <tr>
              <th>Data</th>
              <th>Banco</th>
              <th>Descrição</th>
              <th>Tipo</th>
              <th>Valor</th>
              <th>Status</th>
              <th>Ações</th>
            </tr>
          </thead>
          <tbody>
            ${rows.map(r => `
              <tr>
                <td>${fmt.data(r.data)}</td>
                <td>${r.banco_nome || "—"}</td>
                <td>${r.descricao || "—"}</td>
                <td><span class="badge ${r.tipo === "C" ? "badge-success" : "badge-danger"}">${r.tipo === "C" ? "Crédito" : "Débito"}</span></td>
                <td>${fmt.moeda(r.valor)}</td>
                <td>${fmt.status(r.status)}</td>
                <td>
                  ${r.status === "pendente"
                    ? `<button class="fin-btn-sm fin-btn-primary" data-conc-id="${r.id}">🔗 Conciliar</button>`
                    : "—"}
                </td>
              </tr>
            `).join("")}
          </tbody>
        </table>
      `;

      wrap.querySelectorAll("[data-conc-id]").forEach(btn =>
        btn.addEventListener("click", () => modalConciliar(btn.dataset.concId))
      );
    });
  }

  function modalConciliar(lancamentoId) {
    showModal("Conciliar Lançamento", `
      <div class="fin-form">
        <div class="fin-form-row">
          <label>Tipo de vínculo</label>
          <select id="modal-conc-tipo" class="fin-select">
            <option value="contas_receber">Conta a Receber</option>
            <option value="contas_pagar">Conta a Pagar</option>
          </select>
        </div>
        <div class="fin-form-row">
          <label>ID da conta</label>
          <input id="modal-conc-id" class="fin-input" type="number" placeholder="ID da conta a vincular">
        </div>
      </div>
    `, async () => {
      await api("POST", "/financeiro/extrato/conciliar", {
        lancamento_id:  parseInt(lancamentoId),
        vinculado_a:    parseInt(document.getElementById("modal-conc-id").value),
        vinculado_tipo: document.getElementById("modal-conc-tipo").value,
      });
      closeModal();
      renderTab("conciliacao");
    });
  }

  // ── FLUXO DE CAIXA ───────────────────────────────────────────
  async function renderFluxoCaixa(el) {
    const hoje = new Date();
    const de   = new Date(hoje.getFullYear(), hoje.getMonth(), 1).toISOString().slice(0, 10);
    const ate  = new Date(hoje.getFullYear(), hoje.getMonth() + 1, 0).toISOString().slice(0, 10);

    el.innerHTML = `
      <div class="fin-section">
        <div class="fin-toolbar">
          <h2 class="fin-section-title">Fluxo de Caixa</h2>
          <div class="fin-toolbar-actions">
            <input type="date" id="fc-de"  class="fin-input" value="${de}">
            <input type="date" id="fc-ate" class="fin-input" value="${ate}">
            <button id="fc-filtrar-btn" class="fin-btn fin-btn-secondary">🔍 Atualizar</button>
          </div>
        </div>
        <div id="fc-content"></div>
      </div>
    `;

    async function load() {
      const fcDe  = document.getElementById("fc-de").value;
      const fcAte = document.getElementById("fc-ate").value;
      const data  = await api("GET", `/financeiro/fluxo-caixa?data_de=${fcDe}&data_ate=${fcAte}`);
      const r     = data.resumo;

      document.getElementById("fc-content").innerHTML = `
        <div class="fin-cards">
          <div class="fin-card fin-card-success">
            <div class="fin-card-icon">📥</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Entradas Previstas</span>
              <span class="fin-card-value">${fmt.moeda(r.total_entradas_previstas)}</span>
            </div>
          </div>
          <div class="fin-card fin-card-danger">
            <div class="fin-card-icon">📤</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Saídas Previstas</span>
              <span class="fin-card-value">${fmt.moeda(r.total_saidas_previstas)}</span>
            </div>
          </div>
          <div class="fin-card ${r.saldo_previsto >= 0 ? "fin-card-success" : "fin-card-danger"}">
            <div class="fin-card-icon">⚖️</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Saldo Previsto</span>
              <span class="fin-card-value">${fmt.moeda(r.saldo_previsto)}</span>
            </div>
          </div>
          <div class="fin-card ${r.saldo_realizado >= 0 ? "fin-card-success" : "fin-card-danger"}">
            <div class="fin-card-icon">✅</div>
            <div class="fin-card-body">
              <span class="fin-card-label">Saldo Realizado</span>
              <span class="fin-card-value">${fmt.moeda(r.saldo_realizado)}</span>
              <span class="fin-card-sub">Rec. ${fmt.moeda(r.total_recebido)} / Pago ${fmt.moeda(r.total_pago)}</span>
            </div>
          </div>
        </div>

        ${data.lancamentos.length > 0 ? `
          <table class="fin-table" style="margin-top:1.5rem">
            <thead>
              <tr><th>Data</th><th>Tipo</th><th>Total</th></tr>
            </thead>
            <tbody>
              ${data.lancamentos.map(l => `
                <tr>
                  <td>${fmt.data(l.data)}</td>
                  <td><span class="badge ${l.tipo === "entrada" ? "badge-success" : "badge-danger"}">
                    ${l.tipo === "entrada" ? "Entrada" : "Saída"}
                  </span></td>
                  <td>${fmt.moeda(l.total)}</td>
                </tr>
              `).join("")}
            </tbody>
          </table>
        ` : `<p class="fin-empty" style="margin-top:1rem">Nenhum lançamento no período.</p>`}
      `;
    }

    document.getElementById("fc-filtrar-btn").addEventListener("click", load);
    load();
  }

  // ── GERAR BOLETOS EM LOTE ────────────────────────────────────
  async function renderGerarLote(el) {
    await loadBancos();

    el.innerHTML = `
      <div class="fin-section">
        <h2 class="fin-section-title">⚡ Geração de Boletos em Lote</h2>

        <div class="lote-grid">

          <!-- PAINEL ESQUERDO: Filtros -->
          <div class="lote-panel">
            <div class="lote-panel-title">1. Selecionar orçamentos</div>

            <div class="fin-form">
              <div class="fin-form-row">
                <label>Etapa do orçamento</label>
                <select id="lote-etapa" class="fin-select">
                  <option value="">Todas as etapas</option>
                  <option value="negociacao">Negociação</option>
                  <option value="separacao">Separação</option>
                  <option value="producao">Produção</option>
                  <option value="faturamento">Faturamento</option>
                  <option value="entregue">Entregue</option>
                </select>
              </div>
              <div class="fin-form-row">
                <label>Cliente (CNPJ/CPF ou parte do nome)</label>
                <input id="lote-cliente" class="fin-input" type="text" placeholder="Buscar cliente...">
              </div>
              <div class="fin-form-row fin-form-2col">
                <div>
                  <label>Data criação de</label>
                  <input id="lote-data-de" class="fin-input" type="date">
                </div>
                <div>
                  <label>Data criação até</label>
                  <input id="lote-data-ate" class="fin-input" type="date">
                </div>
              </div>
              <div class="fin-form-row fin-form-2col">
                <div>
                  <label>Valor mínimo (R$)</label>
                  <input id="lote-val-min" class="fin-input" type="number" step="0.01" min="0" placeholder="0,00">
                </div>
                <div>
                  <label>Valor máximo (R$)</label>
                  <input id="lote-val-max" class="fin-input" type="number" step="0.01" min="0">
                </div>
              </div>
              <div class="fin-form-row">
                <label style="display:flex;align-items:center;gap:.5rem;cursor:pointer">
                  <input type="checkbox" id="lote-ignorar" checked style="width:15px;height:15px">
                  Ignorar orçamentos que já possuem faturamento
                </label>
              </div>
              <button id="lote-preview-btn" class="fin-btn fin-btn-primary" style="width:100%;margin-top:.5rem">
                🔍 Buscar orçamentos
              </button>
            </div>
          </div>

          <!-- PAINEL DIREITO: Configuração do boleto -->
          <div class="lote-panel">
            <div class="lote-panel-title">2. Configurar boletos</div>

            <div class="fin-form">
              <div class="fin-form-row">
                <label>Banco para emissão</label>
                <select id="lote-banco" class="fin-select">
                  <option value="">— Selecione o banco —</option>
                  ${_bancos.map(b => `<option value="${b.id}">${b.nome}</option>`).join("")}
                </select>
              </div>
              <div class="fin-form-row fin-form-2col">
                <div>
                  <label>Número de parcelas</label>
                  <input id="lote-parcelas" class="fin-input" type="number" value="1" min="1" max="60">
                </div>
                <div>
                  <label>1º vencimento</label>
                  <input id="lote-vencimento" class="fin-input" type="date">
                </div>
              </div>
              <div class="fin-form-row">
                <label>Forma de recebimento</label>
                <select id="lote-forma" class="fin-select">
                  <option value="boleto">Boleto</option>
                  <option value="pix">PIX</option>
                  <option value="transferencia">Transferência</option>
                </select>
              </div>
              <div class="fin-form-row">
                <label>Descrição adicional (opcional)</label>
                <input id="lote-descricao" class="fin-input" type="text" placeholder="Ex: Venda Junho/2026">
              </div>
            </div>
          </div>
        </div>

        <!-- PRÉVIA -->
        <div id="lote-preview-wrap" style="margin-top:1rem"></div>

      </div>
    `;

    // Setar data padrão de vencimento para hoje
    const hoje = new Date().toISOString().slice(0, 10);
    document.getElementById("lote-vencimento").value = hoje;

    async function buscarPreview() {
      const btn = document.getElementById("lote-preview-btn");
      btn.textContent = "🔄 Buscando...";
      btn.disabled = true;

      try {
        const body = montarFiltros();
        const preview = await api("POST", "/financeiro/boletos/lote/preview", body);
        renderPreview(preview, body);
      } catch (e) {
        document.getElementById("lote-preview-wrap").innerHTML =
          `<div class="fin-error">Erro: ${e.message}</div>`;
      }

      btn.textContent = "🔍 Buscar orçamentos";
      btn.disabled = false;
    }

    function montarFiltros() {
      return {
        banco_id:              document.getElementById("lote-banco").value,
        parcelas:              parseInt(document.getElementById("lote-parcelas").value) || 1,
        vencimento_base:       document.getElementById("lote-vencimento").value,
        forma_recebimento:     document.getElementById("lote-forma").value,
        descricao_extra:       document.getElementById("lote-descricao").value,
        etapa:                 document.getElementById("lote-etapa").value,
        cliente_doc:           document.getElementById("lote-cliente").value,
        data_criacao_de:       document.getElementById("lote-data-de").value,
        data_criacao_ate:      document.getElementById("lote-data-ate").value,
        valor_minimo:          document.getElementById("lote-val-min").value,
        valor_maximo:          document.getElementById("lote-val-max").value,
        ignorar_ja_faturados:  document.getElementById("lote-ignorar").checked,
      };
    }

    function renderPreview(preview, filtros) {
      const wrap = document.getElementById("lote-preview-wrap");

      if (!preview.itens || !preview.itens.length) {
        wrap.innerHTML = `<div class="fin-alert fin-alert-warning">
          ⚠️ Nenhum orçamento encontrado com os filtros selecionados.
        </div>`;
        return;
      }

      const ativos   = preview.itens.filter(i => !i.seria_ignorado);
      const ignorados = preview.itens.filter(i => i.seria_ignorado);

      wrap.innerHTML = `
        <div class="lote-resumo-cards">
          <div class="lote-resumo-card lote-card-blue">
            <span class="lote-resumo-num">${preview.total}</span>
            <span class="lote-resumo-label">Orçamentos encontrados</span>
          </div>
          <div class="lote-resumo-card lote-card-green">
            <span class="lote-resumo-num">${preview.a_processar}</span>
            <span class="lote-resumo-label">Serão processados</span>
          </div>
          <div class="lote-resumo-card lote-card-orange">
            <span class="lote-resumo-num">${preview.total_boletos}</span>
            <span class="lote-resumo-label">Boletos a gerar</span>
          </div>
          <div class="lote-resumo-card lote-card-purple">
            <span class="lote-resumo-num">${fmt.moeda(preview.total_valor)}</span>
            <span class="lote-resumo-label">Valor total</span>
          </div>
          ${preview.ignorados > 0 ? `
          <div class="lote-resumo-card lote-card-gray">
            <span class="lote-resumo-num">${preview.ignorados}</span>
            <span class="lote-resumo-label">Já faturados (ignorados)</span>
          </div>` : ""}
        </div>

        <table class="fin-table" style="margin:.75rem 0">
          <thead>
            <tr>
              <th style="width:36px">
                <input type="checkbox" id="lote-check-all" checked
                       style="width:15px;height:15px;cursor:pointer">
              </th>
              <th>Orçamento</th>
              <th>Cliente</th>
              <th>Etapa</th>
              <th>Valor</th>
              <th>Parcelas</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            ${preview.itens.map(item => `
              <tr class="${item.seria_ignorado ? "row-ignorado" : ""}">
                <td style="text-align:center">
                  <input type="checkbox" class="lote-check-item" value="${item.id}"
                         ${item.seria_ignorado ? "" : "checked"}
                         ${item.seria_ignorado ? "disabled" : ""}
                         style="width:15px;height:15px">
                </td>
                <td><strong>${item.numero}</strong></td>
                <td>${item.cliente}</td>
                <td><span class="badge badge-secondary">${item.etapa || "—"}</span></td>
                <td>${fmt.moeda(item.valor)}</td>
                <td>${item.boletos_a_criar > 0
                  ? item.boletos_a_criar + "x " + fmt.moeda(item.valor_parcela)
                  : "—"}</td>
                <td>${item.ja_faturado
                  ? '<span class="badge badge-info">Já faturado</span>'
                  : '<span class="badge badge-warning">Pendente</span>'}</td>
              </tr>
            `).join("")}
          </tbody>
        </table>

        <div style="display:flex;gap:.75rem;align-items:center;justify-content:flex-end">
          <span id="lote-sel-info" style="font-size:.85rem;color:#64748b"></span>
          <button id="lote-gerar-btn" class="fin-btn fin-btn-primary" style="padding:10px 28px;font-size:1rem">
            ⚡ Gerar boletos selecionados
          </button>
        </div>
      `;

      // Atualizar contador
      function atualizarContador() {
        const checks = document.querySelectorAll(".lote-check-item:checked");
        const total  = [...checks].reduce((s, cb) => {
          const item = preview.itens.find(i => String(i.id) === cb.value);
          return s + (item ? item.valor : 0);
        }, 0);
        const el = document.getElementById("lote-sel-info");
        if (el) el.textContent = `${checks.length} orçamento(s) | ${fmt.moeda(total)}`;
      }

      document.getElementById("lote-check-all").addEventListener("change", (e) => {
        document.querySelectorAll(".lote-check-item:not([disabled])").forEach(cb => cb.checked = e.target.checked);
        atualizarContador();
      });

      document.querySelectorAll(".lote-check-item").forEach(cb =>
        cb.addEventListener("change", atualizarContador)
      );

      atualizarContador();

      document.getElementById("lote-gerar-btn").addEventListener("click", async () => {
        const selecionados = [...document.querySelectorAll(".lote-check-item:checked")]
          .map(cb => parseInt(cb.value));

        if (!selecionados.length) { alert("Selecione ao menos um orçamento."); return; }

        const banco_id = document.getElementById("lote-banco").value;
        if (!banco_id) { alert("Selecione um banco para emissão."); return; }

        const venc = document.getElementById("lote-vencimento").value;
        if (!venc) { alert("Informe a data do 1º vencimento."); return; }

        if (!confirm(
          `Confirmar geração de boletos para ${selecionados.length} orçamento(s)?\n` +
          `Banco: ${_bancos.find(b => String(b.id) === banco_id)?.nome || banco_id}\n` +
          `1º Vencimento: ${venc.split("-").reverse().join("/")}`
        )) return;

        const btnGerar = document.getElementById("lote-gerar-btn");
        btnGerar.disabled = true;
        btnGerar.textContent = "⏳ Gerando...";

        try {
          const body = {
            ...montarFiltros(),
            orcamento_ids: selecionados,
          };

          const resultado = await api("POST", "/financeiro/boletos/lote/gerar", body);
          renderResultado(resultado);
        } catch (e) {
          alert("Erro: " + e.message);
          btnGerar.disabled = false;
          btnGerar.textContent = "⚡ Gerar boletos selecionados";
        }
      });
    }

    function renderResultado(res) {
      const wrap = document.getElementById("lote-preview-wrap");
      const erros = res.erros || [];

      wrap.innerHTML = `
        <div class="fin-alert fin-alert-info" style="background:#dcfce7;border-color:#16a34a;color:#14532d;font-size:1rem">
          ✅ Geração concluída!
          <strong>${res.total_boletos}</strong> boleto(s) gerado(s) de
          <strong>${res.total_orcamentos}</strong> orçamento(s) —
          Total: <strong>${fmt.moeda(res.total_valor)}</strong>
        </div>

        ${erros.length ? `
          <div class="fin-alert fin-alert-danger">
            ⚠️ ${erros.length} erro(s):
            ${erros.map(e => `<br>• ${e.orcamento}: ${e.erro}`).join("")}
          </div>` : ""}

        <table class="fin-table" style="margin:.75rem 0">
          <thead>
            <tr><th>Orçamento</th><th>Cliente</th><th>Valor</th><th>Boletos</th><th>Status</th></tr>
          </thead>
          <tbody>
            ${(res.resultados || []).map(r => `
              <tr>
                <td><strong>${r.orcamento}</strong></td>
                <td>${r.cliente || "—"}</td>
                <td>${fmt.moeda(r.valor)}</td>
                <td>${r.boletos || "—"}</td>
                <td><span class="badge ${r.status === "criado" ? "badge-success" : "badge-secondary"}">
                  ${r.status === "criado" ? "✅ Criado" : r.motivo || r.status}
                </span></td>
              </tr>
            `).join("")}
          </tbody>
        </table>

        <div style="display:flex;gap:.75rem;justify-content:flex-end">
          <button class="fin-btn fin-btn-info" onclick="
            const ids = ${JSON.stringify((res.resultados || []).flatMap(r => r.boleto_ids || []))};
            if (!ids.length) { alert('Nenhum boleto gerado.'); return; }
            const token = (window.AppState && AppState.authToken) ? AppState.authToken : localStorage.getItem('token');
            const form = document.createElement('form');
            form.method = 'GET';
            form.action = '/api/financeiro/boletos/lote/imprimir';
            form.target = '_blank';
            ids.forEach(id => {
              const inp = document.createElement('input');
              inp.type='hidden'; inp.name='ids'; inp.value=id;
              form.appendChild(inp);
            });
            const tk = document.createElement('input');
            tk.type='hidden'; tk.name='token'; tk.value=token||'';
            form.appendChild(tk);
            document.body.appendChild(form);
            form.submit();
            document.body.removeChild(form);
          ">🖨️ Imprimir todos gerados agora</button>

          <button class="fin-btn fin-btn-primary" onclick="
            document.getElementById('lote-preview-btn').click();
          ">🔄 Nova busca</button>

          <button class="fin-btn fin-btn-secondary" onclick="
            window.Financeiro && window.Financeiro.initAndRender('content', 'boletos');
          ">📋 Ver todos os boletos</button>
        </div>
      `;
    }

    document.getElementById("lote-preview-btn").addEventListener("click", buscarPreview);
    document.getElementById("lote-cliente").addEventListener("keydown", e => {
      if (e.key === "Enter") buscarPreview();
    });
  }

  // ── MODAL GENÉRICO ───────────────────────────────────────────
  function showModal(title, body, onConfirm) {
    let existing = document.getElementById("fin-modal-overlay");
    if (existing) existing.remove();

    const overlay = document.createElement("div");
    overlay.id = "fin-modal-overlay";
    overlay.className = "fin-modal-overlay";
    overlay.innerHTML = `
      <div class="fin-modal">
        <div class="fin-modal-header">
          <h3>${title}</h3>
          <button class="fin-modal-close">✕</button>
        </div>
        <div class="fin-modal-body">${body}</div>
        <div class="fin-modal-footer">
          <button id="fin-modal-cancel" class="fin-btn fin-btn-secondary">Cancelar</button>
          <button id="fin-modal-confirm" class="fin-btn fin-btn-primary">Confirmar</button>
        </div>
      </div>
    `;
    document.body.appendChild(overlay);

    overlay.querySelector(".fin-modal-close").addEventListener("click", closeModal);
    document.getElementById("fin-modal-cancel").addEventListener("click", closeModal);
    document.getElementById("fin-modal-confirm").addEventListener("click", async () => {
      const btn = document.getElementById("fin-modal-confirm");
      btn.disabled = true;
      btn.textContent = "Salvando...";
      try {
        await onConfirm();
      } catch (err) {
        alert("Erro: " + err.message);
        btn.disabled = false;
        btn.textContent = "Confirmar";
      }
    });
  }

  function closeModal() {
    const el = document.getElementById("fin-modal-overlay");
    if (el) el.remove();
  }

  // ── API PÚBLICA ──────────────────────────────────────────────
  async function initAndRender(containerId, initialTab) {
    if (initialTab) _currentTab = initialTab;
    const container = document.getElementById(containerId);
    if (!container) return;
    container.innerHTML = renderShell();
    bindTabs();
    await renderTab(_currentTab);
  }

  return { initAndRender };
})();

/* ============================================================
   ADICIONAR AO FINAL DE: public/style.css
   CSS adicional — impressão em lote de boletos
   ============================================================ */

.fin-lote-toolbar {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .75rem 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  margin-bottom: .5rem;
}

/* ── Filtros avançados de boletos ── */
.bol-filtros-card {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: .75rem;
}
.bol-filtros-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr auto;
  gap: .75rem;
  align-items: end;
}
@media (max-width: 900px) {
  .bol-filtros-grid { grid-template-columns: 1fr 1fr; }
}
.bol-label {
  display: block;
  font-size: .78rem;
  font-weight: 600;
  color: #475569;
  margin-bottom: 3px;
  text-transform: uppercase;
}

/* ── Barra de ações em lote ── */
.bol-acoes-lote {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .6rem 1rem;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  margin-bottom: .5rem;
  flex-wrap: wrap;
}
.bol-sel-count {
  font-size: .85rem;
  font-weight: 700;
  color: #1d4ed8;
}

/* ── Resumo total ── */
.bol-resumo {
  padding: .6rem 1rem;
  background: #f1f5f9;
  border-top: 1px solid #e2e8f0;
  font-size: .82rem;
  color: #475569;
  text-align: right;
}

/* ── Linha clicável ── */
.bol-row { cursor: pointer; }
.bol-row:hover td { background: #eff6ff !important; }

/* ── Geração em Lote ── */
.lote-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-bottom: 1rem;
}
@media (max-width: 800px) { .lote-grid { grid-template-columns: 1fr; } }

.lote-panel {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 1.25rem;
}
.lote-panel-title {
  font-size: .9rem;
  font-weight: 700;
  color: #1e293b;
  margin-bottom: 1rem;
  padding-bottom: .5rem;
  border-bottom: 2px solid #e2e8f0;
}

.lote-resumo-cards {
  display: flex;
  gap: .75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.lote-resumo-card {
  flex: 1;
  min-width: 140px;
  border-radius: 10px;
  padding: .85rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.lote-resumo-num   { font-size: 1.4rem; font-weight: 800; }
.lote-resumo-label { font-size: .75rem; font-weight: 600; text-transform: uppercase; opacity: .8; }
.lote-card-blue    { background: #dbeafe; color: #1e3a8a; }
.lote-card-green   { background: #dcfce7; color: #14532d; }
.lote-card-orange  { background: #fed7aa; color: #7c2d12; }
.lote-card-purple  { background: #ede9fe; color: #4c1d95; }
.lote-card-gray    { background: #f1f5f9; color: #475569; }

.row-ignorado td   { opacity: .45; }

/* ── Autocomplete ── */
.autocomplete-lista {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-top: none;
  border-radius: 0 0 8px 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,.12);
  z-index: 999;
  max-height: 260px;
  overflow-y: auto;
}
.autocomplete-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 9px 12px;
  cursor: pointer;
  font-size: .85rem;
  border-bottom: 1px solid #f1f5f9;
  gap: .5rem;
}
.autocomplete-item:last-child   { border-bottom: none; }
.autocomplete-item:hover,
.autocomplete-item.active       { background: #eff6ff; }
.autocomplete-nome              { font-weight: 500; color: #1e293b; flex: 1; }
.autocomplete-doc               { font-size: .75rem; color: #94a3b8; white-space: nowrap; font-family: monospace; }
.autocomplete-vazio             { padding: 10px 12px; font-size: .83rem; color: #94a3b8; font-style: italic; }

/* ============================================================
   ADICIONAR AO FINAL DE: public/style.css
   CSS adicional — impressão em lote de boletos
   ============================================================ */

.fin-lote-toolbar {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .75rem 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  margin-bottom: .5rem;
}

/* ── Filtros avançados de boletos ── */
.bol-filtros-card {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: .75rem;
}
.bol-filtros-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr auto;
  gap: .75rem;
  align-items: end;
}
@media (max-width: 900px) {
  .bol-filtros-grid { grid-template-columns: 1fr 1fr; }
}
.bol-label {
  display: block;
  font-size: .78rem;
  font-weight: 600;
  color: #475569;
  margin-bottom: 3px;
  text-transform: uppercase;
}

/* ── Barra de ações em lote ── */
.bol-acoes-lote {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .6rem 1rem;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  margin-bottom: .5rem;
  flex-wrap: wrap;
}
.bol-sel-count {
  font-size: .85rem;
  font-weight: 700;
  color: #1d4ed8;
}

/* ── Resumo total ── */
.bol-resumo {
  padding: .6rem 1rem;
  background: #f1f5f9;
  border-top: 1px solid #e2e8f0;
  font-size: .82rem;
  color: #475569;
  text-align: right;
}

/* ── Linha clicável ── */
.bol-row { cursor: pointer; }
.bol-row:hover td { background: #eff6ff !important; }

/* ── Geração em Lote ── */
.lote-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-bottom: 1rem;
}
@media (max-width: 800px) { .lote-grid { grid-template-columns: 1fr; } }

.lote-panel {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 1.25rem;
}
.lote-panel-title {
  font-size: .9rem;
  font-weight: 700;
  color: #1e293b;
  margin-bottom: 1rem;
  padding-bottom: .5rem;
  border-bottom: 2px solid #e2e8f0;
}

.lote-resumo-cards {
  display: flex;
  gap: .75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.lote-resumo-card {
  flex: 1;
  min-width: 140px;
  border-radius: 10px;
  padding: .85rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.lote-resumo-num   { font-size: 1.4rem; font-weight: 800; }
.lote-resumo-label { font-size: .75rem; font-weight: 600; text-transform: uppercase; opacity: .8; }
.lote-card-blue    { background: #dbeafe; color: #1e3a8a; }
.lote-card-green   { background: #dcfce7; color: #14532d; }
.lote-card-orange  { background: #fed7aa; color: #7c2d12; }
.lote-card-purple  { background: #ede9fe; color: #4c1d95; }
.lote-card-gray    { background: #f1f5f9; color: #475569; }

.row-ignorado td   { opacity: .45; }

/* ── Autocomplete ── */
.autocomplete-lista {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-top: none;
  border-radius: 0 0 8px 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,.12);
  z-index: 999;
  max-height: 260px;
  overflow-y: auto;
}
.autocomplete-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 9px 12px;
  cursor: pointer;
  font-size: .85rem;
  border-bottom: 1px solid #f1f5f9;
  gap: .5rem;
}
.autocomplete-item:last-child   { border-bottom: none; }
.autocomplete-item:hover,
.autocomplete-item.active       { background: #eff6ff; }
.autocomplete-nome              { font-weight: 500; color: #1e293b; flex: 1; }
.autocomplete-doc               { font-size: .75rem; color: #94a3b8; white-space: nowrap; font-family: monospace; }
.autocomplete-vazio             { padding: 10px 12px; font-size: .83rem; color: #94a3b8; font-style: italic; }

/* ── Abas de origem do lote ── */
.lote-origem-tabs {
  display: flex;
  gap: 4px;
  background: #e2e8f0;
  padding: 4px;
  border-radius: 8px;
  margin-bottom: 1rem;
  width: fit-content;
}
.lote-origem-tab {
  padding: 8px 20px;
  border: none;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  font-size: .88rem;
  font-weight: 500;
  color: #475569;
  transition: all .15s;
}
.lote-origem-tab:hover  { background: #fff; color: #1e293b; }
.lote-origem-tab.active { background: #fff; color: #0f172a; font-weight: 700; box-shadow: 0 1px 3px rgba(0,0,0,.1); }

/* ============================================================
   ADICIONAR AO FINAL DE: public/style.css
   CSS adicional — impressão em lote de boletos
   ============================================================ */

.fin-lote-toolbar {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .75rem 1rem;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  margin-bottom: .5rem;
}

/* ── Filtros avançados de boletos ── */
.bol-filtros-card {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 1rem;
  margin-bottom: .75rem;
}
.bol-filtros-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr auto;
  gap: .75rem;
  align-items: end;
}
@media (max-width: 900px) {
  .bol-filtros-grid { grid-template-columns: 1fr 1fr; }
}
.bol-label {
  display: block;
  font-size: .78rem;
  font-weight: 600;
  color: #475569;
  margin-bottom: 3px;
  text-transform: uppercase;
}

/* ── Barra de ações em lote ── */
.bol-acoes-lote {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .6rem 1rem;
  background: #eff6ff;
  border: 1px solid #bfdbfe;
  border-radius: 8px;
  margin-bottom: .5rem;
  flex-wrap: wrap;
}
.bol-sel-count {
  font-size: .85rem;
  font-weight: 700;
  color: #1d4ed8;
}

/* ── Resumo total ── */
.bol-resumo {
  padding: .6rem 1rem;
  background: #f1f5f9;
  border-top: 1px solid #e2e8f0;
  font-size: .82rem;
  color: #475569;
  text-align: right;
}

/* ── Linha clicável ── */
.bol-row { cursor: pointer; }
.bol-row:hover td { background: #eff6ff !important; }

/* ── Geração em Lote ── */
.lote-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-bottom: 1rem;
}
@media (max-width: 800px) { .lote-grid { grid-template-columns: 1fr; } }

.lote-panel {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 10px;
  padding: 1.25rem;
}
.lote-panel-title {
  font-size: .9rem;
  font-weight: 700;
  color: #1e293b;
  margin-bottom: 1rem;
  padding-bottom: .5rem;
  border-bottom: 2px solid #e2e8f0;
}

.lote-resumo-cards {
  display: flex;
  gap: .75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.lote-resumo-card {
  flex: 1;
  min-width: 140px;
  border-radius: 10px;
  padding: .85rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.lote-resumo-num   { font-size: 1.4rem; font-weight: 800; }
.lote-resumo-label { font-size: .75rem; font-weight: 600; text-transform: uppercase; opacity: .8; }
.lote-card-blue    { background: #dbeafe; color: #1e3a8a; }
.lote-card-green   { background: #dcfce7; color: #14532d; }
.lote-card-orange  { background: #fed7aa; color: #7c2d12; }
.lote-card-purple  { background: #ede9fe; color: #4c1d95; }
.lote-card-gray    { background: #f1f5f9; color: #475569; }

.row-ignorado td   { opacity: .45; }

/* ── Autocomplete ── */
.autocomplete-lista {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-top: none;
  border-radius: 0 0 8px 8px;
  box-shadow: 0 4px 16px rgba(0,0,0,.12);
  z-index: 999;
  max-height: 260px;
  overflow-y: auto;
}
.autocomplete-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 9px 12px;
  cursor: pointer;
  font-size: .85rem;
  border-bottom: 1px solid #f1f5f9;
  gap: .5rem;
}
.autocomplete-item:last-child   { border-bottom: none; }
.autocomplete-item:hover,
.autocomplete-item.active       { background: #eff6ff; }
.autocomplete-nome              { font-weight: 500; color: #1e293b; flex: 1; }
.autocomplete-doc               { font-size: .75rem; color: #94a3b8; white-space: nowrap; font-family: monospace; }
.autocomplete-vazio             { padding: 10px 12px; font-size: .83rem; color: #94a3b8; font-style: italic; }

/* ── Abas de origem do lote ── */
.lote-origem-tabs {
  display: flex;
  gap: 4px;
  background: #e2e8f0;
  padding: 4px;
  border-radius: 8px;
  margin-bottom: 1rem;
  width: fit-content;
}
.lote-origem-tab {
  padding: 8px 20px;
  border: none;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  font-size: .88rem;
  font-weight: 500;
  color: #475569;
  transition: all .15s;
}
.lote-origem-tab:hover  { background: #fff; color: #1e293b; }
.lote-origem-tab.active { background: #fff; color: #0f172a; font-weight: 700; box-shadow: 0 1px 3px rgba(0,0,0,.1); }

/* ── Agente de E-mail ── */
.agente-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: .75rem;
  margin-bottom: 1rem;
}
.agente-card {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: .85rem 1rem;
}
.agente-card-title {
  font-size: .73rem;
  font-weight: 700;
  text-transform: uppercase;
  color: #94a3b8;
  margin-bottom: 4px;
}
.agente-card-value {
  font-size: .92rem;
  font-weight: 600;
  color: #1e293b;
}

/* =================================================================
   CHAT INTERNO — Redesign WhatsApp/Slack style
   ================================================================= */

/* ── Layout ──────────────────────────────────────────────────────── */
.chat-layout {
  display: flex;
  height: calc(100vh - 96px);
  min-height: 500px;
  overflow: hidden;
  border-radius: 10px;
  border: 1px solid #0f172a;
  box-shadow: 0 4px 24px rgba(0,0,0,.18);
}

/* ── Sidebar ─────────────────────────────────────────────────────── */
.chat-sidebar {
  width: 320px;
  min-width: 260px;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  background: #111b21;
  border-right: 1px solid #0a1017;
  flex-shrink: 0;
}

/* ── Sidebar: Header ─────────────────────────────────────────────── */
.chat-sidebar-top {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid #1f2d37;
  flex-shrink: 0;
}

.chat-my-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: #2a7adb;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  text-transform: uppercase;
}

.chat-sidebar-brand {
  flex: 1;
  font-size: 16px;
  font-weight: 700;
  color: #e9edef;
  letter-spacing: .01em;
}

.chat-sidebar-btns { display: flex; gap: 4px; }

/* ── Search ──────────────────────────────────────────────────────── */
.chat-search-wrap {
  padding: 8px 10px;
  background: #111b21;
  border-bottom: 1px solid #1f2d37;
  flex-shrink: 0;
}

.chat-search-input {
  width: 100%;
  box-sizing: border-box;
  background: #202c33;
  border: none;
  border-radius: 8px;
  color: #e9edef;
  font-size: 13px;
  padding: 8px 12px;
  outline: none;
  transition: background .15s;
}
.chat-search-input::placeholder { color: #8696a0; }
.chat-search-input:focus        { background: #2a3942; }

/* ── Room list ───────────────────────────────────────────────────── */
.chat-rooms-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 0 8px;
}
.chat-rooms-list::-webkit-scrollbar       { width: 4px; }
.chat-rooms-list::-webkit-scrollbar-thumb { background: #2a3942; border-radius: 2px; }

.chat-rooms-empty {
  padding: 24px 16px;
  font-size: 12px;
  color: #8696a0;
  text-align: center;
  line-height: 1.6;
}

.chat-section-header {
  padding: 12px 16px 4px;
  font-size: 10px;
  font-weight: 700;
  color: #8696a0;
  text-transform: uppercase;
  letter-spacing: .1em;
  user-select: none;
}

.chat-room-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  cursor: pointer;
  transition: background .1s;
  min-width: 0;
  border-bottom: 1px solid #1f2d37;
}
.chat-room-item:hover         { background: #202c33; }
.chat-room-item--active       { background: #2a3942; }
.chat-room-item--active:hover { background: #2a3942; }

.chat-room-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.chat-room-row1 {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.chat-room-name {
  flex: 1;
  font-size: 13px;
  font-weight: 600;
  color: #e9edef;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-room-time {
  font-size: 10px;
  color: #8696a0;
  white-space: nowrap;
  flex-shrink: 0;
}
.chat-room-item--active .chat-room-time  { color: #aebac1; }

.chat-room-row2 {
  display: flex;
  align-items: center;
  gap: 6px;
}

.chat-room-preview {
  flex: 1;
  font-size: 11.5px;
  color: #8696a0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-room-item--active .chat-room-preview { color: #aebac1; }

.chat-room-badges {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.chat-pin-icon {
  font-size: 10px;
  color: #8696a0;
  line-height: 1;
}

.chat-unread-badge {
  background: #00a884;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  min-width: 18px;
  height: 18px;
  border-radius: 9px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ── Avatar ──────────────────────────────────────────────────────── */
.chat-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #475569;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
  text-transform: uppercase;
  user-select: none;
}
.chat-avatar--sm        { width: 28px; height: 28px; font-size: 11px; }
.chat-avatar--invisible { visibility: hidden; }
.chat-avatar--online::after {
  content: "";
  position: absolute;
  bottom: 1px; right: 1px;
  width: 10px; height: 10px;
  background: #22c55e;
  border: 2px solid #111b21;
  border-radius: 50%;
}

/* ── Main area ───────────────────────────────────────────────────── */
.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: #efeae2;
}

/* ── Empty state ─────────────────────────────────────────────────── */
.chat-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #94a3b8;
  gap: 8px;
  background: #f0f2f5;
  border-top: 3px solid #e9edef;
}
.chat-empty-icon  { font-size: 64px; opacity: .25; }
.chat-empty-title { font-size: 20px; font-weight: 300; color: #41525d; letter-spacing: -.01em; }
.chat-empty-sub   { font-size: 13px; color: #8696a0; }

/* ── Conversation ────────────────────────────────────────────────── */
.chat-conversation {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* ── Conversation header ─────────────────────────────────────────── */
.chat-conv-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  background: #202c33;
  border-bottom: 1px solid #1f2d37;
  flex-shrink: 0;
}

.chat-conv-title { flex: 1; min-width: 0; }
.chat-conv-name  { font-size: 15px; font-weight: 600; color: #e9edef; }

.chat-conv-sub        { font-size: 11px; color: #8696a0; margin-top: 1px; }
.chat-conv-sub--online { color: #00a884; }

.chat-conv-actions { display: flex; gap: 4px; margin-left: auto; }

/* ── Messages area ───────────────────────────────────────────────── */
.chat-messages-area {
  flex: 1;
  overflow-y: auto;
  padding: 16px 10%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: #efeae2;
}
.chat-messages-area::-webkit-scrollbar       { width: 5px; }
.chat-messages-area::-webkit-scrollbar-thumb { background: #ccc; border-radius: 3px; }

.chat-load-more-wrap { text-align: center; margin-bottom: 12px; }
.chat-load-more-btn  {
  background: rgba(255,255,255,.85);
  border: none;
  border-radius: 12px;
  padding: 6px 18px;
  font-size: 12px;
  color: #41525d;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,.12);
  transition: background .1s;
}
.chat-load-more-btn:hover { background: #fff; }

/* ── Day separator ───────────────────────────────────────────────── */
.chat-day-separator {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 12px 0 8px;
}
.chat-day-separator span {
  background: #d2d0c9;
  color: #54656f;
  font-size: 11px;
  font-weight: 600;
  padding: 4px 12px;
  border-radius: 6px;
  box-shadow: 0 1px 2px rgba(0,0,0,.1);
}

/* ── System message ──────────────────────────────────────────────── */
.chat-system-msg {
  text-align: center;
  font-size: 11px;
  color: #54656f;
  font-style: italic;
  background: rgba(210,208,201,.6);
  border-radius: 6px;
  padding: 4px 12px;
  margin: 2px auto;
  max-width: 60%;
}

/* ── Message row ─────────────────────────────────────────────────── */
.chat-msg {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  max-width: 100%;
  margin-bottom: 1px;
}
.chat-msg--mine   { flex-direction: row-reverse; }
.chat-msg--grouped { margin-bottom: 0; }

.chat-msg-col {
  display: flex;
  flex-direction: column;
  max-width: 68%;
  min-width: 0;
}
.chat-msg--mine .chat-msg-col { align-items: flex-end; }

.chat-msg-author {
  font-size: 11px;
  font-weight: 700;
  color: #2a7adb;
  margin-bottom: 2px;
  padding: 0 2px;
}

/* ── Bubble ──────────────────────────────────────────────────────── */
.chat-bubble {
  background: #fff;
  color: #111b21;
  font-size: 13.5px;
  line-height: 1.5;
  padding: 7px 10px 6px;
  border-radius: 0 8px 8px 8px;
  word-break: break-word;
  overflow-wrap: anywhere;
  box-shadow: 0 1px 2px rgba(0,0,0,.12);
  position: relative;
}
.chat-msg--theirs:not(.chat-msg--grouped) .chat-bubble {
  border-radius: 0 8px 8px 8px;
}
.chat-msg--theirs.chat-msg--grouped .chat-bubble {
  border-radius: 8px 8px 8px 8px;
}
.chat-msg--mine .chat-bubble {
  background: #d9fdd3;
  color: #111b21;
  border-radius: 8px 0 8px 8px;
}
.chat-msg--mine.chat-msg--grouped .chat-bubble {
  border-radius: 8px 8px 8px 8px;
}

.chat-bubble-content { margin-bottom: 4px; }
.chat-bubble-footer  {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  margin-top: 2px;
}
.chat-bubble-time { font-size: 10px; color: #8696a0; white-space: nowrap; }

.chat-ticks          { font-size: 12px; color: #8696a0; letter-spacing: -2px; }
.chat-ticks--read    { color: #53bdeb; }

/* ── Reply reference in bubble ───────────────────────────────────── */
.chat-reply-ref {
  background: rgba(0,0,0,.05);
  border-left: 3px solid #53bdeb;
  border-radius: 4px;
  padding: 4px 8px;
  font-size: 11px;
  margin-bottom: 5px;
  cursor: pointer;
  overflow: hidden;
}
.chat-msg--mine .chat-reply-ref { border-left-color: #00a884; }
.chat-reply-ref-author { font-weight: 700; font-size: 11px; color: #2a7adb; margin-bottom: 1px; }
.chat-reply-ref-text   {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 280px;
  color: #54656f;
}

/* ── Message actions (hover) ─────────────────────────────────────── */
.chat-msg-actions {
  display: none;
  gap: 4px;
  align-items: center;
  margin-top: 2px;
}
.chat-msg:hover .chat-msg-actions { display: flex; }
.chat-msg--mine .chat-msg-actions { justify-content: flex-end; }

.chat-action-btn {
  background: rgba(255,255,255,.9);
  border: 1px solid #e2e8f0;
  border-radius: 5px;
  padding: 2px 7px;
  font-size: 11px;
  cursor: pointer;
  color: #54656f;
  transition: background .1s;
}
.chat-action-btn:hover     { background: #f1f5f9; }
.chat-action-del:hover     { background: #fee2e2; color: #dc2626; border-color: #fca5a5; }

/* ── ERP Card ────────────────────────────────────────────────────── */
.chat-erp-card {
  background: #f0f9ff;
  border: 1px solid #bae6fd;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 12px;
  cursor: pointer;
  transition: background .1s;
  min-width: 200px;
  max-width: 300px;
}
.chat-erp-card:hover { background: #e0f2fe; }
.chat-msg--mine .chat-erp-card {
  background: rgba(0,168,132,.1);
  border-color: rgba(0,168,132,.3);
}
.chat-erp-badge { font-size: 10px; font-weight: 700; color: #0369a1; margin-bottom: 4px; display: block; }
.chat-msg--mine .chat-erp-badge { color: #00a884; }
.chat-erp-card-top  { margin-bottom: 3px; }
.chat-erp-card-code { font-family: monospace; font-weight: 700; font-size: 12px; color: #1d4ed8; }
.chat-msg--mine .chat-erp-card-code { color: #00695c; }
.chat-erp-card-desc { font-weight: 600; color: #1e293b; line-height: 1.3; margin: 2px 0; }
.chat-erp-card-info { font-size: 11px; color: #64748b; display: flex; gap: 10px; flex-wrap: wrap; }

/* ── Mention highlight ───────────────────────────────────────────── */
.chat-mention {
  background: #dbeafe;
  color: #1d4ed8;
  font-weight: 700;
  border-radius: 3px;
  padding: 0 2px;
}

/* ── Typing indicator ────────────────────────────────────────────── */
.chat-typing-row { min-height: 22px; padding: 2px 12px; }
.chat-typing-indicator {
  display: flex;
  align-items: center;
  gap: 6px;
}
.chat-typing-text { font-size: 11.5px; color: #8696a0; font-style: italic; }
.chat-typing-dots {
  display: flex;
  gap: 3px;
  align-items: center;
}
.chat-typing-dot {
  width: 5px;
  height: 5px;
  background: #8696a0;
  border-radius: 50%;
  animation: chatTypingPulse 1.2s ease-in-out infinite;
}
.chat-typing-dot:nth-child(2) { animation-delay: .2s; }
.chat-typing-dot:nth-child(3) { animation-delay: .4s; }
@keyframes chatTypingPulse {
  0%, 60%, 100% { opacity: .3; transform: scale(1); }
  30%           { opacity: 1;  transform: scale(1.3); }
}

/* ── Input area ──────────────────────────────────────────────────── */
.chat-input-wrapper {
  background: #202c33;
  border-top: 1px solid #1f2d37;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 0;
  flex-shrink: 0;
}

.chat-input-row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}

.chat-textarea-wrap {
  flex: 1;
  position: relative;
}

.chat-textarea {
  width: 100%;
  box-sizing: border-box;
  resize: none;
  border: none;
  border-radius: 8px;
  padding: 9px 12px;
  font-size: 14px;
  font-family: inherit;
  color: #e9edef;
  background: #2a3942;
  outline: none;
  min-height: 38px;
  max-height: 120px;
  line-height: 1.45;
  overflow-y: auto;
  transition: background .15s;
}
.chat-textarea:focus        { background: #2a3942; }
.chat-textarea::placeholder { color: #8696a0; }

/* ── Emoji picker ────────────────────────────────────────────────── */
.chat-emoji-picker {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 0;
  background: #202c33;
  border: 1px solid #2a3942;
  border-radius: 10px;
  padding: 10px;
  grid-template-columns: repeat(10, 1fr);
  gap: 4px;
  z-index: 200;
  box-shadow: 0 8px 24px rgba(0,0,0,.3);
  width: 320px;
}
.chat-emoji-item {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 20px;
  padding: 4px;
  border-radius: 6px;
  transition: background .1s, transform .1s;
  line-height: 1;
}
.chat-emoji-item:hover {
  background: #2a3942;
  transform: scale(1.2);
}

/* ── Reply preview (input area) ──────────────────────────────────── */
.chat-reply-preview {
  background: #202c33;
  padding: 0 0 8px;
}
.chat-reply-bar {
  display: flex;
  align-items: stretch;
  gap: 0;
  background: #2a3942;
  border-radius: 8px;
  overflow: hidden;
}
.chat-reply-bar-accent {
  width: 4px;
  background: #00a884;
  flex-shrink: 0;
}
.chat-reply-bar-body {
  flex: 1;
  padding: 6px 10px;
  min-width: 0;
}
.chat-reply-bar-author {
  font-size: 11px;
  font-weight: 700;
  color: #00a884;
  margin-bottom: 1px;
}
.chat-reply-bar-text {
  font-size: 12px;
  color: #aebac1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-reply-bar-close {
  background: none;
  border: none;
  cursor: pointer;
  color: #8696a0;
  font-size: 16px;
  padding: 0 10px;
  transition: color .1s;
}
.chat-reply-bar-close:hover { color: #e9edef; }

/* ── Send button ─────────────────────────────────────────────────── */
.chat-send-btn {
  background: #00a884;
  color: #fff;
  border: none;
  border-radius: 50%;
  width: 42px;
  height: 42px;
  cursor: pointer;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background .12s, transform .1s;
}
.chat-send-btn:hover    { background: #06cf9c; transform: scale(1.05); }
.chat-send-btn:disabled { background: #2a3942; color: #8696a0; cursor: default; transform: none; }

/* ── Icon button (generic) ───────────────────────────────────────── */
.chat-icon-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #aebac1;
  font-size: 20px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background .1s, color .1s;
}
.chat-icon-btn:hover { background: rgba(255,255,255,.08); color: #e9edef; }

/* ── ERP search result row ───────────────────────────────────────── */
.chat-erp-result-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 12px;
  cursor: pointer;
  border-bottom: 1px solid #f1f5f9;
  transition: background .1s;
  font-size: 12px;
}
.chat-erp-result-row:last-child { border-bottom: none; }
.chat-erp-result-row:hover      { background: #eff6ff; }

/* ── User row (DM modal) ─────────────────────────────────────────── */
.chat-user-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 6px;
  border-bottom: 1px solid #f1f5f9;
  cursor: pointer;
  border-radius: 6px;
  transition: background .1s;
}
.chat-user-row:last-child { border-bottom: none; }
.chat-user-row:hover      { background: #f8fafc; }

/* ── Nav badge (menu) ────────────────────────────────────────────── */
.chat-nav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #ef4444;
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  min-width: 16px;
  height: 16px;
  border-radius: 8px;
  padding: 0 4px;
  margin-left: 6px;
  vertical-align: middle;
}

/* ── Toast notifications ─────────────────────────────────────────── */
.chat-toasts {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}

.chat-toast {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: #202c33;
  border: 1px solid #2a3942;
  border-radius: 12px;
  padding: 12px 14px;
  box-shadow: 0 8px 24px rgba(0,0,0,.3);
  pointer-events: all;
  cursor: pointer;
  min-width: 280px;
  max-width: 360px;
  opacity: 0;
  transform: translateX(100%);
  transition: opacity .25s, transform .25s;
}
.chat-toast--visible {
  opacity: 1;
  transform: translateX(0);
}
.chat-toast:hover { background: #2a3942; }

.chat-toast-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: #2a7adb;
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  text-transform: uppercase;
}

.chat-toast-body  { flex: 1; min-width: 0; }
.chat-toast-name  { font-size: 13px; font-weight: 700; color: #e9edef; margin-bottom: 1px; }
.chat-toast-group { font-size: 11px; color: #8696a0; margin-bottom: 1px; }
.chat-toast-preview {
  font-size: 12px;
  color: #aebac1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-toast-close {
  background: none;
  border: none;
  cursor: pointer;
  color: #8696a0;
  font-size: 16px;
  padding: 0;
  flex-shrink: 0;
  line-height: 1;
  margin-top: 1px;
}
.chat-toast-close:hover { color: #e9edef; }

/* ── Responsive ──────────────────────────────────────────────────── */
@media (max-width: 768px) {
  .chat-sidebar  { width: 220px; min-width: 180px; }
  .chat-messages-area { padding: 12px 4%; }
  .chat-emoji-picker  { width: 260px; grid-template-columns: repeat(8, 1fr); }
}
@media (max-width: 520px) {
  .chat-sidebar  { width: 0; overflow: hidden; }
  .chat-layout   { flex-direction: column; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   CHAT — Session 7: Tabs, Tasks, Notifications, WhatsApp, ERP Drawer
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── Tab strip ───────────────────────────────────────────────────────────────── */
.chat-tabs {
  display: flex;
  align-items: center;
  background: #111b21;
  border-bottom: 1px solid #2a3942;
  padding: 0 4px;
  flex-shrink: 0;
}
.chat-tab {
  flex: 1;
  position: relative;
  background: none;
  border: none;
  color: #8696a0;
  font-size: 11px;
  font-weight: 600;
  padding: 9px 2px 7px;
  cursor: pointer;
  text-transform: uppercase;
  letter-spacing: .4px;
  transition: color .15s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.chat-tab:hover  { color: #e9edef; }
.chat-tab--active {
  color: #00a884;
  border-bottom: 2px solid #00a884;
}
.chat-tab-badge {
  background: #ef4444;
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  border-radius: 8px;
  padding: 0 4px;
  min-width: 14px;
  line-height: 14px;
  text-align: center;
  display: none;
}
.chat-tab-badge:not(:empty) { display: inline-block; }

/* ── Sidebar body ─────────────────────────────────────────────────────────────── */
.chat-sidebar-body {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* ══ TASK PANEL ══════════════════════════════════════════════════════════════════ */
.chat-task-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}
.chat-task-filters {
  display: flex;
  gap: 4px;
  padding: 8px;
  flex-shrink: 0;
  flex-wrap: wrap;
}
.chat-filter-btn {
  background: #2a3942;
  border: 1px solid #374c59;
  color: #8696a0;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 12px;
  cursor: pointer;
  transition: background .15s, color .15s;
  white-space: nowrap;
}
.chat-filter-btn:hover { background: #3a4f5c; color: #e9edef; }
.chat-filter-btn--active {
  background: #00a884;
  border-color: #00a884;
  color: #fff;
}
.chat-task-list {
  flex: 1;
  overflow-y: auto;
  padding: 0 0 8px;
}
.chat-task-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid #1e2b33;
  cursor: pointer;
  transition: background .12s;
}
.chat-task-item:hover { background: #1e2b33; }
.chat-task-item--overdue { border-left: 3px solid #ef4444; }
.chat-task-item-prio {
  width: 3px;
  border-radius: 2px;
  align-self: stretch;
  flex-shrink: 0;
}
.chat-task-item-body { flex: 1; min-width: 0; }
.chat-task-item-aviso {
  font-size: 11px;
  color: #a78550;
  margin-top: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.chat-task-aviso-btn {
  flex-shrink: 0;
  align-self: center;
  background: #2a3942;
  border: 1px solid #3b4a52;
  color: #8caa96;
  border-radius: 4px;
  width: 22px;
  height: 22px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .12s, color .12s;
}
.chat-task-aviso-btn:hover { background: #00a884; color: #fff; border-color: #00a884; }
.chat-task-item-title {
  font-size: 13px;
  font-weight: 600;
  color: #e9edef;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 3px;
}
.chat-task-item-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.chat-task-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
.chat-task-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  flex-shrink: 0;
  border-top: 1px solid #2a3942;
}
.chat-task-new-btn {
  width: 100%;
  background: #00a884;
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 8px;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s;
}
.chat-task-new-btn:hover { background: #017a61; }

/* ── Priority badges ─────────────────────────────────────────────────────────── */
.chat-priority-badge {
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 8px;
  text-transform: uppercase;
  letter-spacing: .4px;
  white-space: nowrap;
}
.chat-priority-baixa   { background: #064e3b; color: #6ee7b7; }
.chat-priority-normal  { background: #1e3a5f; color: #7dd3fc; }
.chat-priority-alta    { background: #78350f; color: #fcd34d; }
.chat-priority-urgente { background: #7f1d1d; color: #fca5a5; }

/* ── Status badges ───────────────────────────────────────────────────────────── */
.chat-status-badge {
  font-size: 10px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 8px;
  white-space: nowrap;
}
.chat-status-pendente   { background: #374151; color: #9ca3af; }
.chat-status-andamento  { background: #1e3a5f; color: #7dd3fc; }
.chat-status-aguardando { background: #4c1d95; color: #c4b5fd; }
.chat-status-concluida  { background: #064e3b; color: #6ee7b7; }
.chat-status-cancelada  { background: #450a0a; color: #fca5a5; }

/* ══ NOTIFICATION PANEL ═══════════════════════════════════════════════════════ */
.chat-notif-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
}
.chat-notif-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px 6px;
  flex-shrink: 0;
}
.chat-notif-header span {
  font-size: 12px;
  font-weight: 700;
  color: #8696a0;
  text-transform: uppercase;
  letter-spacing: .5px;
}
.chat-notif-read-all {
  background: none;
  border: none;
  color: #00a884;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 0;
}
.chat-notif-read-all:hover { text-decoration: underline; }
.chat-notif-list { flex: 1; overflow-y: auto; }
.chat-notif-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid #1e2b33;
  cursor: pointer;
  transition: background .12s;
  position: relative;
}
.chat-notif-item:hover { background: #1e2b33; }
.chat-notif-item--unread { background: #182229; }
.chat-notif-icon {
  font-size: 20px;
  flex-shrink: 0;
  margin-top: 1px;
}
.chat-notif-body { flex: 1; min-width: 0; }
.chat-notif-title {
  font-size: 13px;
  font-weight: 600;
  color: #e9edef;
  margin-bottom: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-notif-sub {
  font-size: 11px;
  color: #8696a0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-notif-time {
  font-size: 10px;
  color: #667781;
  white-space: nowrap;
  margin-top: 2px;
}
.chat-notif-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #00a884;
  flex-shrink: 0;
  margin-top: 5px;
}

/* ══ WHATSAPP CONFIG PANEL ════════════════════════════════════════════════════ */
.chat-wa-panel {
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow-y: auto;
  padding: 12px;
}
.chat-wa-title {
  font-size: 13px;
  font-weight: 700;
  color: #00a884;
  margin-bottom: 12px;
  text-transform: uppercase;
  letter-spacing: .5px;
}
.chat-wa-fields {
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: 1;
}
.chat-wa-fields label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  color: #8696a0;
  text-transform: uppercase;
  letter-spacing: .5px;
  margin-bottom: 3px;
}
.chat-wa-input {
  width: 100%;
  background: #2a3942;
  border: 1px solid #374c59;
  border-radius: 6px;
  color: #e9edef;
  font-size: 12px;
  padding: 7px 10px;
  outline: none;
  box-sizing: border-box;
  transition: border-color .15s;
}
.chat-wa-input:focus { border-color: #00a884; }
.chat-wa-input option { background: #1e2b33; }

/* ── Safeguard CSS para campos técnicos sensíveis ─────────────────────────────
   Garante que NENHUMA regra CSS aplique text-transform a estes campos.
   Use a classe "no-uppercase" em qualquer input técnico (URL, token, senha,
   API key, webhook, instance) para proteção em três camadas:
     1. CSS   → text-transform: none  (este bloco)
     2. HTML  → data-no-uppercase="true" + autocapitalize="off"
     3. JS    → shouldIgnoreUppercase() em utils.js
   ──────────────────────────────────────────────────────────────────────────── */
input.no-uppercase,
textarea.no-uppercase {
  text-transform: none !important;
}
.chat-wa-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.chat-wa-check-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #aebac1;
  cursor: pointer;
}
.chat-wa-actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
  flex-shrink: 0;
}
.chat-wa-actions button {
  flex: 1;
  padding: 8px;
  border-radius: 8px;
  border: none;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background .15s;
}
.chat-wa-actions button:first-child {
  background: #00a884;
  color: #fff;
}
.chat-wa-actions button:first-child:hover { background: #017a61; }
.chat-wa-actions button:last-child {
  background: #2a3942;
  color: #8696a0;
}
.chat-wa-actions button:last-child:hover { background: #374c59; }
.chat-wa-eye {
  background: #374c59;
  border: 1px solid #4a6070;
  border-radius: 6px;
  color: #aebac1;
  cursor: pointer;
  font-size: 14px;
  padding: 6px 9px;
  flex-shrink: 0;
  transition: background .15s;
}
.chat-wa-eye:hover { background: #4a6070; color: #e9edef; }
.chat-wa-info {
  margin-top: 14px;
  background: #1a2a35;
  border: 1px solid #2a3942;
  border-radius: 8px;
  padding: 10px 12px;
}
.chat-wa-info-title {
  font-size: 11px;
  font-weight: 700;
  color: #8696a0;
  text-transform: uppercase;
  letter-spacing: .4px;
  margin-bottom: 6px;
}
.chat-wa-info-body {
  font-size: 11px;
  color: #667781;
  line-height: 1.6;
}

/* ══ WHATSAPP QR / CONNECTION PANEL ══════════════════════════════════════════ */

/* Seção de conexão — topo do painel */
.wa-connect-section {
  background: #1a2a35;
  border: 1px solid #2a3942;
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 14px;
}
.wa-config-section {
  /* usa o estilo existente do chat-wa-fields */
}

.wa-section-title {
  font-size: 11px;
  font-weight: 700;
  color: #8696a0;
  text-transform: uppercase;
  letter-spacing: .5px;
  margin-bottom: 10px;
}

/* ── Barra de status ─────────────────────────────────────────────────────────── */
.wa-status-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  background: #111b21;
  border: 1px solid #2a3942;
  border-radius: 8px;
  padding: 8px 12px;
  margin-bottom: 12px;
}
.wa-status-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  background: #667781;
  transition: background .3s;
}
.wa-status-dot.connected    { background: #00a884; box-shadow: 0 0 6px #00a88466; }
.wa-status-dot.connecting   { background: #f59e0b; animation: wa-blink 1.2s ease-in-out infinite; }
.wa-status-dot.disconnected { background: #667781; }
.wa-status-dot.error        { background: #ef4444; }
.wa-status-dot.not_configured { background: #4a6070; }

@keyframes wa-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: .3; }
}

.wa-status-text {
  font-size: 12px;
  color: #e9edef;
  flex: 1;
}
.wa-status-text small {
  display: block;
  font-size: 10px;
  color: #8696a0;
  margin-top: 1px;
}

/* ── Botões da seção de conexão ──────────────────────────────────────────────── */
.wa-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: none;
  border-radius: 8px;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  padding: 8px 14px;
  transition: background .15s, opacity .15s;
}
.wa-btn:disabled { opacity: .5; cursor: not-allowed; }

.wa-btn-primary   { background: #00a884; color: #fff; }
.wa-btn-primary:hover:not(:disabled)   { background: #017a61; }

.wa-btn-secondary { background: #2a3942; color: #aebac1; }
.wa-btn-secondary:hover:not(:disabled) { background: #374c59; }

.wa-btn-danger    { background: #3d1f1f; color: #ef4444; border: 1px solid #5a2020; }
.wa-btn-danger:hover:not(:disabled)    { background: #4a2020; }

.wa-btn-lg { width: 100%; padding: 11px; font-size: 13px; }

.wa-connect-btn-wrap { margin-top: 2px; }

/* ── Painel do QR Code ───────────────────────────────────────────────────────── */
.wa-qr-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 4px 0 8px;
}

.wa-qr-wrapper {
  position: relative;
  width: 220px;
  height: 220px;
  background: #fff;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 32px rgba(0,0,0,.5);
}

.wa-qr-img {
  display: block;
  width: 200px;
  height: 200px;
  border-radius: 6px;
  image-rendering: pixelated;
}

.wa-qr-loading {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: rgba(255,255,255,.95);
  border-radius: 16px;
  font-size: 11px;
  color: #374c59;
  font-weight: 600;
}

.wa-qr-spinner {
  width: 28px;
  height: 28px;
  border: 3px solid #e0e0e0;
  border-top-color: #00a884;
  border-radius: 50%;
  animation: wa-spin .8s linear infinite;
}
@keyframes wa-spin { to { transform: rotate(360deg); } }

.wa-qr-timer {
  font-size: 11px;
  color: #8696a0;
  text-align: center;
}
.wa-qr-timer .wa-countdown {
  font-weight: 700;
  color: #f59e0b;
}
.wa-qr-timer.expired .wa-countdown { color: #ef4444; }

.wa-qr-steps {
  font-size: 10px;
  color: #667781;
  line-height: 1.8;
  text-align: left;
  width: 100%;
  padding: 8px 10px;
  background: #111b21;
  border-radius: 8px;
  border: 1px solid #2a3942;
}
.wa-qr-steps b { color: #8696a0; display: block; margin-bottom: 2px; }

.wa-qr-actions {
  display: flex;
  gap: 8px;
  width: 100%;
}
.wa-qr-actions .wa-btn { flex: 1; }

/* ── Painel de conectado ─────────────────────────────────────────────────────── */
.wa-connected-panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 8px 0;
}
.wa-connected-icon  { font-size: 36px; line-height: 1; }
.wa-connected-label { font-size: 14px; font-weight: 700; color: #00a884; }
.wa-connected-phone {
  font-size: 11px;
  color: #8696a0;
  margin-bottom: 6px;
}

/* ── ERP DRAWER ══════════════════════════════════════════════════════════════ */
.chat-erp-drawer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 320px;
  background: #111b21;
  border-left: 1px solid #2a3942;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .25s cubic-bezier(.4,0,.2,1);
  z-index: 50;
  box-shadow: -4px 0 16px rgba(0,0,0,.4);
}
.chat-erp-drawer.open { transform: translateX(0); }
.chat-erp-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid #2a3942;
  flex-shrink: 0;
}
.chat-erp-drawer-header span {
  font-size: 13px;
  font-weight: 700;
  color: #e9edef;
}
.chat-erp-drawer-header button {
  background: none;
  border: none;
  color: #8696a0;
  font-size: 18px;
  cursor: pointer;
  padding: 0;
  line-height: 1;
}
.chat-erp-drawer-header button:hover { color: #e9edef; }
.chat-erp-drawer-search {
  padding: 10px 12px;
  flex-shrink: 0;
  border-bottom: 1px solid #1e2b33;
}
.chat-erp-drawer-search input {
  width: 100%;
  background: #2a3942;
  border: 1px solid #374c59;
  border-radius: 8px;
  color: #e9edef;
  font-size: 13px;
  padding: 8px 12px;
  outline: none;
  box-sizing: border-box;
}
.chat-erp-drawer-search input:focus { border-color: #00a884; }
.chat-erp-drawer-tip {
  padding: 10px 14px;
  font-size: 11px;
  color: #667781;
  text-align: center;
}
.chat-erp-drawer-results {
  flex: 1;
  overflow-y: auto;
  padding: 0 0 8px;
}
.chat-erp-drawer-empty {
  text-align: center;
  padding: 24px 14px;
  font-size: 12px;
  color: #667781;
}
.chat-erp-drawer-item {
  display: flex;
  flex-direction: column;
  padding: 9px 14px;
  border-bottom: 1px solid #1e2b33;
  cursor: grab;
  transition: background .12s;
  user-select: none;
}
.chat-erp-drawer-item:hover { background: #1e2b33; }
.chat-erp-drawer-item--dragging {
  opacity: .5;
  background: #2a3942;
  cursor: grabbing;
}
.chat-erp-drawer-item-code {
  font-size: 10px;
  font-weight: 700;
  color: #00a884;
  letter-spacing: .5px;
  text-transform: uppercase;
  margin-bottom: 2px;
}
.chat-erp-drawer-item-desc {
  font-size: 12px;
  color: #e9edef;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chat-erp-drawer-item-meta {
  font-size: 11px;
  color: #667781;
  margin-top: 2px;
}

/* ── Drop overlay ───────────────────────────────────────────────────────────── */
.chat-drop-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 168, 132, .12);
  border: 3px dashed #00a884;
  border-radius: 12px;
  pointer-events: none;
  opacity: 0;
  transition: opacity .15s;
  z-index: 10;
}
.chat-drop-overlay--active { opacity: 1; }
.chat-drop-label {
  background: #00a884;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  padding: 12px 24px;
  border-radius: 10px;
  box-shadow: 0 4px 16px rgba(0,0,0,.4);
}

/* ── Task cards in messages ─────────────────────────────────────────────────── */
.chat-task-card {
  background: #1e2b33;
  border: 1px solid #2a3942;
  border-left: 3px solid #00a884;
  border-radius: 10px;
  padding: 10px 12px;
  cursor: pointer;
  transition: background .15s;
  min-width: 200px;
  max-width: 280px;
}
.chat-task-card:hover { background: #253540; }
.chat-task-card-top {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}
.chat-task-card-badge {
  font-size: 10px;
  font-weight: 700;
  color: #00a884;
  text-transform: uppercase;
  letter-spacing: .4px;
}
.chat-task-card-title {
  font-size: 13px;
  font-weight: 700;
  color: #e9edef;
  margin-bottom: 6px;
  line-height: 1.4;
}
.chat-task-card-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 11px;
  color: #8696a0;
}

/* ── Task button in input row ───────────────────────────────────────────────── */
.chat-task-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #8696a0;
  font-size: 18px;
  padding: 6px;
  border-radius: 50%;
  line-height: 1;
  transition: background .15s, color .15s;
  flex-shrink: 0;
}
.chat-task-btn:hover {
  background: #2a3942;
  color: #00a884;
}

/* ── ERP button in input row ────────────────────────────────────────────────── */
.chat-erp-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: #8696a0;
  font-size: 16px;
  padding: 6px;
  border-radius: 50%;
  line-height: 1;
  transition: background .15s, color .15s;
  flex-shrink: 0;
}
.chat-erp-btn:hover {
  background: #2a3942;
  color: #00a884;
}

/* ── Responsive (Session 7 additions) ──────────────────────────────────────── */
@media (max-width: 768px) {
  .chat-erp-drawer { width: 100%; border-left: none; }
  .chat-task-card  { max-width: 220px; }
}
