/* =====================================================================
   nulven - Design System
   Identidade visual derivada da logo: navy (#1E3A52) -> teal (#0E8C74)
   Tema claro predominante, tema escuro opcional.
   ===================================================================== */

/* ---------------------------------------------------------------
   1. TOKENS
   --------------------------------------------------------------- */
:root {
  /* Marca */
  --brand-navy-900: #0C1B29;
  --brand-navy-800: #12293D;
  --brand-navy-700: #1E3A52;
  --brand-navy-600: #2A4F6E;
  --brand-teal-700: #0A6F5C;
  --brand-teal-600: #0E8C74;
  --brand-teal-500: #12A085;
  --brand-teal-100: #D3ECE5;
  --brand-teal-50: #EDF7F4;
  --brand-gradient: linear-gradient(135deg, var(--brand-navy-700) 0%, var(--brand-teal-600) 100%);

  /* Superfícies (tema claro) */
  --bg: #F5F7F9;
  --bg-elevated: #FFFFFF;
  --surface: #FFFFFF;
  --surface-2: #FAFBFC;
  --surface-3: #F1F4F7;
  --surface-hover: #F3F6F8;
  --border: #E4E9EF;
  --border-strong: #D2DAE3;

  /* Texto */
  --text: #10263A;
  --text-secondary: #4A5F76;
  --text-muted: #7A8CA0;
  --text-inverse: #FFFFFF;

  /* Semânticos */
  --positive: #0E8C74;
  --positive-bg: #E7F5F1;
  /* Variante clara, para faixas de subtotal ficarem abaixo do total
     na hierarquia sem sair da mesma família de cor. */
  --positive-bg-soft: #F3FAF8;
  --negative: #C7413F;
  --negative-bg: #FBECEB;
  /* Variante mais clara, para faixas de subtotal ficarem abaixo do
     total na hierarquia sem sair da mesma família de cor. */
  --negative-bg-soft: #FEF7F6;
  --warning: #B5761A;
  --warning-bg: #FDF3E4;
  --info: #2A6BB0;
  --info-bg: #EAF2FB;
  /* Variante mais clara, para faixas de subtotal ficarem abaixo do
     total na hierarquia sem sair da mesma família de cor. */
  --info-bg-soft: #F4F8FD;
  --neutral: #7A8CA0;
  --neutral-bg: #F0F3F6;

  /* Paleta de séries para gráficos */
  --c1: #1E3A52;
  --c2: #0E8C74;
  --c3: #2A6BB0;
  --c4: #B5761A;
  --c5: #8E5AA8;
  --c6: #C7413F;
  --c7: #4FA3A0;
  --c8: #6B7F94;
  --c9: #D08A3E;
  --c10: #3E7D5A;

  /* Tipografia */
  --font: "Inter", "Segoe UI", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --font-mono: "SF Mono", "JetBrains Mono", "Cascadia Mono", Consolas, monospace;

  /* Escala */
  --fs-xs: 11px;
  --fs-sm: 12.5px;
  --fs-base: 14px;
  --fs-md: 15px;
  --fs-lg: 18px;
  --fs-xl: 22px;
  --fs-2xl: 28px;
  --fs-3xl: 34px;

  /* Espaçamento */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;

  /* Raio */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 20px;
  --r-full: 999px;

  /* Sombras */
  --sh-xs: 0 1px 2px rgba(16, 38, 58, 0.05);
  --sh-sm: 0 1px 3px rgba(16, 38, 58, 0.07), 0 1px 2px rgba(16, 38, 58, 0.04);
  --sh-md: 0 4px 12px rgba(16, 38, 58, 0.08), 0 1px 3px rgba(16, 38, 58, 0.05);
  --sh-lg: 0 12px 32px rgba(16, 38, 58, 0.12), 0 4px 8px rgba(16, 38, 58, 0.06);
  --sh-xl: 0 24px 64px rgba(16, 38, 58, 0.18);

  /* Layout */
  --sidebar-w: 244px;
  --topbar-h: 60px;
  --transition: 160ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* Tema escuro */
[data-theme="dark"] {
  --bg: #0B1521;
  --bg-elevated: #12202E;
  --surface: #12202E;
  --surface-2: #16283A;
  --surface-3: #1B3145;
  --surface-hover: #1B3145;
  --border: #22374C;
  --border-strong: #2E4761;

  --text: #E8EEF4;
  --text-secondary: #A9BCCE;
  --text-muted: #7C93A9;

  --positive: #2CB99C;
  --positive-bg: #10312B;
  --positive-bg-soft: #0B231F;
  --negative: #E0736F;
  --negative-bg: #33191A;
  --negative-bg-soft: #241113;
  --warning: #D9A048;
  --warning-bg: #33260F;
  --info: #5C9BE0;
  --info-bg: #10243A;
  --info-bg-soft: #0C1B2C;
  --neutral: #8AA0B5;
  --neutral-bg: #1B2C3D;

  --c1: #5C9BE0;
  --c2: #2CB99C;
  --c3: #7FB2EA;
  --c4: #D9A048;
  --c5: #B084C9;
  --c6: #E0736F;
  --c7: #6FC7C4;
  --c8: #92A7BC;

  --sh-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
  --sh-sm: 0 1px 3px rgba(0, 0, 0, 0.4);
  --sh-md: 0 4px 12px rgba(0, 0, 0, 0.45);
  --sh-lg: 0 12px 32px rgba(0, 0, 0, 0.5);
  --sh-xl: 0 24px 64px rgba(0, 0, 0, 0.6);
}

/* ---------------------------------------------------------------
   2. RESET
   --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overscroll-behavior-y: none;
}

h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 600; letter-spacing: -0.015em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button, input, select, textarea { font-family: inherit; font-size: inherit; color: inherit; }
button { cursor: pointer; border: none; background: none; padding: 0; }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; width: 100%; }
img { max-width: 100%; display: block; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: var(--r-full); border: 3px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }

:focus-visible { outline: 2px solid var(--brand-teal-600); outline-offset: 2px; border-radius: var(--r-sm); }

/* ---------------------------------------------------------------
   3. UTILITÁRIOS
   --------------------------------------------------------------- */
.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.txt-pos { color: var(--positive); }
.txt-neg { color: var(--negative); }
.txt-warn { color: var(--warning); }
.txt-muted { color: var(--text-muted); }
.txt-secondary { color: var(--text-secondary); }
.txt-right { text-align: right; }
.txt-center { text-align: center; }
.num {
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum";
  /* O sinal não pode quebrar para a linha de cima: "-" sozinho sobre o
     valor lê como traço de célula vazia, não como negativo. */
  white-space: nowrap;
}
.mono { font-family: var(--font-mono); font-size: var(--fs-sm); }
.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.items-end { align-items: flex-end; }
.justify-between { justify-content: space-between; }
.justify-center { justify-content: center; }
.justify-end { justify-content: flex-end; }
.flex-wrap { flex-wrap: wrap; }
.flex-1 { flex: 1; }
.gap-1 { gap: var(--sp-1); }
.gap-2 { gap: var(--sp-2); }
.gap-3 { gap: var(--sp-3); }
.gap-4 { gap: var(--sp-4); }
.gap-5 { gap: var(--sp-5); }
.gap-6 { gap: var(--sp-6); }
.mt-2 { margin-top: var(--sp-2); }
.mt-3 { margin-top: var(--sp-3); }
.mt-4 { margin-top: var(--sp-4); }
.mt-6 { margin-top: var(--sp-6); }
.mb-2 { margin-bottom: var(--sp-2); }
.mb-3 { margin-bottom: var(--sp-3); }
.mb-4 { margin-bottom: var(--sp-4); }
.mb-6 { margin-bottom: var(--sp-6); }
.w-full { width: 100%; }

/* O Safari aumenta fonte por conta própria ao girar o aparelho. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* ---------------------------------------------------------------
   4. LOGIN
   --------------------------------------------------------------- */
#auth-screen {
  padding-top: env(safe-area-inset-top);
  /* 100vh no iOS inclui a barra do Safari, que recolhe ao rolar. A
     altura do layout mudava no meio da rolagem e o navegador
     reposicionava a página — dava o efeito de travar e voltar.
     100dvh acompanha a área realmente visível; o 100vh acima fica
     como reserva para navegador sem suporte. */
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  background: var(--surface);
}

.auth-brand {
  background: var(--brand-gradient);
  color: var(--text-inverse);
  padding: var(--sp-12);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
  overflow: hidden;
}
.auth-brand::after {
  content: "";
  position: absolute;
  width: 620px; height: 620px;
  right: -220px; bottom: -260px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.06);
}
.auth-brand::before {
  content: "";
  position: absolute;
  width: 380px; height: 380px;
  right: 80px; top: -180px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.04);
}
.auth-brand > * { position: relative; z-index: 1; }
/* Assinatura da marca: símbolo e nome lado a lado, alinhados pelo
   eixo óptico. O nome usa a mesma família do resto da interface para
   não introduzir uma segunda tipografia na tela de entrada. */
.auth-brand-mark { display: flex; align-items: center; gap: var(--sp-4); }
.auth-brand-logo {
  width: 76px; height: 76px; flex: none;
  background: #fff;
  border-radius: var(--r-lg);
  padding: 6px;
  object-fit: contain;
  box-shadow: var(--sh-lg);
}
/* O nome é IMAGEM, não texto: a tipografia da marca não está
   disponível como fonte web, e aproximá-la com a família da interface
   produzia duas versões diferentes do mesmo nome na mesma tela. */
.auth-brand-nome { height: 34px; width: auto; display: block; }
.auth-brand h1 { font-size: 40px; line-height: 1.15; margin-bottom: var(--sp-4); font-weight: 650; }
.auth-brand p { font-size: var(--fs-md); opacity: 0.86; max-width: 44ch; line-height: 1.65; }
.auth-brand-features { margin-top: var(--sp-8); display: flex; flex-direction: column; gap: var(--sp-3); }
.auth-brand-features li { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-base); opacity: 0.9; }
.auth-brand-features li::before {
  content: ""; width: 18px; height: 18px; flex: none;
  border-radius: 50%; background: rgba(255,255,255,0.18);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,0.5);
}
.auth-brand-foot { font-size: var(--fs-sm); opacity: 0.6; }

.auth-panel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-8);
}
.auth-card { width: 100%; max-width: 380px; }
.auth-card h2 { font-size: var(--fs-2xl); margin-bottom: var(--sp-2); }
.auth-card > .auth-sub { color: var(--text-muted); margin-bottom: var(--sp-8); font-size: var(--fs-md); }
.auth-mobile-logo { display: none; }
.auth-alt { margin-top: var(--sp-6); text-align: center; font-size: var(--fs-sm); color: var(--text-muted); }
.auth-alt button { color: var(--brand-teal-600); font-weight: 600; }
.auth-alt button:hover { text-decoration: underline; }
.auth-hint {
  margin-top: var(--sp-6); padding: var(--sp-3) var(--sp-4);
  background: var(--surface-3); border-radius: var(--r-md);
  font-size: var(--fs-sm); color: var(--text-secondary); line-height: 1.6;
}

/* ---------------------------------------------------------------
   5. LAYOUT DA APLICAÇÃO
   --------------------------------------------------------------- */
#app-shell { display: flex; min-height: 100vh; min-height: 100dvh; }

.sidebar {
  width: var(--sidebar-w);
  padding-top: env(safe-area-inset-top);
  flex: none;
  background: var(--brand-navy-800);
  color: rgba(255, 255, 255, 0.72);
  display: flex;
  flex-direction: column;
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 60;
  transition: transform var(--transition);
}
.sidebar-head {
  height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 0 var(--sp-5);
  flex: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.07);
}
/* A regra é do ÍCONE, não de "toda imagem do cabeçalho". Quando o
   nome virou imagem, `.sidebar-head img` a esmagou em 34x34 com fundo
   branco: texto branco sobre fundo branco dentro de um quadrado — o
   que apareceu no celular foi um quadrado branco ao lado do ícone.
   Mesma classe do defeito de seletor por id que travou a navegação em
   setembro: regra ampla demais atropela a específica. */
.sidebar-head .sidebar-icone {
  width: 34px; height: 34px; background: #fff;
  border-radius: var(--r-sm); padding: 2px; object-fit: contain;
  flex: none;
}
.sidebar-head .sidebar-marca {
  height: 19px; width: auto; display: block;
  background: none; padding: 0; border-radius: 0;
}

.sidebar-nav { flex: 1; overflow-y: auto; padding: var(--sp-4) var(--sp-3) var(--sp-6); }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.14); border-color: transparent; }
.nav-group-label {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.09em;
  color: rgba(255, 255, 255, 0.36); font-weight: 600;
  padding: var(--sp-4) var(--sp-3) var(--sp-2);
}
.nav-item {
  display: flex; align-items: center; gap: var(--sp-3);
  width: 100%; padding: 9px var(--sp-3);
  border-radius: var(--r-md); font-size: var(--fs-base); font-weight: 500;
  color: rgba(255, 255, 255, 0.72);
  transition: background var(--transition), color var(--transition);
  text-align: left;
}
.nav-item:hover { background: rgba(255, 255, 255, 0.07); color: var(--text-inverse); }
.nav-item.active { background: var(--brand-teal-600); color: var(--text-inverse); box-shadow: var(--sh-sm); }
.nav-item .ic { flex: none; opacity: 0.9; }
.nav-item .nav-badge {
  margin-left: auto; font-size: var(--fs-xs); font-weight: 700;
  background: var(--negative); color: var(--text-inverse);
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: var(--r-full); display: grid; place-items: center;
}

.sidebar-foot { flex: none; padding: var(--sp-3); border-top: 1px solid rgba(255, 255, 255, 0.07); }
.sidebar-user {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md); width: 100%;
  transition: background var(--transition);
}
.sidebar-user:hover { background: rgba(255, 255, 255, 0.07); }
.sidebar-user .avatar { flex: none; }
.sidebar-user-info { min-width: 0; text-align: left; }
.sidebar-user-info b { display: block; color: var(--text-inverse); font-size: var(--fs-sm); font-weight: 600; }
.sidebar-user-info small { color: rgba(255, 255, 255, 0.5); font-size: var(--fs-xs); }

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

/* Instalado na tela inicial, o sistema roda em tela cheia com a barra
   de status translúcida por cima (`viewport-fit=cover` +
   `black-translucent`). Sem reservar a área segura, o topo da barra
   fica escondido atrás do relógio e do entalhe. O valor é zero em
   navegador comum e no computador, então vale para todos. */
.topbar {
  height: calc(var(--topbar-h) + env(safe-area-inset-top));
  padding-top: env(safe-area-inset-top);
  flex: none;
  position: sticky; top: 0; z-index: 40;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: var(--sp-4);
  padding: 0 var(--sp-6);
}
[data-theme="dark"] .topbar { background: rgba(18, 32, 46, 0.85); }
.topbar h1 { font-size: var(--fs-lg); font-weight: 650; }
.topbar-sub { font-size: var(--fs-sm); color: var(--text-muted); }
/* Escondido no desktop, onde a barra lateral já está visível e o botão
   não teria função. Precisa da especificidade de .topbar: .icon-btn é
   declarado depois e traz display:grid, que vencia por ordem — o botão
   aparecia e o clique não produzia efeito visível nenhum. */
.topbar .menu-toggle { display: none; }

.topbar-sep {
  width: 1px; height: 22px; background: var(--border);
  flex: none; margin: 0 2px;
}
.icon-btn-sair:hover { background: var(--negative-bg); color: var(--negative); }

.search-global {
  position: relative; margin-left: auto; width: 268px;
}
.search-global input {
  width: 100%; height: 36px;
  padding: 0 var(--sp-3) 0 34px;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface-3); color: var(--text);
  transition: border-color var(--transition), background var(--transition);
  font-size: var(--fs-sm);
}
.search-global input:focus { outline: none; border-color: var(--brand-teal-600); background: var(--surface); }
.search-global .ic { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; }
.search-results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--sh-lg);
  max-height: 380px; overflow-y: auto; z-index: 50; padding: var(--sp-2);
}
.search-results .sr-group { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.07em; color: var(--text-muted); padding: var(--sp-2) var(--sp-3) var(--sp-1); font-weight: 600; }
.search-results button { display: block; width: 100%; text-align: left; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm); font-size: var(--fs-sm); }
.search-results button:hover { background: var(--surface-hover); }

.content { flex: 1; padding: var(--sp-6); max-width: 1560px; width: 100%; margin: 0 auto; }
.view { display: none; }
.view.active { display: block; animation: fadeUp 220ms ease; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap; margin-bottom: var(--sp-5);
}
.page-head h2 { font-size: var(--fs-xl); }
.page-head p { color: var(--text-muted); font-size: var(--fs-sm); margin-top: 2px; }
.page-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }

/* ---------------------------------------------------------------
   6. BOTÕES
   --------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  height: 36px; padding: 0 var(--sp-4);
  border-radius: var(--r-md); font-size: var(--fs-sm); font-weight: 600;
  border: 1px solid transparent; white-space: nowrap;
  transition: background var(--transition), border-color var(--transition), color var(--transition), transform var(--transition), box-shadow var(--transition);
}
.btn:active { transform: translateY(0.5px); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-primary { background: var(--brand-teal-600); color: var(--text-inverse); box-shadow: var(--sh-xs); }
.btn-primary:hover:not(:disabled) { background: var(--brand-teal-700); box-shadow: var(--sh-sm); }
.btn-navy { background: var(--brand-navy-700); color: var(--text-inverse); }
.btn-navy:hover:not(:disabled) { background: var(--brand-navy-800); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--text-muted); }
.btn-ghost { background: transparent; color: var(--text-secondary); }
.btn-ghost:hover:not(:disabled) { background: var(--surface-hover); color: var(--text); }
.btn-danger { background: var(--negative); color: var(--text-inverse); }
.btn-danger:hover:not(:disabled) { filter: brightness(0.92); }
.btn-danger-ghost { background: transparent; color: var(--negative); border-color: var(--border-strong); }
.btn-danger-ghost:hover:not(:disabled) { background: var(--negative-bg); border-color: var(--negative); }
.btn-block { width: 100%; }
.btn-lg { height: 42px; padding: 0 var(--sp-5); font-size: var(--fs-base); }
.btn-sm { height: 30px; padding: 0 var(--sp-3); font-size: var(--fs-xs); }
.btn-icon { width: 34px; padding: 0; flex: none; }
.btn-icon.btn-sm { width: 28px; height: 28px; }

.icon-btn {
  width: 34px; height: 34px; border-radius: var(--r-md);
  display: grid; place-items: center; color: var(--text-secondary);
  transition: background var(--transition), color var(--transition);
}
.icon-btn:hover { background: var(--surface-hover); color: var(--text); }

/* ---------------------------------------------------------------
   7. FORMULÁRIOS
   --------------------------------------------------------------- */
.field { margin-bottom: var(--sp-4); }
.field > label, .field-label {
  display: block; font-size: var(--fs-sm); font-weight: 600;
  color: var(--text-secondary); margin-bottom: 6px;
}
.field-hint { font-size: var(--fs-xs); color: var(--text-muted); margin-top: 5px; line-height: 1.5; }
.field-error { font-size: var(--fs-xs); color: var(--negative); margin-top: 5px; font-weight: 500; }

.input, .select, .textarea {
  width: 100%; height: 38px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--border-strong); border-radius: var(--r-md);
  background: var(--surface); color: var(--text);
  transition: border-color var(--transition), box-shadow var(--transition);
  font-size: var(--fs-base);
}
.textarea { height: auto; min-height: 78px; padding: var(--sp-2) var(--sp-3); resize: vertical; line-height: 1.55; }
/* -----------------------------------------------------------------
   Campos de data, hora e mês no Safari.

   O WebKit dá a esses campos uma aparência de sistema com largura
   intrínseca própria, que ignora o `width: 100%` da regra acima. No
   iPhone isso fazia o campo de data ficar alguns pixels mais largo que
   os vizinhos, encostar na borda e empurrar o formulário — a rolagem
   lateral sutil dentro do modal de novo lançamento.

   `appearance: none` devolve o controle da largura ao CSS.
   `min-width: 0` impede que o conteúdo interno estabeleça um piso.
   O valor interno vem centralizado por padrão no iOS; alinhar à
   esquerda deixa a data na mesma posição do texto dos outros campos.
   ----------------------------------------------------------------- */
.input[type="date"],
.input[type="time"],
.input[type="datetime-local"],
.input[type="month"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  max-width: 100%;
  text-align: left;
}
.input[type="date"]::-webkit-date-and-time-value,
.input[type="time"]::-webkit-date-and-time-value,
.input[type="datetime-local"]::-webkit-date-and-time-value,
.input[type="month"]::-webkit-date-and-time-value {
  text-align: left;
  margin: 0;
}
.input[type="date"]::-webkit-calendar-picker-indicator { margin-left: auto; }

/* Campo de formulário nunca pode alargar a coluna que o contém: sem
   isto, um único campo teimoso arrasta a grade inteira. */
.form-grid > *, .form-grid-3 > * { min-width: 0; }

.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--brand-teal-600);
  box-shadow: 0 0 0 3px var(--brand-teal-100);
}
[data-theme="dark"] .input:focus, [data-theme="dark"] .select:focus, [data-theme="dark"] .textarea:focus {
  box-shadow: 0 0 0 3px rgba(18, 160, 133, 0.22);
}
.input.is-invalid, .select.is-invalid { border-color: var(--negative); }
.input::placeholder, .textarea::placeholder { color: var(--text-muted); }
.input:disabled, .select:disabled { background: var(--surface-3); color: var(--text-muted); cursor: not-allowed; }
.select {
  appearance: none; -webkit-appearance: none;
  padding-right: 30px; cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237A8CA0' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: right 9px center;
}
.input-group { position: relative; display: flex; align-items: center; }
.input-group .input { padding-left: 40px; }
.input-group .prefix {
  position: absolute; left: 12px; color: var(--text-muted);
  font-size: var(--fs-sm); font-weight: 600; pointer-events: none;
}
.input-group .suffix-btn { position: absolute; right: 4px; }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--sp-4); }
.form-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 var(--sp-4); }
.col-span-2 { grid-column: span 2; }
.col-span-3 { grid-column: span 3; }

.checkbox, .radio { display: flex; align-items: flex-start; gap: var(--sp-2); cursor: pointer; font-size: var(--fs-base); user-select: none; }
.checkbox input, .radio input { width: 17px; height: 17px; margin: 1px 0 0; accent-color: var(--brand-teal-600); flex: none; cursor: pointer; }

/* Rótulo e switch como um bloco só: o gap fixo mantém o controle
   ligado ao seu texto, e o auto-margin final absorve a sobra da
   coluna sem afastar os dois. */
.field-switch { display: flex; align-items: center; gap: var(--sp-3); }
.field-switch > div:first-child { min-width: 0; }
.field-switch > .switch { margin-right: auto; }

.switch { position: relative; display: inline-block; width: 40px; height: 22px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track {
  position: absolute; inset: 0; background: var(--border-strong);
  border-radius: var(--r-full); transition: background var(--transition);
}
.switch .track::before {
  content: ""; position: absolute; width: 18px; height: 18px; left: 2px; top: 2px;
  background: #fff; border-radius: 50%; transition: transform var(--transition); box-shadow: var(--sh-xs);
}
.switch input:checked + .track { background: var(--brand-teal-600); }
.switch input:checked + .track::before { transform: translateX(18px); }

.segmented {
  display: inline-flex; background: var(--surface-3); border-radius: var(--r-md);
  padding: 3px; gap: 2px; border: 1px solid var(--border);
}
.segmented button {
  padding: 5px var(--sp-3); border-radius: 7px;
  font-size: var(--fs-sm); font-weight: 600; color: var(--text-secondary);
  transition: background var(--transition), color var(--transition); white-space: nowrap;
}
.segmented button.active { background: var(--surface); color: var(--text); box-shadow: var(--sh-xs); }

/* ---------------------------------------------------------------
   8. CARDS
   --------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-xs);
}
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--border);
}
.card-head h3 { font-size: var(--fs-md); font-weight: 650; }
.card-head .sub { font-size: var(--fs-xs); color: var(--text-muted); margin-top: 1px; }
.card-body { padding: var(--sp-5); }
.card-body.tight { padding: var(--sp-3); }
.card-body.flush { padding: 0; }
.card-foot { padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--border); background: var(--surface-2); border-radius: 0 0 var(--r-lg) var(--r-lg); }

/* KPI
   Altura minima fixa e rodape empurrado para baixo garantem que todos
   os cartoes fiquem alinhados, mesmo quando a legenda ocupa duas linhas
   em um card e uma linha em outro. */
.kpi-grid {
  display: grid; gap: var(--sp-4);
  /* auto-fit e nao auto-fill: com auto-fill o navegador cria trilhas
     vazias sobrando a direita, e a fileira deixa de acompanhar a
     largura da faixa de indicadores e dos paineis abaixo. */
  grid-template-columns: repeat(auto-fit, minmax(214px, 1fr));
  grid-auto-rows: 1fr;
}
.kpi {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--sp-4) var(--sp-5);
  box-shadow: var(--sh-xs); position: relative; overflow: hidden;
  transition: box-shadow var(--transition), transform var(--transition);
  display: flex; flex-direction: column;
  /* Altura mínima existe para alinhar os cartões numa linha, não para
     reservar espaço vazio. Em coluna única — que é o caso do celular —
     não há vizinho para alinhar, e o mínimo só empurra a próxima
     informação para longe do polegar. */
  min-height: 128px;
}
.kpi:hover { box-shadow: var(--sh-md); transform: translateY(-1px); }
.kpi-label {
  font-size: var(--fs-xs); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.06em; font-weight: 650;
  line-height: 1.3; min-height: 15px;
}
.kpi-value {
  font-size: var(--fs-2xl); font-weight: 650; letter-spacing: -0.03em;
  margin-top: 6px; font-variant-numeric: tabular-nums; line-height: 1.15;
}
.kpi-value.sm { font-size: var(--fs-xl); }
.kpi-meta {
  font-size: var(--fs-xs); color: var(--text-muted);
  margin-top: auto; padding-top: 6px; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: 30px;
}
.kpi-accent { position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--brand-teal-600); }
.kpi-accent.navy { background: var(--brand-navy-700); }
.kpi-accent.neg { background: var(--negative); }
.kpi-accent.warn { background: var(--warning); }
.kpi-accent.info { background: var(--info); }

.kpi-hero {
  background: var(--brand-gradient); color: var(--text-inverse);
  border: none; position: relative; overflow: hidden;
}
.kpi-hero::after {
  content: ""; position: absolute; width: 220px; height: 220px;
  right: -80px; top: -110px; border-radius: 50%; background: rgba(255,255,255,0.07);
}
.kpi-hero .kpi-label { color: rgba(255,255,255,0.7); }
.kpi-hero .kpi-meta { color: rgba(255,255,255,0.72); }

/* ---------------------------------------------------------------
   9. TABELAS
   --------------------------------------------------------------- */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.tbl { font-size: var(--fs-sm); }
table.tbl thead th {
  text-align: left; font-weight: 650; font-size: var(--fs-xs);
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted);
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border);
  background: var(--surface-2); white-space: nowrap; position: sticky; top: 0; z-index: 2;
}
/* O seletor acima e mais especifico que as utilitarias .txt-right e
   .txt-center, entao o text-align:left vencia e o titulo da coluna
   ficava a esquerda enquanto os dados iam para a direita. Estas duas
   regras devolvem o alinhamento declarado em cada coluna. */
table.tbl thead th.txt-right { text-align: right; }
table.tbl thead th.txt-center { text-align: center; }

table.tbl thead th.sortable { cursor: pointer; user-select: none; }
table.tbl thead th.sortable:hover { color: var(--text); }
table.tbl tbody td { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border); vertical-align: middle; }
table.tbl tbody tr { transition: background var(--transition); }
table.tbl tbody tr:hover { background: var(--surface-hover); }
table.tbl tbody tr:last-child td { border-bottom: none; }
table.tbl tfoot td { padding: var(--sp-3) var(--sp-4); font-weight: 650; border-top: 2px solid var(--border-strong); background: var(--surface-2); }
table.tbl .row-actions { display: flex; gap: 2px; justify-content: flex-end; opacity: 0; transition: opacity var(--transition); }
table.tbl tbody tr:hover .row-actions { opacity: 1; }
@media (hover: none) { table.tbl .row-actions { opacity: 1; } }
table.tbl .cell-strong { font-weight: 600; color: var(--text); }

/* ---------------------------------------------------------------
   10. BADGES, PILLS, AVATARES
   --------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--r-full);
  font-size: var(--fs-xs); font-weight: 650; white-space: nowrap;
  background: var(--neutral-bg); color: var(--text-secondary);
}
.badge-pos { background: var(--positive-bg); color: var(--positive); }
.badge-neg { background: var(--negative-bg); color: var(--negative); }
.badge-warn { background: var(--warning-bg); color: var(--warning); }
.badge-info { background: var(--info-bg); color: var(--info); }
.badge-dot::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

.tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 8px; border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: 500;
  background: var(--surface-3); color: var(--text-secondary); border: 1px solid var(--border);
}

.avatar {
  width: 34px; height: 34px; border-radius: var(--r-full);
  display: grid; place-items: center; font-weight: 650; font-size: var(--fs-sm);
  background: var(--brand-teal-600); color: var(--text-inverse); flex: none; letter-spacing: -0.02em;
}
.avatar.sm { width: 26px; height: 26px; font-size: var(--fs-xs); }
.avatar.lg { width: 48px; height: 48px; font-size: var(--fs-lg); }

.cat-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; display: inline-block; }
.cat-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-sm); font-weight: 500;
}

.progress { height: 7px; background: var(--surface-3); border-radius: var(--r-full); overflow: hidden; }
.progress > div { height: 100%; background: var(--brand-teal-600); border-radius: var(--r-full); transition: width 400ms cubic-bezier(0.4,0,0.2,1); }
.progress.thin { height: 5px; }
.progress > div.warn { background: var(--warning); }
.progress > div.neg { background: var(--negative); }

/* ---------------------------------------------------------------
   11. MODAIS, DRAWER, TOAST
   --------------------------------------------------------------- */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(12, 27, 41, 0.45);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  display: flex; align-items: center; justify-content: center;
  padding: var(--sp-4); overflow-y: auto;
  animation: fadeIn 140ms ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.modal {
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--sh-xl); width: 100%; max-width: 540px;
  max-height: calc(100vh - 48px); max-height: calc(100dvh - 48px);
  display: flex; flex-direction: column;
  animation: modalIn 200ms cubic-bezier(0.16, 1, 0.3, 1); margin: auto;
}
@keyframes modalIn { from { opacity: 0; transform: translateY(14px) scale(0.985); } to { opacity: 1; transform: none; } }
.modal.md { max-width: 680px; }
.modal.lg { max-width: 880px; }
.modal.xl { max-width: 1120px; }
.modal-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-5) var(--sp-4); border-bottom: 1px solid var(--border); flex: none;
}
.modal-head h3 { font-size: var(--fs-lg); }
.modal-head .sub { font-size: var(--fs-sm); color: var(--text-muted); margin-top: 3px; }
.modal-body { padding: var(--sp-5); overflow-y: auto; flex: 1; }
.modal-foot {
  display: flex; justify-content: flex-end; gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--border);
  background: var(--surface-2); border-radius: 0 0 var(--r-lg) var(--r-lg); flex: none;
}

#toasts {
  position: fixed; bottom: var(--sp-5); right: var(--sp-5); z-index: 200;
  display: flex; flex-direction: column; gap: var(--sp-2); max-width: 380px;
}
.toast {
  background: var(--brand-navy-800); color: var(--text-inverse);
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  box-shadow: var(--sh-lg); font-size: var(--fs-sm);
  display: flex; align-items: flex-start; gap: var(--sp-3);
  animation: toastIn 240ms cubic-bezier(0.16, 1, 0.3, 1);
  border-left: 3px solid var(--brand-teal-500);
}
.toast.error { border-left-color: var(--negative); }
.toast.warn { border-left-color: var(--warning); }
.toast.out { animation: toastOut 200ms ease forwards; }
@keyframes toastIn { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateX(24px); } }

/* ---------------------------------------------------------------
   12. ESTADOS VAZIOS / LOADING
   --------------------------------------------------------------- */
.empty { padding: var(--sp-12) var(--sp-5); text-align: center; }
.empty-icon {
  width: 52px; height: 52px; margin: 0 auto var(--sp-4);
  border-radius: var(--r-lg); background: var(--surface-3);
  display: grid; place-items: center; color: var(--text-muted);
}
.empty h4 { font-size: var(--fs-md); margin-bottom: var(--sp-2); }
.empty p { color: var(--text-muted); font-size: var(--fs-sm); max-width: 42ch; margin: 0 auto var(--sp-4); line-height: 1.6; }

.skeleton {
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-hover) 50%, var(--surface-3) 75%);
  background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: var(--r-sm);
}
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

.spinner {
  width: 15px; height: 15px; border: 2px solid currentColor;
  border-right-color: transparent; border-radius: 50%;
  animation: spin 0.65s linear infinite; display: inline-block;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------
   13. GRÁFICOS (SVG nativo)
   --------------------------------------------------------------- */
.chart { width: 100%; display: block; overflow: visible; }
/* O texto dentro do SVG é medido em unidades do viewBox, não em pixels
   de tela. Num viewBox de 760 comprimido para 324px a escala é 0,426 e
   `font-size: 11px` renderiza a 4,7px — ilegível, e foi o que
   transformou seis gráficos em decoração. Estes valores compensam a
   compressão para devolver ~11px reais. */
@media (max-width: 820px) {
  .chart .axis-text { font-size: 19px; }
}
@media (max-width: 520px) {
  .chart .axis-text { font-size: 26px; }
}
.chart .grid-line { stroke: var(--border); stroke-width: 1; }
.chart .axis-text { fill: var(--text-muted); font-size: var(--fs-xs); font-family: var(--font); font-variant-numeric: tabular-nums; }
.chart .bar { transition: opacity var(--transition); }
.chart .bar:hover { opacity: 0.78; }
.chart .dot { transition: r var(--transition); }
.chart-legend { display: flex; flex-wrap: wrap; gap: var(--sp-3) var(--sp-4); margin-top: var(--sp-4); }
.chart-legend .li { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--text-secondary); }
.chart-legend .sw { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.chart-tip {
  position: fixed; z-index: 300; pointer-events: none;
  background: var(--brand-navy-900); color: var(--text-inverse);
  padding: 7px 10px; border-radius: var(--r-sm);
  font-size: var(--fs-xs); box-shadow: var(--sh-lg); white-space: nowrap; line-height: 1.5;
}
.chart-empty { display: grid; place-items: center; color: var(--text-muted); font-size: var(--fs-sm); }

.donut-center { text-anchor: middle; }
.donut-center .v { fill: var(--text); font-size: 19px; font-weight: 650; font-family: var(--font); }
.donut-center .l { fill: var(--text-muted); font-size: var(--fs-xs); font-family: var(--font); }

/* ---------------------------------------------------------------
   14. COMPONENTES ESPECÍFICOS
   --------------------------------------------------------------- */
/* Faixa de indicadores */
/* min-width/max-width segura a barra dentro da coluna. Sem eles, o
   item flexível cresce até caber e é a PÁGINA que ganha rolagem
   horizontal, em vez da barra rolar por dentro — no celular isso
   arrastava o dashboard inteiro para o lado. */
.indicadores-bar {
  display: flex; gap: 0; overflow-x: auto; min-width: 0; max-width: 100%;
  overscroll-behavior-x: contain;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-xs); scrollbar-width: none;
}
.indicadores-bar::-webkit-scrollbar { display: none; }
.ind-item { padding: var(--sp-3) var(--sp-5); border-right: 1px solid var(--border); flex: 1; min-width: 128px; }
.ind-item:last-child { border-right: none; }
.ind-item .l { font-size: var(--fs-xs); color: var(--text-muted); font-weight: 650; text-transform: uppercase; letter-spacing: 0.06em; }
.ind-item .v { font-size: var(--fs-lg); font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; margin-top: 1px; }
.ind-item .d { font-size: var(--fs-xs); color: var(--text-muted); margin-top: 1px; }
.ind-stale { color: var(--warning); }

/* Cartão de crédito visual */
.credit-card {
  background: var(--brand-gradient); color: var(--text-inverse);
  border-radius: var(--r-lg); padding: var(--sp-5);
  min-height: 158px; display: flex; flex-direction: column; justify-content: space-between;
  position: relative; overflow: hidden; box-shadow: var(--sh-md);
}
.credit-card::after {
  content: ""; position: absolute; width: 190px; height: 190px;
  right: -70px; bottom: -100px; border-radius: 50%; background: rgba(255,255,255,0.07);
}
.credit-card > * { position: relative; z-index: 1; }
.credit-card .cc-bank { font-size: var(--fs-md); font-weight: 650; }
.credit-card .cc-brand { font-size: var(--fs-xs); opacity: 0.7; text-transform: uppercase; letter-spacing: 0.1em; }
.credit-card .cc-value { font-size: var(--fs-xl); font-weight: 650; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.credit-card .cc-label { font-size: var(--fs-xs); opacity: 0.72; }
.credit-card .progress { background: rgba(255,255,255,0.2); }
.credit-card .progress > div { background: #fff; }
.credit-card.inativo { filter: grayscale(0.75); opacity: 0.7; }

/* Conta bancária */
/* Exemplos clicaveis do lancamento inteligente */
.nlp-exemplos {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-2); margin-top: var(--sp-3);
}
.nlp-exemplos .lbl {
  font-size: var(--fs-xs); color: var(--text-muted); font-weight: 650;
  text-transform: uppercase; letter-spacing: 0.05em;
}
.nlp-exemplo {
  font-size: var(--fs-xs); font-family: var(--font-mono);
  padding: 4px 10px; border-radius: var(--r-full);
  background: var(--surface-3); color: var(--text-secondary);
  border: 1px solid var(--border);
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.nlp-exemplo:hover {
  background: var(--brand-teal-50); color: var(--brand-teal-600);
  border-color: var(--brand-teal-100);
}
[data-theme="dark"] .nlp-exemplo:hover { background: var(--surface-hover); color: var(--brand-teal-500); }

/* Conta bancaria */
.conta-nome {
  font-weight: 650; font-size: var(--fs-base); line-height: 1.35;
  overflow-wrap: anywhere;
}
.conta-nome .badge { vertical-align: middle; }
.conta-acoes {
  display: flex; align-items: center; gap: var(--sp-1);
  margin-top: var(--sp-4); padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
}
.conta-acoes .btn-ghost { padding: 0 8px; }

.account-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: var(--sp-4) var(--sp-5); box-shadow: var(--sh-xs);
  transition: box-shadow var(--transition), transform var(--transition);
  display: flex; flex-direction: column;
}
.account-card:hover { box-shadow: var(--sh-md); transform: translateY(-1px); }
.account-card.inativa { opacity: 0.62; }
.bank-mark {
  width: 38px; height: 38px; border-radius: var(--r-md); flex: none;
  display: grid; place-items: center; font-weight: 700; font-size: var(--fs-sm);
  color: var(--text-inverse); letter-spacing: -0.03em;
}

/* Timeline / lista */
.list-row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5); border-bottom: 1px solid var(--border);
  transition: background var(--transition);
}
.list-row:last-child { border-bottom: none; }
.list-row:hover { background: var(--surface-hover); }
.list-row .li-main { flex: 1; min-width: 0; }
.list-row .li-title { font-weight: 600; font-size: var(--fs-base); }
.list-row .li-sub { font-size: var(--fs-xs); color: var(--text-muted); margin-top: 1px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.list-row .li-value { font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Painel de pendencias */
.pend-resumo {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--sp-3); padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--border); background: var(--surface-2);
}
.pend-resumo .l {
  display: block; font-size: var(--fs-xs); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: 0.05em; font-weight: 650;
}
.pend-resumo .v { font-size: var(--fs-md); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }

.pend-lista { max-height: 460px; overflow-y: auto; }

.pend-mes {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px var(--sp-5); background: var(--surface-3);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm); font-weight: 650; text-transform: capitalize;
  position: sticky; top: 0; z-index: 2;
}

.pend-dia { border-bottom: 1px solid var(--border); }
.pend-dia:last-child { border-bottom: none; }
.pend-dia-head {
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%; padding: 9px var(--sp-5); text-align: left;
  transition: background var(--transition);
}
.pend-dia-head:hover { background: var(--surface-hover); }
.pend-dia-head .dt { font-weight: 600; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.pend-dia-head .cv { margin-left: auto; font-weight: 650; font-size: var(--fs-sm); }
.pend-dia-head .ic { color: var(--text-muted); flex: none; transition: transform var(--transition); }
.pend-dia.aberto .pend-dia-head .ic { transform: rotate(180deg); }

.pend-corpo { display: none; padding-bottom: var(--sp-2); }
.pend-dia.aberto .pend-corpo { display: block; }

.pend-cat {
  display: flex; align-items: center; gap: 6px;
  padding: 5px var(--sp-5) 5px 42px;
  font-size: var(--fs-xs); font-weight: 650; color: var(--text-secondary);
}
.pend-cat .cv { margin-left: auto; font-variant-numeric: tabular-nums; }

.pend-item {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 5px var(--sp-5) 5px 56px; font-size: var(--fs-sm);
  transition: background var(--transition);
}
.pend-item:hover { background: var(--surface-hover); }
.pend-item .desc { flex: 1; min-width: 0; color: var(--text-secondary); }
.pend-item .val { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.pend-acoes { display: flex; gap: 2px; flex: none; opacity: 0; transition: opacity var(--transition); }
.pend-item:hover .pend-acoes { opacity: 1; }
@media (hover: none) { .pend-acoes { opacity: 1; } }

/* Carrossel de cartoes no dashboard */
.cc-scroller {
  display: flex; gap: var(--sp-3);
  overflow-x: auto; padding-bottom: var(--sp-2);
  scroll-snap-type: x proximity;
}
.cc-mini {
  flex: 0 0 232px; scroll-snap-align: start;
  border: 1px solid var(--border); border-radius: var(--r-md);
  padding: var(--sp-4); background: var(--surface-2);
  transition: box-shadow var(--transition), transform var(--transition), border-color var(--transition);
}
.cc-mini:hover { box-shadow: var(--sh-md); transform: translateY(-1px); border-color: var(--border-strong); }
.cc-mini-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2); margin-top: var(--sp-3);
  padding-top: var(--sp-3); border-top: 1px solid var(--border);
  font-size: var(--fs-xs); font-weight: 600;
}

/* Categorias: painel mestre e detalhe */
.cat-workspace { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); align-items: start; }
.cat-painel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-xs); overflow: hidden;
}
.cat-painel-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.cat-painel-head h3 { font-size: var(--fs-sm); font-weight: 650; }
.cat-acoes { display: flex; gap: 2px; flex: none; }
.cat-acoes .icon-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.cat-acoes .icon-btn:not(:disabled):hover { background: var(--surface-3); color: var(--brand-teal-600); }

.cat-lista { max-height: 420px; overflow-y: auto; padding: var(--sp-2); }
.cat-item {
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%; padding: 8px var(--sp-3); border-radius: var(--r-sm);
  text-align: left; font-size: var(--fs-sm);
  transition: background var(--transition), color var(--transition);
}
.cat-item:hover { background: var(--surface-hover); }
.cat-item.ativo { background: var(--brand-teal-50); color: var(--brand-teal-600); font-weight: 650; }
[data-theme="dark"] .cat-item.ativo { background: var(--surface-3); color: var(--brand-teal-500); }
.cat-item .cat-nome { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cat-item .cat-valor { flex: none; font-size: var(--fs-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.cat-item.ativo .cat-valor { color: inherit; }
.cat-vazio {
  padding: var(--sp-8) var(--sp-4); text-align: center;
  font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.7;
}

@media (max-width: 780px) {
  .cat-workspace { grid-template-columns: 1fr; }
  .cat-lista { max-height: 300px; }
}

/* Opcoes de limpeza de dados */
.limpeza-op {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4);
  padding: var(--sp-4); border: 1px solid var(--border); border-radius: var(--r-md);
}
.limpeza-nome { font-weight: 650; font-size: var(--fs-sm); }
.limpeza-desc { font-size: var(--fs-xs); color: var(--text-muted); line-height: 1.55; margin-top: 3px; }
.limpeza-op .btn { flex: none; }
@media (max-width: 780px) {
  .limpeza-op { flex-direction: column; align-items: stretch; }
  .limpeza-op .btn { width: 100%; }
}

/* Manual de instrucoes */
.ajuda-layout { display: grid; grid-template-columns: 258px 1fr; gap: var(--sp-4); align-items: start; }
.ajuda-indice {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-xs);
  padding: var(--sp-3); position: sticky; top: calc(var(--topbar-h) + var(--sp-4));
  max-height: calc(100dvh - var(--topbar-h) - var(--sp-8)); overflow-y: auto;
}
.ajuda-busca { margin-bottom: var(--sp-2); }
.ajuda-busca .input { height: 34px; font-size: var(--fs-sm); }
.ajuda-grupo { color: var(--text-muted); padding: var(--sp-4) var(--sp-2) var(--sp-1); }
.ajuda-item {
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%; padding: 7px var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--fs-sm); font-weight: 500; color: var(--text-secondary); text-align: left;
  transition: background var(--transition), color var(--transition);
}
.ajuda-item .ic { flex: none; opacity: 0.7; }
.ajuda-item:hover { background: var(--surface-hover); color: var(--text); }
.ajuda-item.active { background: var(--brand-teal-50); color: var(--brand-teal-600); font-weight: 650; }
.ajuda-item.active .ic { opacity: 1; }
[data-theme="dark"] .ajuda-item.active { background: var(--surface-3); color: var(--brand-teal-500); }

.ajuda-conteudo { max-width: 860px; }
.ajuda-cabecalho { margin-bottom: var(--sp-5); padding-bottom: var(--sp-4); border-bottom: 1px solid var(--border); }
.ajuda-grupo-tag {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--brand-teal-600); font-weight: 700;
}
.ajuda-titulo { font-size: var(--fs-2xl); margin-top: 4px; letter-spacing: -0.025em; }

.aj-h {
  font-size: var(--fs-md); font-weight: 650; margin: var(--sp-6) 0 var(--sp-3);
  padding-top: var(--sp-2);
}
.aj-h:first-child { margin-top: 0; padding-top: 0; }
.aj-sub { font-size: var(--fs-base); font-weight: 650; margin: var(--sp-5) 0 var(--sp-2); }
.aj-p { font-size: var(--fs-md); line-height: 1.75; color: var(--text-secondary); margin-bottom: var(--sp-3); }
.aj-p b, .aj-lista b, .aj-passos b { color: var(--text); font-weight: 650; }
.aj-lista { margin: 0 0 var(--sp-4); padding-left: var(--sp-5); }
.aj-lista li {
  font-size: var(--fs-md); line-height: 1.7; color: var(--text-secondary);
  margin-bottom: var(--sp-2); position: relative;
}
.aj-lista li::before {
  content: ""; position: absolute; left: -16px; top: 10px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--brand-teal-600);
}
.aj-passos { counter-reset: passo; margin: 0 0 var(--sp-4); padding-left: 0; }
.aj-passos li {
  counter-increment: passo; position: relative; padding-left: 34px;
  font-size: var(--fs-md); line-height: 1.7; color: var(--text-secondary);
  margin-bottom: var(--sp-3);
}
.aj-passos li::before {
  content: counter(passo); position: absolute; left: 0; top: 1px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--brand-teal-600); color: var(--text-inverse);
  font-size: var(--fs-xs); font-weight: 700;
  display: grid; place-items: center;
}
.aj-nota { margin: var(--sp-4) 0; }
.ajuda-conteudo .formula { margin-bottom: var(--sp-4); }
.ajuda-conteudo .table-wrap { margin-bottom: var(--sp-4); border: 1px solid var(--border); border-radius: var(--r-md); }
.ajuda-nav {
  display: flex; justify-content: space-between; gap: var(--sp-3);
  margin-top: var(--sp-8); padding-top: var(--sp-5); border-top: 1px solid var(--border);
}
.ajuda-nav .btn { max-width: 46%; overflow: hidden; }
@media print {
  .ajuda-layout, .ajuda-nav { display: none !important; }
  .ajuda-print { display: block !important; }
  .aj-print-h { font-size: 16px; margin: 22px 0 10px; padding-bottom: 6px; border-bottom: 1px solid #D2DAE3; break-after: avoid; }
}

/* Alertas */
.alert {
  display: flex; gap: var(--sp-3); align-items: flex-start;
  padding: var(--sp-3) var(--sp-4); border-radius: var(--r-md);
  font-size: var(--fs-sm); line-height: 1.55; border: 1px solid transparent;
}
.alert-info { background: var(--info-bg); color: var(--info); border-color: rgba(42,107,176,0.18); }
.alert-warn { background: var(--warning-bg); color: var(--warning); border-color: rgba(181,118,26,0.2); }
.alert-neg { background: var(--negative-bg); color: var(--negative); border-color: rgba(199,65,63,0.2); }
.alert-pos { background: var(--positive-bg); color: var(--positive); border-color: rgba(14,140,116,0.2); }
.alert b { font-weight: 650; }

/* Memória de cálculo */
.memoria { font-size: var(--fs-sm); }
.memoria h4 {
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: 0.07em;
  color: var(--text-muted); margin: var(--sp-5) 0 var(--sp-2); font-weight: 650;
}
.memoria h4:first-child { margin-top: 0; }
.memoria-row {
  display: flex; justify-content: space-between; gap: var(--sp-4);
  padding: 7px 0; border-bottom: 1px dashed var(--border);
}
.memoria-row:last-child { border-bottom: none; }
.memoria-row .k { color: var(--text-secondary); }
.memoria-row .v { font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.formula {
  background: var(--surface-3); border: 1px solid var(--border);
  border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4);
  font-family: var(--font-mono); font-size: var(--fs-sm);
  line-height: 1.85; overflow-x: auto; color: var(--text-secondary);
}
.formula .hl { color: var(--brand-teal-600); font-weight: 600; }

/* Sugestão do NLP */
.nlp-box { border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.nlp-input-wrap { position: relative; }
/* Estrela bem junto da borda esquerda: 7px de respiro, o suficiente
   para nao encostar na linha do campo. Texto 18px depois dela. */
.nlp-input {
  width: 100%; height: 50px; padding: 0 var(--sp-4) 0 43px;
  border: 1px solid var(--border-strong); border-radius: var(--r-md);
  background: var(--surface); font-size: var(--fs-md); color: var(--text);
}
.nlp-input:focus { outline: none; border-color: var(--brand-teal-600); box-shadow: 0 0 0 3px var(--brand-teal-100); }
.nlp-input-wrap .ic {
  position: absolute; left: 7px; top: 50%; transform: translateY(-50%);
  color: var(--brand-teal-600); display: block; pointer-events: none;
}
.nlp-preview {
  margin-top: var(--sp-3); padding: var(--sp-4);
  background: var(--brand-teal-50); border: 1px solid var(--brand-teal-100);
  border-radius: var(--r-md);
}
[data-theme="dark"] .nlp-preview { background: var(--surface-2); border-color: var(--border); }
.nlp-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.nlp-chip {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 5px 10px; font-size: var(--fs-xs);
}
.nlp-chip .k { color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; font-size: var(--fs-xs); display: block; font-weight: 650; }
.nlp-chip .v { font-weight: 650; font-size: var(--fs-sm); }
.nlp-conf { font-size: var(--fs-xs); color: var(--text-muted); }

/* Meta */
.goal-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: var(--sp-5); box-shadow: var(--sh-xs); }
.goal-ring { position: relative; width: 78px; height: 78px; flex: none; }
.goal-ring .pct {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-weight: 650; font-size: var(--fs-base); font-variant-numeric: tabular-nums;
}

/* Filtros */
.filter-bar {
  display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); margin-bottom: var(--sp-4);
}
.filter-bar .input, .filter-bar .select { height: 34px; width: auto; min-width: 120px; font-size: var(--fs-sm); }
.filter-bar .input[type="search"] { min-width: 190px; }

/* Os filtros avançados. No computador são parte da mesma linha; no
   celular se recolhem atrás do botão.

   Esta regra vem ANTES do bloco de celular de propósito: com a mesma
   especificidade vence quem vem depois, e foi assim que o botão de
   alertas nasceu invisível no v84. */
.filter-extra { display: contents; }
.filtros-toggle { display: none; }
.badge-filtro {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 6px;
  border-radius: 9px; background: var(--primary); color: #fff;
  font-size: var(--fs-xs); font-weight: 700;
}

.month-nav { display: flex; align-items: center; gap: var(--sp-1); background: var(--surface-3); border-radius: var(--r-md); padding: 3px; border: 1px solid var(--border); }
.month-nav .lbl { font-weight: 650; font-size: var(--fs-sm); min-width: 118px; text-align: center; text-transform: capitalize; }

/* Tabs */
.tabs { display: flex; gap: var(--sp-1); border-bottom: 1px solid var(--border); margin-bottom: var(--sp-5); overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs button {
  padding: var(--sp-3) var(--sp-4); font-size: var(--fs-sm); font-weight: 600;
  color: var(--text-muted); border-bottom: 2px solid transparent;
  margin-bottom: -1px; white-space: nowrap; transition: color var(--transition), border-color var(--transition);
}
.tabs button:hover { color: var(--text); }
.tabs button.active { color: var(--brand-teal-600); border-bottom-color: var(--brand-teal-600); }

/* Grids de página */
.grid-2 { display: grid; gap: var(--sp-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { display: grid; gap: var(--sp-4); grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Mesmo motivo do kpi-grid: auto-fit evita trilha vazia e mantem as
   fileiras alinhadas com os demais blocos da pagina. */
.grid-auto { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(288px, 1fr)); }
.grid-auto-lg { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }

/* Contrapartida do auto-fit: com um unico item ele esticaria pela
   largura inteira. Navegadores sem :has() apenas ignoram esta regra. */
.grid-auto:has(> :only-child) { grid-template-columns: minmax(288px, 520px); }
.grid-auto-lg:has(> :only-child) { grid-template-columns: minmax(360px, 560px); }
.grid-2-1 { display: grid; gap: var(--sp-4); grid-template-columns: 1.7fr 1fr; }

/* Item de grid nasce com min-width:auto, ou seja, nunca fica menor que
   o conteúdo. Um cabeçalho de cartão com título longo e botões ao lado
   empurrava a coluna além da tela, e quem rolava para o lado era a
   página inteira. Deixar encolher é o que faz "1fr" valer no celular. */
.grid-auto > *, .grid-auto-lg > *, .grid-2 > *, .grid-2-1 > *, .grid-3 > * { min-width: 0; }

/* No computador o painel de alertas fica sempre aberto: há espaço, e
   botão que não faz nada é pior que botão nenhum. A regra vem ANTES do
   bloco de celular de propósito: com a mesma especificidade, quem vem
   depois vence, e o botão precisa reaparecer lá. */
.alertas-toggle { display: none; }

/* Nav inferior mobile */
.mobile-nav { display: none; }

/* ---------------------------------------------------------------
   15. RESPONSIVO
   --------------------------------------------------------------- */
@media (max-width: 1180px) {
  .grid-2-1, .grid-3 { grid-template-columns: 1fr; }
}

@media (max-width: 960px) {
  #auth-screen { grid-template-columns: 1fr; }
  .auth-brand { display: none; }
  .auth-mobile-logo { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-8); }
  .auth-mobile-logo .mobile-icone { width: 42px; height: 42px; }
  .auth-mobile-logo .mobile-marca { height: 24px; width: auto; }
  .grid-2 { grid-template-columns: 1fr; }
  .form-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .col-span-3 { grid-column: span 2; }
}

@media (max-width: 780px) {
  :root { --topbar-h: 56px; }

  .sidebar { transform: translateX(-100%); box-shadow: var(--sh-xl); width: 272px; }
  .sidebar.open { transform: none; }
  .main { margin-left: 0; }
  .topbar .menu-toggle { display: grid; }
  .content { padding: var(--sp-4) var(--sp-4) 84px; }
  .topbar { padding: 0 var(--sp-4); gap: var(--sp-3); }
  .topbar h1 { font-size: var(--fs-md); }
  .topbar-sub { display: none; }

  /* -----------------------------------------------------------
     Busca recolhida vira botão de lupa.

     Encolher um input[type=search] para 40px não funciona no Safari:
     o campo de busca tem aparência própria de sistema, com largura
     mínima e recuo interno que ignoram a regra — o texto do
     placeholder escapava para fora da caixa. Zerar a aparência e
     esconder o texto enquanto está recolhido resolve nos dois motores.
     ----------------------------------------------------------- */
  .search-global { width: auto; margin-left: auto; flex: none; }
  .search-global input {
    -webkit-appearance: none; appearance: none;
    box-sizing: border-box;
    width: 44px; height: 44px; padding: 0;
    /* 16px mesmo recolhido: o Safari decide ampliar no momento do
       toque, antes de o campo abrir. */
    font-size: 16px;
    color: transparent; cursor: pointer;
  }
  .search-global input::placeholder { color: transparent; }
  .search-global input::-webkit-search-decoration,
  .search-global input::-webkit-search-cancel-button,
  .search-global input::-webkit-search-results-button { -webkit-appearance: none; display: none; }

  .search-global input:focus {
    width: min(62vw, 280px); padding: 0 var(--sp-3) 0 36px;
    color: var(--text); cursor: text;
  }
  .search-global input:focus::placeholder { color: var(--text-muted); }
  .search-global .ic { left: 14px; }
  .search-global input:focus ~ .ic, .search-global:focus-within .ic { left: 12px; }
  .search-global .search-results { width: min(84vw, 320px); left: auto; right: 0; }

  .sidebar-overlay {
    position: fixed; inset: 0; z-index: 55;
    background: rgba(12, 27, 41, 0.5); backdrop-filter: blur(2px);
    animation: fadeIn 140ms ease;
  }

  .mobile-nav {
    display: flex; position: fixed; bottom: 0; left: 0; right: 0; z-index: 45;
    background: var(--surface); border-top: 1px solid var(--border);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
    box-shadow: 0 -1px 12px rgba(16, 38, 58, 0.07);
  }
  .mobile-nav button {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 5px 2px; font-size: var(--fs-xs); font-weight: 600; color: var(--text-muted);
    border-radius: var(--r-sm); transition: color var(--transition);
  }
  .mobile-nav button.active { color: var(--brand-teal-600); }

  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-3); }
  .kpi { padding: var(--sp-3) var(--sp-4); min-height: 100px; }
  /* Coluna única: sem vizinho para alinhar, a altura segue o conteúdo. */
  .kpi-value { font-size: var(--fs-xl); }
  .kpi-value.sm { font-size: var(--fs-lg); }
  .kpi-meta { min-height: 28px; }
  .nlp-input { padding-left: 40px; }
  .nlp-input-wrap .ic { left: 6px; }
  .grid-auto, .grid-auto-lg { grid-template-columns: 1fr; }
  .form-grid, .form-grid-3 { grid-template-columns: 1fr; }
  .col-span-2, .col-span-3 { grid-column: span 1; }
  .card-body { padding: var(--sp-4); }
  /* Título e ações do cartão passam a quebrar em duas linhas em vez de
     alargar o cartão. */
  .card-head { padding: var(--sp-4); flex-wrap: wrap; }
  .card-head h3 { min-width: 0; overflow-wrap: anywhere; }
  .page-head h2 { font-size: var(--fs-lg); }

  .modal-backdrop { padding: 0; align-items: flex-end; }
  .modal {
    max-width: 100%; max-height: 94vh;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    animation: sheetIn 240ms cubic-bezier(0.16, 1, 0.3, 1);
  }
  @keyframes sheetIn { from { transform: translateY(100%); } to { transform: none; } }
  .modal-foot { border-radius: 0; padding-bottom: calc(var(--sp-4) + env(safe-area-inset-bottom)); }
  .modal-foot .btn { flex: 1; }

  #toasts { left: var(--sp-3); right: var(--sp-3); bottom: 78px; max-width: none; }
  .filter-bar { padding: var(--sp-3); }
  .filter-bar .input, .filter-bar .select { flex: 1; min-width: 130px; }
  /* Onze controles empilhados ocupavam 314px e empurravam o primeiro
     lançamento para além de uma tela e meia de rolagem. Ficam mês,
     período e busca; o resto entra pelo botão. */
  .filtros-toggle { display: inline-flex; align-items: center; gap: 4px; flex: 1 0 100%; justify-content: center; min-height: 44px; }
  .filter-extra { display: flex; flex-wrap: wrap; gap: var(--sp-2); width: 100%; }
  .filter-extra.filtros-recolhido { display: none; }
  .filter-extra .select, .filter-extra .input { flex: 1; min-width: 130px; }
  /* No celular a barra rola: item que estica força a barra a crescer. */
  .ind-item { flex: 0 0 auto; min-width: 116px; padding: var(--sp-3) var(--sp-4); }
  .indicadores-bar { scroll-snap-type: x proximity; }
  .ind-item { scroll-snap-align: start; }

  /* Alvo de toque na gaveta: 35px de altura é abaixo do mínimo
     confortável para o dedo. */
  .sidebar .nav-item { min-height: 44px; }
  .mobile-nav button { min-height: 46px; font-size: 11px; }
  /* -----------------------------------------------------------
     Tabela vira cartão empilhado.

     Uma linha de lançamento tem data, descrição, categoria, conta e
     valor. Em 360px isso não cabe em colunas: ou encolhe até ficar
     ilegível, ou a lista rola para o lado e a pessoa perde o valor,
     que é justamente a coluna que ela foi ver. Empilhado, cada linha
     ocupa a largura toda e o rótulo vem junto do dado.
     ----------------------------------------------------------- */
  /* -----------------------------------------------------------
     O Safari do iPhone amplia a página inteira quando o dedo toca um
     campo com fonte menor que 16px — e o zoom NÃO volta sozinho ao
     sair do campo. Era isso que deixava a tela cortada à esquerda e
     obrigava a fechar com os dedos.

     A correção é a fonte, não o viewport: travar o zoom com
     `maximum-scale=1` tiraria de quem precisa ampliar para enxergar.
     ----------------------------------------------------------- */
  .input, .select, .textarea, input, select, textarea { font-size: 16px; }
  .input, .select { height: 44px; }
  /* Os campos compactos (barra de filtros, lançamento inteligente,
     busca da ajuda) têm regra própria e venceriam a de cima. Precisam
     ser nomeados um a um: basta UM campo abaixo de 16px para o Safari
     ampliar a página inteira. */
  .filter-bar .input, .filter-bar .select { height: 44px; font-size: 16px; }
  .ajuda-busca .input { height: 44px; font-size: 16px; }
  .nlp-input { font-size: 16px; }

  /* Título da tela encurta em vez de ser cortado pela barra de ícones.
     Os ícones e o espaçamento cedem primeiro: com seis alvos de toque
     numa tela de 390px, sobrava largura para "Dashbo…" e o título
     deixava de servir para orientar quem chegou. */
  .topbar { gap: var(--sp-2); }
  .topbar h1 { min-width: 0; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar .icon-btn { width: 40px; height: 40px; }

  /* Seis alvos de toque de 40px numa tela de 390px deixavam ~110px
     para o título, e "Lançamentos" virava "Lançame…". O atalho de
     Instruções sai da barra: continua no menu do usuário, que é onde
     alguém procura ajuda de qualquer forma. */
  .topbar #btn-ajuda { display: none; }

  /* Painel de alertas recolhido: no celular ele tomava quase toda a
     primeira tela e empurrava patrimônio e saldos para baixo da dobra.
     O cabeçalho continua visível com a contagem, que é a informação
     que decide se vale abrir. */
  .card.alertas-recolhido > .card-body { display: none; }
  .alertas-toggle { display: grid; }

  table.tbl { display: block; }
  table.tbl thead { display: none; }
  table.tbl tbody, table.tbl tfoot { display: block; }

  table.tbl tbody tr {
    display: block; padding: var(--sp-3) var(--sp-4);
    border: 1px solid var(--border); border-radius: var(--r-md);
    margin-bottom: var(--sp-3); background: var(--surface);
  }
  table.tbl tbody tr:last-child { margin-bottom: 0; }

  table.tbl tbody td {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--sp-4); padding: 3px 0; border: none;
    text-align: left; white-space: normal;
  }
  table.tbl tbody td::before {
    content: attr(data-rotulo);
    flex: 0 0 auto; color: var(--text-muted);
    font-size: var(--fs-xs); font-weight: 650;
    text-transform: uppercase; letter-spacing: 0.04em;
  }
  /* Coluna sem título (ações, ícones) ocupa a linha inteira. */
  table.tbl tbody td[data-rotulo=""] { justify-content: flex-end; padding-top: var(--sp-2); }
  table.tbl tbody td[data-rotulo=""]::before { display: none; }

  /* Cabeçalho de seção e subtotal continuam sendo faixas, não cartões. */
  table.tbl tbody tr.tabela-secao,
  table.tbl tbody tr.tabela-subtotal {
    border: none; border-radius: 0; padding: var(--sp-3) 0 var(--sp-2);
    margin-bottom: var(--sp-2); background: none;
  }
  table.tbl tbody tr.tabela-secao td,
  table.tbl tbody tr.tabela-subtotal td { display: block; text-align: left; }
  table.tbl tbody tr.tabela-secao td::before { display: none; }
  /* O subtotal MANTÉM o rótulo. Sem ele, "Total de entradas" virava no
     celular uma pilha de quatro números soltos — R$ 0,00 / R$ 16.700,00
     / -- / R$ 45.545,45 — sem dizer qual é planejado, realizado,
     diferença ou projetado. Número sem rótulo não é informação. */
  table.tbl tbody tr.tabela-subtotal td { display: flex; justify-content: space-between; gap: var(--sp-3); }
  table.tbl tbody tr.tabela-subtotal td::before {
    display: inline; color: var(--text-muted); font-weight: 600;
  }
  table.tbl tbody tr.tabela-subtotal td:first-child::before { display: none; }

  table.tbl tfoot tr { display: flex; flex-wrap: wrap; gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-4); border-top: 2px solid var(--border); }
  table.tbl tfoot td { border: none; padding: 0; }

  /* Ações ficam sempre visíveis: não há passar o mouse no celular. */
  table.tbl .row-actions { opacity: 1; }
  table.tbl .icon-btn { min-width: 40px; min-height: 40px; }

  .pend-resumo { grid-template-columns: repeat(3, 1fr); gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); }
  .pend-resumo .v { font-size: var(--fs-base); }
  .pend-lista { max-height: 380px; }
  .pend-mes, .pend-dia-head { padding-left: var(--sp-4); padding-right: var(--sp-4); }
  .pend-cat { padding-left: 34px; padding-right: var(--sp-4); }
  .pend-item { padding-left: 44px; padding-right: var(--sp-4); }
  .cc-mini { flex-basis: 78vw; max-width: 260px; }
  .card-head .segmented button { padding: 5px 10px; }

  .ajuda-layout { grid-template-columns: 1fr; }
  .ajuda-indice { position: static; max-height: none; }
  .ajuda-titulo { font-size: var(--fs-xl); }
  .aj-p, .aj-lista li, .aj-passos li { font-size: var(--fs-base); }
  .ajuda-nav { flex-direction: column; }
  .ajuda-nav .btn { max-width: none; }
  .topbar-sep { display: none; }
}

/* ---------------------------------------------------------------
   LINHA DE LANÇAMENTO NO CELULAR — dois andares em vez de cinco

   O cartão empilhado repetia o rótulo em cada registro: DATA,
   DESCRIÇÃO, CATEGORIA, ORIGEM, VALOR, dezoito vezes. Medido: 204px
   por lançamento, 3674px só de lista. Quem rola uma lista lê a
   descrição e o valor; data, categoria e origem são contexto, não
   manchete.

   O recorte é por `data-rotulo`, não por posição: coluna que mude de
   lugar não quebra a regra.
   --------------------------------------------------------------- */
@media (max-width: 820px) {
  #view-lancamentos table.tbl tbody tr {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 2px var(--sp-3);
    align-items: baseline;
    padding: var(--sp-3) var(--sp-4);
  }
  #view-lancamentos table.tbl tbody td {
    display: block; padding: 0; min-height: 0; border: none;
  }
  #view-lancamentos table.tbl tbody td::before { display: none; }

  #view-lancamentos table.tbl tbody td[data-rotulo="Descrição"] {
    grid-column: 1; grid-row: 1; font-weight: 600;
  }
  #view-lancamentos table.tbl tbody td[data-rotulo="Valor"] {
    grid-column: 2; grid-row: 1; text-align: right; white-space: nowrap;
  }
  #view-lancamentos table.tbl tbody td[data-rotulo="Data"] {
    grid-column: 1; grid-row: 2; color: var(--text-muted); font-size: var(--fs-sm);
  }
  #view-lancamentos table.tbl tbody td[data-rotulo="Categoria"] {
    grid-column: 1; grid-row: 3; font-size: var(--fs-sm);
  }
  #view-lancamentos table.tbl tbody td[data-rotulo="Origem"] {
    grid-column: 2; grid-row: 2; text-align: right; font-size: var(--fs-sm);
  }
  /* A coluna de ações não tem título; é ela que fica sem rótulo. */
  #view-lancamentos table.tbl tbody td[data-rotulo=""] {
    grid-column: 2; grid-row: 3; justify-content: flex-end; padding-top: 0;
  }
}

/* Lançamentos no celular: a caixa de lançamento por texto livre e os
   chips de exemplo ocupavam 244px ANTES da lista. Quem abre
   Lançamentos quer ver lançamentos, não o tutorial. Vai para o fim;
   continua a um toque de distância, e o botão de novo lançamento
   permanece no topo.

   Mesma ideia no Dashboard com a faixa de indicadores do Banco
   Central: 88px de CDI/SELIC/IPCA em contingência acima do patrimônio
   da pessoa. Informação boa, prioridade errada. */
@media (max-width: 820px) {
  /* `.active` no seletor é obrigatório. Sem ele o id vence o
     `.view { display: none }` por especificidade, e a tela fica
     visível mesmo desativada — foi o que travou a navegação no
     celular: o dashboard cobria todas as outras telas e parecia que
     nenhum botão do menu funcionava. */
  /* O lançamento por texto livre VOLTA ao topo: é o caminho mais
     rápido de registrar alguma coisa, e caminho rápido escondido no
     rodapé não é caminho rápido. O espaço veio de dentro do cartão —
     marcador curto, exemplo numa linha só, atalhos apenas no
     computador — e não de mandá-lo embora. */
  .nlp-exemplos { display: none; }

  #view-dashboard.active { display: flex; flex-direction: column; }
  #view-dashboard > .faixa-indicadores { order: 4; }
}

/* Planejamento no celular: os dois gráficos vão para DEPOIS da tabela.
   Medido: a primeira categoria — o motivo da tela — começava a 1732px
   do topo, duas telas inteiras de rolagem, atrás de KPIs e gráficos.
   `order` resolve sem tocar no HTML e sem mudar nada no computador. */
@media (max-width: 820px) {
  #view-planejamento.active { display: flex; flex-direction: column; }
  #view-planejamento > .grid-2-1 { order: 2; }
  #view-planejamento > .mt-4 { order: 3; }
}

@media (max-width: 420px) {
  /* Coluna única empilhava oito indicadores em 813px — duas telas de
     rolagem antes do primeiro dado do usuário. Em duas colunas cabem
     em 430px, e o número continua legível em 171px de largura. */
  .kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }
  .kpi { min-height: 0; padding: var(--sp-3); }

  /* Duas colunas economizaram 600px de rolagem, mas encolheram o
     número para 14px — e o número É o cartão. Aumentar só a fonte
     apertaria tudo; o que se faz é abrir espaço tirando peso do que
     não é o número: rótulo com menos espaçamento entre letras, apoio
     em duas linhas no máximo, e as alturas mínimas do desktop fora do
     caminho. O valor volta a 18px e o principal a 22px. */
  .kpi-value { font-size: var(--fs-xl); margin-top: 2px; }
  .kpi-value.sm { font-size: var(--fs-lg); }
  .kpi-label { letter-spacing: 0.03em; min-height: 0; }
  .kpi-meta { min-height: 0; padding-top: 4px; line-height: 1.35; }
  /* O indicador principal continua em largura cheia: é o que a pessoa
     abre o aplicativo para ver. */
  .kpi-hero { grid-column: 1 / -1; }
}

/* Indicador de sincronização. Fica escondido enquanto está tudo
   certo: aviso permanente vira paisagem e deixa de ser aviso. */
.status-sync { position: relative; }
.status-sync.alerta { color: var(--warning); }
.status-sync.pendente { color: var(--info); }
.status-sync .nav-badge { background: var(--warning); color: #fff; }
.status-sync.pendente .nav-badge { background: var(--info); }
@keyframes girarSync { to { transform: rotate(360deg); } }
.status-sync.sincronizando svg { animation: girarSync 1.1s linear infinite; }

/* Faixa de ambiente: existe só fora de produção, e existe para ser
   impossível de ignorar. */
.faixa-ambiente {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
  background: var(--warning); color: #1a1205;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .04em;
  text-align: center; padding: 4px 8px 5px;
}
.faixa-ambiente.risco { background: var(--negative); color: #fff; }
body.com-faixa-ambiente .mobile-nav { bottom: 22px; }
@media (max-width: 820px) {
  body.com-faixa-ambiente #content { padding-bottom: 106px; }
}

.toast-acao {
  display: block; margin-top: var(--sp-2); padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm); background: rgba(255,255,255,0.16);
  color: inherit; font-weight: 650; font-size: var(--fs-sm); min-height: 44px; width: 100%;
}

/* ---------------------------------------------------------------
   15.1 ALVO DE TOQUE
   Dedo não tem ponta de mouse. Medido: nenhum controle de conteúdo
   alcançava 44px, e o pior — o nome da categoria em Planejamento, que
   é o único caminho para abri-la — tinha 14px de altura.
   `pointer: coarse` pega o toque sem penalizar quem usa mouse numa
   janela estreita.
   --------------------------------------------------------------- */
@media (pointer: coarse) {
  .btn-sm,
  .icon-btn,
  .icon-btn.btn-sm,
  .cat-chip,
  .segmented button,
  .tabs button,
  .month-nav button {
    min-height: 44px;
  }
  .icon-btn, .icon-btn.btn-sm { min-width: 44px; }
  .cat-chip { padding-block: var(--sp-2); display: inline-flex; align-items: center; }
  .segmented button, .tabs button { padding-block: var(--sp-2); }
}

/* ---------------------------------------------------------------
   16. IMPRESSÃO (base para exportação em PDF)
   --------------------------------------------------------------- */
@media print {
  @page { margin: 14mm; size: A4; }
  body { background: #fff; }
  .sidebar, .topbar, .mobile-nav, .page-actions, .filter-bar,
  .modal-foot, #toasts, .no-print, .row-actions { display: none !important; }
  .main { margin-left: 0 !important; }
  .content { padding: 0 !important; max-width: none; }
  .card, .kpi { box-shadow: none !important; border: 1px solid #D2DAE3 !important; break-inside: avoid; }
  .modal-backdrop { position: static; background: none; padding: 0; display: block; }
  .modal { max-width: none; box-shadow: none; max-height: none; animation: none; }
  .view { display: none !important; }
  .view.active { display: block !important; }
  .print-only { display: block !important; }
  table.tbl thead th { position: static; background: #F1F4F7 !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}
.print-only { display: none; }
.print-header { display: none; }
@media print { .print-header { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; padding-bottom: 12px; border-bottom: 2px solid #1E3A52; } }

/* Reduzir movimento */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* =====================================================================
   CALCULADORA
   ===================================================================== */

/* Premissas à esquerda, resultado à direita. Abaixo de 1100px a
   coluna do resultado desceria comprimida demais para ler número
   de sete dígitos, então empilha. */
.grid-calc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: start;
}
@media (max-width: 1100px) {
  .grid-calc { grid-template-columns: 1fr; }
}

/* Sufixo de unidade dentro do campo (meses, anos, %). Ocupa espaço
   reservado à direita para não ficar por cima do valor digitado. */
.input-group .sufixo {
  position: absolute; right: 12px;
  font-size: var(--fs-sm); color: var(--text-muted);
  pointer-events: none; font-weight: 500;
}
.input-group:has(.sufixo) .input { padding-right: 58px; }
.input-group:has(.sufixo) .input { padding-left: 12px; }
.input-group .prefix ~ .input { padding-left: 40px; }

/* Ação textual dentro da dica do campo: preenche o valor a partir
   dos dados reais do usuário sem parecer um botão de formulário. */
.btn-link {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--brand-teal-600); font-size: var(--fs-sm);
  font-weight: 600; font-family: inherit; text-align: left;
}
.btn-link:hover { text-decoration: underline; }

/* Marcação de despesa bancada por resgate. Âmbar em vez de neutro:
   é informação de exceção, precisa saltar na lista. */
.tag.tag-warn {
  background: var(--warn-bg, #FEF3C7);
  color: var(--warn-fg, #92400E);
  border-color: transparent;
}

/* Restauração de backup na tela de login. Só aparece em navegador sem
   nenhuma conta: hospedagem nova, aparelho novo ou cache limpo. */
.auth-restore {
  margin-top: var(--sp-6);
  padding: var(--sp-4);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface-2);
}
.auth-restore-t { font-size: var(--fs-base); font-weight: 650; margin-bottom: 4px; }
.auth-restore p {
  font-size: var(--fs-sm); color: var(--text-muted);
  line-height: 1.6; margin-bottom: var(--sp-3);
}
.auth-restore .input { padding: 7px 10px; height: auto; font-size: var(--fs-sm); }

/* Marcação de gasto bancado pelo dinheiro livre do mês. Azul em vez
   de âmbar: não é exceção contábil como o resgate, é classificação. */
.tag.tag-livre {
  background: var(--info-bg);
  color: var(--info);
  border-color: transparent;
}

/* =====================================================================
   DETALHAMENTO (drill down)
   ===================================================================== */

/* Fatia de gráfico e item de legenda que abrem a composição. */
.bar.clicavel, .chart-legend .li.clicavel { cursor: pointer; }

/* Ranking horizontal clicável: a linha inteira é o alvo, não só a barra. */
.barh-clicavel { cursor: pointer; border-radius: var(--r-sm); transition: background .12s; }
.barh-clicavel:hover { background: var(--surface-2); }

/* Seções e subtotais em tabelas que misturam receita e despesa. */
.tabela-secao td {
  padding: 8px var(--sp-4);
  background: var(--surface-2);
  font-size: 11px; font-weight: 650; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted);
  border-top: 1px solid var(--border);
}
.tabela-subtotal td {
  background: var(--surface-2);
  font-weight: 650;
  border-top: 1px solid var(--border);
}


.bar.clicavel:hover { opacity: 0.82; }
.chart-legend .li.clicavel:hover { color: var(--brand-teal-600); }

/* Card de relatório que abre o detalhamento ao clicar. */
.card-drill { cursor: pointer; transition: border-color var(--transition), box-shadow var(--transition); }
.card-drill:hover { border-color: var(--brand-teal-600); box-shadow: var(--sh-md); }

/* Faixas de total e subtotal.
   Fundo azul-claro separa o que é soma do que é item: percorrendo a
   lista, o olho encontra as quebras sem precisar ler os rótulos.
   O recuo negativo estende a faixa até as bordas do modal, senão ela
   fica flutuando dentro do respiro lateral. */
.drill-topo {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px var(--sp-5); margin: 0 calc(-1 * var(--sp-5)) var(--sp-2);
  background: var(--info-bg);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm); color: var(--info);
}
.drill-topo b { font-size: var(--fs-md); color: var(--info); }

/* Cabeçalho de subgrupo dentro do detalhamento. */
.drill-grupo {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px var(--sp-5); margin: var(--sp-3) calc(-1 * var(--sp-5)) 0;
  background: var(--info-bg-soft);
  font-size: 11px; font-weight: 650; letter-spacing: .06em;
  text-transform: uppercase; color: var(--info);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.drill-grupo b {
  font-size: var(--fs-base); letter-spacing: 0; text-transform: none;
  color: var(--info);
}
/* O primeiro subgrupo encosta na faixa do total: sem margem dupla. */
.drill-topo + .drill-grupo { margin-top: calc(-1 * var(--sp-2)); border-top: none; }

/* Tom por natureza: entrada em verde, saída em rosa. O azul fica
   para recortes mistos, como o mês do fluxo de caixa, onde receita e
   despesa aparecem juntas e nenhuma das duas cores seria honesta. */
.drill.tom-pos .drill-topo { background: var(--positive-bg); color: var(--positive); }
.drill.tom-pos .drill-topo b { color: var(--positive); }
.drill.tom-pos .drill-grupo { background: var(--positive-bg-soft); color: var(--positive); }
.drill.tom-pos .drill-grupo b { color: var(--positive); }

.drill.tom-neg .drill-topo { background: var(--negative-bg); color: var(--negative); }
.drill.tom-neg .drill-topo b { color: var(--negative); }
.drill.tom-neg .drill-grupo { background: var(--negative-bg-soft); color: var(--negative); }
.drill.tom-neg .drill-grupo b { color: var(--negative); }

/* Grade fixa: data estreita, descrição elástica, valor alinhado. */
.drill-row {
  display: grid; grid-template-columns: 62px minmax(0, 1fr) auto;
  gap: var(--sp-3); align-items: center;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.drill-row:last-child { border-bottom: none; }
.drill-data { font-size: var(--fs-sm); color: var(--text-muted); }
.drill-desc { min-width: 0; }
.drill-valor { font-weight: 650; white-space: nowrap; }

@media (max-width: 560px) {
  .drill-row { grid-template-columns: 52px minmax(0, 1fr) auto; gap: var(--sp-2); }
}

/* Célula que abre o detalhamento. Sublinhado pontilhado sinaliza a
   ação sem competir com os botões de verdade da tela. */
.drill-link {
  cursor: pointer;
  border-bottom: 1px dashed var(--border-strong);
}
.drill-link:hover { color: var(--brand-teal-600); border-bottom-color: var(--brand-teal-600); }
