:root,
[data-theme="light"] {
  --bg-canvas: #E3E7EF;
  --bg-surface: #FFFFFF;
  --bg-surface-elevated: #DBDFE8;
  --text-primary: #161A2B;
  --text-secondary: #5B6072;
  --text-inverse: #FFFFFF;
  --border-default: #D2D6E2;
  /* Tom "premium" pedido pela Lorena, com base numa referência visual --
     indigo-navy mais profundo/saturado que o azul-marinho meio acinzentado
     de antes (era #28345C). Continua escuro o bastante pra texto branco em
     cima (botões) e pra --sidebar-accent/--brand-gold não perderem contraste. */
  --brand-navy: #17244A;
  --brand-navy-hover: #0F1836;
  /* Degradê clareado (pedido da Lorena, "o leve"): mantém o azul-marinho
     da marca (#17244A) no topo e escurece só um pouco até a base, em vez
     do quase-preto de antes (era #0A1122 -> #0F1730). */
  --sidebar-bg: #101B36;
  --sidebar-bg-top: #17244A;
  --sidebar-text: #FFFFFF;
  /* Acento fixo (não varia por tema) pro cromo do admin — a sidebar é
     sempre escura mesmo no tema claro, então usar --brand-navy (que troca
     de valor por tema) pro "ativo" ali ficaria ilegível no tema claro,
     onde --brand-navy vira um azul-marinho escuro demais pra ler em cima
     de um fundo já escuro. */
  --sidebar-accent: #7C93F0;
  --brand-gold: #9C7A12;
  --brand-gold-soft: #C9A227;
  --semantic-success: #1E7A4C;
  --semantic-warning: #B45309;
  --semantic-warning-bg: #FCEFE0;
  --semantic-danger: #B3261E;
  --action-primary: var(--brand-navy);
  --action-primary-hover: var(--brand-navy-hover);
  --border-hover: #C7CBD9;

  /* Rampa de elevação: cards em repouso usam --shadow-xs (sombra bem sutil,
     só pra separar do fundo) + hairline border; elevação de verdade (dropdown,
     modal, hover de algo clicável) usa --shadow-sm/md pra cima. */
  --shadow-xs: 0 1px 2px rgba(22, 26, 43, 0.04);
  --shadow-sm: 0 1px 3px rgba(22, 26, 43, 0.06), 0 1px 2px rgba(22, 26, 43, 0.04);
  --shadow-md: 0 8px 24px rgba(22, 26, 43, 0.10), 0 2px 6px rgba(22, 26, 43, 0.05);
  --shadow-lg: 0 16px 40px rgba(22, 26, 43, 0.14), 0 4px 12px rgba(22, 26, 43, 0.06);

  /* 3 radii + círculo — nunca um 4º valor solto (chega de 9/10/12/16/18px espalhados).
     --radius-md subiu de 12 pra 14px (pedido: aproximar a cara dos cards da
     referência de um dashboard fintech mais arredondado, sem reinventar o
     sistema — um token só, propaga pra todo card que já usa --radius-md). */
  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 18px;

  /* ---------- Escala tipográfica (8 passos) ----------
     Regra: nenhum font-size no resto do arquivo deve ser um valor fora
     desta lista (nada de 9.5px/11.5px/12.5px soltos). */
  --text-2xs: 11px;
  --text-xs: 12px;
  --text-sm: 13px;
  --text-base: 14px;
  --text-md: 16px;
  --text-lg: 20px;
  --text-xl: 26px;
  --text-2xl: 34px;

  --font-regular: 400;
  --font-medium: 500;
  --font-semibold: 600;
  --font-bold: 700;
  --font-black: 800;

  --leading-tight: 1.15;
  --leading-snug: 1.35;
  --leading-normal: 1.5;

  --tracking-tight: -0.02em;
  --tracking-normal: 0;
  --tracking-wide: 0.06em;

  /* ---------- Escala de espaçamento ----------
     Regra: no máximo 2 paddings de card no sistema (space-6 pra card
     "principal", space-4 pra card "denso/aninhado") — nunca um 3º valor. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;
}

[data-theme="dark"] {
  --bg-canvas: #0E1118;
  --bg-surface: #171B27;
  --bg-surface-elevated: #1F2433;
  --text-primary: #EDEFF5;
  --text-secondary: #9BA1B6;
  --text-inverse: #0E1118;
  --border-default: #2A2F40;
  /* Mesmo tom "premium" pedido pela Lorena, versão clara o bastante pra
     ler em cima do fundo escuro (era #5B72D6). */
  --brand-navy: #6672DD;
  --brand-navy-hover: #7C89EA;
  --brand-gold: #D4AF37;
  --brand-gold-soft: #E8C766;
  --semantic-success: #3FB87F;
  /* Antes quase idêntico ao brand-gold (#D4AF37) — os dois lados a lados
     liam como "tudo amarelo". Puxado mais pro laranja pra ficar claramente
     um alerta, não a cor da marca. */
  --semantic-warning: #E2984A;
  --semantic-warning-bg: #2E2012;
  --semantic-danger: #F2545B;
  --action-primary: var(--brand-gold);
  --action-primary-hover: var(--brand-gold-soft);
  --border-hover: #3A4058;
  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.25);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.4), 0 2px 6px rgba(0, 0, 0, 0.25);
  --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  /* Fundo levemente variado (não chapado) — bem sutil de propósito, só
     pra dar profundidade sem competir com o conteúdo. */
  background:
    radial-gradient(ellipse at 15% -10%, color-mix(in srgb, var(--brand-navy) 7%, transparent), transparent 55%),
    var(--bg-canvas);
  background-attachment: fixed;
  color: var(--text-primary);
  font-family: 'Inter', -apple-system, sans-serif;
  transition: background 0.2s ease, color 0.2s ease;
}

a { text-decoration: none; color: inherit; }

.app-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* ---------- Navegação (páginas novas do cliente): sidebar fixa no
   desktop/tablet, vira barra inferior fixa no mobile — ver renderNav() em
   app.js. .app-body é o wrapper novo abaixo da topbar contendo [sidebar][main]. ---------- */
.app-body { display: flex; flex: 1; min-height: 0; }

.nav-sidebar {
  width: 220px;
  flex-shrink: 0;
  padding: var(--space-6) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  border-right: 1px solid var(--border-default);
}
.nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--text-base);
  font-weight: var(--font-medium);
}
.nav-item:hover { background: var(--bg-surface-elevated); color: var(--text-primary); }
.nav-item.active { background: var(--bg-surface-elevated); color: var(--brand-navy); font-weight: var(--font-semibold); }
.nav-item-icon { display: flex; flex-shrink: 0; }
.nav-item-icon .icon { width: 18px; height: 18px; }

.nav-bottom { display: none; }
.nav-bottom-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: var(--space-2) 0;
  color: var(--text-secondary);
  font-size: var(--text-2xs);
}
.nav-bottom-item.active { color: var(--brand-navy); }
.nav-bottom-icon .icon { width: 20px; height: 20px; }

/* ---------- Topbar ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 32px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-default);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
}

.brand-mark {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.brand-mark img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Logo é PNG com fundo transparente de verdade — o "T" é navy sólido, que
   fica invisível sobre fundo escuro (sidebar, tema escuro, cabeçalho navy
   do PDF). logo-glyph-dark.png é a mesma logo com só o T recolorido pra
   branco (o dourado do gráfico continua dourado); troca automática por
   tema, sem precisar mexer em nenhum HTML que já usa logo-glyph.png. */
[data-theme="dark"] img[src$="logo-glyph.png"] {
  content: url("../img/logo-glyph-dark.png");
}
/* A sidebar do admin é sempre navy escuro, mesmo no tema claro — não dá
   pra depender só do data-theme aqui, ou o T some quando o app inteiro
   está no tema claro mas a sidebar continua escura. */
.admin-sidebar-header img[src$="logo-glyph.png"] {
  content: url("../img/logo-glyph-dark.png");
}

.brand-name {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.4px;
}

.brand-sub {
  font-size: 11px;
  color: var(--text-secondary);
  letter-spacing: 0.5px;
}

.topbar-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

.theme-toggle {
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-primary);
  border-radius: 100px;
  padding: 8px 14px;
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  transition: border-color 0.15s ease-out, transform 0.1s ease-out;
}

.theme-toggle:hover { border-color: var(--brand-gold-soft); }
.theme-toggle:active { transform: scale(0.96); }

.user-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-secondary);
}

.avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--brand-navy);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  color: #FFFFFF;
  box-shadow: var(--shadow-sm);
}

.avatar-ring {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  margin: 0 auto 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-surface-elevated);
  border: 2px solid var(--brand-navy);
  padding: 3px;
}
.avatar-ring-inner {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: var(--bg-surface);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  font-weight: 800;
  color: var(--brand-navy);
  background-size: cover;
  background-position: center;
  overflow: hidden;
}

/* Campo de foto/logo: avatar + ação, lado a lado — comunica "isso é upload de imagem" */
.avatar-field {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  cursor: pointer;
  margin-bottom: 22px;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.avatar-field:hover { border-color: var(--brand-navy); background: var(--bg-surface-elevated); }
.avatar-thumb { position: relative; flex-shrink: 0; }
.avatar-field .avatar-ring { width: 52px; height: 52px; margin: 0; flex-shrink: 0; }
.avatar-field .avatar-ring-inner { font-size: 16px; }
.avatar-field .avatar-ring-inner .icon { width: 20px; height: 20px; color: var(--text-secondary); }

.avatar-upload-badge {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--brand-navy);
  color: #FFFFFF;
  border: 2px solid var(--bg-surface);
  display: flex;
  align-items: center;
  justify-content: center;
}
.avatar-upload-badge .icon { width: 10px; height: 10px; }

.avatar-field-info p { margin: 0 0 3px; font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 7px; }
.avatar-field-info span { font-size: 11.5px; color: var(--text-secondary); }

/* Seletor Pessoa Física / Jurídica no cadastro de cliente — controle
   segmentado (trilho cinza + "pill" ativo elevado), não dois botões soltos. */
.tipo-pessoa-toggle, .segmented-toggle {
  display: flex;
  gap: 3px;
  padding: 3px;
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  margin-bottom: 20px;
}
.tipo-pessoa-option, .segmented-option {
  flex: 1;
  padding: 9px 14px;
  border-radius: calc(var(--radius-md) - 3px);
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease-out;
}
.tipo-pessoa-option:hover:not(.active), .segmented-option:hover:not(.active) { color: var(--text-primary); }
.tipo-pessoa-option.active, .segmented-option.active { background: var(--bg-surface); color: var(--brand-navy); box-shadow: var(--shadow-sm); }
.tipo-pessoa-option:active, .segmented-option:active { transform: scale(0.97); }
/* Travado (ex: "Tipo de categoria" depois de já criada) — continua
   mostrando qual opção está ativa, só sem parecer clicável. */
.segmented-option:disabled { cursor: default; }
.segmented-toggle.disabled .segmented-option:hover:not(.active) { color: var(--text-secondary); }
.segmented-toggle.disabled .segmented-option:active { transform: none; }

.tag-optional {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--text-secondary);
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: 100px;
  padding: 1px 7px;
}

/* Agrupamento de campos em seções com respiro próprio (evita "blocos soltos") */
.form-section { margin-bottom: 22px; }
.form-section:last-child { margin-bottom: 0; }

.form-section-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin: 0 0 14px;
}
.form-section + .form-section {
  padding-top: 20px;
  border-top: 1px solid var(--border-default);
}

.modal-icon-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 4px;
}
.modal-icon-badge {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--brand-navy);
  color: #FFFFFF;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* Mesmo friso interno claro dos chips (.stat-icon-chip/.cat-icon/.doc-icon)
     — aqui fixo em branco porque o fundo é sempre uma cor sólida saturada
     (navy/danger/etc via style inline), não a superfície do tema. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), inset 0 -1px 1px rgba(0, 0, 0, 0.12);
}
.modal-icon-badge .icon { width: 18px; height: 18px; }

/* ---------- Layout ---------- */
.main {
  flex: 1;
  padding: 40px 32px;
  max-width: 1280px;
  width: 100%;
  margin: 0 auto;
}
/* Painel administrativo usa mais largura de tela que as páginas do cliente
   (mais colunas de dado por tela — tabela de clientes/documentos, não um
   formulário) — mesmo container, só mais largo. */
.main.admin-main { max-width: 1600px; }

.page-header { margin-bottom: 28px; }
/* Pedido explícito: tirar todo o "fixado" da página — o cabeçalho global
   (e o resto da pilha sticky do Financeiro/Detalhe do cliente) volta a
   rolar normal junto com o resto do conteúdo, sem grudar no topo. */
#admin-page-header { position: static; }

.page-title {
  font-size: 24px;
  font-weight: 700;
  margin: 0 0 6px;
}

.page-subtitle {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 0;
}

.eyebrow {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.5px;
  color: var(--brand-navy);
  text-transform: uppercase;
  margin: 0 0 8px;
}

/* ---------- Login ---------- */
.login-screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-canvas);
  position: relative;
  overflow: hidden;
}

/* Textura de fundo: grade discreta de pontos + um leve véu de navy vindo do
   topo, os dois esmaecendo pra fora do centro via mask — no lugar dos blobs
   desfocados antigos, que são um "tell" de template genérico tão comum
   quanto o próprio card sem graça que eles tentavam disfarçar. */
.login-screen::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--brand-navy) 10%, transparent), transparent 60%),
    radial-gradient(var(--border-default) 1px, transparent 1px);
  background-size: auto, 28px 28px;
  -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 35%, black, transparent 80%);
  mask-image: radial-gradient(ellipse 70% 60% at 50% 35%, black, transparent 80%);
  pointer-events: none;
}

.login-graphic {
  position: relative;
  z-index: 1;
}

.login-card {
  width: 380px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: var(--space-10) var(--space-8);
  box-shadow: var(--shadow-lg);
}

.login-logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-8);
}

.login-logo .brand-mark { width: 76px; height: 76px; }

.login-logo .brand-name { font-size: var(--text-md); font-weight: var(--font-bold); letter-spacing: var(--tracking-tight); text-align: center; }
.login-logo .brand-sub {
  text-align: center;
  color: var(--brand-gold);
  font-weight: var(--font-semibold);
  letter-spacing: var(--tracking-wide);
}

/* ---------- Login: fundo atmosférico + cartão de vidro ----------
   Usado só nas duas telas de entrada de verdade (index.html / admin-login.html)
   — as telas auxiliares (esqueci-senha, redefinir-senha, primeiro-acesso)
   continuam no .login-screen/.login-card de coluna única, sem risco de
   quebrar layout que já funciona. Fundo sempre escuro, nos dois temas —
   é identidade de marca, não superfície de app. */
.auth-atmosphere {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: #12172B;
  overflow: hidden;
}

.auth-atmosphere::before,
.auth-atmosphere::after {
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
}
.auth-atmosphere::before {
  width: 560px;
  height: 560px;
  top: -180px;
  left: -120px;
  background: radial-gradient(circle, #3B4A87 0%, transparent 70%);
}
.auth-atmosphere::after {
  width: 480px;
  height: 480px;
  bottom: -200px;
  right: -140px;
  background: radial-gradient(circle, #7A5A14 0%, transparent 70%);
  opacity: 0.5;
}

.auth-glass-card {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 400px;
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 20px;
  padding: 44px 40px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}

.auth-glass-logo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-bottom: 30px;
}
.auth-glass-logo .brand-mark { width: 68px; height: 68px; }
.auth-glass-logo .brand-name { font-size: 15px; font-weight: var(--font-bold); color: #fff; }
.auth-glass-logo .brand-sub {
  font-size: 11px;
  font-weight: var(--font-semibold);
  letter-spacing: var(--tracking-wide);
  color: #E8C766;
  text-transform: uppercase;
}

.auth-glass-card .field label { color: rgba(244, 241, 232, 0.75); }
.auth-glass-card .field input {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.auth-glass-card .field input::placeholder { color: rgba(244, 241, 232, 0.4); }
.auth-glass-card .field input:focus {
  border-color: #E8C766;
  box-shadow: 0 0 0 3px rgba(232, 199, 102, 0.18);
}
/* O autofill do navegador (Chrome etc.) ignora background/color normais e
   pinta o campo de branco sólido com texto preto — nesse cartão escuro isso
   sumia com o botão de "ver senha" (ícone claro em cima de branco). Força o
   autofill a manter a mesma aparência de vidro escuro. */
.auth-glass-card .field input:-webkit-autofill,
.auth-glass-card .field input:-webkit-autofill:hover,
.auth-glass-card .field input:-webkit-autofill:focus {
  -webkit-text-fill-color: #fff;
  -webkit-box-shadow: 0 0 0 1000px rgba(40, 46, 74, 0.9) inset;
  box-shadow: 0 0 0 1000px rgba(40, 46, 74, 0.9) inset;
  transition: background-color 5000s ease-in-out 0s;
}
.auth-glass-card .password-toggle-btn { color: rgba(244, 241, 232, 0.6); }
.auth-glass-card .password-toggle-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.1); }
.auth-glass-card .btn-primary { background: #E8C766; color: #1F2A4D; }
.auth-glass-card .btn-primary:hover:not(:disabled) { background: #D4AF37; }
.auth-glass-card .btn-secondary {
  background: rgba(255, 255, 255, 0.05);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.auth-glass-card .btn-secondary:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.3);
}
.auth-glass-card .login-footnote { color: rgba(244, 241, 232, 0.6); }
.auth-glass-card .login-footnote a { color: #E8C766; }

/* O cartão de login é sempre escuro (identidade de marca, ver comentário
   em .auth-atmosphere), independente do tema claro/escuro escolhido no
   resto do sistema — então qualquer componente reaproveitado aqui (barra
   de força de senha, checklist de critérios, spinner de carregamento,
   texto de "hint", erro de campo) precisa da própria cor fixa, sem
   depender de --text-secondary/--semantic-danger etc., que no tema claro
   (o padrão da maioria de quem acessa) ficam escuros demais pra ler em
   cima do fundo #12172B. Usado nas telas auxiliares de login (esqueci
   senha, redefinir senha, primeiro acesso) que passaram a usar o mesmo
   cartão de vidro da tela principal, em vez do cartão claro de antes. */
.auth-glass-card .hint { color: rgba(244, 241, 232, 0.65); }
.auth-glass-card .senha-forca-bar-seg { background: rgba(255, 255, 255, 0.14); }
.auth-glass-card .senha-forca-bar-seg.on.danger { background: #FF8A80; }
.auth-glass-card .senha-forca-bar-seg.on.warning { background: #E2984A; }
.auth-glass-card .senha-forca-bar-seg.on.ok { background: #3FB87F; }
.auth-glass-card .senha-forca-label.danger { color: #FF8A80; }
.auth-glass-card .senha-forca-label.warning { color: #E2984A; }
.auth-glass-card .senha-forca-label.ok { color: #3FB87F; }
.auth-glass-card .senha-criterio { color: rgba(244, 241, 232, 0.55); }
.auth-glass-card .senha-criterio .icon { color: rgba(244, 241, 232, 0.4); }
.auth-glass-card .senha-criterio.ok { color: #3FB87F; }
.auth-glass-card .senha-criterio.ok .icon { color: #3FB87F; }
.auth-glass-card .field-error { color: #FF8A80; }
.auth-glass-card .auth-guard-spinner { border-color: rgba(255, 255, 255, 0.15); border-top-color: #E8C766; }

/* Seletor Cliente / Administrador no topo do cartão de login — mesmo
   padrão de trilho + "pill" do .segmented-toggle, mas com a opção ativa em
   dourado sólido (não dá pra confundir com nenhum outro estado do cartão
   escuro) em vez do estilo claro usado no resto do sistema. Pedido: o tipo
   de acesso tem que ser "impossível de ignorar", não um link discreto no
   rodapé como era antes. */
.auth-type-toggle {
  display: flex;
  gap: 4px;
  padding: 4px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 12px;
  margin-bottom: 24px;
}
.auth-type-option {
  flex: 1;
  padding: 11px 14px;
  border-radius: 8px;
  border: none;
  background: transparent;
  color: rgba(244, 241, 232, 0.6);
  font-size: 13px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease-out;
}
.auth-type-option:hover:not(.active) { color: #fff; }
.auth-type-option.active {
  background: #E8C766;
  color: #1F2A4D;
  box-shadow: 0 4px 16px rgba(232, 199, 102, 0.35);
}
.auth-type-option:active { transform: scale(0.97); }
.auth-type-caption {
  text-align: center;
  color: rgba(244, 241, 232, 0.55);
  font-size: 12.5px;
  margin-top: -18px;
  margin-bottom: 26px;
}

/* Divisor "ou" entre o login por senha e o "Continuar com Google" — separa
   visualmente sem competir com o seletor Cliente/Administrador lá em cima
   (esse é o elemento de maior destaque do cartão; o Google é uma alternativa
   discreta abaixo do formulário, não um segundo protagonista). */
.auth-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 22px 0 18px;
  color: rgba(244, 241, 232, 0.4);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.auth-divider::before, .auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: rgba(255, 255, 255, 0.12);
}

.auth-glass-card .btn-google {
  width: 100%;
  background: rgba(255, 255, 255, 0.05);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.16);
}
.auth-glass-card .btn-google:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.3);
}
.auth-glass-card .btn-google:disabled { opacity: 0.6; cursor: default; }
.auth-glass-card .btn-google svg { flex-shrink: 0; }

@media (max-width: 480px) {
  .auth-glass-card { padding: 32px 24px; }
}

.field { margin-bottom: 18px; }

.field label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--text-secondary);
}
/* Asterisco de campo obrigatório — content: " *" em vez de escrever o
   asterisco no texto do label, pra não precisar mexer em cada label
   individualmente se o texto mudar, e pra ficar visualmente idêntico em
   TODO formulário do sistema (cliente e admin). Cor = mesma do texto de
   erro (--semantic-danger), que já é a cor "de atenção" que o sistema usa
   — sem inventar um vermelho novo. */
.field label.required::after {
  content: " *";
  color: var(--semantic-danger);
}
/* Legenda "* Campos obrigatórios" — mesmo estilo em qualquer formulário que
   a use, discreta (tamanho de hint), fica no topo do formulário logo
   abaixo do título. */
.form-required-legend {
  font-size: 11.5px;
  color: var(--text-secondary);
  margin: -8px 0 16px;
}
.form-required-legend::before {
  content: "* ";
  color: var(--semantic-danger);
  font-weight: 700;
}

.field input,
.field textarea {
  width: 100%;
  padding: 11px 14px;
  border-radius: 8px;
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-primary);
  font-size: 14px;
  font-family: inherit;
  resize: vertical;
}

.field input,
.field textarea,
.select-like {
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.field-error {
  color: var(--semantic-danger);
  font-size: 12px;
  margin: -10px 0 14px;
  display: none;
}
/* Borda vermelha no campo com erro — antes só existia a mensagem em texto
   (.field-error), sem nenhum destaque no próprio input/select/textarea.
   :has() cobre os dois jeitos que o sistema usa de posicionar o
   <p class="field-error">: dentro do .field (a maioria) ou logo depois dele
   como irmão (telas de trocar senha). */
.field:has(> .field-error.show) input,
.field:has(> .field-error.show) select,
.field:has(> .field-error.show) textarea,
.field:has(+ .field-error.show) input,
.field:has(+ .field-error.show) select,
.field:has(+ .field-error.show) textarea {
  border-color: var(--semantic-danger);
}
/* Mostrar/ocultar senha — wrapper próprio (não position:relative direto em
   .field, que é usado em campos sem senha nenhuma por toda a aplicação) só
   pra não vazar esse posicionamento pra outros campos. */
.password-field-wrap { position: relative; }
.password-field-wrap input { padding-right: 42px; }
.password-toggle-btn {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  cursor: pointer;
  transition: color 0.15s ease-out, background 0.15s ease-out, transform 0.1s ease-out;
}
.password-toggle-btn:hover { color: var(--text-primary); background: var(--bg-surface-elevated); }
.password-toggle-btn:active { transform: scale(0.9); }
.password-toggle-btn:focus-visible { outline: 2px solid var(--brand-navy); outline-offset: 1px; }
.password-toggle-btn .icon { width: 18px; height: 18px; }
.field-error.show { display: block; }
.field input:focus,
.field textarea:focus,
.select-like:focus {
  outline: none;
  border-color: var(--brand-navy);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-navy) 16%, transparent);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: none;
  border-radius: 8px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 12px 20px;
  cursor: pointer;
  transition: background 0.15s ease-out, color 0.15s ease-out, border-color 0.15s ease-out, transform 0.15s ease-out, box-shadow 0.15s ease-out;
}
/* Elevação sutil no hover + "afundada" no clique — mesmo padrão que já
   existia só em .login-card .btn-primary, promovido pra todo botão do
   sistema (cliente e admin), sempre por transform/box-shadow (nunca
   width/height, pra não ter custo de reflow). :not(:disabled) porque um
   botão em "Salvando..."/"Enviando..." não deve reagir a hover/clique. */
.btn:hover:not(:disabled) { transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.btn:active:not(:disabled) { transform: translateY(0); box-shadow: none; }

.btn-primary {
  background: var(--action-primary);
  color: var(--text-inverse);
}

.btn-primary:hover { background: var(--action-primary-hover); }

.login-card .btn-primary,
.auth-glass-card .btn-primary { width: 100%; }

.btn-secondary {
  background: var(--bg-surface-elevated);
  color: var(--text-primary);
  border: 1px solid var(--border-default);
}

.btn-secondary:hover { border-color: var(--brand-gold-soft); }

.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  padding: 8px 12px;
}

.login-footnote {
  text-align: center;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  margin-top: var(--space-5);
  line-height: var(--leading-normal);
}
.login-footnote a { color: var(--brand-navy); font-weight: var(--font-medium); }

/* ---------- Category cards ---------- */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}

.cat-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  padding: 22px;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.1s ease;
  position: relative;
}

.cat-card:hover {
  border-color: var(--brand-gold-soft);
  transform: translateY(-2px);
}

.cat-icon {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface-elevated);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  margin-bottom: 14px;
  color: var(--brand-navy);
}

.cat-title { font-size: 15px; font-weight: 600; margin: 0 0 4px; }
.cat-meta { font-size: 12px; color: var(--text-secondary); margin: 0; }

.cat-badge {
  position: absolute;
  top: 18px;
  right: 18px;
  background: var(--semantic-warning-bg);
  color: var(--semantic-warning);
  font-size: 11px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 100px;
}

/* Hero section: boletos com destaque */
.category-section-hero {
  margin-bottom: 40px;
}

.card-grid-hero {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 20px;
  margin-top: 16px;
}

.cat-card-hero {
  padding: 28px;
  border-width: 2px;
  border-color: var(--brand-navy);
  background: linear-gradient(135deg, var(--bg-surface) 0%, var(--bg-surface-elevated) 100%);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.cat-card-hero:hover {
  border-color: var(--brand-gold);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  transform: translateY(-4px);
}

/* Seção de arquivo: outros documentos */
.category-section-archive {
  margin-top: 48px;
  opacity: 0.95;
}

.section-label-secondary {
  color: var(--text-secondary);
  font-size: 13px;
  letter-spacing: 0.5px;
}

.card-grid-archive {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
  margin-top: 14px;
}

.cat-card-archive {
  padding: 16px;
  background: var(--bg-surface);
  border-color: var(--border-default);
  box-shadow: none;
}

.cat-card-archive:hover {
  border-color: var(--text-secondary);
  transform: translateY(-1px);
}

.cat-card-archive .cat-icon {
  width: 32px;
  height: 32px;
  font-size: 14px;
  margin-bottom: 10px;
  opacity: 0.7;
}

.cat-card-archive .cat-title {
  font-size: 13px;
  margin-bottom: 2px;
}

/* ---------- Document list ---------- */
.doc-list { display: flex; flex-direction: column; gap: 10px; }

.doc-row {
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: 14px 18px;
}

.doc-icon {
  width: 38px;
  height: 38px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface-elevated);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  flex-shrink: 0;
}

.doc-info { flex: 1; min-width: 0; }
.doc-name { font-size: 14px; font-weight: 600; margin: 0 0 3px; }
.doc-meta { font-size: 12px; color: var(--text-secondary); margin: 0; }

.due-tag {
  font-size: 11px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 100px;
  white-space: nowrap;
}
.due-tag.warning { background: var(--semantic-warning-bg); color: var(--semantic-warning); }
.due-tag.ok { background: var(--bg-surface-elevated); color: var(--semantic-success); }
.due-tag.danger { background: color-mix(in srgb, var(--semantic-danger) 15%, var(--bg-surface)); color: var(--semantic-danger); }
.due-tag.neutral { background: var(--bg-surface-elevated); color: var(--text-secondary); }

/* ---------- Badge único (páginas novas do cliente) ----------
   4 variantes só — mapeia 1:1 com o "cls" que statusBoleto() (app.js) já
   retorna (ok/warning/danger/neutral). Não mexe em .due-tag/.status-badge
   (usados pelo admin.html, fora de escopo desta rodada) — componente novo,
   paralelo, pras páginas novas. */
.badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--text-2xs);
  font-weight: var(--font-bold);
  letter-spacing: 0.02em;
  padding: var(--space-1) var(--space-2);
  border-radius: 100px;
  white-space: nowrap;
  line-height: 1;
}
.badge.ok { background: color-mix(in srgb, var(--semantic-success) 12%, var(--bg-surface)); color: var(--semantic-success); }
.badge.warning { background: var(--semantic-warning-bg); color: var(--semantic-warning); }
.badge.danger { background: color-mix(in srgb, var(--semantic-danger) 12%, var(--bg-surface)); color: var(--semantic-danger); }
.badge.neutral { background: var(--bg-surface-elevated); color: var(--text-secondary); }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 18px;
  cursor: pointer;
}
.back-link:hover { color: var(--brand-navy); }

/* ---------- Admin table ---------- */
.table-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  overflow-x: auto;
}

/* Pedido explícito: tirar todo o "fixado" da página — sem nada sticky
   aqui dentro, .table-card volta a usar o overflow-x:auto padrão (scroll
   horizontal normal em telas estreitas), como qualquer outra tabela. */
#tab-financeiro .table-scroll-wrap thead th {
  position: static;
}

.table-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-top: 1px solid var(--border-default);
}
.table-pagination:empty { display: none; }
.pagination-info { font-size: 12.5px; color: var(--text-secondary); }
.pagination-controls { display: flex; align-items: center; gap: 10px; }
.pagination-page { font-size: 12.5px; color: var(--text-secondary); min-width: 40px; text-align: center; }
.pagination-prev:disabled, .pagination-next:disabled { opacity: 0.4; cursor: not-allowed; }

.table-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-default);
}

table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 16px 20px; font-size: 13px; vertical-align: middle; }
th {
  color: var(--text-secondary);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  background: var(--bg-surface-elevated);
  padding-top: 13px;
  padding-bottom: 13px;
  white-space: nowrap;
}
table.table-clients th { white-space: normal; }
table.table-clients td:last-child { white-space: nowrap; width: 1%; }
tbody tr:not(:last-child) td { border-bottom: 1px solid var(--border-default); }
tbody tr.row-clickable { cursor: pointer; transition: background 0.12s ease; }
tbody tr.row-clickable:hover { background: var(--bg-surface-elevated); }
.client-link { cursor: pointer; font-weight: 600; color: var(--text-primary); }
.client-link:hover { color: var(--brand-navy); text-decoration: underline; }
[data-theme="dark"] .client-link:hover { color: var(--brand-gold); }

.client-cell { display: flex; align-items: center; gap: 12px; }
.client-cell .avatar { width: 34px; height: 34px; font-size: 13px; flex-shrink: 0; }
.client-doc { font-size: 11.5px; color: var(--text-secondary); margin-top: 2px; }

/* Hierarquia tipográfica: e-mail é dado auxiliar, não compete com o nome do cliente */
table.table-clients td { color: var(--text-secondary); }
table.table-clients .client-link,
table.table-clients .last-doc strong { color: var(--text-primary); }

.status-tag { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; }
.status-tag .status-dot { width: 7px; height: 7px; border-radius: 50%; }
.status-tag.active { color: var(--semantic-success); }
.status-tag.active .status-dot { background: var(--semantic-success); }
.status-tag.inactive { color: var(--text-secondary); }
.status-tag.inactive .status-dot { background: var(--text-secondary); }
.status-tag.warning { color: var(--semantic-warning); }
.status-tag.warning .status-dot { background: var(--semantic-warning); }
.status-tag.danger { color: var(--semantic-danger); }
.status-tag.danger .status-dot { background: var(--semantic-danger); }

/* Pendências: indicador fixo (ícone + contador), não escala com a quantidade de categorias */
.pending-indicator {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  width: 30px;
  height: 26px;
  border-radius: var(--radius-sm);
  cursor: default;
  justify-content: center;
}
.pending-indicator .icon { width: 13px; height: 13px; flex-shrink: 0; }
.pending-indicator strong { font-size: 12px; font-weight: 700; }
.pending-indicator.ok { color: var(--semantic-success); }
.pending-indicator.warn {
  width: auto;
  padding: 0 9px;
  background: var(--semantic-warning-bg);
  color: var(--semantic-warning);
}

.last-doc { display: flex; flex-direction: column; gap: 2px; }
.last-doc strong { font-size: 13px; font-weight: 600; }
.last-doc span { font-size: 11px; color: var(--text-secondary); }
.last-doc span.valor-danger { color: var(--semantic-danger); font-weight: 600; }

/* ---------- Admin: sidebar fixa de altura total ----------
   Substitui a antiga barra de navegação solta dentro do grid de conteúdo.
   .admin-shell é o wrapper [sidebar fixa][conteúdo]; a sidebar preenche
   100vh com --brand-navy (o "painel azul" do pedido) e três seções fixas
   (topo: marca / meio: navegação, rolável / rodapé: usuário). Recolhe pra
   76px (só ícone) via botão no topo — preferência salva em safeStorage e
   aplicada como classe em .admin-shell. Em telas ≤1024px vira um drawer
   que fica fora da tela por padrão (transform) e abre por cima do conteúdo
   via botão de menu + fundo escurecido, em vez do modo ícone (não faz
   sentido colapsar por ícone numa tela que já não tem espaço lateral). */
.admin-shell { display: flex; min-height: 100vh; }

.admin-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: 260px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  /* Três camadas de gradiente puro — nenhum backdrop-filter, de propósito:
     não há nada atrás da sidebar pra "ver através" (ela é opaca e o
     conteúdo fica ao lado, não por baixo), então blur de verdade não teria
     efeito visível nenhum, só custaria performance à toa. A sensação de
     vidro/profundidade vem inteiramente de luz e sombra simuladas por
     gradiente, que o navegador pinta de graça: um brilho radial bem fraco
     saindo do canto superior esquerdo (como luz pegando a borda de um
     painel), um escurecimento gradual em direção à base (aterra o painel,
     em vez dele "flutuar" uniforme), e por baixo de tudo o degradê vertical
     principal entre as duas cores de referência. */
  background:
    radial-gradient(130% 55% at 12% 0%, rgba(255, 255, 255, 0.09), transparent 60%),
    linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.14) 100%),
    linear-gradient(180deg, var(--sidebar-bg-top) 0%, var(--sidebar-bg) 100%);
  border-right: 1px solid rgba(255, 255, 255, 0.07);
  box-shadow: var(--shadow-md);
  z-index: 30;
  transition: width 0.18s ease, transform 0.18s ease;
}
.admin-sidebar.resizing { transition: none; }
.admin-content.resizing { transition: none; }

.admin-sidebar-resize-handle {
  position: absolute;
  top: 0;
  right: -3px;
  width: 6px;
  height: 100%;
  cursor: col-resize;
  z-index: 31;
}
.admin-sidebar-resize-handle:hover { background: rgba(255, 255, 255, 0.14); }
.admin-shell.sidebar-collapsed .admin-sidebar-resize-handle { display: none; }

.admin-sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: var(--space-5) var(--space-4);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
  flex-shrink: 0;
}
.admin-sidebar-header .brand { min-width: 0; flex: 1; overflow: hidden; }
.admin-sidebar-header .brand-mark { width: 44px; height: 44px; border-color: transparent; flex-shrink: 0; }
.admin-sidebar-header .brand-name { color: var(--sidebar-text); font-size: 13.5px; letter-spacing: 0.2px; }
.admin-sidebar-header .brand-sub { color: color-mix(in srgb, var(--sidebar-text) 60%, transparent); }
.admin-sidebar-brand-text { min-width: 0; overflow: hidden; }
.admin-sidebar-brand-text .brand-name, .admin-sidebar-brand-text .brand-sub { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.admin-nav-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-sm);
  color: color-mix(in srgb, var(--sidebar-text) 65%, transparent);
  flex-shrink: 0;
  border: none;
  background: none;
  cursor: pointer;
}
.admin-nav-toggle:hover { background: rgba(255, 255, 255, 0.1); color: var(--sidebar-text); }
.admin-nav-toggle:focus-visible { outline: 2px solid var(--sidebar-accent); outline-offset: 1px; }
.admin-nav-toggle .icon { width: 16px; height: 16px; }

.admin-nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: var(--space-3);
}

.admin-nav-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: 10px 12px;
  border: none;
  background: none;
  border-radius: var(--radius-sm);
  color: color-mix(in srgb, var(--sidebar-text) 70%, transparent);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
}
.admin-nav-item:hover { background: rgba(255, 255, 255, 0.07); color: var(--sidebar-text); }
/* "Pill" limpo — sem borda lateral (era o que deixava o item ativo com
   cara de protótipo). Só um preenchimento azul translúcido, arredondado
   igual ao resto do item, com um glow bem discreto pra dar um toque de
   destaque sem gritar. */
.admin-nav-item.active {
  background: color-mix(in srgb, var(--sidebar-accent) 22%, transparent);
  color: #FFFFFF;
  font-weight: 700;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--sidebar-accent) 25%, transparent), 0 0 14px color-mix(in srgb, var(--sidebar-accent) 20%, transparent);
}
.admin-nav-item:focus-visible { outline: 2px solid var(--sidebar-accent); outline-offset: -2px; }
/* Ícone só aparece na navegação recolhida (onde é a única coisa visível na
   linha) — a Lorena achou os ícones ao lado do texto no menu expandido
   pouco profissionais, então no dia a dia (menu expandido) só o nome mesmo. */
.admin-nav-item-icon { display: none; flex-shrink: 0; }
.admin-nav-item-icon .icon { width: 18px; height: 18px; }
.admin-shell.sidebar-collapsed .admin-nav-item-icon { display: flex; }
@media (max-width: 1024px) {
  .admin-shell.sidebar-collapsed .admin-nav-item-icon { display: none; }
}
.admin-nav-item-label { overflow: hidden; text-overflow: ellipsis; }

.admin-nav-section-label {
  margin: var(--space-5) 12px 8px;
  padding-top: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: color-mix(in srgb, var(--sidebar-text) 45%, transparent);
}

.admin-sidebar-footer {
  flex-shrink: 0;
  padding: var(--space-4);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.admin-sidebar-footer .user-chip { padding: 6px; border-radius: var(--radius-sm); color: color-mix(in srgb, var(--sidebar-text) 85%, transparent); }
.admin-sidebar-footer .user-chip:hover { background: rgba(255, 255, 255, 0.08); color: var(--sidebar-text); }
.admin-sidebar-user-text { display: flex; flex-direction: column; min-width: 0; overflow: hidden; }
.admin-sidebar-user-text span { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admin-sidebar-user-text small { font-size: 11px; color: color-mix(in srgb, var(--sidebar-text) 55%, transparent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admin-sidebar-footer .avatar { background: rgba(255, 255, 255, 0.16); flex-shrink: 0; }
.admin-sidebar-footer .dropdown-panel { top: auto; bottom: calc(100% + 10px); left: 0; right: auto; }

.admin-sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15, 18, 30, 0.5);
  z-index: 29;
}

.admin-content { flex: 1; min-width: 0; margin-left: 260px; transition: margin-left 0.18s ease; }

.admin-content-footer { text-align: center; font-size: 12px; color: var(--text-secondary); padding: var(--space-6) 32px; margin: 0; }

.admin-mobile-topbar { display: none; align-items: center; gap: 10px; margin-bottom: var(--space-5); }
.admin-mobile-menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  color: var(--text-primary);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
}
.admin-mobile-menu-btn:focus-visible { outline: 2px solid var(--brand-navy); outline-offset: 1px; }
.admin-mobile-menu-btn .icon { width: 20px; height: 20px; }

.admin-shell.sidebar-collapsed .admin-sidebar { width: 76px; }
.admin-shell.sidebar-collapsed .admin-content { margin-left: 76px; }
.admin-shell.sidebar-collapsed .admin-sidebar-header { justify-content: center; }
.admin-shell.sidebar-collapsed .admin-sidebar-brand-text { display: none; }
.admin-shell.sidebar-collapsed .admin-nav-toggle .icon { transform: rotate(180deg); }
.admin-shell.sidebar-collapsed .admin-nav-item { justify-content: center; padding: 10px; }
.admin-shell.sidebar-collapsed .admin-nav-item-label { display: none; }
.admin-shell.sidebar-collapsed .admin-sidebar-footer .user-chip { justify-content: center; }
.admin-shell.sidebar-collapsed .admin-sidebar-user-text { display: none; }
.admin-shell.sidebar-collapsed .admin-nav-section-label { text-align: center; }
.admin-shell.sidebar-collapsed .admin-nav-section-label span { display: none; }

.admin-layout { display: block; }

@media (max-width: 1024px) {
  .admin-sidebar, .admin-shell.sidebar-collapsed .admin-sidebar { width: 260px; transform: translateX(-100%); }
  .admin-sidebar.mobile-open { transform: translateX(0); }
  .admin-content, .admin-shell.sidebar-collapsed .admin-content { margin-left: 0; }
  .admin-shell.sidebar-collapsed .admin-sidebar-brand-text { display: block; }
  .admin-shell.sidebar-collapsed .admin-nav-item { justify-content: flex-start; padding: 10px 12px; }
  .admin-shell.sidebar-collapsed .admin-nav-item-label { display: inline; }
  .admin-shell.sidebar-collapsed .admin-sidebar-footer .user-chip { justify-content: flex-start; }
  .admin-shell.sidebar-collapsed .admin-sidebar-user-text { display: flex; }
  .admin-shell.sidebar-collapsed .admin-nav-section-label span { display: inline; }
  /* No mobile a barra "recolhida" na verdade abre em largura cheia -- o
     botão de busca volta a mostrar texto e atalho, igual os itens de nav. */
  .admin-shell.sidebar-collapsed #busca-global-wrap { padding: 14px 14px 0; }
  .admin-shell.sidebar-collapsed .busca-global-trigger { justify-content: flex-start; padding: 9px 12px; }
  .admin-shell.sidebar-collapsed .busca-global-trigger-label,
  .admin-shell.sidebar-collapsed .busca-global-trigger .busca-global-kbd { display: inline; }
  .admin-nav-toggle { display: none; }
  .admin-sidebar-resize-handle { display: none; }
  .admin-mobile-topbar { display: flex; }
  .admin-sidebar-backdrop.open { display: block; }
}

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.5);
  display: none;
  align-items: center;
  justify-content: center;
  /* Bug real encontrado: modais de confirmação abertos de dentro de um
     painel lateral já aberto (ex: Desativar cliente, chamado a partir do
     painel de detalhe) ficavam completamente invisíveis atrás do painel,
     porque .panel-overlay usa z-index 60-62 e este ficava em 50 — o clique
     em "Confirmar" ainda funcionava (o elemento existia no DOM), mas
     ninguém via o quê estava confirmando. Modal de confirmação precisa
     sempre vencer qualquer painel já aberto, nunca o contrário.
   */
  z-index: 70;
}
.modal-overlay.open { display: flex; }
.modal {
  width: 420px;
  background: var(--bg-surface);
  border-radius: var(--radius-lg);
  padding: 28px;
  border: 1px solid var(--border-default);
  box-shadow: var(--shadow-md);
}
.modal h3 { margin: 0 0 4px; font-size: 17px; }
.modal p.hint { margin: 0 0 20px; font-size: 13px; color: var(--text-secondary); }
.modal-actions { display: flex; gap: 10px; margin-top: 22px; }
.modal-actions .btn { flex: 1; }
/* Variantes de largura — NUNCA usar style="width:Npx" inline num .modal: um
   estilo inline tem prioridade sobre qualquer regra de classe, então a
   media query mobile (.modal { width:92vw }) seria ignorada nesses casos. */
.modal-sm { width: 380px; }
.modal-md { width: 400px; }
.modal-lg { width: 460px; }
.modal-xl { width: 560px; }

/* ---------- Busca global do admin (Ctrl+K) ----------
   Ancorada perto do topo (não centralizada como os outros modais) — é o
   lugar onde esse padrão de "command palette" sempre aparece, e centralizar
   ficaria estranho puxando o olho pro meio da tela toda vez que abre.
   Busca só em CLIENTES/DOCUMENTOS já carregados em memória (mesmo dado que
   os filtros de cada aba já usam) -- nenhuma chamada nova ao Supabase. */
.busca-global-overlay { align-items: flex-start; padding-top: 12vh; }
.busca-global-modal { width: 560px; max-width: 92vw; padding: 0; overflow: hidden; }
.busca-global-input-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border-default);
}
.busca-global-input-row .icon { width: 18px; height: 18px; color: var(--text-secondary); flex-shrink: 0; }
.busca-global-input-row input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  font-size: 15px;
  font-family: inherit;
  color: var(--text-primary);
}
.busca-global-kbd {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
  border-radius: 5px;
  padding: 2px 6px;
  white-space: nowrap;
  flex-shrink: 0;
}
.busca-global-resultados { max-height: 420px; overflow-y: auto; padding: 8px; }
.busca-global-grupo-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
  padding: 10px 10px 4px;
  margin: 0;
}
.busca-global-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.1s ease;
}
.busca-global-item:hover, .busca-global-item.active { background: var(--bg-surface-elevated); }
.busca-global-item-icon {
  width: 34px; height: 34px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  font-size: 12px; font-weight: 700;
}
.busca-global-item-icon .icon { width: 16px; height: 16px; }
.busca-global-item-main { min-width: 0; }
.busca-global-item-main p { margin: 0; font-size: 13.5px; font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.busca-global-item-main span { font-size: 12px; color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.busca-global-vazio { padding: 32px 20px; text-align: center; color: var(--text-secondary); font-size: 13px; }

/* Botão-gatilho na sidebar — parece um campo de busca, mas só abre o
   modal (o campo de digitar de verdade é o de dentro do modal). */
.busca-global-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 9px 12px;
  margin: 0 0 14px;
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.1s ease-out;
}
.busca-global-trigger:hover { border-color: var(--brand-gold-soft); color: var(--text-primary); }
.busca-global-trigger:active { transform: scale(0.98); }
.busca-global-trigger .icon { width: 15px; height: 15px; flex-shrink: 0; }
.busca-global-trigger-label { flex: 1; text-align: left; }

/* Menu recolhido: o botão de busca segue o mesmo tratamento dos itens de
   navegação -- só o ícone, centralizado; o texto "Buscar..." e o atalho
   "Ctrl K" somem (antes vazavam pra fora da barra estreita). */
.admin-shell.sidebar-collapsed #busca-global-wrap { padding: 12px 12px 0; }
.admin-shell.sidebar-collapsed .busca-global-trigger { justify-content: center; padding: 9px; }
.admin-shell.sidebar-collapsed .busca-global-trigger-label,
.admin-shell.sidebar-collapsed .busca-global-trigger .busca-global-kbd { display: none; }

.select-like {
  width: 100%;
  padding: 11px 14px;
  border-radius: 8px;
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-primary);
  font-size: 14px;
  font-family: inherit;
}
/* Select compacto pra caber dentro de uma célula de tabela (ex: status de boleto) */
.select-sm { width: auto; min-width: 110px; padding: 6px 10px; font-size: 13px; }
/* Feedback visual do status de pagamento do boleto — precisa ser óbvio
   sem ler o texto da opção selecionada, não só mais um select cinza igual
   a todos os outros da tela. */
.doc-status-select.pago {
  border-color: var(--semantic-success);
  background: color-mix(in srgb, var(--semantic-success) 12%, var(--bg-surface-elevated));
  color: var(--semantic-success);
  font-weight: 700;
}

/* ---------- Alert box (feedback informativo) ---------- */
.alert-box {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  border-radius: var(--radius-sm);
  padding: 13px 14px;
  margin-top: 18px;
  border: 1px solid transparent;
}
.alert-icon {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.alert-icon .icon { width: 14px; height: 14px; }
.alert-title { margin: 0; font-size: 13px; font-weight: 700; line-height: 1.4; }
.alert-subtitle { margin: 3px 0 0; font-size: 12px; color: var(--text-secondary); }
.alert-subtitle strong { color: var(--text-primary); font-weight: 600; }

.alert-info {
  background: color-mix(in srgb, var(--brand-navy) 7%, var(--bg-surface));
  border-color: color-mix(in srgb, var(--brand-navy) 22%, var(--border-default));
}
.alert-info .alert-icon { background: var(--brand-navy); color: #FFFFFF; }
.alert-info .alert-title { color: var(--brand-navy); }
[data-theme="dark"] .alert-info .alert-title { color: var(--text-primary); }

/* ---------- Dropzone ---------- */
.dropzone {
  position: relative;
  /* Borda sólida em repouso — tracejado só aparece durante o drag ativo
     (ver .drag-over), como sinal transiente, não como estado permanente
     de "provisório/placeholder". */
  border: 1.5px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-6) var(--space-5);
  text-align: center;
  background: var(--bg-surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.dropzone:hover { border-color: var(--border-hover); }
.dropzone.drag-over {
  border-style: dashed;
  border-color: var(--brand-navy);
  background: color-mix(in srgb, var(--brand-navy) 4%, var(--bg-surface));
}
/* Variante usada nas páginas novas do cliente: ícone pequeno ao lado do
   texto, uma linha só — em vez do ícone grande empilhado acima do texto
   (esse empilhamento centralizado é um dos "tells" de template mais óbvios). */
.dropzone-inline {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  text-align: left;
  padding: var(--space-8) var(--space-5);
}
.dropzone-inline .dropzone-icon { width: 20px; height: 20px; margin: 0; background: none; border: none; flex-shrink: 0; }
.dropzone-inline .dropzone-icon .icon { width: 20px; height: 20px; }
.dropzone-inline .dropzone-text { display: flex; flex-direction: column; }
.dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.dropzone-icon {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 12px;
  color: var(--text-secondary);
  pointer-events: none;
}
.dropzone-icon .icon { width: 17px; height: 17px; }
.dropzone-title { margin: 0; font-size: 13px; font-weight: 600; color: var(--text-primary); pointer-events: none; }
.dropzone-title span { color: var(--brand-navy); text-decoration: underline; }
.dropzone-hint { margin: 4px 0 0; font-size: 11.5px; color: var(--text-secondary); pointer-events: none; }

.upload-file-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.upload-file-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
}
.upload-file-item .doc-icon { width: 32px; height: 32px; flex-shrink: 0; }
.upload-file-item .doc-icon .icon { width: 16px; height: 16px; }
.upload-file-item-info { flex: 1; min-width: 0; }
.upload-file-item-info p { margin: 0; font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.upload-file-item-info span { font-size: 11px; color: var(--text-secondary); }
.upload-file-remove {
  width: 24px; height: 24px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.upload-file-remove:hover { background: var(--semantic-warning-bg); color: var(--semantic-danger); }
.upload-file-remove .icon { width: 13px; height: 13px; }

/* ---------- Page transition ---------- */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}
.app-shell, .login-screen { animation: fadeUp 0.35s ease both; }

/* ---------- Icons ---------- */
.icon { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.cat-icon .icon, .doc-icon .icon { width: 20px; height: 20px; }

/* ---------- Sistema de ícones: chips com leve profundidade ----------
   Toda "caixa com ícone" do sistema (KPI, categoria, documento) é da mesma
   família — fundo com tom sutil da cor semântica + friso interno claro no
   topo, a MESMA técnica que .stat-card já usa (inset via --text-inverse, só
   mais concentrada por serem caixas pequenas). Um lugar só pra ajustar em
   vez de bordas/sombra diferentes em cada tela — é isso que fazia os chips
   do Financeiro/Categorias/Documentos parecerem de "sistemas" diferentes
   mesmo sendo o mesmo componente. */
.stat-icon-chip, .cat-icon, .doc-icon {
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--text-inverse) 20%, transparent);
  transition: transform 0.15s ease;
}
.stat-card:hover .stat-icon-chip,
.cat-card:hover .cat-icon,
.upload-file-item:hover .doc-icon {
  transform: translateY(-1px);
}

/* ---------- Icon buttons / bell ---------- */
.icon-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.1s ease-out;
}
.icon-btn:hover { border-color: var(--brand-gold-soft); background: var(--semantic-warning-bg); color: var(--brand-gold); }
.icon-btn:active { transform: scale(0.92); }
.icon-btn .icon { width: 18px; height: 18px; }
/* Variante pra ações destrutivas (excluir) — hover vermelho em vez do
   dourado padrão, mesmo tom usado nos outros avisos de perigo do sistema. */
.icon-btn-danger:hover { border-color: var(--semantic-danger); background: color-mix(in srgb, var(--semantic-danger) 15%, var(--bg-surface)); color: var(--semantic-danger); }

.notif-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--semantic-warning);
  border: 1.5px solid var(--bg-surface);
}

/* ---------- Dropdown ---------- */
.dropdown-wrap { position: relative; }
.dropdown-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 300px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 14px;
  box-shadow: var(--shadow-md);
  padding: 8px;
  display: none;
  z-index: 40;
}
.dropdown-panel.open { display: block; animation: fadeUp 0.15s ease both; }
.dropdown-panel.filtros-dropdown { width: 340px; padding: 14px; }
.dropdown-header { padding: 10px 12px 6px; font-size: 12px; font-weight: 700; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.5px; }
.dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  font-size: 13px;
  cursor: pointer;
}
.dropdown-item:hover { background: var(--bg-surface-elevated); }
.dropdown-item .icon { width: 16px; height: 16px; color: var(--text-secondary); }
.dropdown-divider { height: 1px; background: var(--border-default); margin: 6px 4px; }

/* ---------- Painel de upload: cliente por contexto ou busca ---------- */
.cliente-picker-locked, .cliente-picker-escolhido {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface-elevated);
}
.cliente-picker-locked p, .cliente-picker-escolhido p { margin: 0; font-size: 13.5px; font-weight: 600; }
.cliente-picker-locked span { display: block; margin-top: 2px; font-size: 11.5px; color: var(--text-secondary); }
.cliente-picker-busca { position: relative; }
/* Mesmo combobox de busca de cliente do upload, reaproveitado nos filtros
   "Cliente" das abas Documentos e Boletos -- só precisa do position:relative
   pro dropdown de resultados (.cliente-picker-resultados) se posicionar por
   baixo do campo de texto. */
.filtro-cliente-combo { position: relative; }
.cliente-picker-resultados {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  width: auto;
  max-height: 240px;
  overflow-y: auto;
}
.cliente-picker-resultados.open { display: block; }

.notif-item { display: flex; gap: 10px; padding: 10px 12px; border-radius: 10px; }
.notif-item:hover { background: var(--bg-surface-elevated); }
.notif-item .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--semantic-warning); margin-top: 5px; flex-shrink: 0; }
.notif-item p { margin: 0; font-size: 13px; }
.notif-item span { font-size: 11px; color: var(--text-secondary); }

/* ---------- Stat cards ---------- */
.stats-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 28px; }
/* Pedido explícito: tirar todo o "fixado" da página — KPIs e
   busca/filtros do Financeiro voltam a rolar normal junto com o resto do
   conteúdo, sem grudar no topo. */
#financial-summary-row { position: static; }
#tab-financeiro .docs-toolbar { position: static; margin-top: var(--space-6); }
.stat-card {
  background: linear-gradient(160deg, var(--bg-surface) 0%, color-mix(in srgb, var(--bg-surface-elevated) 45%, var(--bg-surface)) 100%);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm), inset 0 1px 0 color-mix(in srgb, var(--text-inverse) 6%, transparent);
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
/* Leve elevação no hover em QUALQUER stat-card do sistema (Visão geral,
   Financeiro, Configurações) — antes só os .clickable reagiam ao hover, o
   que fazia o mesmo componente parecer "vivo" numa tela e "morto" noutra. */
.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
  border-color: color-mix(in srgb, var(--brand-navy) 22%, var(--border-default));
}
/* KPIs de alerta ganham peso visual que os neutros não têm, mas por
   tipografia (peso/tamanho) e um risco lateral discreto — não pintando o
   card inteiro nem o número de amarelo/laranja, que é chamativo demais
   pra um dado que só precisa se destacar um pouco. */
.stat-card.attention { border-left: 3px solid var(--semantic-warning); }
.stat-card.attention .stat-value { font-weight: 800; }
.stat-card.attention.danger { border-left-color: var(--semantic-danger); }
.stat-card.attention.danger .stat-value { color: var(--semantic-danger); }
.stat-card.clickable { cursor: pointer; }
.stat-card.clickable:hover { box-shadow: var(--shadow-md); }

/* KPIs "hero" da Visão geral (receita mensal, % de clientes com
   pendências) — mesma família visual do .stat-card comum, só maiores, pra
   dar hierarquia às 2 métricas que um dono de escritório olha primeiro,
   sem precisar de paleta de cor nova. */
.stats-row-hero { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; margin-bottom: 16px; }
/* position:relative -- âncora pro chevron absoluto (.stat-card-hero-chev). */
.stat-card-hero { padding: 24px 26px; position: relative; overflow: hidden; }
.stat-card-hero .stat-icon-chip { width: 54px; height: 54px; }
.stat-card-hero .stat-icon-chip .icon { width: 24px; height: 24px; }
.stat-card-hero .stat-label { font-size: 13px; }
.stat-card-hero .stat-value { font-size: 36px; }
.stat-card-hero .stat-trend { font-size: 12px; }

/* ---------- Visão geral: KPIs "hero" com tingimento + Atenção do dia ----------
   Pedido explícito da Lorena, com base numa referência visual (aprovada por
   ela numa prévia à parte antes de mexer aqui): os 2 KPIs "hero" (Receita
   mensal, Clientes com pendências) ganham um tingimento sutil da própria
   cor em vez do fundo neutro que .stat-card já tinha. O card de Receita
   chegou a ter um gráfico de área decorativo aqui -- removido a pedido
   dela ("tire essa imagem de gráfico de fundo desse KPI"), o número/
   tendência/texto já contam a história real sem precisar de floreio. */
.stat-card-hero.tint-navy { background: linear-gradient(135deg, color-mix(in srgb, var(--brand-navy) 13%, var(--bg-surface)) 0%, var(--bg-surface) 62%); }
.stat-card-hero.tint-warning { background: linear-gradient(135deg, color-mix(in srgb, var(--semantic-warning) 16%, var(--bg-surface)) 0%, var(--bg-surface) 62%); }
.stat-card-hero-chev { position: absolute; top: 22px; right: 24px; color: var(--text-secondary); pointer-events: none; }
.stat-insight { font-size: 11.5px; color: var(--text-secondary); margin: 9px 0 0; line-height: 1.45; position: relative; z-index: 1; }
.stat-insight b { color: var(--text-primary); }

/* Cards agrupados "Operação"/"Financeiro" -- substituem, só na Visão Geral,
   4 .stat-card soltos por 2 cards com cabeçalho clicável (navega pra aba
   correspondente) e 2 métricas lado a lado com divisor -- pedido explícito
   dela pra bater com a referência (ícone da métrica sem fundo circular,
   diferente do .stat-icon-chip usado no resto do sistema). */
.group-card { background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); cursor: pointer; transition: box-shadow 0.15s ease; }
.group-card:hover { box-shadow: var(--shadow-md); }
.group-head { display: flex; align-items: center; gap: 10px; padding: 14px 18px; background: color-mix(in srgb, var(--brand-navy) 6%, var(--bg-surface)); }
.group-head-icon { width: 30px; height: 30px; border-radius: 9px; background: color-mix(in srgb, var(--brand-navy) 18%, var(--bg-surface)); color: var(--brand-navy); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.group-head-icon .icon { width: 15px; height: 15px; }
.group-head-label { flex: 1; font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--text-primary); }
.group-head-chev { color: var(--text-secondary); flex-shrink: 0; }
.group-head-chev .icon { width: 16px; height: 16px; }
.group-body { display: flex; cursor: default; }
.group-metric { flex: 1; padding: 16px 18px; }
.group-metric + .group-metric { border-left: 1px solid var(--border-default); }
.group-metric-label { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-secondary); margin-bottom: 7px; }
.group-metric-label .icon { width: 15px; height: 15px; flex-shrink: 0; color: var(--text-secondary); }
.group-metric-value { font-size: 22px; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.group-metric-trend { font-size: 11px; color: var(--text-secondary); margin-top: 4px; }

/* Faixa "Atenção do dia" -- resumo de itens urgentes do dia, clicável,
   pedido explícito da Lorena. Reaproveita cálculo já feito em renderKpis()
   (admin.html) -- ver renderAtencaoDoDia(). Faixa larga (largura toda),
   colada logo abaixo de .dashboard-charts-row -- margin-top pequeno e
   igual ao gap que já separa os 2 gráficos ali em cima, pra não sobrar um
   vão desalinhado entre a linha dos gráficos e a faixa. */
.atencao-dia { display: flex; align-items: center; gap: 16px; margin-top: 20px; padding: 16px 22px; border-radius: var(--radius-lg); border: 1px solid color-mix(in srgb, var(--semantic-danger) 25%, var(--border-default)); background: linear-gradient(135deg, color-mix(in srgb, var(--semantic-danger) 8%, var(--bg-surface)) 0%, var(--bg-surface) 68%); flex-wrap: wrap; }
.atencao-dia-icon { width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--semantic-danger) 20%, var(--bg-surface)); color: var(--semantic-danger); }
.atencao-dia-icon .icon { width: 20px; height: 20px; }
.atencao-dia-texto h3 { margin: 0; font-size: 14.5px; font-weight: 800; }
.atencao-dia-texto p { margin: 2px 0 0; font-size: 12px; color: var(--text-secondary); }
.atencao-dia-itens { display: flex; gap: 10px; margin-left: auto; flex-wrap: wrap; }
.atencao-dia-item { display: flex; align-items: center; gap: 10px; background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: var(--radius-md); padding: 10px 16px 10px 12px; cursor: pointer; transition: border-color 0.15s ease, transform 0.1s ease-out; }
.atencao-dia-item:hover { border-color: var(--brand-navy); transform: translateY(-1px); }
.atencao-dia-item-icon { width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.atencao-dia-item-icon .icon { width: 15px; height: 15px; }
.atencao-dia-item-texto { min-width: 0; }
.atencao-dia-item strong { font-size: 14.5px; font-weight: 800; display: block; }
.atencao-dia-item span { font-size: 11.5px; color: var(--text-secondary); }
.atencao-dia-item-chev { color: var(--text-secondary); margin-left: 4px; flex-shrink: 0; }
.atencao-dia-item-chev .icon { width: 14px; height: 14px; }

@keyframes pulseHighlight {
  0%, 100% { box-shadow: 0 0 0 0 rgba(180, 83, 9, 0); }
  30% { box-shadow: 0 0 0 4px var(--semantic-warning-bg); }
}
.side-card.pulse { animation: pulseHighlight 0.9s ease; border-color: var(--semantic-warning); }
.stat-card .stat-top { display: flex; margin-bottom: 8px; }
.stat-card-hero .stat-top { margin-bottom: 10px; }
/* Label denso e caixa-alta (mesmo tratamento de .admin-nav-section-label/
   .dropdown-header) em vez de texto corrido — deixa os KPIs escaneáveis
   num piscar de olho, igual em Visão geral, Financeiro e Configurações. */
.stat-label {
  text-transform: uppercase;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  color: var(--text-secondary);
  margin: 0 0 2px;
}
.stat-value { font-size: 26px; font-weight: 800; margin: 0; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
/* Centavos/decimais em destaque menor e mais leve — mesmo truque
   tipográfico de painel financeiro ("$34,680" grande + ".05" pequeno) pra
   o número inteiro ser o que o olho pega primeiro. Só usado onde o valor é
   dinheiro (realceDecimais() em app.js monta esse span); em contadores
   simples (quantidade de boletos etc.) o número não passa por isso. */
.stat-value-decimals { font-size: 0.5em; font-weight: 600; color: var(--text-secondary); letter-spacing: 0; }
.stat-icon-chip {
  width: 44px; height: 44px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.stat-icon-chip .icon { width: 20px; height: 20px; }
/* Chips mais saturados (24% em vez de 14-16%) — o pedido foi "mais parecido"
   com uma referência de dashboard fintech, e o tom sutil de antes não
   estava lendo como intencional o suficiente perto de um card branco liso. */
.stat-icon-chip-navy { background: color-mix(in srgb, var(--brand-navy) 24%, var(--bg-surface)); color: var(--brand-navy); }
.stat-icon-chip-success { background: color-mix(in srgb, var(--semantic-success) 26%, var(--bg-surface)); color: var(--semantic-success); }
.stat-icon-chip-warning { background: color-mix(in srgb, var(--semantic-warning) 26%, var(--bg-surface)); color: var(--semantic-warning); }
.stat-icon-chip-danger { background: color-mix(in srgb, var(--semantic-danger) 24%, var(--bg-surface)); color: var(--semantic-danger); }
/* Pill neutro por padrão — só ganha cor quando é de fato uma alta/queda
   real (.trend-up/.trend-down, atribuída via JS em renderVariacao). Antes
   era sempre verde, mesmo pra texto neutro tipo "1 inativo(s)". */
.stat-trend {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  font-size: 11px;
  margin-top: 4px;
  padding: 3px 9px;
  border-radius: 20px;
  font-weight: 700;
  background: var(--bg-surface-elevated);
  color: var(--text-secondary);
}
.stat-trend.trend-up { background: color-mix(in srgb, var(--semantic-success) 15%, transparent); color: var(--semantic-success); }
.stat-trend.trend-down { background: color-mix(in srgb, var(--semantic-danger) 15%, transparent); color: var(--semantic-danger); }
.stat-period { font-size: 10.5px; color: var(--text-secondary); margin: 2px 0 0; }
.stat-spark { display: flex; align-items: flex-end; gap: 3px; height: 28px; margin-top: 4px; }
.stat-spark span { flex: 1; border-radius: 3px 3px 0 0; background: var(--bg-surface-elevated); }
.stat-spark span.hi { background: var(--brand-navy); }

.resumo-financeiro { display: flex; flex-direction: column; }
.resumo-linha {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: var(--space-2) 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-default);
}
.resumo-linha strong { font-variant-numeric: tabular-nums; color: var(--text-primary); font-weight: var(--font-semibold); }
.resumo-linha.total { border-bottom: none; padding-top: var(--space-3); font-weight: var(--font-semibold); color: var(--text-primary); }
.resumo-linha.total strong { font-size: var(--text-md); font-weight: var(--font-bold); }
.resumo-nota { margin: var(--space-3) 0 0; font-size: var(--text-xs); color: var(--text-secondary); }

/* ---------- Lista de boletos (boletos.html) ----------
   Componente novo, sob medida — NÃO é uma <table>. Linhas separadas por
   hairline dentro de um único container (borda só no container, não por
   linha) — é isso que dá o ar Stripe/Mercury em vez de "tabela pesada". */
.boleto-list {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
.boleto-row {
  display: grid;
  grid-template-columns: 40px 1fr 110px 100px 100px auto;
  grid-template-areas: "icon main valor vencimento status actions";
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-bottom: 1px solid var(--border-default);
}
.boleto-row:last-child { border-bottom: none; }
.boleto-row:hover { background: var(--bg-surface-elevated); }
.boleto-row-icon {
  grid-area: icon;
  width: 40px; height: 40px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface-elevated);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-secondary);
}
.boleto-row-icon .icon { width: 18px; height: 18px; }
.boleto-row-main { grid-area: main; min-width: 0; }
.boleto-row-competencia { margin: 0; font-size: var(--text-base); font-weight: var(--font-semibold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.boleto-row-tipo { margin: 2px 0 0; font-size: var(--text-xs); color: var(--text-secondary); }
.boleto-row-valor {
  grid-area: valor;
  text-align: right;
  font-size: var(--text-base);
  font-weight: var(--font-bold);
  font-variant-numeric: tabular-nums;
}
.boleto-row-valor .moeda { font-size: 70%; font-weight: var(--font-medium); color: var(--text-secondary); margin-right: 2px; }
.boleto-row-vencimento { grid-area: vencimento; text-align: right; font-size: var(--text-xs); color: var(--text-secondary); }
/* Bug real de mobile encontrado: quando um boleto tem os dois selos (status
   + "Pagamento avisado"), eles ficavam lado a lado (row, o padrão do flex) —
   no grid compacto do celular, a coluna "status" é "auto" (só a largura do
   que tem dentro), então dois selos juntos ficavam bem largos e espremiam a
   competência do boleto até truncar ("Set..." em vez de "Setembro de
   2026"). Empilhado (column) em vez de lado a lado, a coluna "status" nunca
   fica mais larga que o selo individual mais largo — sobra espaço pro
   título em qualquer largura de tela. */
.boleto-row-status { grid-area: status; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.boleto-row-actions { grid-area: actions; display: flex; gap: var(--space-1); }

@media (max-width: 640px) {
  .boleto-list { background: none; border: none; }
  .boleto-row {
    grid-template-columns: 40px 1fr auto;
    grid-template-areas:
      "icon main status"
      "valor valor vencimento"
      "actions actions actions";
    row-gap: var(--space-2);
    padding: var(--space-4);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-3);
  }
  .boleto-row:last-child { margin-bottom: 0; }
  .boleto-row-valor { text-align: left; font-size: var(--text-md); }
  .boleto-row-actions { margin-top: var(--space-2); }
  .boleto-row-actions .btn { flex: 1; }
}

/* ---------- Chips de filtro por status (boletos.html) ---------- */
.status-chip-row { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-5); }

/* ---------- Medidor de força de senha (primeiro-acesso / redefinir-senha) ---------- */
.senha-forca-bar { display: flex; gap: 4px; margin: var(--space-2) 0; }
.senha-forca-bar-seg { height: 4px; flex: 1; border-radius: 2px; background: var(--bg-surface-elevated); }
.senha-forca-bar-seg.on.danger { background: var(--semantic-danger); }
.senha-forca-bar-seg.on.warning { background: var(--semantic-warning); }
.senha-forca-bar-seg.on.ok { background: var(--semantic-success); }
.senha-forca-label { font-size: var(--text-xs); font-weight: var(--font-semibold); min-height: 16px; }
.senha-forca-label.danger { color: var(--semantic-danger); }
.senha-forca-label.warning { color: var(--semantic-warning); }
.senha-forca-label.ok { color: var(--semantic-success); }
.senha-criterios { list-style: none; padding: 0; margin: var(--space-4) 0 0; display: flex; flex-direction: column; gap: var(--space-1); }
.senha-criterio { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--text-secondary); }
.senha-criterio.ok { color: var(--semantic-success); }
.senha-criterio .icon { width: 14px; height: 14px; flex-shrink: 0; }

/* ---------- Documentos (drive-like) ---------- */
.documentos-layout { display: flex; gap: var(--space-8); align-items: flex-start; }
.doc-categories { display: flex; flex-direction: column; gap: var(--space-1); width: 200px; flex-shrink: 0; }
.doc-cat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  color: var(--text-secondary);
  cursor: pointer;
}
.doc-cat-item:hover { background: var(--bg-surface-elevated); }
.doc-cat-item.active { background: var(--bg-surface-elevated); color: var(--brand-navy); font-weight: var(--font-semibold); }
.doc-cat-count { font-size: var(--text-2xs); color: var(--text-secondary); }
.doc-main { flex: 1; min-width: 0; }

/* Linha de arquivo no estilo Drive/Dropbox: ícone + nome/meta (categoria ·
   data) numa linha só que quebra sozinha, sem colunas fixas de vencimento/
   status (documento comum não tem nenhum dos dois). */
.drive-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-default);
}
.drive-row:last-child { border-bottom: none; }
.drive-row:hover { background: var(--bg-surface-elevated); }
.drive-row-icon {
  width: 36px; height: 36px;
  border-radius: var(--radius-sm);
  background: var(--bg-surface-elevated);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.drive-row-icon .icon { width: 16px; height: 16px; }
.drive-row-main { flex: 1; min-width: 0; }
.drive-row-nome { margin: 0; font-size: var(--text-base); font-weight: var(--font-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.drive-row-meta { display: flex; align-items: center; gap: var(--space-2); margin-top: 2px; }
.drive-row-cat { font-size: var(--text-2xs); color: var(--text-secondary); background: var(--bg-surface-elevated); padding: 2px 8px; border-radius: 100px; white-space: nowrap; }
.drive-row-date { font-size: var(--text-xs); color: var(--text-secondary); white-space: nowrap; }
.drive-row-kebab, .drive-row-delete { flex-shrink: 0; }

/* ---------- Documentos agrupados por Ano / Mês / Dia ---------- */
.date-group-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  user-select: none;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
}
.date-group-header:hover { background: var(--bg-surface-elevated); }
.date-group-header:focus-visible { outline: 2px solid var(--brand-navy); outline-offset: -2px; }
.date-group-header.year, .date-group-header.client { font-size: var(--text-lg); font-weight: var(--font-bold); margin-top: var(--space-3); }
.date-group-header.month { font-size: var(--text-base); font-weight: var(--font-semibold); margin-left: var(--space-5); }
.date-group-header.day { font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--text-secondary); margin-left: var(--space-8); cursor: default; }
.date-group-chevron { display: flex; flex-shrink: 0; transition: transform 0.15s ease; color: var(--text-secondary); }
.date-group-chevron .icon { width: 14px; height: 14px; }
.date-group-header.collapsed .date-group-chevron { transform: rotate(-90deg); }
.date-group-count {
  margin-left: auto;
  font-size: var(--text-2xs);
  color: var(--text-secondary);
  background: var(--bg-surface-elevated);
  padding: 2px 8px;
  border-radius: 100px;
  white-space: nowrap;
}
.date-group-body.month-body { margin-left: var(--space-5); }
.date-group-body.day-body { margin-left: var(--space-8); }
.date-group-body.collapsed { display: none; }
@media (max-width: 640px) {
  .date-group-header.month { margin-left: var(--space-3); }
  .date-group-header.day { margin-left: var(--space-5); }
  .date-group-body.month-body { margin-left: var(--space-3); }
  .date-group-body.day-body { margin-left: var(--space-5); }
}

/* Data de envio + data de recebimento deixaram a meta de cada linha bem mais
   longa ("PDF · 99 KB · Enviado em 07/09/2026 · Aguardando análise") — no
   mobile isso não cabe mais numa linha só e o .drive-row (flex, sem wrap)
   empurrava o modal inteiro pra fora, exigindo rolagem horizontal. */
@media (max-width: 640px) {
  .drive-row-meta { flex-wrap: wrap; row-gap: 2px; }
  .drive-row-date { white-space: normal; }
}

/* Mesmo agrupamento, mas quando vira uma linha de <table> (painel do admin)
   em vez de um cartão de lista (documentos.html do cliente) — a célula não
   pode manter o padding padrão de td, senão soma com o padding do cabeçalho
   e a linha fica desproporcionalmente alta. */
.date-group-row td { padding: 0; }
.date-group-row.ano .date-group-header, .date-group-row.cliente .date-group-header { background: var(--bg-surface-elevated); }
.date-group-row.mes .date-group-header { background: color-mix(in srgb, var(--bg-surface-elevated) 55%, transparent); }
.date-group-row .date-group-header.year, .date-group-row .date-group-header.month, .date-group-row .date-group-header.client { border-radius: 0; margin-top: 0; }

@media (max-width: 860px) {
  .documentos-layout { flex-direction: column; gap: var(--space-4); }
  .doc-categories { flex-direction: row; overflow-x: auto; white-space: nowrap; width: 100%; max-width: 100%; gap: var(--space-2); padding-bottom: var(--space-2); }
  .doc-cat-item { flex-shrink: 0; }
}

.activity-item.urgent .dot-icon { background: var(--semantic-warning-bg); color: var(--semantic-warning); }

/* ---------- Painel "Precisa de atenção" consolidado (admin) ---------- */
.attention-panel-section + .attention-panel-section { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--border-default); }
.attention-panel-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-secondary); margin: 0 0 10px; }
.upcoming-empty { font-size: 12.5px; color: var(--text-secondary); }

/* ---------- Dashboard layout ---------- */
.dashboard-layout { display: grid; grid-template-columns: 1fr 320px; gap: 24px; align-items: start; }
.dashboard-main { min-width: 0; container-type: inline-size; container-name: dashmain; }

.section-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin: 0 0 14px;
}

/* ---------- Cliente: faixa de urgência ----------
   Propositalmente NÃO segue o mesmo raio/sombra dos cards do grid —
   precisa parecer estruturalmente diferente, não só "mais um card colorido". */
.urgent-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  background: var(--semantic-warning);
  border-radius: 10px;
  padding: 16px 20px;
  margin-bottom: 24px;
}
[data-theme="dark"] .urgent-banner { background: color-mix(in srgb, var(--semantic-warning) 80%, black); }
.urgent-banner-icon {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: rgba(255,255,255,0.22);
  color: #FFFFFF;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.urgent-banner-text { flex: 1; min-width: 0; }
.urgent-banner-text p { margin: 0 0 2px; font-size: 14px; font-weight: 800; color: #FFFFFF; }
.urgent-banner-text span { font-size: 12.5px; color: rgba(255,255,255,0.85); }
.urgent-banner .btn-primary { background: #FFFFFF; color: var(--semantic-warning); flex-shrink: 0; }
.urgent-banner .btn-primary:hover { background: rgba(255,255,255,0.9); }

/* Categoria com algo urgente: peso visual diferente das demais, não só um badge */
.cat-card-urgent { border-color: var(--semantic-warning); border-width: 1.5px; background: var(--semantic-warning-bg); }
.cat-card-urgent .cat-icon { background: var(--bg-surface); color: var(--semantic-warning); }

.unseen-tag {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--semantic-warning);
  background: var(--semantic-warning-bg);
  border-radius: 100px;
  padding: 1px 6px;
  margin-left: 4px;
  vertical-align: middle;
}

/* ---------- Cliente: card de ajuda/contato ---------- */
.help-card { background: var(--bg-surface-elevated); border-style: dashed; }
.help-text { margin: 0 0 14px; font-size: 12.5px; color: var(--text-secondary); line-height: 1.5; }
.help-contact {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 10px;
}
.help-contact-icon {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  display: flex; align-items: center; justify-content: center;
  color: var(--brand-navy);
  flex-shrink: 0;
}
.help-contact-icon .icon { width: 12px; height: 12px; }
.help-hours { margin: 4px 0 0; font-size: 11.5px; color: var(--text-secondary); }

/* ---------- Cliente: card de ajuda/contato ---------- */
.help-card { background: var(--bg-surface-elevated); border-style: dashed; }
.help-text { margin: 0 0 14px; font-size: 12.5px; color: var(--text-secondary); line-height: 1.5; }
.help-contact {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 10px;
}
.help-contact-icon {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  display: flex; align-items: center; justify-content: center;
  color: var(--brand-navy);
  flex-shrink: 0;
}
.help-contact-icon .icon { width: 12px; height: 12px; }
.help-hours { margin: 4px 0 0; font-size: 11.5px; color: var(--text-secondary); }

/* Cards inside the main column adapt to the column's real width
   (which shrinks once the sidebar appears) rather than the viewport. */
@container dashmain (max-width: 520px) {
  .page-header-flex > div:last-child { width: 100%; }
  .page-header-flex .btn { flex: 1; }
}

.side-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  padding: 20px;
  margin-bottom: 20px;
}
.side-card-head { margin-bottom: 14px; }
.side-card-head h3 { margin: 0; font-size: 14px; font-weight: 700; }

.attention-list { display: flex; flex-direction: column; gap: 10px; }
.attention-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: 10px;
  background: var(--bg-surface-elevated);
  cursor: pointer;
  transition: background 0.12s ease;
}
.attention-item:hover { background: var(--semantic-warning-bg); }
.attention-item .dot-icon {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--semantic-warning-bg);
  color: var(--semantic-warning);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.attention-item .dot-icon .icon { width: 14px; height: 14px; }
/* Texto cresce pra ocupar o espaço disponível — sem isso a linha inteira
   (fundo, hover) ficava larga mas o conteúdo ficava todo espremido à
   esquerda, com uma faixa vazia enorme à direita até o badge/botão. */
.attention-item-texto { flex: 1; min-width: 0; }
.attention-item .status-badge, .attention-item .cat-attach-btn { flex-shrink: 0; }
/* Vencido é mais grave que vencendo — precisa ler diferente à distância, não
   só no texto. Sem isso os dois casos ficam com o mesmo peso visual (mesmo
   ícone laranja), que é exatamente o tipo de ambiguidade que compromete a
   experiência (um item já vencido não deveria parecer só "mais um aviso"). */
.attention-item.danger:hover { background: color-mix(in srgb, var(--semantic-danger) 12%, var(--bg-surface)); }
.attention-item.danger .dot-icon { background: color-mix(in srgb, var(--semantic-danger) 15%, var(--bg-surface)); color: var(--semantic-danger); }
.attention-item p { margin: 0; font-size: 12.5px; font-weight: 600; line-height: 1.4; }
.attention-item span { font-size: 11px; color: var(--text-secondary); }
.attention-empty { font-size: 12.5px; color: var(--text-secondary); padding: 4px 2px; }

/* ---------- Próximos vencimentos: identidade própria (data + prazo), não um feed genérico ---------- */
.due-list { display: flex; flex-direction: column; gap: 8px; }
.due-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background 0.12s ease;
}
.due-item:hover { background: var(--bg-surface-elevated); }
.due-item-date {
  width: 42px; height: 42px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  line-height: 1.1;
}
.due-item-date strong { font-size: 14px; font-weight: 800; }
.due-item-date span { font-size: 9px; color: var(--text-secondary); text-transform: uppercase; }
.due-item.urgent .due-item-date { border-color: var(--semantic-warning); background: var(--semantic-warning-bg); color: var(--semantic-warning); }
.due-item.danger .due-item-date { border-color: var(--semantic-danger); background: color-mix(in srgb, var(--semantic-danger) 15%, var(--bg-surface)); color: var(--semantic-danger); }
.due-item-info { flex: 1; min-width: 0; }
.due-item-info p { margin: 0 0 2px; font-size: 12.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.due-item-info span { font-size: 11px; color: var(--text-secondary); }
.due-item-badge {
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 100px;
  background: var(--bg-surface-elevated);
  color: var(--text-secondary);
  flex-shrink: 0;
  white-space: nowrap;
}
.due-item.urgent .due-item-badge { background: var(--semantic-warning-bg); color: var(--semantic-warning); }
.due-item.danger .due-item-badge { background: color-mix(in srgb, var(--semantic-danger) 15%, var(--bg-surface)); color: var(--semantic-danger); }

.activity-feed { display: flex; flex-direction: column; }
.activity-item {
  display: flex;
  gap: 10px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--border-default);
}
.activity-item:last-child { border-bottom: none; padding-bottom: 0; }
.activity-item .dot-icon {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--bg-surface-elevated);
  color: var(--brand-navy);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.activity-item .dot-icon .icon { width: 13px; height: 13px; }
.activity-item p { margin: 0; font-size: 12.5px; line-height: 1.4; }
.activity-item p strong { font-weight: 700; }
.activity-item span { font-size: 11px; color: var(--text-secondary); }

@media (max-width: 1024px) {
  .dashboard-layout { grid-template-columns: 1fr; }
}

/* ---------- Chart card ---------- */
.chart-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  padding: 24px 26px;
  margin-bottom: 28px;
}
.chart-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 22px; flex-wrap: wrap; gap: 10px; }
.chart-head h3 { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.chart-head p { margin: 0; font-size: 12px; color: var(--text-secondary); }
/* Virou uma linha de mini-cards (um por status: Pago/Pendente/Vencido) em
   vez de texto corrido -- pedido explícito da Lorena com base numa
   referência visual, pra cada número ficar com mais destaque próprio. */
.chart-legend { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.chart-legend-item { display: flex; flex-direction: column; gap: 3px; background: var(--bg-surface-elevated); border-radius: var(--radius-md); padding: 9px 14px; }
.chart-legend-dot-row { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-secondary); }
.chart-legend .dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.chart-legend-num { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
.chart-legend-val { font-size: 10.5px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }

/* ---------- Gráfico de linha: receita ao longo do tempo ---------- */
.line-chart-wrap { position: relative; }
.line-chart { width: 100%; height: 200px; display: block; overflow: visible; }
.linha-receita-ponto { transition: r 0.12s ease; cursor: pointer; }
.linha-receita-ponto:hover { r: 5.5; }
.line-chart-tooltip {
  position: absolute;
  display: none;
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: var(--shadow-sm);
  z-index: 5;
}

/* ---------- Barra empilhada: status dos boletos ---------- */
.stacked-bar { display: flex; height: 18px; border-radius: 100px; overflow: hidden; background: var(--bg-surface-elevated); }
.stacked-bar-segment { height: 100%; transition: width 0.4s ease; }
.stacked-bar-segment:not(:last-child) { border-right: 2px solid var(--bg-surface); }

/* ---------- Visão geral: layout dos 2 gráficos lado a lado ----------
   align-items:stretch (o padrão do grid, por isso nem precisa declarar) --
   pedido explícito da Lorena pra "Status dos boletos" ficar com a MESMA
   altura de "Receita ao longo do tempo", não só uma altura parecida. */
.dashboard-charts-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 1024px) {
  .dashboard-charts-row { grid-template-columns: 1fr; }
}

/* ---------- KPI: variação real vs mês anterior ---------- */
.trend-up { color: var(--semantic-success); font-weight: 700; }
.trend-down { color: var(--semantic-danger); font-weight: 700; }

/* ---------- Visão Geral: visual mais reto/denso, só nesta tela ----------
   Achata só aqui (via custom property em cascata) em vez de mudar
   --radius-md/--radius-lg globais — os mesmos .stat-card/.side-card são
   usados em Clientes/Financeiro/Detalhe, que não foram pedidos pra
   mudar. Remove também o gradiente decorativo do .stat-card, só nesta
   tela — cartão plano, mais denso, sem "cara de template". */
#tab-visao-geral {
  --radius-md: 4px;
  --radius-lg: 6px;
}
#tab-visao-geral .stat-card {
  background: var(--bg-surface);
  padding: 14px 16px;
  gap: 2px;
}
/* Os 2 KPIs "hero" são a única exceção ao "sem gradiente" desta tela --
   pedido explícito da Lorena (tingimento sutil da própria cor, com base
   numa referência visual). Precisa do #tab-visao-geral pra vencer a regra
   flat logo acima (mesma especificidade por ID). */
#tab-visao-geral .stat-card-hero.tint-navy { background: linear-gradient(135deg, color-mix(in srgb, var(--brand-navy) 13%, var(--bg-surface)) 0%, var(--bg-surface) 62%); }
#tab-visao-geral .stat-card-hero.tint-warning { background: linear-gradient(135deg, color-mix(in srgb, var(--semantic-warning) 16%, var(--bg-surface)) 0%, var(--bg-surface) 62%); }
#tab-visao-geral .stat-card-hero { padding: 18px 20px; }
#tab-visao-geral .chart-card { padding: 18px 20px; margin-bottom: 0; }
/* Espaçamento vertical mais apertado só nesta tela -- pedido da Lorena
   ("sobe um pouquinho a Atenção do dia, não fica visível quando entro na
   Visão geral"): sem isso, os KPIs + os 2 gráficos empurravam a faixa pra
   fora da primeira dobra. Gráfico de linha um pouco mais baixo (era 200px)
   e as margens entre as fileiras encolhidas. */
#tab-visao-geral .stats-row-hero { margin-bottom: 10px; }
#tab-visao-geral .stats-row { margin-bottom: 12px; }
/* 150px tinha ficado apertado demais (rótulos de valor grudando no topo);
   voltou pra 182px -- perto do original (200px), mas ainda economizando
   um pouco de altura pra "Atenção do dia" continuar visível na entrada.
   "Status dos boletos" acompanha a altura automaticamente (grid stretch). */
#tab-visao-geral .line-chart { height: 182px; }
#tab-visao-geral .chart-head { margin-bottom: 14px; }
#tab-visao-geral .group-metric { padding: 12px 18px; }
#tab-visao-geral .atencao-dia { margin-top: 14px; }
/* "Status dos boletos" fica com a MESMA altura de "Receita ao longo do
   tempo" ao lado -- pedido explícito da Lorena (.dashboard-charts-row usa
   align-items:stretch, o padrão do grid, então os 2 cards da linha sempre
   ficam do tamanho do mais alto). Só que "Status dos boletos" tem bem menos
   conteúdo (uma barra + a legenda) que o gráfico ao lado -- em vez de
   deixar a sobra de altura como um vão vazio grudado embaixo, o cabeçalho
   fica no topo (pra alinhar com o título do card vizinho) e o resto do
   espaço vira flex:1 com o conteúdo (.chart-card-boletos-body) centralizado
   dentro dele, distribuindo a sobra em cima e embaixo da barra/legenda em
   vez de sobrar tudo de um lado só. */
.chart-card-boletos { display: flex; flex-direction: column; }
.chart-card-boletos .chart-head { flex-shrink: 0; }
.chart-card-boletos-body { flex: 1; display: flex; flex-direction: column; justify-content: center; }
/* Label/valor/tendência/hover viraram regra global (.stat-card etc., acima)
   — aplicada em Financeiro e Configurações também, não só aqui. */

/* ---------- Visão Geral: gráficos com um pouco mais de "dado", sem
   reintroduzir o gradiente decorativo que já foi removido dos cards ---------- */
#tab-visao-geral .chart-head h3 { font-size: 15px; letter-spacing: -0.01em; }
/* Barra mais fina/discreta (era 42px) -- pedido explícito com base na
   referência visual; pill nas pontas já era assim, continua. */
#tab-visao-geral .stacked-bar { height: 18px; border-radius: 100px; }
#tab-visao-geral .stacked-bar-segment:first-child { border-top-left-radius: 100px; border-bottom-left-radius: 100px; }
#tab-visao-geral .stacked-bar-segment:last-child { border-top-right-radius: 100px; border-bottom-right-radius: 100px; }
#tab-visao-geral .chart-legend .dot { width: 7px; height: 7px; }

/* ---------- Empty state ---------- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-12) var(--space-5);
  color: var(--text-secondary);
}
.empty-state .icon { width: 18px; height: 18px; margin-bottom: var(--space-3); opacity: 0.7; }
.empty-state h3 { color: var(--text-primary); margin: 0 0 var(--space-1); font-size: var(--text-base); font-weight: var(--font-semibold); }
.empty-state p { margin: 0; font-size: var(--text-sm); max-width: 360px; }

/* ---------- Toast ---------- */
#toast-host { position: fixed; bottom: 24px; left: 24px; display: flex; flex-direction: column; gap: 10px; z-index: 100; }
.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-left: 3px solid var(--semantic-success);
  border-radius: 10px;
  padding: 12px 16px;
  box-shadow: var(--shadow-md);
  font-size: 13px;
  animation: fadeUp 0.2s ease both;
  min-width: 240px;
}
.toast .icon { width: 16px; height: 16px; color: var(--semantic-success); flex-shrink: 0; }

/* ---------- Preview modal ---------- */
.preview-card { width: 100%; height: 260px; border-radius: 10px; background: var(--bg-surface-elevated); display: flex; align-items: center; justify-content: center; margin-bottom: 16px; color: var(--text-secondary); }
.preview-card .icon { width: 48px; height: 48px; }
.btn-loading .icon { animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Guarda de sessão (evita mostrar a tela real antes de confirmar login) ---------- */
.auth-guard-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--bg-surface);
  display: flex;
  align-items: center;
  justify-content: center;
}
.auth-guard-spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--bg-surface-elevated);
  border-top-color: var(--brand-gold);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

/* ---------- Side panel ---------- */
.panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease;
  z-index: 60;
}
.panel-overlay.open { opacity: 1; visibility: visible; }

.side-panel {
  position: fixed;
  top: 0;
  right: 0;
  height: 100vh;
  width: 440px;
  max-width: 92vw;
  background: var(--bg-surface);
  border-left: 1px solid var(--border-default);
  box-shadow: var(--shadow-md);
  transform: translateX(100%);
  transition: transform 0.25s ease;
  z-index: 61;
  display: flex;
  flex-direction: column;
}
.panel-overlay.open .side-panel { transform: translateX(0); }
/* Drawer do detalhe de Impostos pagos: tabela de 4 colunas não cabe bem
   nos 440px padrão (pensados pra formulário de 1 coluna). */
.side-panel-wide { width: 640px; }
.side-panel.resizing { transition: none; user-select: none; }

.panel-resize-handle {
  position: absolute;
  top: 0;
  left: -3px;
  width: 7px;
  height: 100%;
  cursor: ew-resize;
  z-index: 62;
}
.panel-resize-handle::after {
  content: "";
  position: absolute;
  top: 0; left: 3px;
  width: 1px;
  height: 100%;
  background: transparent;
  transition: background 0.12s ease;
}
.panel-resize-handle:hover::after,
.side-panel.resizing .panel-resize-handle::after {
  background: var(--brand-gold-soft);
  width: 2px;
}

.side-panel-header {
  padding: 24px 24px 18px;
  border-bottom: 1px solid var(--border-default);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.panel-title { margin: 0 0 4px; font-size: 18px; font-weight: 800; letter-spacing: -0.2px; }
.panel-subtitle { margin: 0; font-size: 13px; color: var(--text-secondary); }
.side-panel-body {
  padding: 22px 24px;
  overflow-y: auto;
  flex: 1;
}
.side-panel-footer {
  padding: 16px 24px;
  border-top: 1px solid var(--border-default);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.side-panel-footer .btn { flex: 0 0 auto; min-width: 112px; }
/* Secundária com peso reduzido (ghost) para não competir com a ação principal */
.side-panel-footer .btn-secondary {
  background: transparent;
  border-color: transparent;
  color: var(--text-secondary);
}
.side-panel-footer .btn-secondary:hover { background: var(--bg-surface-elevated); border-color: var(--border-default); }

.panel-close {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.panel-close .icon { width: 16px; height: 16px; }

.panel-section-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin: 0 0 12px;
}

.info-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 24px; }
.info-grid .label { margin: 0 0 4px; font-size: 12px; color: var(--text-secondary); }
.info-grid .value { margin: 0; font-size: 14px; font-weight: 600; }

/* Dois campos lado a lado num formulário (ex: Nome/Nome fantasia, E-mail/
   Telefone no painel de Perfil da empresa) — antes era inline style repetido
   sem tratamento de mobile, então em telas estreitas cada campo ficava com
   uns 170px, apertado demais pra digitar e-mail/telefone. */
.field-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 16px; }

/* ---------- Detalhe do cliente (visão central) ---------- */
/* Botão "Voltar" acima do cabeçalho, não dentro dele — não é uma ação
   sobre o cliente, é navegação de volta pra onde o admin estava. */
.detalhe-voltar-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 4px;
  margin-bottom: 14px;
  border: none;
  background: transparent;
}
.detalhe-voltar-btn .icon { width: 15px; height: 15px; }
/* O detalhe do cliente precisa parecer um lugar diferente da lista, não
   só "a mesma tela com um card diferente dentro" — fundo elevado + padding
   generoso fazem ele se destacar do canvas, igual um "modo foco". */
#tab-detalhe-cliente {
  /* Degradê único, contínuo, ao longo de toda a altura do card — não um
     tom "chapado" por seção (isso virava caixa/card, exatamente o que não
     era pra ser). Diferença quase imperceptível entre os stops: só o
     suficiente pra tirar a sensação de página branca infinita, sem nenhuma
     borda visível entre uma seção e outra. */
  background: linear-gradient(
    180deg,
    var(--bg-surface-elevated) 0%,
    color-mix(in srgb, var(--bg-surface-elevated) 95%, var(--bg-surface) 5%) 45%,
    color-mix(in srgb, var(--bg-surface-elevated) 90%, var(--bg-surface) 10%) 75%,
    var(--bg-surface-elevated) 100%
  );
  border-radius: var(--radius-lg);
  padding: 28px 32px 32px;
}
@media (max-width: 700px) {
  #tab-detalhe-cliente { padding: 20px 16px 24px; }
}
.detalhe-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  padding-bottom: 20px;
  margin-bottom: 20px;
  border-bottom: 2px solid var(--brand-navy);
}
.detalhe-header-info { display: flex; flex-direction: column; gap: 4px; }
.detalhe-header-nome-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.detalhe-header-nome-row h2 { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -0.2px; }
.detalhe-header-meta { margin: 0; font-size: 13px; color: var(--text-secondary); }
.detalhe-header-meta-dot { margin: 0 6px; color: var(--border-default); }
/* Indicador de topo — só os 2 números com valor operacional real
   (documentos pendentes, boletos vencidos), como texto, nunca card. */
.detalhe-indicadores { margin: 6px 0 0; font-size: 12.5px; font-weight: 600; color: var(--text-secondary); }
.detalhe-header-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* Ações destrutivas isoladas do resto por um divisor sutil, em vez de só
   confiar na cor vermelha pra separar — reforça a hierarquia sem precisar
   de mais contraste de cor. */
.detalhe-header-actions-destrutivas {
  display: flex;
  gap: 10px;
  padding-left: 14px;
  margin-left: 4px;
  border-left: 1px solid var(--border-default);
}
/* Ação principal do header — compacta e no tom navy da marca: mais peso
   que o "Editar" cinza comum, mas discreta o bastante pra não competir
   com nome/status do cliente ao lado. Outline (não preenchido) e hover
   com um tingimento leve, não uma cor sólida forte. */
.btn-upload-contextual {
  padding: 8px 14px;
  font-size: 13px;
  background: transparent;
  color: var(--brand-navy);
  border: 1px solid var(--brand-navy);
}
.btn-upload-contextual:hover { background: color-mix(in srgb, var(--brand-navy) 10%, transparent); }
.btn-upload-contextual .icon { width: 14px; height: 14px; }
@media (max-width: 900px) {
  .detalhe-header-actions { width: 100%; }
  .detalhe-header-actions .btn { flex: 1 1 auto; }
  .detalhe-header-actions-destrutivas { width: 100%; padding-left: 0; margin-left: 0; border-left: none; }
}

/* Sub-abas do detalhe usam o MESMO componente .status-chip-row/.period-chip
   das sub-abas de Clientes — sem diferença nenhuma, as duas telas liam como
   "a mesma tela". Aqui ganham um tratamento de aba sublinhada (em vez de
   chip/pill), reforçando que é outro modo de navegação. */
#detalhe-subtabs.status-chip-row { gap: 4px; border-bottom: 1px solid var(--border-default); }
#detalhe-subtabs .period-chip {
  background: transparent;
  border: none;
  border-radius: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: 10px 6px;
}
#detalhe-subtabs .period-chip:hover { border-color: var(--border-default); color: var(--text-primary); }
#detalhe-subtabs .period-chip.active {
  background: transparent;
  color: var(--brand-navy);
  border-bottom-color: var(--brand-navy);
}
/* Pedido explícito: tirar todo o "fixado" da página — essa nav volta a
   rolar normal junto com o resto do conteúdo, sem grudar no topo.
   "relative" (não "static") de propósito: a barra de progresso de scroll
   (.detalhe-scroll-progress, logo abaixo) é position:absolute e precisa
   de um ancestral posicionado pra se ancorar embaixo desta nav — com
   "static" ela perdia essa referência e ia se pendurar no ancestral
   posicionado mais próximo lá em cima na árvore (ou no body), reaparecendo
   como uma linha solta no meio do conteúdo, bem longe de onde devia ficar.
   "relative" não gruda em lugar nenhum ao rolar (mesmo comportamento visual
   de "static" pro layout), só devolve a referência de posicionamento. */
.detalhe-nav-sticky {
  position: relative;
  background: var(--bg-surface-elevated);
  padding-top: 4px;
}

/* ---------- Detalhe: seções da página única ---------- */
/* scroll-margin-top vai na própria seção (é ela que scrollIntoView() alvo),
   não no título — senão não tem efeito nenhum. Cada seção precisa ler como
   um bloco funcional próprio, não só um <h3> solto em cima de espaço vazio
   — a borda superior marca onde uma seção termina e a próxima começa mesmo
   quando o conteúdo dela é curto (Dados cadastrais, Pendências sem nada
   pendente etc. ficam compactas de propósito, não "flutuando" no meio de
   espaço em branco). */
.detalhe-secao { padding: 32px 0 4px; border-top: 1px solid var(--border-default); scroll-margin-top: 56px; }
.detalhe-secao:first-of-type { padding-top: 24px; border-top: none; }
.detalhe-secao-titulo {
  margin: 0 0 18px;
  padding-bottom: 10px;
  padding-left: 10px;
  border-bottom: 1px solid var(--border-default);
  border-left: 3px solid var(--brand-navy);
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -0.1px;
  color: var(--text-primary);
}
/* Barra de progresso fina dentro da nav sticky — só a peça de JS nova
   desta fase (largura = % de scroll pela página do cliente), discreta,
   sem competir com os chips de navegação. */
.detalhe-scroll-progress {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--border-default);
}
.detalhe-scroll-progress::after {
  content: "";
  display: block;
  height: 100%;
  width: var(--detalhe-scroll-pct, 0%);
  background: var(--brand-navy);
  transition: width 0.1s linear;
}
#detalhe-boletos-period-presets { margin-bottom: 12px; }
.detalhe-financeiro-resumo {
  margin: 0 0 16px;
  font-size: 13px;
  color: var(--text-secondary);
}
.detalhe-financeiro-resumo strong { color: var(--text-primary); font-weight: 700; }
.detalhe-fin-danger { color: var(--semantic-danger) !important; }

/* ---------- Detalhe: Histórico (linha do tempo de eventos) ---------- */
.timeline-list { display: flex; flex-direction: column; }
.timeline-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border-default);
  font-size: 13.5px;
  transition: background 0.12s ease;
}
.timeline-item:last-child { border-bottom: none; }
.timeline-item:hover { background: var(--bg-surface-elevated); }
.timeline-data { flex-shrink: 0; font-weight: 700; color: var(--text-primary); min-width: 130px; }
.timeline-seta { flex-shrink: 0; color: var(--text-secondary); }
.timeline-texto { color: var(--text-secondary); }

/* Filtro de contexto dentro da seção Documentos do Detalhe — pill preenchida
   (não sublinhado) de propósito, pra não se confundir visualmente com a nav
   de âncoras do topo da página (essa é hierarquia inferior, escopada só a
   esta seção). */
.docs-filtro-row { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.docs-filtro-chip {
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: 100px;
}
.docs-filtro-chip:hover { border-color: var(--brand-navy); color: var(--text-primary); }
.docs-filtro-chip.active { background: var(--brand-navy); border-color: var(--brand-navy); color: #FFFFFF; }
.docs-filtro-count { margin-left: 3px; opacity: 0.85; }

/* ---------- Toolbar (busca + ação em lote) ---------- */
.docs-toolbar { display: flex; gap: 12px; margin-bottom: 14px; }
.docs-search {
  flex: 1;
  max-width: 420px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface-elevated);
}
.docs-search span { display: flex; color: var(--text-secondary); flex-shrink: 0; }
.docs-search input {
  flex: 1;
  border: none;
  background: transparent;
  padding: 10px 0;
  font-size: 13.5px;
  color: var(--text-primary);
  font-family: inherit;
}
.docs-search input:focus { outline: none; }
.docs-toolbar #docs-download-all { margin-left: auto; }

/* ---------- Presets de período ---------- */
.period-presets { display: flex; gap: 6px; }
.period-chip {
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-secondary);
  font-size: 12.5px;
  font-weight: 600;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.period-chip:hover { border-color: var(--brand-navy); }
.period-chip.active { background: var(--brand-navy); border-color: var(--brand-navy); color: #FFFFFF; }

/* ---------- Toggle "Só novidades" ---------- */
.filter-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  margin-bottom: 1px;
}
.filter-toggle input { display: none; }
.filter-toggle-track {
  width: 32px; height: 18px;
  border-radius: 100px;
  background: var(--border-default);
  position: relative;
  transition: background 0.15s ease;
  flex-shrink: 0;
}
.filter-toggle-track::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #FFFFFF;
  transition: transform 0.15s ease;
}
.filter-toggle input:checked + .filter-toggle-track { background: var(--brand-navy); }
.filter-toggle input:checked + .filter-toggle-track::after { transform: translateX(14px); }

/* ---------- Status badge (boletos e documentos) ---------- */
.status-badge {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 100px;
}
.status-badge.danger { background: color-mix(in srgb, var(--semantic-danger) 15%, var(--bg-surface)); color: var(--semantic-danger); }
.status-badge.warning { background: var(--semantic-warning-bg); color: var(--semantic-warning); }
.status-badge.ok { background: color-mix(in srgb, var(--semantic-success) 15%, var(--bg-surface)); color: var(--semantic-success); }
.status-badge.neutral { background: var(--bg-surface-elevated); color: var(--text-secondary); }

/* "Obrigatório" (documentos.html, cliente) — antes era só texto solto
   "(obrigatória)" ao lado do nome, do mesmo peso/cor do resto, quase
   invisível numa lista de várias categorias. Virou um selo separado, no
   mesmo padrão visual do .status-badge (pill + fundo tingido), pra chamar
   atenção sem se confundir com o badge de status (Pendente/Aprovado/etc). */
.badge-obrigatorio {
  display: inline-flex;
  align-items: center;
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 100px;
  background: color-mix(in srgb, var(--brand-gold) 16%, var(--bg-surface));
  color: var(--brand-gold);
  flex-shrink: 0;
}

/* ---------- Menu de ações por linha (kebab) ---------- */
.doc-menu-panel, .team-menu-panel {
  width: 210px;
  top: calc(100% + 4px);
}
.doc-menu-panel.open, .team-menu-panel.open { display: block; }
/* Linha perto do fim de um container pequeno (ex: tabela de documentos
   dentro do painel de detalhamento de categoria) -- o clique no "..." já
   mede se o menu cabe abaixo e, se não couber, some essa classe pra abrir
   pra cima em vez de pra baixo. */
.doc-menu-panel.abre-para-cima { top: auto; bottom: calc(100% + 4px); }

/* ---------- Centro de equipe e acessos ---------- */
.avatar-status-wrap { position: relative; flex-shrink: 0; }
.status-dot-ring {
  position: absolute;
  bottom: -2px; right: -2px;
  width: 12px; height: 12px;
  border-radius: 50%;
  border: 2px solid var(--bg-surface);
  background: var(--text-secondary);
}
.status-dot-ring.online { background: var(--semantic-success); }
.status-dot-ring.offline { background: var(--text-secondary); }

.member-cell { display: flex; align-items: center; gap: 12px; }
.member-cell .avatar { width: 34px; height: 34px; font-size: 13px; }
.member-name-row { display: flex; align-items: center; gap: 6px; }
.member-name-row strong { font-size: 13px; }
.member-email { font-size: 11.5px; color: var(--text-secondary); margin-top: 1px; }

.role-badge {
  display: inline-flex;
  align-items: center;
  font-size: 11.5px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 100px;
}
.role-badge.proprietario { background: color-mix(in srgb, var(--brand-gold) 18%, var(--bg-surface)); color: var(--brand-gold); }
.role-badge.administrador { background: color-mix(in srgb, var(--brand-navy) 14%, var(--bg-surface)); color: var(--brand-navy); }
.role-badge.colaborador { background: var(--bg-surface-elevated); color: var(--text-secondary); }

.status-line { display: flex; flex-direction: column; gap: 2px; }
.status-line-top { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; }
.status-line-top .dot { width: 7px; height: 7px; border-radius: 50%; }
.status-line span.muted { font-size: 11px; color: var(--text-secondary); }

.twofa-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 700; }
.twofa-badge.on { color: var(--semantic-success); }
.twofa-badge.off { color: var(--text-secondary); }
.twofa-badge .icon { width: 13px; height: 13px; }

.invite-row td { color: var(--text-secondary); }

.session-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-default);
  background: var(--bg-surface);
}
.session-item .dot-icon { width: 28px; height: 28px; }
.session-item-info { flex: 1; min-width: 0; }
.session-item-info p { margin: 0; font-size: 12.5px; font-weight: 600; }
.session-item-info span { font-size: 11px; color: var(--text-secondary); }
.session-current-tag {
  font-size: 9.5px;
  font-weight: 800;
  text-transform: uppercase;
  color: var(--semantic-success);
  background: color-mix(in srgb, var(--semantic-success) 15%, var(--bg-surface));
  border-radius: 100px;
  padding: 2px 7px;
}
.session-revoke-btn {
  border: none;
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  flex-shrink: 0;
}
.session-revoke-btn:hover { background: var(--semantic-warning-bg); color: var(--semantic-danger); }
.session-revoke-btn .icon { width: 13px; height: 13px; }

.danger-zone {
  border: 1px solid color-mix(in srgb, var(--semantic-danger) 30%, var(--border-default));
  border-radius: var(--radius-md);
  padding: 14px;
  background: color-mix(in srgb, var(--semantic-danger) 5%, var(--bg-surface));
}

/* ---------- Filter bar (Documentos enviados) ---------- */
.filter-bar {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xs);
  padding: 16px 18px;
  margin-bottom: 16px;
}
.filter-bar-row { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; }
.filter-field { display: flex; flex-direction: column; gap: 6px; }
.filter-field label { font-size: 11.5px; font-weight: 700; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.3px; }
.filter-field .select-like { width: 210px; }

.filter-date-range {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 0 10px;
}
.filter-date-range input[type="date"] {
  border: none;
  background: transparent;
  padding: 10px 0;
  font-size: 13px;
  color: var(--text-primary);
  font-family: inherit;
  width: 124px;
}
.filter-date-range input[type="date"]:focus { outline: none; }
.filter-date-range span { font-size: 12px; color: var(--text-secondary); flex-shrink: 0; }

.filter-bar #docs-filter-clear { margin-left: auto; }

.filter-bar-summary {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-default);
}
.filter-bar-summary:empty { display: none; }
.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--brand-navy);
  background: color-mix(in srgb, var(--brand-navy) 8%, var(--bg-surface));
  border: 1px solid color-mix(in srgb, var(--brand-navy) 22%, var(--border-default));
  border-radius: 100px;
  padding: 4px 8px 4px 12px;
}
.filter-chip button {
  border: none;
  background: transparent;
  color: inherit;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 2px;
  border-radius: 50%;
}
.filter-chip button:hover { background: color-mix(in srgb, var(--brand-navy) 15%, transparent); }
.filter-chip .icon { width: 11px; height: 11px; }
.filter-results-count { font-size: 12px; color: var(--text-secondary); }

/* Botão que abre/fecha o painel de filtros — o painel em si (.filter-bar)
   começa escondido; só os chips de filtro ativo (.filter-bar-summary) ficam
   sempre visíveis na toolbar, pra dar feedback sem ocupar o espaço da tela
   com campos que a maioria das visitas nem usa. */
.filter-toggle-btn { position: relative; }
.filter-count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  margin-left: 6px;
  border-radius: 100px;
  background: var(--brand-navy);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
}

/* ---------- Icon picker (nova categoria) ---------- */
.icon-picker { display: flex; gap: 8px; flex-wrap: wrap; }
.icon-picker-option {
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  cursor: pointer;
}
.icon-picker-option .icon { width: 17px; height: 17px; }
.icon-picker-option.selected { border-color: var(--brand-navy); background: var(--bg-surface); color: var(--brand-navy); }

/* ---------- Painel de configuração de categoria ---------- */
.config-panel {
  width: 960px;
  max-width: 94vw;
  max-height: 88vh;
  background: var(--bg-surface);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-default);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.config-panel-header {
  padding: 20px 24px;
  border-bottom: 1px solid var(--border-default);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
}
.config-panel-body { display: flex; flex: 1; min-height: 0; }

.config-tabs {
  width: 200px;
  flex-shrink: 0;
  border-right: 1px solid var(--border-default);
  padding: 14px 10px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
}
.config-tab {
  display: flex;
  align-items: center;
  gap: 8px;
  text-align: left;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.config-tab .icon { width: 15px; height: 15px; flex-shrink: 0; }
.config-tab:hover { background: var(--bg-surface-elevated); color: var(--text-primary); }
.config-tab.active { background: var(--bg-surface-elevated); color: var(--brand-navy); }
.tab-badge {
  font-size: 9px;
  font-weight: 800;
  text-transform: uppercase;
  background: var(--semantic-warning-bg);
  color: var(--semantic-warning);
  border-radius: 100px;
  padding: 1px 6px;
  margin-left: auto;
}

.config-content {
  flex: 1;
  min-width: 0;
  padding: 22px 26px;
  overflow-y: auto;
}
.config-pane { display: none; }
.config-pane.active { display: block; animation: fadeUp 0.15s ease both; }

.config-preview {
  width: 240px;
  flex-shrink: 0;
  border-left: 1px solid var(--border-default);
  padding: 20px;
  overflow-y: auto;
  background: var(--bg-surface-elevated);
}
.preview-label { font-size: 11px; color: var(--text-secondary); margin: 0 0 8px; }
.preview-select { display: flex; align-items: center; gap: 8px; cursor: default; }
.preview-select .icon { width: 15px; height: 15px; color: var(--text-secondary); }

.config-panel-footer {
  padding: 16px 24px;
  border-top: 1px solid var(--border-default);
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-shrink: 0;
}

/* Painel de pré-visualização de documento — reaproveita o .config-panel
   (mesmo cartão centralizado já usado em Categoria/Todo o histórico), só
   com o corpo dedicado a mostrar o arquivo de verdade (PDF/imagem) em vez
   de abas de configuração. Maior que os outros usos do .config-panel —
   diferente de um formulário, aqui o conteúdo é o próprio documento, e
   pequeno demais obriga a pessoa a dar zoom manual pra ler um PDF de A4. */
.doc-viewer-panel { width: 1100px; height: 92vh; }
.doc-viewer-filetabs {
  display: flex;
  gap: 6px;
  padding: 10px 24px 0;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.doc-viewer-stage {
  flex: 1;
  min-height: 0;
  background: var(--bg-surface-elevated);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: auto;
  position: relative;
}
.doc-viewer-stage iframe { width: 100%; height: 100%; border: none; }
.doc-viewer-stage img { max-width: 100%; max-height: 100%; object-fit: contain; }
/* Escape hatch pro visualizador de PDF nativo do aparelho (ver comentário
   em renderizarArquivoNoPalco, js/app.js) -- flutua sobre o canto do
   iframe, sempre visível sem atrapalhar o PDF por baixo. */
.doc-viewer-abrir-nova-aba {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
  box-shadow: var(--shadow-md);
}
.doc-viewer-abrir-nova-aba:hover { border-color: var(--brand-gold-soft); }
.doc-viewer-abrir-nova-aba .icon { width: 14px; height: 14px; }
@media (max-width: 640px) {
  /* Documento é lido, não digitado -- em telas pequenas o link vira um
     botão de largura total logo acima do PDF em vez de flutuar por cima
     escondendo o conteúdo (que já compete por pouco espaço vertical).
     flex-direction:column empilha os dois -- inofensivo pro caso de
     imagem/vazio, que só têm um filho e continuam centralizados igual. */
  .doc-viewer-stage { flex-direction: column; }
  .doc-viewer-stage iframe { flex: 1; height: auto; }
  .doc-viewer-abrir-nova-aba { position: static; width: calc(100% - 24px); margin: 12px 12px 0; justify-content: center; flex-shrink: 0; }
}
.doc-viewer-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 40px;
  text-align: center;
  color: var(--text-secondary);
}
.doc-viewer-empty .icon { width: 40px; height: 40px; }
@media (max-width: 900px) {
  .doc-viewer-panel { width: 100vw; height: 100vh; max-height: 100vh; max-width: 100vw; border-radius: 0; }
}

/* "Todo o histórico" (documentos.html) — mesmo raciocínio do
   .doc-viewer-panel acima: o conteúdo aqui é a lista de documentos em si
   (potencialmente muitos, agora que dá pra filtrar por categoria e ver
   todo o histórico de uma categoria recorrente), então maior que o
   .config-panel padrão de formulário significa ver mais linhas de uma vez
   sem precisar rolar. */
.historico-panel { width: 1200px; max-width: 95vw; height: 88vh; max-height: 88vh; }
@media (max-width: 900px) {
  .historico-panel { width: 100vw; height: 100vh; max-height: 100vh; max-width: 100vw; border-radius: 0; }
}

/* Detalhamento de categoria (admin) — mesmo raciocínio do .historico-panel:
   o conteúdo é subcategorias + tabela de documentos, precisa de espaço de
   verdade. */
.categoria-detalhe-panel { width: 1100px; max-width: 95vw; height: 86vh; max-height: 86vh; }
/* Bug real: de dentro deste painel dá pra abrir outros modais de verdade
   (pré-visualizar documento, Analisar, confirmar exclusão) -- todos
   dividem a mesma classe .modal-overlay (z-index 70), e como este painel
   vem DEPOIS deles no HTML, ele sempre pintava por cima e escondia
   completamente o modal que acabou de abrir (clicar em "Analisar"/
   "Excluir"/no nome do documento parecia não fazer nada). Mesma lógica já
   documentada acima pra .panel-overlay vs modal de confirmação: quem abre
   por cima de quem já está aberto tem que vencer -- esse painel de
   detalhamento é "navegação", não ação, então fica num degrau abaixo dos
   modais de ação de verdade (que continuam em 70).
   Consequência: 3 pontinhos > Visualizar/Analisar/Excluir agora aparecem
   corretamente por cima; e a mesma ordem em modal-confirm-categoria, que
   abre quando se exclui uma subcategoria direto do card dentro deste
   painel, também passa a vencer. */
#modal-categoria-detalhe { z-index: 65; }
@media (max-width: 900px) {
  .categoria-detalhe-panel { width: 100vw; height: 100vh; max-height: 100vh; max-width: 100vw; border-radius: 0; }
}

.field-optional {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--text-secondary);
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: 100px;
  padding: 1px 7px;
  margin-left: 4px;
}
.field-hint { margin: 6px 0 0; font-size: 11.5px; color: var(--text-secondary); }
.config-content textarea {
  width: 100%;
  padding: 11px 14px;
  border-radius: 8px;
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-primary);
  font-size: 14px;
  font-family: inherit;
  resize: vertical;
}
.config-content textarea:focus {
  outline: none;
  border-color: var(--brand-navy);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-navy) 16%, transparent);
}

.icon-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface-elevated);
  margin-bottom: 12px;
}
.icon-search span { display: flex; color: var(--text-secondary); }
.icon-search input { flex: 1; border: none; background: transparent; padding: 9px 0; font-size: 13px; color: var(--text-primary); font-family: inherit; }
.icon-search input:focus { outline: none; }

.color-row { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 22px; }
.color-swatch {
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  position: relative;
}
.color-swatch.selected { border-color: var(--text-primary); }
.color-swatch.selected::after { content: "✓"; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #FFFFFF; font-size: 13px; font-weight: 800; }
.color-swatch[data-color="navy"] { background: #1F2D6E; }
.color-swatch[data-color="gold"] { background: #B8860B; }
.color-swatch[data-color="green"] { background: #1E7A4C; }
.color-swatch[data-color="red"] { background: #B3261E; }
.color-swatch[data-color="purple"] { background: #6B3FA0; }
.color-swatch[data-color="teal"] { background: #137A6B; }
.color-swatch[data-color="gray"] { background: #5B6072; }

.switch-list { display: flex; flex-direction: column; gap: 4px; }
.switch-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border-default);
}
.switch-item:last-child { border-bottom: none; }
.switch-item-text p { margin: 0; font-size: 13px; font-weight: 600; }
.switch-item-text span { font-size: 11.5px; color: var(--text-secondary); }
.switch-item.disabled { opacity: 0.55; }

.filetype-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.filetype-chip {
  border: 1px solid var(--border-default);
  background: var(--bg-surface-elevated);
  color: var(--text-secondary);
  font-size: 12.5px;
  font-weight: 700;
  padding: 8px 14px;
  border-radius: 100px;
  cursor: pointer;
}
.filetype-chip.selected { background: var(--brand-navy); border-color: var(--brand-navy); color: #FFFFFF; }

.future-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--semantic-warning-bg);
  color: var(--semantic-warning);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-size: 12.5px;
  font-weight: 600;
  margin-bottom: 20px;
}
.future-banner .icon { width: 16px; height: 16px; flex-shrink: 0; }

@media (max-width: 860px) {
  .config-panel-body { flex-direction: column; overflow-y: auto; }
  .config-tabs { width: 100%; flex-direction: row; overflow-x: auto; border-right: none; border-bottom: 1px solid var(--border-default); }
  .config-preview { width: 100%; border-left: none; border-top: 1px solid var(--border-default); }
}

/* ---------- Category card (aba Categorias) ---------- */
.cat-admin-card { position: relative; }
.cat-admin-card.cat-locked { opacity: 0.75; }
.cat-admin-card.cat-inativa { opacity: 0.6; border-style: dashed; }
/* Subcategoria — renderizada logo depois da categoria-pai no mesmo
   .card-grid (nunca um wrapper aninhado: quebraria o auto-fill do grid).
   Só o fundo levemente distinto marca que ela "pertence" à categoria
   anterior (o texto "Subcategoria de X" no card já deixa isso explícito
   de qualquer forma) — nada de borda mais grossa de um lado só: isso
   deixava a borda dourada do hover desigual (grossa de um lado, quase
   some nos outros três), parecendo que só um pedaço do retângulo
   arredondava. Borda sempre 1px nos 4 lados, igual todo outro card. */
.cat-admin-card.cat-subcategoria { background: var(--bg-surface-elevated); }

.cat-admin-tag {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--text-secondary);
  background: var(--bg-surface-elevated);
  border-radius: 100px;
  padding: 2px 8px;
}

.cat-admin-actions {
  position: absolute;
  top: 14px;
  right: 14px;
  display: flex;
  align-items: center;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.cat-admin-card:hover .cat-admin-actions { opacity: 1; }
.cat-admin-actions:has(.cat-admin-tag) { opacity: 1; } /* tag "Padrão" sempre visível */

.cat-action-btn {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: none;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.cat-action-btn .icon { width: 13px; height: 13px; }
.cat-action-edit:hover { border-color: var(--brand-navy); color: var(--brand-navy); }
[data-theme="dark"] .cat-action-edit:hover { border-color: var(--brand-gold); color: var(--brand-gold); }
.cat-action-remove:hover { background: var(--semantic-warning-bg); border-color: var(--semantic-danger); color: var(--semantic-danger); }

.cat-lock-hint {
  width: 28px; height: 28px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
  cursor: help;
}
.cat-lock-hint .icon { width: 13px; height: 13px; }

.cat-icon-editable.clickable { cursor: pointer; }
.cat-icon-editable.clickable:hover { background: var(--bg-surface); box-shadow: 0 0 0 2px var(--brand-navy); }
[data-theme="dark"] .cat-icon-editable.clickable:hover { box-shadow: 0 0 0 2px var(--brand-gold); }

.cat-title-input {
  font-size: 15px;
  font-weight: 600;
  font-family: inherit;
  width: 100%;
  border: 1px solid var(--brand-navy);
  border-radius: var(--radius-sm);
  padding: 4px 8px;
  margin: 0 0 4px;
  background: var(--bg-surface);
  color: var(--text-primary);
}
.cat-title-input:focus { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-navy) 16%, transparent); }

.icon-popover {
  position: absolute;
  top: 50px;
  left: 0;
  z-index: 20;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 10px;
  width: 220px;
}

/* ---------- Tooltip simples (ações bloqueadas) ---------- */
.tooltip-wrap { position: relative; display: inline-flex; }
.tooltip-bubble {
  display: none;
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  background: var(--text-primary);
  color: var(--bg-surface);
  font-size: 11.5px;
  font-weight: 600;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  z-index: 10;
}
.tooltip-wrap:hover .tooltip-bubble { display: block; }

/* ---------- Banner de modo leitura ---------- */
.readonly-banner {
  display: none;
  align-items: center;
  gap: 10px;
  background: var(--bg-surface-elevated);
  border: 1px dashed var(--border-default);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  margin-bottom: 16px;
  font-size: 13px;
  color: var(--text-secondary);
}
.readonly-banner .icon { width: 16px; height: 16px; flex-shrink: 0; }

/* ---------- Seletor de papel (demo) no menu da conta ---------- */
.role-demo-tag {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 100px;
  padding: 1px 6px;
  margin-left: 6px;
}
.role-check { width: 14px; height: 14px; color: var(--semantic-success); flex-shrink: 0; }
.role-check .icon { width: 14px; height: 14px; }
.role-option { justify-content: flex-start; }

/* ---------- Category groups (client detail panel) ---------- */
.cat-group {
  border: 1px solid var(--border-default);
  border-radius: 12px;
  padding: 14px;
}
.cat-group.sent { border-color: var(--semantic-success); background: color-mix(in srgb, var(--semantic-success) 6%, var(--bg-surface)); }
.cat-group.pending { border-style: dashed; opacity: 0.85; }

.cat-group-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.cat-status-icon {
  width: 24px; height: 24px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.cat-status-icon .icon { width: 13px; height: 13px; }
.cat-group.sent .cat-status-icon { background: var(--semantic-success); color: #FFFFFF; }
.cat-group.pending .cat-status-icon { background: var(--bg-surface-elevated); color: var(--text-secondary); }
.cat-group-name { font-size: 13px; font-weight: 700; flex: 1; min-width: 0; }
.cat-group-count {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-secondary);
  background: var(--bg-surface-elevated);
  border-radius: 100px;
  padding: 2px 9px;
}
.cat-group.sent .cat-group-count { color: var(--semantic-success); background: transparent; }

/* .cat-pill-btn é o visual (pill pequeno); .cat-attach-btn continua sendo o
   IDENTIFICADOR único do botão de anexar (documentos.html faz
   card.querySelector(".cat-attach-btn") pra achar esse botão específico e
   ligar o input de arquivo escondido nele). Antes o botão "Ver enviados"
   também levava a classe .cat-attach-btn só pelo visual, e como ele vem
   ANTES do botão de anexar de verdade no HTML, esse querySelector pegava o
   botão errado -- clicar em "Ver enviados" abria o seletor de arquivo do
   Windows por engano, sem a pessoa ter pedido upload nenhum. */
.cat-attach-btn, .cat-pill-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--brand-navy);
  background: var(--bg-surface-elevated);
  border: 1px solid var(--border-default);
  border-radius: 100px;
  padding: 5px 11px;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
}
.cat-attach-btn:hover, .cat-pill-btn:hover { border-color: var(--brand-gold-soft); }
.cat-attach-btn:disabled { opacity: 0.6; cursor: default; }
.cat-attach-btn .icon, .cat-pill-btn .icon { width: 13px; height: 13px; }

.cat-group-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.cat-group-actions .icon-btn { width: 30px; height: 30px; }
.cat-group-actions .icon-btn .icon { width: 15px; height: 15px; }

/* "Ver enviados (N)" — mesmo pill (.cat-pill-btn) do botão de anexar, só que
   em tom neutro (não é a ação principal do card) e com contador, pra já
   avisar quantos envios existem antes de abrir o histórico. */
.cat-historico-btn { color: var(--text-secondary); }
.cat-historico-btn:hover { color: var(--brand-navy); }

@media (max-width: 480px) {
  .cat-group-head { flex-wrap: wrap; row-gap: 8px; }
  .cat-group-name { flex-basis: 100%; }
  .cat-group-actions { margin-left: auto; }
}

/* ---------- Skeleton loading ---------- */
.skeleton { background: linear-gradient(90deg, var(--bg-surface-elevated) 25%, var(--border-default) 50%, var(--bg-surface-elevated) 75%); background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: 8px; }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ---------- Page header (wraps on mobile) ---------- */
.page-header-flex {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 16px;
}
.page-header-flex > div:last-child {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* =====================================================
   RESPONSIVE — TABLET & MOBILE
   ===================================================== */
@media (max-width: 1024px) {
  .main { padding: 32px 24px; }
  .card-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
  .card-grid-hero { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
  .card-grid-archive { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
}

/* Sidebar de navegação vira barra inferior fixa — mesmo breakpoint já usado
   pelo config-panel (860px) pra colapsar layouts de múltiplas colunas. */
@media (max-width: 860px) {
  .nav-sidebar { display: none; }
  .nav-bottom {
    display: flex;
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: var(--bg-surface);
    border-top: 1px solid var(--border-default);
    z-index: 60;
    padding: var(--space-1) var(--space-2);
  }
  .main { padding-bottom: 80px; }
}

@media (max-width: 640px) {
  /* iOS dá zoom automático ao focar qualquer campo com font-size abaixo de
     16px — acontecia em TODOS os formulários (login, perfil, upload,
     filtros de data) porque os campos usam 13-14px no resto do site.
     16px aqui não muda a aparência em telas grandes (só se aplica no
     mobile), só evita esse zoom indesejado a cada toque num campo. */
  .field input, .field textarea, .select-like, .docs-search input,
  input[type="date"], input[type="email"], input[type="password"], input[type="text"] {
    font-size: 16px;
  }

  .main { padding: 20px 16px 80px; }
  .topbar { padding: 12px 16px; }
  .brand-sub { display: none; }
  .user-chip span { display: none; }
  .topbar-actions { gap: 8px; }
  .page-title { font-size: 20px; }

  .stats-row { grid-template-columns: 1fr 1fr; gap: 10px; }
  .stat-value { font-size: 21px; }
  .stat-card { padding: 14px; }

  .card-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
  .card-grid-hero { grid-template-columns: 1fr; gap: 12px; }
  .card-grid-archive { grid-template-columns: 1fr 1fr; gap: 10px; }
  .cat-card { padding: 16px; }
  .cat-card-hero { padding: 20px; }

  .tabs { overflow-x: auto; white-space: nowrap; }

  /* Sub-abas do Detalhe do cliente (Dados cadastrais/Boletos e Financeiro/
     Documentos/Pendências/Histórico) são 5 rótulos — em telas estreitas
     isso quebrava em 2-3 linhas (herdava o flex-wrap do .status-chip-row
     genérico) e comia espaço vertical logo no topo da página. Mesmo
     tratamento de scroll horizontal que .tabs/.config-tabs já usam. */
  #detalhe-subtabs.status-chip-row { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  #detalhe-subtabs .period-chip { flex-shrink: 0; }

  /* Abas de arquivo do visualizador de documento (quando um documento tem
     mais de um arquivo anexado) -- mesmo tratamento de scroll horizontal:
     em vez de quebrar linha e empurrar o PDF/imagem pra baixo, rola de lado
     preservando o nome de cada arquivo por inteiro. */
  .doc-viewer-filetabs { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .doc-viewer-filetabs .period-chip { flex-shrink: 0; }

  /* Tabelas viram cartões empilhados em vez de forçar scroll horizontal —
     cada <td> já recebe um atributo data-label (definido em admin.html) que
     vira o rótulo à esquerda via ::before, então nenhuma linha fica "sem
     contexto" só porque o cabeçalho da coluna sumiu de vista. */
  .table-card { overflow-x: visible; }
  .table-card table { min-width: 0; }
  .table-card thead { display: none; }
  .table-card tbody { display: block; }
  .table-card tr {
    display: block;
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    margin-bottom: 10px;
  }
  .table-card tbody tr:last-child { margin-bottom: 0; }
  .table-card tbody tr td { border-bottom: none; }
  .table-card td {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
    text-align: right;
    width: auto;
  }
  .table-card td::before {
    content: attr(data-label);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    color: var(--text-secondary);
    text-align: left;
    flex-shrink: 0;
  }
  /* Última coluna é sempre a ação (botão/kebab/select) — sem rótulo, alinhada à direita.
     width:100% sobrescreve o truque de coluna estreita "width:1%" do modo
     desktop (table.table-clients td:last-child) — em modo cartão a linha
     inteira deve ficar disponível, senão o botão fica espremido. */
  .table-card td:last-child, table.table-clients td:last-child { justify-content: flex-end; white-space: normal; width: 100%; }
  .table-card td:last-child::before { display: none; }

  .modal, .login-card { max-width: 92vw; width: 92vw; }
  .modal { padding: 22px; }

  .info-grid { grid-template-columns: 1fr; }
  .field-grid-2 { grid-template-columns: 1fr; }
  .side-panel { width: 100vw; max-width: 100vw; }
  .side-panel-header, .side-panel-body, .side-panel-footer { padding-left: 18px; padding-right: 18px; }

  .doc-row { flex-wrap: wrap; }
  .doc-row .btn { margin-left: auto; }

  .login-card { padding: 32px 24px; }

  /* Dropdown (notificações/conta) — largura fixa de 300px podia estourar a
     borda da tela em celulares estreitos; passa a caber dentro da viewport. */
  .dropdown-panel { width: calc(100vw - 32px); max-width: 320px; }

  /* Filtros do admin (Documentos enviados / Administradores): campos de
     210px fixos quebravam linha mas ficavam desalinhados — agora ocupam
     100% da largura, um por linha. */
  .filter-bar-row { flex-direction: column; align-items: stretch; }
  .filter-field { width: 100%; }
  .filter-field .select-like { width: 100%; }
  .filter-bar #docs-filter-clear, .filter-bar #team-filter-clear { margin-left: 0; }
  .period-presets { width: 100%; }
  /* Escopado a .period-presets -- .period-chip sozinho pegava QUALQUER
     reaproveitamento da classe (ex: as abas de arquivo do visualizador de
     documento, .doc-viewer-filetabs, e #detalhe-subtabs) e esmagava cada
     uma pra 1/3 da largura sem olhar pro conteúdo (flex:1 = flex-basis:0),
     cortando nome de arquivo em vez de só deixar os chips de período
     "7 dias/30 dias/Personalizado" ocupando a largura toda. */
  .period-presets .period-chip { flex: 1; text-align: center; }
  .filter-date-range { flex-wrap: wrap; }
  .filter-date-range input[type="date"] { flex: 1; width: auto; min-width: 100px; }

  /* Banner de boleto urgente: em telas estreitas o botão desce pra própria linha
     em vez de espremer o texto. */
  .urgent-banner { flex-wrap: wrap; }
  .urgent-banner .btn-primary { width: 100%; }

  /* Alvo de toque mínimo pros botões-ícone (bell, kebab, avatar-upload etc.) */
  .icon-btn { width: 40px; height: 40px; }
  /* .upload-file-remove (X de cada arquivo selecionado em Enviar Documento)
     era 24x24 — bom o suficiente pra mouse, pequeno demais pra dedo. */
  .upload-file-remove { width: 36px; height: 36px; }
}

@media (max-width: 420px) {
  .stats-row { grid-template-columns: 1fr; }
  .card-grid { grid-template-columns: 1fr; }
  .card-grid-hero { grid-template-columns: 1fr; }
  .card-grid-archive { grid-template-columns: 1fr; }
  .topbar-actions .user-chip span { display: none; }

  /* Calendário mini: mantém a grade de 7 colunas (não vira lista), só reduz
     a escala das células pra não ficar apertado em telas bem estreitas. */
  .cal-cell { height: 22px; }
  .cal-daynum { width: 18px; height: 17px; font-size: 10px; }
  .calendar-mini-head span { min-width: 60px; font-size: 10.5px; }
  .icon-btn-sm { width: 24px; height: 24px; }

  /* Busca + "Mais filtros"/"Filtros" disputando espaço numa linha só ficava
     apertado demais nesse tamanho de tela — cada um ganha a linha inteira. */
  .docs-toolbar { flex-direction: column; align-items: stretch; }
  .docs-toolbar .btn { width: 100%; justify-content: center; }
}

/* ---------- Microinterações: feedback de "pressionado" ----------
   .btn já ganhou hover (elevação) + active (afundada) próprios, definidos
   junto da classe. Pra chips/pílulas/abas/ícones pequenos, um translateY de
   botão fica estranho (são elementos quadrados/redondos, não retangulares) —
   em vez disso, um scale sutil no clique, só a garantia de que TODO
   controle clicável do sistema (cliente e admin) responde visualmente ao
   toque, não só os que já tinham :hover com troca de cor. Um ponto só de
   manutenção em vez de repetir a mesma regra em cada componente. */
.icon-btn:active,
.password-toggle-btn:active,
.theme-toggle:active,
.admin-nav-toggle:active,
.tipo-pessoa-option:active,
.segmented-option:active,
.auth-type-option:active,
.docs-filtro-chip:active,
.period-chip:active,
.filetype-chip:active,
.config-tab:active,
.cat-action-edit:active,
.cat-action-remove:active,
.stat-card.clickable:active,
.cat-card:active {
  transform: scale(0.96);
}

/* Cards já tinham hover de elevação (.stat-card, .cat-card) mas nenhum
   feedback de clique — reduz a elevação do hover em vez de "afundar" mais,
   senão o scale acima + o translateY do hover se somam de um jeito
   estranho. */
.stat-card.clickable:active { box-shadow: var(--shadow-xs); }
.cat-card:active { box-shadow: var(--shadow-xs); }

/* Respeita quem pediu menos movimento no sistema operacional/navegador —
   as transições continuam existindo (cor, sombra), só a duração vira
   instantânea, sem a sensação de elevação/deslocamento. */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* =====================================================================
   Portal do cliente — redesign visual (referência fintech aprovada)
   Tudo aqui embaixo do <body class="client-portal"> (dashboard/boletos/
   documentos/perfil) — o admin usa exatamente as mesmas classes-base
   (.stat-card, .side-card, .section-label, .period-chip...) e não pode
   herdar nada disso sem querer, por isso cada regra é escopada com
   ".client-portal" na frente em vez de mudar a classe-base. Puramente
   visual: nenhuma classe nova aqui é lida por JS, nenhuma lógica muda.
   ===================================================================== */

/* ---------- Cabeçalho: eyebrow + título + ação (dashboard) ---------- */
.client-portal .page-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--text-secondary);
  margin: 0 0 6px;
}
.client-portal .page-header-flex { align-items: center; }

/* ---------- Hero de boas-vindas ----------
   Cartão de identidade fixa (sempre no tom navy/dourado da marca,
   independente do tema claro/escuro) — é o "cartão de banco" da tela,
   por isso não usa os tokens de tema: um cartão assim tem que continuar
   contrastando bem tanto num canvas claro quanto escuro, sem herdar o
   branco do tema claro (é exatamente o problema de "card sem
   preenchimento" que a Lorena queria evitar). */
/* Hero + os 2 KPIs de gravidade + Resumo financeiro numa linha só: hero
   largo à esquerda, coluna estreita à direita com os 2 KPIs em cima e o
   Resumo financeiro embaixo (puxado pra cá a pedido da Lorena — antes
   morava embaixo, junto de Alertas). Com o card pra preencher, a coluna
   volta a esticar até a altura do hero ("align-items: stretch"). Abaixo
   de 1024px empilha (mesmo ponto de corte já usado no resto desta tela). */
.client-portal .client-hero-row { display: grid; grid-template-columns: 2fr 1fr; gap: 20px; align-items: stretch; margin-bottom: 20px; }
.client-portal .client-hero-row .client-hero { margin-bottom: 0; height: 100%; display: flex; flex-direction: column; }
.client-portal .client-hero-row .client-hero-footer { margin-top: auto; }
.client-portal .client-hero-side { display: flex; flex-direction: column; gap: 16px; }
.client-portal .client-hero-side-kpis { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.client-portal .client-hero-side .side-card { flex: 1; }
@media (max-width: 1024px) {
  .client-portal .client-hero-row { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  .client-portal .client-hero-side-kpis { grid-template-columns: 1fr; }
}

/* Alertas + Próximos vencimentos lado a lado, abaixo da linha do hero.
   Empilha em 1 coluna abaixo de 1024px — mesmo ponto de corte já usado
   no resto desta tela. */
.client-portal .client-two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 1024px) {
  .client-portal .client-two-col { grid-template-columns: 1fr; }
}

.client-hero {
  position: relative;
  overflow: hidden;
  /* Degradê clareado ("o leve", pedido da Lorena -- mesmo tratamento da
     barra lateral do admin, pra os dois painéis ficarem no mesmo tom): era
     linear-gradient(150deg, #0B1220 0%, #182552 55%, #24316B 100%), quase
     preto no começo. Agora começa no próprio azul-marinho da marca. */
  background: linear-gradient(150deg, #101B36 0%, #17244A 55%, #223564 100%);
  border-radius: var(--radius-lg);
  padding: 28px 30px;
  color: #EDEFF5;
  box-shadow: var(--shadow-md);
  margin-bottom: 20px;
}
.client-hero::after {
  /* mesmo truque de "luz pegando o canto" já usado na sidebar — profundidade
     só com gradiente, sem custo de blur. Pedido explícito: mais dourado
     visível no degradê (a referência tem um brilho quente atravessando o
     canto do cartão, não só um traço quase imperceptível) — mais opaco e
     cobrindo mais área que a versão anterior, ainda sem virar um cartão
     amarelo (é luz batendo no canto, não fundo colorido). */
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(130% 90% at 88% -15%, rgba(212, 175, 55, 0.38), transparent 65%);
  pointer-events: none;
}
.client-hero-top { position: relative; }
.client-hero-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: #E8C766;
  margin: 0 0 10px;
}
.client-hero .page-title {
  color: #FFFFFF;
  font-size: 26px;
  margin: 0 0 8px;
  max-width: 34ch;
}
.client-hero .page-subtitle {
  color: rgba(237, 239, 245, 0.72);
  margin: 0;
  max-width: 52ch;
}
.client-hero-footer {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid rgba(237, 239, 245, 0.14);
  flex-wrap: wrap;
}
.client-hero-total-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: rgba(237, 239, 245, 0.55);
  margin: 0 0 4px;
}
.client-hero-total-value {
  font-size: 30px;
  font-weight: 800;
  color: #FFFFFF;
  margin: 0;
  font-variant-numeric: tabular-nums;
}
.client-hero-total-value .stat-value-decimals { color: rgba(237, 239, 245, 0.6); }
.client-hero-updated { text-align: right; font-size: 11px; color: rgba(237, 239, 245, 0.55); }
.client-hero-updated strong { display: block; color: rgba(237, 239, 245, 0.85); font-size: 12px; margin-top: 2px; }

/* ---------- KPIs: selo de atenção como ponto colorido, não risco lateral ----------
   A referência marca "precisa de atenção" com um ponto no canto do card e,
   pro caso mais grave (vencidos), um contorno inteiro na cor — não um
   risco só na borda esquerda. Mesma informação (mesmas classes .attention/
   .danger que o JS já aplica), leitura mais parecida com a referência. */
.client-portal .stat-card { position: relative; border-left: none !important; }
.client-portal .stat-card.attention::after {
  content: "";
  position: absolute;
  top: 18px;
  right: 18px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--semantic-warning);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--semantic-warning) 20%, transparent);
}
.client-portal .stat-card.attention.danger {
  border: 1px solid color-mix(in srgb, var(--semantic-danger) 45%, var(--border-default));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--semantic-danger) 18%, transparent), var(--shadow-sm);
}
.client-portal .stat-card.attention.danger::after { background: var(--semantic-danger); box-shadow: 0 0 0 3px color-mix(in srgb, var(--semantic-danger) 22%, transparent); }
.client-portal .stat-card.attention.danger .stat-value { color: var(--semantic-danger); }

/* ---------- Cards de apoio (Alertas / Resumo / Próximos vencimentos) ---------- */
.client-portal .side-card { border-radius: var(--radius-lg); padding: 22px; }

/* Alertas: cada item virou um cartão com contorno na cor da gravidade
   (âmbar = vencendo, vermelho = vencido) em vez de uma linha simples —
   título curto (o que é) + descrição (o quê/quando) em vez de uma frase
   só. Contador "N pendentes" no cabeçalho do card (ver .alertas-pendentes-badge
   logo abaixo) mostra o total real, mesmo a lista só exibindo os 5 primeiros. */
.client-portal .side-card-head.with-count { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.client-portal .alertas-pendentes-badge { font-size: 12px; font-weight: 700; color: var(--semantic-warning); }
.client-portal .alertas-pendentes-badge.danger { color: var(--semantic-danger); }

.client-portal .attention-item {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: left;
  gap: 4px;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  border: 1px solid color-mix(in srgb, var(--semantic-warning) 40%, var(--border-default));
  background: color-mix(in srgb, var(--semantic-warning) 8%, var(--bg-surface));
}
.client-portal .attention-item:hover { background: color-mix(in srgb, var(--semantic-warning) 14%, var(--bg-surface)); }
.client-portal .attention-item.danger {
  border-color: color-mix(in srgb, var(--semantic-danger) 45%, var(--border-default));
  background: color-mix(in srgb, var(--semantic-danger) 8%, var(--bg-surface));
}
.client-portal .attention-item.danger:hover { background: color-mix(in srgb, var(--semantic-danger) 14%, var(--bg-surface)); }
.client-portal .attention-item-head { display: flex; align-items: center; gap: 8px; }
.client-portal .attention-item-head strong { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.client-portal .attention-item .dot-icon {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--semantic-warning);
  flex-shrink: 0;
}
.client-portal .attention-item.danger .dot-icon { background: var(--semantic-danger); }
.client-portal .attention-item-desc { margin: 0; padding-left: 16px; font-size: 12px; color: var(--text-secondary); }

/* Próximos vencimentos: selo de data em tom dourado por padrão (nem todo
   vencimento é urgente) — urgent/danger continuam com as cores de alerta
   que já existiam. */
.client-portal .due-item-date {
  background: color-mix(in srgb, var(--brand-gold) 16%, var(--bg-surface-elevated));
  color: var(--brand-gold);
  border-color: transparent;
}

/* Resumo financeiro: barra de proporção paga vs. em aberto — elemento
   novo (só decorativo, resumo-progress-bar recebe a largura via style
   inline no JS), não substitui nenhuma linha existente. */
.client-portal .resumo-progress {
  margin-top: 14px;
  height: 6px;
  border-radius: 100px;
  background: var(--bg-surface-elevated);
  overflow: hidden;
}
.client-portal .resumo-progress-bar {
  height: 100%;
  border-radius: 100px;
  background: linear-gradient(90deg, var(--brand-gold-soft), var(--brand-gold));
}

/* ---------- Rótulo de grupo (Documentos: Societário/Jurídico/...) ---------- */
.client-portal .section-label { color: var(--brand-gold); letter-spacing: 0.8px; }

/* ---------- Chip de filtro ativo em dourado (Boletos/Documentos) ----------
   Só dentro do portal do cliente — os mesmos .period-chip no admin
   continuam navy, sem mudar nada por lá. Só no tema ESCURO: no claro,
   --brand-gold é um tom escuro/fechado (pensado pra ler bem como TEXTO
   sobre fundo claro) que como FUNDO de um chip inteiro lia como amarelo
   mostarda — pedido explícito da Lorena pra tirar isso. No claro, o chip
   ativo volta a usar a mesma cor navy que o resto do sistema (a regra
   base .period-chip.active, sem essa sobrescrita). */
[data-theme="dark"] .client-portal .period-chip.active { background: var(--brand-gold); border-color: var(--brand-gold); color: #1F2A4D; }

/* ---------- Ícone de linha (Boletos) num tom mais quente ---------- */
.client-portal .boleto-row-icon { background: color-mix(in srgb, var(--brand-navy) 14%, var(--bg-surface-elevated)); color: var(--brand-navy); }

/* ---------- Tema claro: cards com preenchimento de verdade, não branco ----------
   Pedido explícito: no claro, --bg-surface é #FFFFFF puro — ao lado do
   canvas bem claro (#E3E7EF), os cards liam como "sem cor", genéricos.
   Aqui só (tema claro + portal do cliente), troca o branco por um branco
   com uma pitada de navy (a cor de marca), o suficiente pra cada card
   parecer intencional sem virar um bloco colorido — o dourado continua
   reservado só pros acentos pontuais já definidos acima. Escopado a
   :not([data-theme="dark"]) porque o dark já resolve isso com os tokens
   --bg-surface/--bg-surface-elevated de verdade escuros, sem esse problema. */
:root:not([data-theme="dark"]) .client-portal .stat-card {
  background: linear-gradient(160deg, color-mix(in srgb, var(--brand-navy) 9%, #FFFFFF) 0%, color-mix(in srgb, var(--brand-navy) 19%, #FFFFFF) 100%);
  border-color: color-mix(in srgb, var(--brand-navy) 18%, var(--border-default));
}
:root:not([data-theme="dark"]) .client-portal .side-card,
:root:not([data-theme="dark"]) .client-portal .table-card {
  background: color-mix(in srgb, var(--brand-navy) 8%, #FFFFFF);
  border-color: color-mix(in srgb, var(--brand-navy) 16%, var(--border-default));
}
:root:not([data-theme="dark"]) .client-portal .attention-item:hover,
:root:not([data-theme="dark"]) .client-portal .due-item:hover,
:root:not([data-theme="dark"]) .client-portal .boleto-row:hover {
  background: color-mix(in srgb, var(--brand-navy) 11%, #FFFFFF);
}

/* ---------- Perfil: cabeçalho vira um mini-hero (mesma família visual do
   hero do Início — degradê navy/dourado, identidade fixa nos dois temas —
   só bem mais sutil: card menor, texto sem o peso de "página inteira", o
   brilho do canto quase imperceptível em vez de ser o protagonista). Fica
   num cartão próprio, separado dos dados cadastrais logo abaixo — antes
   viviam espremidos no mesmo card, com só um fio horizontal separando. ---------- */
.client-portal .perfil-hero {
  position: relative;
  overflow: hidden;
  /* Mesmo degradê clareado do .client-hero (ver acima) -- mantém a mesma
     família visual entre o hero do Início e o do Perfil. */
  background: linear-gradient(150deg, #101B36 0%, #17244A 55%, #223564 100%);
  border-radius: var(--radius-lg);
  padding: 22px 26px;
  box-shadow: var(--shadow-md);
  margin-bottom: 20px;
}
.client-portal .perfil-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 70% at 88% -15%, rgba(212, 175, 55, 0.14), transparent 65%);
  pointer-events: none;
}
.client-portal .perfil-header {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
}
.client-portal .perfil-header .avatar {
  width: 56px; height: 56px;
  font-size: 17px;
  background: rgba(232, 199, 102, 0.16);
  color: #E8C766;
  border: 1px solid rgba(232, 199, 102, 0.28);
}
.client-portal .perfil-header-nome { margin: 0; font-weight: var(--font-bold); font-size: var(--text-md); color: #FFFFFF; }
.client-portal .perfil-header-status { margin: 2px 0 0; font-size: var(--text-sm); color: rgba(237, 239, 245, 0.65); }
.client-portal .perfil-fields-title { margin: 0 0 var(--space-5); font-size: 14px; font-weight: 700; }
.client-portal .perfil-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 24px; }
.client-portal .perfil-fields .field { margin: 0; }
.client-portal .perfil-fields .field label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.client-portal .perfil-fields .field input:disabled {
  border: none;
  background: transparent;
  padding: 4px 0 0;
  font-weight: var(--font-semibold);
  color: var(--text-primary);
  -webkit-text-fill-color: var(--text-primary);
  opacity: 1;
}
@media (max-width: 640px) {
  .client-portal .perfil-fields { grid-template-columns: 1fr; }
  .client-hero-footer { flex-direction: column; align-items: flex-start; }
  .client-hero-updated { text-align: left; }
}
