/* ==========================================================================
   Innov Tech — Controle Geral de Vendas — Design System (v3, tema escuro)
   Rebrand de Sallute ADM: troca de paleta (verde/claro -> navy/menta,
   escuro) a partir do design system em shadcn/tokens.css passado pelo
   time. Mesma estrutura de sempre — nomes "antigos" (--ink, --surface,
   --primary...) usados no resto deste arquivo, aliases pros nomes do
   shadcn (--card, --sidebar-primary, --chart-1...) no fim do bloco —, só
   os valores de cada um mudaram.
   Onde o token novo não dava pra usar ao pé da letra (ver comentários
   pontuais abaixo: --amber, --surface-2/--muted-bg, --sidebar-*,
   --popover), foi porque o valor batido do shadcn/tokens.css era um
   token de LIGHT mode que não tinha sido customizado (ex.: sidebar e
   popover brancos) — usado do jeito que veio, ficaria ilegível/quebrado
   num tema escuro. O resto é fiel ao que foi passado.
   ========================================================================== */

:root {
  /* ---------- Paleta "Eclipse" (redesign fase 1) ----------
     Os nomes abaixo são os mesmos de sempre (usados no arquivo inteiro e
     em estilos inline dos templates); os VALORES agora vêm de tokens.css
     (--innov-*), carregado antes deste arquivo em base.html/login.html. */
  --ink:        var(--innov-text);
  --ink-soft:   var(--innov-text-secondary);
  --ink-faint:  var(--innov-text-muted);
  --night-1:    var(--innov-bg);     /* hero do login */
  --night-2:    #1E2A6B;             /* glow índigo profundo do login */
  --night-line: rgba(255, 255, 255, 0.08);
  --bg:         var(--innov-bg);
  /* Antes #01021a — card MAIS escuro que o fundo, profundidade invertida.
     Agora cada camada sobe um degrau de luminosidade (ver tokens.css). */
  --surface:    var(--innov-surface);
  --surface-2:  var(--innov-surface-raised);
  /* Antes #172554 (azul saturado) — origem das "bordas azuis pesadas". */
  --line:       var(--innov-border);
  --line-subtle:var(--innov-border);
  --primary:    var(--innov-primary);
  /* --primary-dk segue com o papel que já tinha na prática: texto índigo
     legível sobre fundo escuro/chip translúcido (badges, ícones de seção,
     links) — por isso aponta pro tom claro, não pra um hover mais escuro. */
  --primary-dk: var(--innov-primary-text);
  --primary-bg: var(--innov-primary-soft);
  --amber:      hsl(43 74% 66%); /* secondary — mantém o nome antigo (cor de
                               destaque em gradiente/borda), mas usa --chart-4
                               do tema (dourado) em vez de --secondary (#000,
                               invisível nesses usos) */

  /* Cores de "medalha" em rankings (vendedor do mês / leaderboard). */
  --rank-gold:   var(--amber);
  --rank-bronze: #c2793d;

  /* Cards escuros do dashboard (KPIs) — cada um é o --card da paleta
     tingido com uma cor diferente do tema (--primary + --chart-2/3/4/5 +
     --destructive), mesma ideia de antes (tons profundos derivados da
     marca), só que calculados com color-mix() em vez de hex fixo. */
  --stat-1: color-mix(in srgb, var(--primary)   30%, var(--surface)); /* Vidas ativas */
  --stat-2: color-mix(in srgb, var(--chart-2)   38%, var(--surface)); /* Vidas novas no mês */
  --stat-3: color-mix(in srgb, var(--chart-3)   55%, var(--surface)); /* Receita mensal */
  --stat-4: color-mix(in srgb, var(--chart-5)   38%, var(--surface)); /* Ticket médio */
  --stat-aguardando: color-mix(in srgb, var(--chart-4) 38%, var(--surface)); /* Aguardando implantação */
  --stat-neg: color-mix(in srgb, var(--destructive) 35%, var(--surface)); /* Perdas */

  /* Status — em tema escuro o padrão vira "texto saturado" (lê tanto
     sozinho — ícone, borda — quanto sobre o -bg translúcido do próprio
     tom), em vez do antigo par claro (fundo pastel + texto escuro). */
  --ok-fg:      var(--innov-success);  --ok-bg:      var(--innov-success-soft);
  --warn-fg:    var(--innov-warning);  --warn-bg:    var(--innov-warning-soft);
  --bad-fg:     var(--innov-danger);   --bad-bg:     var(--innov-danger-soft);
  --muted-fg:   var(--innov-text-secondary);  --muted-bg: var(--innov-neutral-soft);

  /* Estrutura */
  --sidebar-w:            260px;
  --sidebar-w-collapsed:  68px;
  --radius:     var(--innov-radius-md);
  --radius-sm:  var(--innov-radius-sm);
  --shadow:     var(--innov-shadow-sm);

  /* Fontes: o tema passado só trazia fallback genérico (ui-sans-serif...),
     sem indício de ter sido customizado — Inter/Space Grotesk (carregadas
     via Google Fonts no base.html/login.html) continuam, é identidade
     tipográfica do produto, não faz parte da paleta de cor que mudou. */
  --font-body:    'Inter', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: 'Space Grotesk', 'Inter', sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, monospace;

  /* ---------- Aliases das variáveis antigas ----------
     Mantêm compatível qualquer regra ou estilo inline que
     ainda use os nomes do design system anterior. */
  --bg-elevated:    var(--surface);
  --bg-elevated-2:  var(--surface-2);
  --border:         var(--line);
  --border-subtle:  var(--line-subtle);
  --text:           var(--ink);
  --text-muted:     var(--ink-soft);
  --text-faint:     var(--ink-faint);
  --accent-hover:   var(--primary-dk);
  --accent-bg:      var(--primary-bg);
  --success:        var(--ok-fg);
  --success-hover:  #3BC98A;
  --danger:         var(--bad-fg);
  --danger-hover:   #D93D42;
  --warning:        var(--warn-fg);
  --neutral:        var(--muted-fg);
  --neutral-hover:  #94a3b8;
  --font:           var(--font-body);

  /* ---------- Tokens do tema (nomes originais) ----------
     Valores literais do shadcn/tokens.css passado pelo time, com 2
     desvios documentados (--popover e os --sidebar-*): o tema passado
     trazia esses tokens ainda como light mode padrão (branco), o que
     quebraria visualmente num app todo escuro — usei os equivalentes de
     dark mode do mesmo tokens.css (bloco .dark) pra esses casos, com o
     ativo (--sidebar-primary) puxando pro azul royal da marca em vez do
     branco genérico do dark mode do shadcn. */
  --card:                       var(--surface);
  --card-foreground:            var(--innov-text-secondary);
  --popover:                    var(--innov-surface-overlay);
  --popover-foreground:         var(--ink);
  --primary-foreground:         #f8fafc; /* era #111827 (texto escuro, certo pro
                               verde claro antigo) — azul royal precisa de
                               texto claro em cima pra manter contraste */
  --secondary:                  #000000;
  --secondary-foreground:       #94a3b8;
  --muted:                      #000000;
  --accent:                     hsl(210 40% 96%);
  --accent-foreground:          hsl(222.2 84% 4.9%);
  --destructive:                hsl(0 84.2% 60.2%);
  --destructive-foreground:     hsl(210 40% 98%);
  --input:                      var(--innov-border-strong);
  --ring:                       var(--innov-primary-bright);
  --chart-1: hsl(12 76% 61%); --chart-2: hsl(173 58% 39%); --chart-3: hsl(197 37% 24%);
  --chart-4: hsl(43 74% 66%); --chart-5: hsl(27 87% 67%);
  /* Sidebar: azul-marinho profundo de fundo (estrutura própria, não muda
     com o rebrand) + --primary pro ativo/destaque — agora que --primary É
     o azul royal (rebrand pedido depois da sidebar), --sidebar-primary só
     realiasa pra ele em vez de duplicar o hex; um único lugar pra trocar
     o azul no futuro. */
  --sidebar:                    var(--innov-bg);
  --sidebar-foreground:         var(--innov-text);
  --sidebar-primary:            var(--primary);
  --sidebar-primary-foreground: var(--primary-foreground);
  --sidebar-accent:             rgba(148, 172, 212, 0.07);
  --sidebar-accent-foreground:  var(--ink);
  /* Continua = var(--line): --sidebar-border é reaproveitado como token
     genérico de "borda no hover" em telas fora da sidebar (cliente_form,
     multiselect...) — mudar o valor aqui vazaria pra elas também. */
  --sidebar-border:             var(--innov-border-strong);
  --sidebar-ring:               var(--primary);
  --font-serif:                 ui-serif, Georgia, serif;
}

/* ==========================================================================
   Reset e base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  color-scheme: dark;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  margin: 0 0 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* Link usa o índigo CLARO (--primary-dk = --innov-primary-text, 6.6:1 no
   card): o --primary é tom de preenchimento de botão, escuro demais pra
   texto fino sobre fundo escuro. */
a { color: var(--primary-dk); text-decoration: none; }
a:hover { text-decoration: underline; }

hr {
  border: none;
  border-top: 1px solid var(--line);
  margin: 1rem 0 1.5rem;
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--innov-canvas); }
::-webkit-scrollbar-thumb { background-color: var(--innov-border-strong); border-radius: 10px; }

/* Anel de foco único do sistema (teclado): índigo "elétrico", nunca
   removido sem substituto — inputs trocam por box-shadow (ver abaixo). */
:focus-visible {
  outline: 2px solid var(--innov-primary-bright);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ==========================================================================
   Layout: sidebar + conteúdo (base.html / _sidebar.html)

   O azul royal nasceu aqui como acento exclusivo da sidebar (decisão da
   fase anterior) e depois virou o --primary do sistema inteiro (rebrand
   pedido em seguida) — --sidebar-primary/--sidebar-primary-foreground
   agora só realiasam pra --primary/--primary-foreground (ver :root),
   mantidos como tokens à parte só porque a estrutura de fundo da sidebar
   (--sidebar, --sidebar-accent) é mesmo própria dela, não do resto do app.
   ========================================================================== */

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

.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--sidebar);
  color: var(--sidebar-foreground);
  border-right: 1px solid var(--innov-border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  transition: width 0.22s ease;
}

.sidebar-top {
  flex-shrink: 0;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  padding: 20px 18px 18px;
  border-bottom: 1px solid var(--innov-border);
}

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

.brand-mark {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--sidebar-primary); /* fallback enquanto a logo carrega/se faltar */
  display: grid;
  place-items: center;
  flex-shrink: 0;
  overflow: hidden;
  /* Halo índigo discreto atrás da marca — mesma "luz" usada atrás do
     avatar no detalhe do cliente; único brilho da sidebar. */
  box-shadow: 0 0 0 1px var(--innov-border-strong), 0 4px 14px -4px rgba(99, 119, 255, 0.55);
}

.brand-mark svg { display: block; }

.brand-mark-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.brand-text { min-width: 0; overflow: hidden; display: flex; flex-direction: column; gap: 3px; }

.brand-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15.5px;
  letter-spacing: 0.1px;
  color: var(--sidebar-foreground);
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.brand-sub {
  font-size: 9.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.6px;
  line-height: 1.35;
  color: var(--innov-text-muted);
}

/* Botão de recolher — vive no topo, ao lado da marca, só desktop
   (regra 24: "OrunTech [‹]"). Ícone gira 180° quando recolhida. */
.sidebar-collapse-btn {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-sm);
  background: none;
  border: none;
  color: var(--ink-faint);
  display: grid;
  place-items: center;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.15s ease, color 0.15s ease;
}
.sidebar-collapse-btn:hover { background: var(--sidebar-accent); color: var(--ink); }
.sidebar-collapse-btn svg { transition: transform 0.2s ease; }

.sidebar-nav {
  flex: 1;
  padding: 14px 10px;
  overflow-y: auto;
  /* overflow-x seria "hidden" pra nunca dar scroll horizontal (regra 43),
     mas isso também cortaria o tooltip/popover do modo recolhido, que
     propositalmente "vazam" pra fora da faixa de ícones (left: 100% + Npx).
     Como cada link já trunca com ellipsis (.nav-link-text), largura nunca
     estoura o container mesmo sem o corte — visible fica seguro aqui. */
  overflow-x: visible;
  /* Scrollbar discreta (regra 38): quase invisível, aparece no hover. */
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.sidebar-nav:hover { scrollbar-color: var(--sidebar-border) transparent; }
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: transparent; border-radius: 10px; }
.sidebar-nav:hover::-webkit-scrollbar-thumb { background: var(--sidebar-border); }

.nav-group + .nav-group { margin-top: var(--sp-5); }

/* Cabeçalho do grupo é só rótulo estático (regra 41: "discreto, não
   competir com links") — quem abre/fecha agora é cada item com filhos
   (.nav-parent), não a seção inteira. */
.nav-group-title {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  color: var(--innov-text-muted);
  padding: 0 12px var(--sp-2);
}

.nav-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 38px;
  padding: 8px 12px;
  margin: 1px 0;
  border-radius: var(--radius-sm);
  color: var(--innov-text-secondary);
  font-size: 13.5px;
  font-weight: 500;
  position: relative;
  transition: background var(--innov-dur) var(--innov-ease), color var(--innov-dur) var(--innov-ease);
}

.nav-link:hover {
  background: var(--sidebar-accent);
  color: var(--innov-text);
  text-decoration: none;
}

/* Item ativo (redesign "Eclipse"): em vez do bloco azul sólido, um
   tingimento índigo leve + rail vertical de 2px com brilho curto — a
   identidade vem do acento, não de pintar a linha inteira. A rail também
   mantém a regra antiga de "não depender somente da cor" (daltonismo). */
.nav-link.active {
  background: var(--innov-primary-soft);
  color: var(--innov-text);
  font-weight: 600;
}
.nav-link.active .nav-link-icon { color: var(--innov-primary-text); opacity: 1; }
.nav-link.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 9px;
  bottom: 9px;
  width: 2px;
  border-radius: 2px;
  background: var(--innov-edge-vertical);
  box-shadow: 0 0 8px rgba(99, 119, 255, 0.7);
}

.nav-link-main {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.nav-link-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nav-link-icon { flex-shrink: 0; opacity: 0.85; }

/* Contagem de pendências (ex.: Solicitações, Fechamentos) — só aparece
   quando > 0, ver app/context_processors.py:papel_usuario. */
.nav-badge {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  background: var(--primary-bg);
  color: var(--primary-dk);
}

.nav-link.active .nav-badge {
  background: var(--innov-primary-soft);
  color: var(--innov-primary-text);
}

.nav-sub {
  display: block;
  padding: 4px 12px 4px 38px;
  border-radius: var(--radius-sm);
  color: var(--innov-text-muted);
  font-size: 12.5px;
}

.nav-sub:hover {
  color: var(--sidebar-accent-foreground);
  background: var(--sidebar-accent);
  text-decoration: none;
}

/* ---------- Item pai com filhos (ex.: "Comissões") ----------
   .nav-parent-toggle reaproveita a cara de .nav-link (mesmo padding/hover);
   só precisa dos resets de <button> que .nav-link nunca precisou até agora.
   Estado aberto vem do Django (classe .is-open renderizada no servidor
   quando algum filho é a rota atual — regra 13/53), o JS só alterna a
   partir daí; sem JS o submenu do item ativo continua visível. */
.nav-parent { position: relative; }

.nav-parent-toggle {
  width: 100%;
  background: none;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
}

.nav-parent-chevron {
  flex-shrink: 0;
  opacity: 0.7;
  transition: transform 0.15s ease;
}
.nav-parent.is-open .nav-parent-chevron { transform: rotate(90deg); }

/* Submenu: max-height + opacity (regra 14, 150–250ms) — .prefers-reduced-
   motion já é neutralizado globalmente por "* { transition: none }" mais
   abaixo no arquivo (regra 86). */
.nav-children {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  margin: 2px 0 var(--sp-1) 19px;
  padding-left: 10px;
  /* Rail vertical do submenu: amarra os filhos como UM grupo em vez de
     blocos soltos — o filho ativo acende um trecho dela (.nav-child.active). */
  border-left: 1px solid var(--innov-border);
  transition: max-height 0.2s ease, opacity 0.15s ease;
}
.nav-parent.is-open > .nav-children { max-height: 480px; opacity: 1; }

.nav-child {
  position: relative;
  display: block;
  padding: 6px 10px;
  margin: 1px 0;
  border-radius: var(--radius-sm);
  color: var(--innov-text-secondary);
  font-size: 13px;
  transition: background var(--innov-dur) var(--innov-ease), color var(--innov-dur) var(--innov-ease);
}
.nav-child:hover { color: var(--innov-text); background: var(--sidebar-accent); text-decoration: none; }
.nav-child.active { color: var(--innov-text); font-weight: 600; background: var(--innov-primary-soft); }
/* Trecho aceso da rail do submenu, exatamente sobre a linha de
   .nav-children (padding-left 10px + borda 1px = -11px). */
.nav-child.active::before {
  content: '';
  position: absolute;
  left: -11px;
  top: 6px;
  bottom: 6px;
  width: 2px;
  border-radius: 2px;
  background: var(--innov-edge-vertical);
}

.sidebar-footer {
  flex-shrink: 0;
  padding: var(--sp-3) var(--sp-4);
  border-top: 1px solid var(--innov-border);
  display: flex;
  align-items: center;
  gap: 10px;
}

/* ==========================================================================
   Sidebar recolhida (modo ícone) — só desktop; no mobile a sidebar vira
   drawer off-canvas (ver bloco "Responsivo" mais abaixo). Classe fica na
   <html> (não em .sidebar) porque o script que evita o flash roda no
   <head>, antes de qualquer elemento do body existir.
   ========================================================================== */
@media (min-width: 901px) {
  html.sidebar-collapsed .sidebar { width: var(--sidebar-w-collapsed); }

  html.sidebar-collapsed .sidebar-top { padding: 18px 0 16px; align-items: center; justify-content: center; }
  html.sidebar-collapsed .sidebar-top,
  html.sidebar-collapsed .brand { flex-direction: column; }
  html.sidebar-collapsed .brand { justify-content: center; }
  html.sidebar-collapsed .brand-text,
  html.sidebar-collapsed .sidebar-collapse-btn svg { display: none; }
  html.sidebar-collapsed .sidebar-collapse-btn { margin-top: 10px; }
  html.sidebar-collapsed .sidebar-collapse-btn::after {
    content: '';
    display: block;
    width: 14px; height: 14px;
    border: 1.6px solid currentColor;
    border-radius: 4px;
  }

  html.sidebar-collapsed .nav-group-title { display: none; }

  html.sidebar-collapsed .nav-link,
  html.sidebar-collapsed .nav-parent-toggle { justify-content: center; padding: 9px; }
  html.sidebar-collapsed .nav-link-text,
  html.sidebar-collapsed .nav-badge,
  html.sidebar-collapsed .nav-sub,
  html.sidebar-collapsed .nav-parent-chevron { display: none; }

  /* Filho com rota ativa: força o pai aberto mesmo sem hover/clique, senão
     o usuário recolhe a sidebar exatamente na tela que estava vendo e o
     item ativo "some" dentro de um submenu fechado. */
  html.sidebar-collapsed .nav-parent:has(.nav-child.active) .nav-children,
  html.sidebar-collapsed .nav-parent.is-open .nav-children {
    display: block;
    max-height: none;
    opacity: 1;
  }
  /* Submenu de item recolhido vira popover lateral (regra 26), não
     acordeão empurrando o resto da lista pra baixo.

     position:fixed (não absolute) de propósito: .sidebar-nav precisa de
     overflow-y:auto pra rolar com muitos itens (regra 37) e, por regra do
     próprio CSS, o par overflow-x/overflow-y não deixa um eixo ficar
     "visible" enquanto o outro não é — ou seja, um popover position:absolute
     aqui dentro seria sempre cortado no eixo X pelo scroll da lista. Como
     'collapsed' já é 100% dependente de JS pra existir (a classe só é
     ligada por JS/localStorage), calcular a posição em px via
     getBoundingClientRect() em sidebar.js não é uma perda de progressive
     enhancement — sem JS o usuário nunca chega nesse estado. */
  html.sidebar-collapsed .nav-children {
    position: fixed;
    width: 210px;
    margin: 0;
    padding: 6px;
    border-left: none;
    background: var(--innov-surface-overlay);
    border: 1px solid var(--innov-border-strong);
    border-radius: var(--radius);
    box-shadow: var(--innov-shadow-md);
    z-index: 40;
    display: none;
  }
  html.sidebar-collapsed .nav-child { padding: 8px 10px; }
  html.sidebar-collapsed .nav-child.active::before { display: none; }

  html.sidebar-collapsed #sidebar-collapse-icon { transform: rotate(180deg); }

  html.sidebar-collapsed .sidebar-footer { flex-direction: column; padding: 12px 6px; }
  html.sidebar-collapsed .user-meta,
  html.sidebar-collapsed .btn-logout-text { display: none; }
  html.sidebar-collapsed .sidebar-footer .logout-form .btn-logout { padding: 6px; border-radius: 50%; }
}

/* Tooltip (regra 27): só no modo recolhido, no hover/foco de qualquer
   [data-label]. Mesmo motivo do popover acima pra ser position:fixed
   + JS (sidebar.js liga/desliga .is-visible e posiciona), em vez de
   ::after — teria o mesmo corte pelo scroll de .sidebar-nav. */
.sidebar-flyout-tooltip {
  position: fixed;
  z-index: 50;
  background: var(--innov-surface-overlay);
  color: var(--ink);
  border: 1px solid var(--innov-border-strong);
  padding: 5px 10px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  box-shadow: var(--shadow);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.1s ease;
}
.sidebar-flyout-tooltip.is-visible { opacity: 1; visibility: visible; }

/* ==========================================================================
   Mobile: drawer off-canvas (regras 44-52)
   ========================================================================== */

.mobile-topbar { display: none; }
.sidebar-overlay { display: none; }

@media (max-width: 900px) {
  .mobile-topbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    background: var(--sidebar);
    border-bottom: 1px solid var(--innov-border);
    position: sticky;
    top: 0;
    z-index: 30;
  }
  .mobile-menu-btn {
    width: 34px; height: 34px;
    display: grid; place-items: center;
    background: none;
    border: 1px solid var(--sidebar-border);
    border-radius: var(--radius-sm);
    color: var(--sidebar-foreground);
    cursor: pointer;
    touch-action: manipulation;
    flex-shrink: 0;
  }
  .mobile-menu-btn .icon-close { display: none; }
  .mobile-menu-btn[aria-expanded="true"] .icon-open { display: none; }
  .mobile-menu-btn[aria-expanded="true"] .icon-close { display: block; }

  .mobile-topbar-brand { display: flex; align-items: center; gap: 8px; min-width: 0; }
  .mobile-topbar-brand img { width: 24px; height: 24px; border-radius: 6px; flex-shrink: 0; }
  .mobile-topbar-brand span {
    font-family: var(--font-display); font-weight: 700; font-size: 14.5px;
    color: var(--sidebar-foreground); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }

  .app { flex-direction: column; }

  .sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 85vw;
    max-width: 300px;
    height: 100vh;
    z-index: 60;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    box-shadow: 0 0 0 transparent;
  }
  .sidebar.is-open { transform: translateX(0); box-shadow: 24px 0 48px -12px rgba(1, 2, 10, 0.5); }

  /* Recolher-pra-ícone é recurso de desktop — o drawer mobile já abre/fecha
     inteiro pelo hambúrguer do topbar, não tem "modo compacto" próprio. */
  .sidebar-collapse-btn { display: none; }

  .sidebar-overlay {
    display: block;
    position: fixed;
    inset: 0;
    background: var(--innov-overlay);
    z-index: 55;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease;
  }
  .sidebar-overlay.is-open { opacity: 1; pointer-events: auto; }
}

.avatar-block { position: relative; flex-shrink: 0; }

.user-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--sidebar-primary);
  color: var(--sidebar-primary-foreground);
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: 600;
  flex-shrink: 0;
  border: 2px solid var(--sidebar-border);
}

.user-avatar-img {
  display: block;
  width: 38px;
  max-width: 38px;
  height: 38px;
  max-height: 38px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  overflow: hidden;
  border: 2px solid var(--sidebar-border);
}

.avatar-settings-btn {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--primary);
  color: var(--innov-on-primary);
  border: 2px solid var(--sidebar);
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.15s ease, transform 0.15s ease;
}

.avatar-settings-btn:hover { background: var(--primary-dk); transform: scale(1.08); }
.avatar-settings-btn svg { flex-shrink: 0; }

.user-meta {
  min-width: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.user-name { color: var(--sidebar-foreground); font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-role { color: var(--ink-faint); font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Fica FORA de .user-meta de propósito (bug corrigido nesta reforma): antes
   o botão de Sair vivia dentro do span escondido no modo recolhido, e
   desaparecia junto — regra 32 exige que logout continue acessível sempre. */
.logout-form { margin: 0; flex-shrink: 0; }

/* Seletor "extra" (.sidebar-footer .logout-form .btn-logout, em vez de só
   .btn-logout) não é enfeite — é achado nesta reforma: existe uma regra
   global `form button[type="submit"]:not(.btn)` (mais abaixo no arquivo)
   com especificidade maior (0,2,2) que uma classe solta (0,1,0), que
   SEMPRE vencia e pintava o botão de Sair inteiro com --primary (verde
   antes, azul agora) — a pílula discreta abaixo nunca chegava a aparecer.
   Prefixando com os ancestrais reais do DOM (b=3) a regra passa a vencer
   de vez, sem precisar adicionar classe .btn no HTML (que traria padding/
   border-radius do sistema de botões, quebrando a pílula). */
.sidebar-footer .logout-form .btn-logout {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid transparent;
  padding: 7px 10px;
  border-radius: 999px;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.btn-logout svg { flex-shrink: 0; }

.sidebar-footer .logout-form .btn-logout:hover {
  background: rgba(239, 68, 68, 0.14);
  color: var(--destructive);
  border-color: rgba(239, 68, 68, 0.35);
  text-decoration: none;
}

.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;
}

/* ---------- Modal: foto de perfil ---------- */

.avatar-modal {
  position: fixed;
  margin: auto;
  inset: 0;
  width: 100%;
  max-width: 320px;
  max-height: calc(100vh - 4rem);
  padding: 1.5rem;
  background: var(--innov-surface-raised);
  border: 1px solid var(--innov-border);
  border-radius: var(--radius);
  box-shadow: var(--innov-shadow-md);
  color: var(--ink);
}

.avatar-modal::backdrop {
  background: var(--innov-overlay);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

@media (prefers-reduced-motion: no-preference) {
  .avatar-modal[open]          { animation: avatar-modal-in 0.18s ease-out; }
  .avatar-modal[open]::backdrop { animation: avatar-modal-backdrop-in 0.18s ease-out; }
}

@keyframes avatar-modal-in {
  from { opacity: 0; transform: scale(0.96) translateY(6px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes avatar-modal-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.avatar-modal-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: var(--surface-2);
  color: var(--ink-soft);
  font-size: 16px;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.15s ease, color 0.15s ease;
}

.avatar-modal-close:hover { background: var(--line); color: var(--ink); }

.avatar-modal-title {
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
}

.avatar-modal-preview {
  width: 96px;
  height: 96px;
  margin: 0 auto 1.25rem;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
}

.avatar-modal-preview-img {
  display: block;
  width: 96px;
  max-width: 96px;
  height: 96px;
  max-height: 96px;
  object-fit: cover;
}

.avatar-modal-preview-placeholder {
  font-size: 30px;
  font-weight: 700;
  color: var(--ink-faint);
}

.avatar-modal-form { margin: 0; }

.avatar-modal-form label {
  margin-top: 0;
  font-size: 0.85rem;
}

.avatar-modal-form input[type="file"] { font-size: 12.5px; }

.avatar-modal-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  margin-top: 1.25rem;
}

.avatar-modal-actions .btn-primary { margin-left: auto; }

/* Solicitação Financeira — modal "Ações financeiras" no detalhe do cliente
   (financeiro/forms.py: SolicitacaoFinanceiraForm). Mesmo padrão de
   .avatar-modal (dialog nativo + JS só pra abrir/fechar, reaproveita as
   mesmas keyframes) — namespace próprio pra não acoplar aos estilos do
   avatar nem aos do resto da página. */
.sf-modal {
  position: fixed;
  margin: auto;
  inset: 0;
  width: 100%;
  max-width: 480px;
  max-height: calc(100vh - 4rem);
  padding: 1.5rem;
  background: var(--innov-surface-raised);
  border: 1px solid var(--innov-border);
  border-radius: var(--radius);
  box-shadow: var(--innov-shadow-md);
  color: var(--ink);
  overflow-y: auto;
}

.sf-modal::backdrop {
  background: var(--innov-overlay);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

@media (prefers-reduced-motion: no-preference) {
  .sf-modal[open]          { animation: avatar-modal-in 0.18s ease-out; }
  .sf-modal[open]::backdrop { animation: avatar-modal-backdrop-in 0.18s ease-out; }
}

.sf-modal-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: var(--surface-2);
  color: var(--ink-soft);
  font-size: 16px;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  touch-action: manipulation;
  transition: background 0.15s ease, color 0.15s ease;
}
.sf-modal-close:hover { background: var(--line); color: var(--ink); }

.sf-modal-title {
  margin: 0 0 1.1rem;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  padding-right: 1.5rem;
}

.sf-form { margin: 0; display: flex; flex-direction: column; gap: 12px; }

.sf-field { display: flex; flex-direction: column; gap: 4px; }
.sf-field[hidden] { display: none; }
.sf-field label { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.sf-field select,
.sf-field input[type="text"],
.sf-field input[type="number"],
.sf-field input[type="date"],
.sf-field textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: 13.5px;
}
.sf-field select:focus,
.sf-field input:focus,
.sf-field textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: var(--innov-ring);
}
.sf-field textarea { resize: vertical; min-height: 64px; }
.sf-field-error { margin: 2px 0 0; font-size: 12px; color: var(--bad-fg); }

.sf-fatura-vivo { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.sf-fatura-vivo .text-muted { margin: 0; font-size: 11.5px; }

.sf-dropzone {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 20px 12px;
  border: 1.5px dashed var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.sf-dropzone.is-dragover,
.sf-dropzone:hover { border-color: var(--primary); background: var(--primary-bg); }
.sf-dropzone-icon { font-size: 18px; color: var(--ink-faint); }
.sf-dropzone-text { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.sf-dropzone-hint { font-size: 11.5px; color: var(--ink-faint); }
.sf-dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.sf-modal-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

/* ==========================================================================
   Login
   ========================================================================== */

.login-body {
  position: relative;
  overflow: hidden;
  margin: 0;
  min-height: 100vh;
  background: radial-gradient(120% 120% at 15% 0%, var(--night-2) 0%, var(--night-1) 55%, #01020a 100%);
  color-scheme: dark;
  font-family: var(--font-body);
}

/* Layout 2 colunas (painel visual + formulário) — o painel visual é só
   decorativo (aria-hidden) e some abaixo de 980px, ficando só o form
   centralizado, igual era antes. */
.login-screen {
  position: relative;
  z-index: 1;
  display: flex;
  min-height: 100vh;
}

.login-visual {
  flex: 1 1 50%;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 2rem;
}

.login-form-panel {
  flex: 1 1 50%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

@media (max-width: 980px) {
  .login-visual { display: none; }
  .login-form-panel { flex: 1 1 100%; }
}

/* ---------- Painel visual: ripple ---------- */

.login-ripple {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  mask-image: radial-gradient(circle at center, black, transparent 72%);
  -webkit-mask-image: radial-gradient(circle at center, black, transparent 72%);
}

.login-ripple-ring {
  position: absolute;
  width: var(--ripple-size, 200px);
  height: var(--ripple-size, 200px);
  border-radius: 50%;
  border: 1px solid rgba(84, 104, 240, 0.3);
  opacity: 0.16;
}

@media (prefers-reduced-motion: no-preference) {
  .login-ripple-ring {
    opacity: 0;
    animation: login-ripple 3.6s ease-out infinite;
    animation-delay: var(--ripple-delay, 0s);
  }
}

@keyframes login-ripple {
  0%   { transform: scale(0.6);  opacity: 0.45; }
  70%  { opacity: 0.12; }
  100% { transform: scale(1.15); opacity: 0; }
}

/* ---------- Painel visual: órbita ---------- */

.login-orbit {
  position: relative;
  width: 420px;
  height: 420px;
  max-width: 90%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.login-orbit-path {
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--radius, 100px) * 2);
  height: calc(var(--radius, 100px) * 2);
  margin: calc(var(--radius, 100px) * -1);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 50%;
  pointer-events: none;
}

.login-orbit-dot {
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--size, 10px);
  height: var(--size, 10px);
  margin: calc(var(--size, 10px) / -2) 0 0 calc(var(--size, 10px) / -2);
  border-radius: 50%;
  background: var(--color, var(--primary));
  box-shadow: 0 0 10px 1px var(--color, var(--primary));
}

@media (prefers-reduced-motion: no-preference) {
  .login-orbit-dot {
    animation: login-orbit var(--duration, 20s) linear infinite;
    animation-delay: var(--delay, 0s);
  }
  .login-orbit-dot.is-reverse { animation-direction: reverse; }
}

@media (prefers-reduced-motion: reduce) {
  .login-orbit-dot { display: none; }
}

@keyframes login-orbit {
  from { transform: rotate(0deg)   translateX(var(--radius, 100px)) rotate(0deg); }
  to   { transform: rotate(360deg) translateX(var(--radius, 100px)) rotate(-360deg); }
}

/* Selos das operadoras parceiras que orbitam a logo — mesma trilha/animação
   dos pontinhos (login-orbit-dot), só que como "pill" branca carregando o
   logo em vez de uma bolinha colorida. */
.login-orbit-badge {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 72px;
  height: 28px;
  margin: -14px 0 0 -36px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px 9px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.login-orbit-badge-lg {
  width: 86px;
  height: 34px;
  margin: -17px 0 0 -43px;
  padding: 6px 11px;
}

.login-orbit-badge img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  display: block;
}

@media (prefers-reduced-motion: no-preference) {
  .login-orbit-badge {
    animation: login-orbit var(--duration, 20s) linear infinite;
    animation-delay: var(--delay, 0s);
  }
  .login-orbit-badge.is-reverse { animation-direction: reverse; }
}

@media (prefers-reduced-motion: reduce) {
  .login-orbit-badge { display: none; }
}

.login-orbit-center {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
}

.login-orbit-logo {
  width: 64px;
  height: 64px;
  border-radius: 18px;
  display: block;
  object-fit: cover;
  position: relative;
  z-index: 1;
  box-shadow: 0 0 0 1px rgba(232, 197, 115, 0.25), 0 8px 24px -8px rgba(232, 197, 115, 0.55);
}

.login-orbit-center .brand-mark-ring { inset: -8px; border-radius: 22px; }

.login-visual-caption {
  position: relative;
  z-index: 2;
  margin-top: 2rem;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.35rem;
  color: #FFF;
}

.login-visual-caption span {
  display: block;
  margin-top: 4px;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 1.4px;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ---------- Reveal (título/subtítulo do form "descobertos" por uma
   barra colorida que desliza — só decorativo, nunca atrasa o form em si:
   inputs/botão ficam fora do .reveal, sempre interativos de imediato) ---- */

.reveal { position: relative; overflow: hidden; }

@media (prefers-reduced-motion: no-preference) {
  .reveal-content {
    animation: login-reveal-content 0.5s ease-out both;
    animation-delay: var(--reveal-delay, 0s);
  }

  .reveal::after {
    content: "";
    position: absolute;
    inset: 2px 0;
    background: var(--amber);
    border-radius: 4px;
    z-index: 2;
    pointer-events: none;
    animation: login-reveal-box 0.5s ease-in both;
    animation-delay: var(--reveal-delay, 0s);
  }
}

@keyframes login-reveal-content {
  from { opacity: 0; transform: translateY(60%); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes login-reveal-box {
  from { transform: translateX(0); }
  to   { transform: translateX(101%); }
}

/* .login-brand (pequena, logo+nome acima do card) só existe pra cobrir o
   mobile, onde .login-visual (com a órbita e o nome grande) está escondido
   — no desktop ela ficaria redundante com a legenda da órbita ao lado. */
@media (min-width: 981px) {
  .login-brand-mobile { display: none; }
}

.login-glow {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  pointer-events: none;
  z-index: 0;
}

.login-glow-1 {
  width: 380px;
  height: 380px;
  top: -120px;
  right: -80px;
  background: radial-gradient(circle, rgba(232, 197, 115, 0.35), transparent 70%);
}

.login-glow-2 {
  width: 420px;
  height: 420px;
  bottom: -160px;
  left: -120px;
  background: radial-gradient(circle, rgba(84, 104, 240, 0.45), transparent 70%);
}

.login-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
  background-size: 42px 42px;
  mask-image: radial-gradient(ellipse at center, black, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse at center, black, transparent 75%);
  pointer-events: none;
  z-index: 0;
}

.login-wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 380px;
  padding: 1.5rem;
}

.login-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 1.5rem;
  color: #FFF;
}

.login-brand .brand-name { font-family: var(--font-display); font-size: 1.1rem; font-weight: 600; }
.login-brand .brand-sub { font-size: 0.78rem; color: var(--ink-soft); }

.brand-mark-lg {
  width: 46px;
  height: 46px;
  border-radius: 13px;
  position: relative;
  box-shadow: 0 0 0 1px rgba(232, 197, 115, 0.25), 0 8px 24px -8px rgba(232, 197, 115, 0.55);
}

.brand-mark-lg .brand-mark-img,
.brand-mark-lg svg { position: relative; z-index: 1; }

.brand-mark-ring {
  position: absolute;
  inset: -6px;
  border-radius: 16px;
  border: 1px solid rgba(232, 197, 115, 0.35);
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .brand-mark-ring { animation: login-ring-pulse 2.6s ease-in-out infinite; }
}

@keyframes login-ring-pulse {
  0%, 100% { transform: scale(1);    opacity: 0.55; }
  50%      { transform: scale(1.08); opacity: 0.15; }
}

.login-card {
  max-width: none;
  position: relative;
  padding-top: 2rem;
  box-shadow: 0 24px 60px -20px rgba(1, 2, 10, 0.55), 0 2px 6px rgba(1, 2, 10, 0.08);
}

.login-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 1.5rem;
  right: 1.5rem;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: linear-gradient(90deg, var(--amber), var(--primary));
}

.login-title { margin: 0 0 0.35rem; text-align: left; }

.login-subtitle {
  margin: 0 0 1.5rem;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.field-icon { position: relative; }

.field-icon input { padding-left: 2.5rem; }

.field-icon::before {
  content: "";
  position: absolute;
  left: 0.85rem;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  background-repeat: no-repeat;
  background-size: contain;
  opacity: 0.5;
  pointer-events: none;
}

.field-icon-user::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2394a3b8' stroke-width='1.4'%3E%3Ccircle cx='8' cy='5.2' r='2.6'/%3E%3Cpath d='M2.8 13.2c0-2.6 2.3-4.2 5.2-4.2s5.2 1.6 5.2 4.2'/%3E%3C/svg%3E");
}

.field-icon-lock::before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2394a3b8' stroke-width='1.4'%3E%3Crect x='3.2' y='7.2' width='9.6' height='6.4' rx='1.2'/%3E%3Cpath d='M5.2 7.2V5a2.8 2.8 0 0 1 5.6 0v2.2'/%3E%3C/svg%3E");
}

.field-icon-lock input { padding-right: 2.4rem; }

.field-toggle-visibility {
  position: absolute;
  right: 0.5rem;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  padding: 4px;
  background: none;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--ink-faint);
  cursor: pointer;
  touch-action: manipulation;
}

.field-toggle-visibility:hover { color: var(--ink-soft); background: var(--surface-2); }

/* O atributo `hidden` sozinho não é confiável em <svg> em todo browser —
   o UA stylesheet do próprio SVG pode competir com a regra genérica
   `[hidden] { display: none }` do HTML e "ganhar" (visto no Chrome: um
   <svg hidden> renderiza display:inline mesmo assim). Regra de autor
   sempre vence regra de UA (origem do cascade, não especificidade), então
   isso aqui é garantia — sem depender de qual delas o browser aplicaria. */
.field-toggle-visibility svg[hidden] { display: none; }

.login-submit {
  width: 100%;
  margin-top: 1.5rem;
  position: relative;
  touch-action: manipulation;
  box-shadow: 0 8px 20px -6px rgba(84, 104, 240, 0.55);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.login-submit:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 24px -6px rgba(84, 104, 240, 0.65);
}

.login-submit:active { transform: translateY(0); }

.login-submit.is-loading { cursor: default; opacity: 0.9; }

.login-submit.is-loading::after {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.45);
  border-top-color: #FFF;
  animation: login-spin 0.7s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .login-submit.is-loading::after { animation: none; }
}

@keyframes login-spin { to { transform: rotate(360deg); } }

/* Canvas (nível 1) com o detalhe "blueprint": grade de pontos de 1px a
   cada 24px + uma luz índigo bem difusa no topo. Tudo CSS (zero imagem),
   opacidade baixa de propósito — é pra quase não ser notado
   conscientemente, só tirar a sensação de "chapado" e diferenciar o Innov
   Tech. background-attachment: fixed mantém a grade parada no scroll (não
   "anda" junto com o conteúdo, que é o que denunciaria um wallpaper). */
.content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background-color: var(--innov-canvas);
  background-image:
    radial-gradient(1100px 420px at 78% -140px, rgba(99, 119, 255, 0.10), transparent 70%),
    radial-gradient(circle at 1px 1px, rgba(148, 172, 212, 0.075) 1px, transparent 0);
  background-size: auto, 24px 24px;
  background-attachment: fixed, fixed;
}

.main {
  flex: 1;
  padding: var(--sp-6) var(--sp-6) 40px;
  max-width: 1520px;
  width: 100%;
  margin: 0 auto;
}

/* Telas com tabela muito larga (muitas colunas, ex.: lista_clientes.html)
   usam o espaço todo disponível ao lado da sidebar, em vez do teto de 1440px
   das outras telas — que sobra em monitores largos e força scroll horizontal
   justamente na tabela que mais precisa de espaço. */
.main-wide { max-width: none; }

.app-footer {
  padding: 16px 32px;
  color: var(--ink-faint);
  font-size: 12.5px;
  text-align: center;
  border-top: 1px solid var(--innov-border);
  background: transparent;
}

/* ==========================================================================
   Cabeçalho de página
   ========================================================================== */

.page-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.page-title {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.2px;
  margin: 0 0 0.25rem;
  text-align: left;
}

.page-subtitle {
  margin: 4px 0 0;
  color: var(--ink-soft);
  font-size: 13.5px;
}

.result-count { font-weight: 600; color: var(--ink); }

/* ==========================================================================
   Botões
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 9px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  user-select: none;
  line-height: 1.2;
  white-space: nowrap;
  transition:
    background var(--innov-dur) var(--innov-ease),
    border-color var(--innov-dur) var(--innov-ease),
    color var(--innov-dur) var(--innov-ease),
    transform var(--innov-dur) var(--innov-ease),
    box-shadow var(--innov-dur) var(--innov-ease);
}

.btn:hover { text-decoration: none; }

/* Hierarquia (redesign fase 1):
   primary   índigo preenchido — a ação principal da tela
   secondary superfície elevada + borda sutil
   ghost     transparente, texto índigo claro
   danger    vermelho preenchido SÓ onde a ação destrutiva é o foco
             (tela de confirmação); em cabeçalho vai pra menu (ver .menu) */
.btn-primary {
  background: var(--innov-primary);
  color: var(--innov-on-primary);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 1px 2px rgba(3, 8, 20, 0.4);
}
.btn-primary:hover { background: var(--innov-primary-hover); transform: translateY(-1px); }

.btn-secondary {
  background: var(--innov-surface-raised);
  color: var(--innov-text);
  border-color: var(--innov-border-strong);
}
.btn-secondary:hover { background: var(--innov-surface-hover); border-color: rgba(148, 172, 212, 0.34); }

.btn-danger { background: var(--innov-danger-strong); color: var(--innov-on-primary); }
.btn-danger:hover { background: var(--danger-hover); }

/* Texto escuro sobre o verde claro: branco em #4ADE9B mede 1.7:1. */
.btn-success { background: var(--success); color: var(--innov-bg); }
.btn-success:hover { background: var(--success-hover); }

.btn-ghost { background: transparent; color: var(--innov-primary-text); }
.btn-ghost:hover { background: var(--innov-primary-soft); }

.btn:active { transform: translateY(0); }

.btn-sm { padding: 6px 11px; font-size: 12.5px; }

/* Botão só-ícone (ex.: "•••" de mais ações) — quadrado, mesma altura do .btn. */
.btn-icon { padding: 9px; width: 36px; height: 36px; }
.btn-icon.btn-sm { padding: 6px; width: 30px; height: 30px; }

/* Link discreto de linha de tabela ("Detalhe") — sem cara de botão pra não
   competir com os valores/badges da linha. */
.link-subtle {
  color: var(--innov-text-secondary);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.link-subtle:hover { color: var(--innov-primary-text); text-decoration: underline; }

.btn:disabled, .btn.disabled {
  opacity: 0.5;
  cursor: default;
  pointer-events: none;
}

/* Botões de submit SEM classe .btn (form.as_p das páginas de cadastro).
   O :not(.btn) evita que esta regra sobrescreva .btn-secondary/.btn-danger
   nos botões de submit que já usam o sistema de botões. */
form button[type="submit"]:not(.btn) {
  background-color: var(--primary);
  color: var(--innov-on-primary);
  border: none;
  padding: 0.65rem 1.4rem;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
form button[type="submit"]:not(.btn):hover {
  background-color: var(--innov-primary-hover);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.toolbar {
  display: flex;
  justify-content: flex-end;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.toolbar-start { justify-content: flex-start; }

/* ==========================================================================
   Campos de formulário (globais — usados pelas páginas de cadastro)
   ========================================================================== */

label {
  display: block;
  margin-top: 1rem;
  margin-bottom: 0.35rem;
  font-weight: 500;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

label:first-of-type { margin-top: 0; }

input, select, textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-sm);
  /* Input um degrau ACIMA do card (raised) + borda um pouco mais visível
     que a dos cards: era "quase preto dentro de quase preto". */
  border: 1px solid var(--innov-border-strong);
  background-color: var(--innov-surface-raised);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
  transition: border-color var(--innov-dur) ease, box-shadow var(--innov-dur) ease, background-color var(--innov-dur) ease;
}

input:hover, select:hover, textarea:hover { border-color: rgba(148, 172, 212, 0.34); }

input::placeholder, textarea::placeholder { color: var(--ink-faint); }

/* outline trocado por anel (box-shadow) — substituto explícito, nunca
   "outline: none" sozinho. */
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--innov-primary-bright);
  box-shadow: var(--innov-ring);
}

input[readonly] {
  color: var(--ink-soft);
  background-color: var(--innov-surface);
  cursor: default;
}

input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--primary);
  vertical-align: middle;
  cursor: pointer;
}

.checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 500;
  margin-top: 1rem;
}

/* Lista <ul> gerada pelo widget CheckboxSelectMultiple (ex.: Situação
   Unimed no cadastro/edição de cliente) — vira uma linha de opções em vez
   de uma lista com marcadores. */
#id_situacao_unimed {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

#id_situacao_unimed li {
  display: flex;
  align-items: center;
}

#id_situacao_unimed label {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 500;
  font-size: 12.5px;
  color: var(--ink-soft);
  cursor: pointer;
  padding: 6px 12px 6px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: background-color .15s, border-color .15s, color .15s;
}

#id_situacao_unimed label:hover { border-color: var(--sidebar-border); }

#id_situacao_unimed label:has(input:checked) {
  background: var(--primary-bg);
  border-color: var(--primary);
  color: var(--primary-dk);
  font-weight: 600;
}

/* ==========================================================================
   Cartões, detalhe e formulários (páginas de cadastro/visualização)
   ========================================================================== */

.card {
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 1.75rem;
}

.card + .card { margin-top: 1.5rem; }

.detail-card {
  max-width: 760px;
  margin: 0 auto;
}

.detail-card h3.form-section-title:first-of-type { margin-top: 1.5rem; }

.detail-card dl {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.6rem 1.25rem;
  margin: 0;
}

.detail-card dt { color: var(--ink-soft); font-weight: 500; }
.detail-card dd { margin: 0; color: var(--ink); }

.form-card {
  max-width: 560px;
  margin: 0 auto;
}

.form-card form p { margin: 0 0 1rem; }

.form-card ul.errorlist {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
  color: var(--danger);
  font-size: 0.85rem;
}

.field-error {
  color: var(--danger);
  font-size: 0.85rem;
  margin-top: 0.25rem;
}

.field-hint {
  color: var(--ink-faint);
  font-size: 0.82rem;
  margin: 0.4rem 0 0;
  line-height: 1.4;
}

.dependente-block {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
  padding: 1.1rem 1.25rem 1.25rem;
  margin-bottom: 1rem;
}

.dependente-block label:first-of-type { margin-top: 0; }
.dependente-block .btn-remove-dependente { margin-top: 1rem; }

#add-dependente-btn { margin-bottom: 0.5rem; }

/* Linha de parcela do form de Regra de comissão
   (comissoes/templates/comissoes_regra_form.html) — mesmo idioma visual do
   .dependente-block (bordas/fundo), mas em linha, pra caber número da
   parcela + percentual + remover num único renglão compacto. */
.parcela-row {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background-color: var(--surface-2);
  padding: 0.85rem 1.1rem;
  margin-bottom: 0.75rem;
}

.parcela-row .field-inline {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.parcela-row .field-inline label {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.parcela-row .field-inline input { width: 140px; }

/* Modo "dentro de <iframe>" (base.html detecta window.self !== window.top
   e marca <html class="embed-frame">) — usado pra abrir Nova
   regra/Editar regra como janela modal a partir de comissoes_regras.html
   sem duplicar a navegação (sidebar/topbar/rodapé) dentro da janelinha.
   .content é flex:1 dentro de .app (flex), então escondendo .sidebar ela
   já ocupa a largura toda sozinha — não precisa mexer em margin/padding. */
html.embed-frame .sidebar,
html.embed-frame .mobile-topbar,
html.embed-frame .sidebar-overlay,
html.embed-frame .app-footer { display: none !important; }

/* ---------- Modal: Regra de comissão (Nova/Editar como "janela") ----------
   comissoes_regras.html abre um <dialog> com um <iframe> apontando pra
   comissoes_regra_nova/comissoes_regra_editar — reaproveita o mesmo
   padrão do .avatar-modal (dialog nativo + JS só pra abrir/fechar), mas
   maior (é uma página inteira lá dentro, não um upload de foto) e sem
   ajax nenhum: o iframe é uma navegação HTTP normal, só a "moldura" é que
   dá a sensação de janela. */
.regra-modal {
  position: fixed;
  margin: auto;
  inset: 0;
  width: calc(100% - 3rem);
  max-width: 900px;
  height: calc(100vh - 4rem);
  padding: 0;
  background: var(--innov-surface-raised);
  border: 1px solid var(--innov-border);
  border-radius: var(--radius);
  box-shadow: var(--innov-shadow-md);
  color: var(--ink);
  overflow: hidden;
}

.regra-modal::backdrop {
  background: var(--innov-overlay);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

@media (prefers-reduced-motion: no-preference) {
  .regra-modal[open]          { animation: avatar-modal-in 0.18s ease-out; }
  .regra-modal[open]::backdrop { animation: avatar-modal-backdrop-in 0.18s ease-out; }
}

.regra-modal iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: none;
  background: var(--surface);
}

.regra-modal-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  border: none;
  background: var(--surface-2);
  color: var(--ink-soft);
  font-size: 18px;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  z-index: 2;
  box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
  touch-action: manipulation;
  transition: background 0.15s ease, color 0.15s ease;
}

.regra-modal-close:hover { background: var(--line); color: var(--ink); }

@media (max-width: 640px) {
  .regra-modal { width: calc(100% - 1.5rem); height: calc(100vh - 2rem); }
}

.form-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1.5rem;
}

.cancel-link {
  display: block;
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.9rem;
  text-align: center;
  margin-top: 1rem;
}

.cancel-link:hover {
  color: var(--ink);
  text-decoration: underline;
}

.form-section-title {
  font-size: 1rem;
  color: var(--ink);
  margin: 2rem 0 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--line);
}

.form-section-title:first-child { margin-top: 0; }

.field-with-spinner { position: relative; }

.spinner {
  display: none;
  width: 18px;
  height: 18px;
  border: 2px solid var(--primary);
  border-top: 2px solid transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
  position: absolute;
  right: 0.75rem;
  top: 0.6rem;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.field-with-action {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.field-with-action input {
  flex: 1;
  min-width: 0;
}

.field-with-action .btn {
  flex-shrink: 0;
  white-space: nowrap;
}

/* ==========================================================================
   Barra de busca + painel de filtros (lista de clientes)
   ========================================================================== */

.toolbar-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: 16px;
  overflow: hidden;
}

.search-bar {
  display: flex;
  gap: 10px;
  padding: 14px 16px;
  margin: 0;
}

.search-field {
  flex: 1;
  position: relative;
  min-width: 200px;
}

.search-field svg {
  position: absolute;
  left: 11px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--ink-faint);
  pointer-events: none;
}

.search-field input {
  width: 100%;
  padding-left: 36px;
}

.filter-panel {
  display: none;
  margin: 0;
  padding: 16px;
  border-top: 1px dashed var(--line);
  /* Transparente (fica no tom do card): com os inputs agora "raised", um
     painel raised por trás os deixaria sem contraste. */
  background: transparent;
}

.filter-panel.open { display: block; }

.filter-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px 14px;
  margin-bottom: 14px;
}

.filter-fields label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.filter-fields select,
.filter-fields input { width: 100%; }

.filter-fields label.filter-checkbox {
  flex-direction: row;
  align-items: center;
  gap: 7px;
  justify-content: flex-start;
}

.filter-fields label.filter-checkbox input { width: auto; }

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

/* ==========================================================================
   MultiSelectFilter — filtro de múltipla seleção estilo Excel
   (clientes/templates/_multiselect_filter.html + multiselect_filter.js)
   ========================================================================== */

.msf {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.msf-control {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--innov-border-strong);
  background: var(--innov-surface-raised);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  text-align: left;
  cursor: pointer;
}

.msf-control:hover { border-color: var(--sidebar-border); }

.msf-control[aria-expanded="true"],
.msf-control:focus-visible {
  outline: none;
  border-color: var(--primary);
  box-shadow: var(--innov-ring);
}

.msf-control-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.msf-chevron { flex-shrink: 0; color: var(--ink-faint); }

/* Reparentado para <body> ao abrir (position:fixed calculado via JS), pra
   nunca ser cortado por .toolbar-card/.filter-panel/.table-wrap com overflow. */
.msf-panel {
  position: fixed;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  width: 300px;
  max-height: 360px;
  /* Popover = nível 4 (mais claro que o card de onde abre) — a camada
     flutuante se lê pela luminosidade + sombra moderada. */
  background: var(--innov-surface-overlay);
  border: 1px solid var(--innov-border-strong);
  border-radius: var(--radius);
  box-shadow: var(--innov-shadow-md);
  overflow: hidden;
}

.msf-panel[hidden] { display: none; }

.msf-search-wrap { padding: 10px 10px 6px; flex-shrink: 0; }

.msf-search {
  width: 100%;
  padding: 0.5rem 0.65rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  font-family: var(--font-body);
  font-size: 0.9rem;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

.msf-bulk {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px 8px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--line-subtle);
}

.msf-bulk-btn {
  background: none;
  border: none;
  padding: 0;
  color: var(--primary-dk);
  font-size: 12px;
  font-weight: 600;
  text-transform: none;
  letter-spacing: normal;
  cursor: pointer;
}

.msf-bulk-btn:hover { text-decoration: underline; }

.msf-bulk-sep { color: var(--line); }

.msf-options {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 4px;
}

.msf-option {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  font-size: 0.9rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink);
  cursor: pointer;
}

.msf-option:hover { background: var(--primary-bg); }

.msf-option input[type="checkbox"] { flex-shrink: 0; margin: 0; }

.msf-option-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Busca esconde opções por classe (não [hidden]) — evita conflito com
   qualquer regra de especificidade maior que force display noutro lugar. */
.msf-option.msf-option--hidden { display: none; }

.msf-empty {
  display: none;
  margin: 10px 8px;
  font-size: 0.85rem;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--ink-faint);
}

.msf-empty.msf-empty--visible { display: block; }

.msf-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  flex-shrink: 0;
  border-top: 1px solid var(--line-subtle);
  background: var(--innov-surface-overlay);
}

.msf-count {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-faint);
  text-transform: none;
  letter-spacing: normal;
  white-space: nowrap;
}

.msf-footer-actions { display: flex; gap: 6px; flex-shrink: 0; }

@media (max-width: 480px) {
  .msf-panel { width: min(300px, calc(100vw - 16px)); }
}

/* ==========================================================================
   Ações em lote
   ========================================================================== */

.lote-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
  /* Sticky pra nunca sumir de vista: a tabela abaixo rola dentro do próprio
     .table-wrap (overflow-y própria), então sem isso dava pra marcar um
     checkbox mais abaixo na lista, ou com o painel de filtros aberto
     empurrando tudo pra baixo, e nunca ver esta barra (e o botão de ação
     nela) "aparecer" — ela só nasce fora da área visível do topo. */
  position: sticky;
  top: 0;
  z-index: 3;
}

.lote-toolbar span {
  color: var(--ink-soft);
  font-size: 13px;
}

.lote-count { font-size: 13px; color: var(--ink-soft); }
.lote-count strong { color: var(--ink); font-weight: 700; }

.lote-todos-filtrados {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
}

.lote-todos-filtrados input { width: auto; accent-color: var(--primary); }

.lote-spacer { flex: 1; }

.lote-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.lote-actions input { width: auto; }

/* ==========================================================================
   Tabelas
   ========================================================================== */

.table-wrap {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow-x: auto;
}

/* Quando a tabela vem logo após a barra de lote, elas se emendam */
.lote-toolbar + .table-wrap {
  border-radius: 0 0 var(--radius) var(--radius);
  max-height: calc(100vh - 120px);
  overflow-y: auto;
}

/* Tabela "leve" (redesign fase 1): linhas transparentes sobre o card
   (.table-wrap), só o thead sobe um degrau; divisórias na cor neutra da
   borda e zebra quase imperceptível — antes cada linha repintava o fundo
   e tudo virava um bloco único pesado. */
table {
  width: 100%;
  border-collapse: collapse;
  background-color: transparent;
}

thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--innov-surface-raised);
  border-bottom: 1px solid var(--innov-border);
  padding: 10px 14px;
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--innov-text-muted);
  white-space: nowrap;
}

tbody td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--innov-border);
  vertical-align: middle;
  white-space: nowrap;
}

tbody tr:nth-child(even) { background-color: var(--innov-zebra); }

tbody tr:last-child td { border-bottom: none; }

tbody tr { transition: background-color var(--innov-dur) var(--innov-ease); }
tbody tr:hover { background-color: rgba(148, 172, 212, 0.05); }

tr.clickable-row { cursor: pointer; }
tr.clickable-row:hover { background: var(--innov-primary-soft); }

/* Hierarquia dentro da linha: valor principal (líquido) forte, valores de
   apoio (bruto/desconto) recuados. */
td.num-strong { font-weight: 700; color: var(--innov-text); font-variant-numeric: tabular-nums; }
td.num-sec    { color: var(--innov-text-secondary); font-variant-numeric: tabular-nums; }

.select-col { width: 40px; text-align: center; }
.select-col input { width: 16px; height: 16px; }

/* Célula do cliente: avatar com iniciais + nome + doc/e-mail */
.cliente-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 200px;
}

.cliente-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--primary-bg);
  color: var(--primary-dk);
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
}

.cliente-nome { font-weight: 600; color: var(--ink); }
.cliente-doc {
  font-size: 12px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.cliente-dependente-match {
  display: inline-block;
  margin-top: 2px;
  font-size: 11px;
  font-weight: 600;
  color: var(--primary-dk);
}

/* Célula do plano: nome do plano + vigência/valor como linha secundária —
   mesma ideia da .cliente-cell (telefone virou 3ª linha ali), pra não
   precisar de 1 coluna inteira só pra Vigência e outra só pra Valor. */
.plano-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 260px;
  white-space: normal;
}
.plano-nome { font-weight: 600; color: var(--ink); }
.plano-meta {
  font-size: 12px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.num {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.valor {
  font-family: var(--font-display);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
}

td.muted { color: var(--ink-faint); }

/* Célula com vários badges (ex.: Situação Unimed, que agora aceita mais de
   uma marcação) — precisa quebrar linha em vez do nowrap padrão da tabela. */
.badges-cell {
  white-space: normal;
  min-width: 160px;
}
.badges-cell .status-badge { margin: 2px 4px 2px 0; }

/* Colunas com texto que pode ser longo (nome de plano, nome de vendedor):
   quebrar em 2 linhas quando precisar em vez de forçar a tabela inteira a
   ficar mais larga por causa de 1 registro com nome comprido. */
.cell-wrap {
  white-space: normal;
  max-width: 220px;
}

td.empty-state, th.empty-state {
  text-align: center;
  padding: 48px 16px !important;
  color: var(--ink-faint);
  white-space: normal;
}

.empty-state strong {
  display: block;
  color: var(--ink-soft);
  font-size: 15px;
  margin-bottom: 4px;
}

.row-actions a {
  color: var(--ink-soft);
  text-decoration: none;
  margin-right: 0.5rem;
}
.row-actions a:hover { color: var(--primary-dk); }

/* ==========================================================================
   Badges de status
   Nomes JÁ USADOS no projeto (is-active, status-aguardando...) + sinônimos
   ========================================================================== */

/* Badge "Eclipse": fundo translúcido do próprio tom (~12%) + texto no tom
   + dot. Um hairline interno (inset) do mesmo tom dá definição sem a
   aparência "acesa" do tema anterior (fundo 16% + texto saturado). */
.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 9px 2px 7px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
  background: var(--muted-bg);
  color: var(--muted-fg);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 18%, transparent);
}

.status-badge::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex-shrink: 0;
}

/* Nomes usados pelo projeto (status_css_class) */
.status-badge.is-active,
.status-badge.status-implantado { background: var(--ok-bg);    color: var(--ok-fg); }
.status-badge.status-aguardando { background: var(--warn-bg);  color: var(--warn-fg); }
.status-badge.status-declinada  { background: var(--bad-bg);   color: var(--bad-fg); }
.status-badge.is-inactive,
.status-badge.status-desistencia{ background: var(--muted-bg); color: var(--muted-fg); }

/* Sinônimos genéricos (compatibilidade com templates novos) */
.status-badge.status-ativo      { background: var(--ok-bg);    color: var(--ok-fg); }
.status-badge.status-pendente   { background: var(--warn-bg);  color: var(--warn-fg); }
.status-badge.status-cancelado  { background: var(--bad-bg);   color: var(--bad-fg); }
.status-badge.status-inativo    { background: var(--muted-bg); color: var(--muted-fg); }

/* Etapa concluída aguardando ação interna (ex.: Ficha+DS assinada, aguardando
   o comprovante de pagamento ser anexado) — mesma cor do banner "info". */
.status-badge.status-info       { background: var(--primary-bg); color: var(--primary-dk); }

/* Indicador de visualização (bolinha abaixo do status de assinatura):
   verde quando o cliente já abriu/assinou/recusou o documento, vermelho
   enquanto ainda não abriu (ver AssinaturaZapSign.visualizado). A bolinha
   só reflete o que já foi consultado na ZapSign — ver management command
   consultar_assinaturas_pendentes. */
.indicador-visualizacao {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: var(--ink-soft);
  margin-top: 2px;
}
.indicador-visualizacao::before {
  content: "";
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--bad-fg);
}
.indicador-visualizacao.visto::before {
  background: var(--ok-fg);
}

/* ==========================================================================
   Utilitários de texto
   ========================================================================== */

.text-muted { color: var(--ink-soft); }
.text-danger { color: var(--danger); }
.text-pre-line { white-space: pre-line; }

.total-geral {
  font-size: 1.1rem;
  margin-top: 1.25rem;
  color: var(--ok-fg);
  text-align: right;
  font-weight: 600;
}

/* ==========================================================================
   Paginação
   ========================================================================== */

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  margin-top: 18px;
  flex-wrap: wrap;
}

.pagination a,
.pagination .current {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  padding: 7px 11px;
  text-align: center;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
}

.pagination a {
  color: var(--ink-soft);
  border: 1px solid var(--line);
  background: var(--surface);
}

.pagination a:hover {
  border-color: var(--innov-border-strong);
  background: var(--innov-surface-raised);
  color: var(--innov-text);
  text-decoration: none;
}

.pagination .current {
  background: var(--innov-primary-soft);
  color: var(--innov-text);
  border: 1px solid var(--innov-primary-bright);
}

/* ==========================================================================
   Confirmação de exclusão
   ========================================================================== */

.confirm-card {
  max-width: 480px;
  margin: 3rem auto;
  text-align: center;
}

.confirm-card h2 { color: var(--danger); }

.confirm-card p {
  color: var(--ink-soft);
  margin-bottom: 1.75rem;
}

.confirm-card form {
  display: flex;
  justify-content: center;
  gap: 1rem;
}

/* ==========================================================================
   Mensagens (django.contrib.messages)
   ========================================================================== */

.messages {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.message {
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid;
  font-size: 13.5px;
  font-weight: 500;
}

/* Borda no tom a ~35% em vez de 100%: a mensagem continua identificável
   pela cor do texto/fundo sem o contorno "aceso". */
.message-success { background: var(--ok-bg);      color: var(--ok-fg);      border-color: color-mix(in srgb, var(--ok-fg) 35%, transparent); }
.message-warning { background: var(--warn-bg);    color: var(--warn-fg);    border-color: color-mix(in srgb, var(--warn-fg) 35%, transparent); }
.message-error   { background: var(--bad-bg);     color: var(--bad-fg);     border-color: color-mix(in srgb, var(--bad-fg) 35%, transparent); }
.message-info    { background: var(--primary-bg); color: var(--primary-dk); border-color: color-mix(in srgb, var(--innov-primary-bright) 35%, transparent); }

/* ==========================================================================
   Documentos do cliente
   ========================================================================== */

.documento-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--line-subtle);
  flex-wrap: wrap;
}

.documento-row:last-child { border-bottom: none; }

.documento-info {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.documento-nome {
  font-weight: 600;
  color: var(--ink);
}

.documento-meta {
  font-size: 0.8rem;
  color: var(--ink-faint);
}

.documento-acoes {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.documento-acoes form {
  display: inline-flex;
  margin: 0;
}

.documento-gerar { position: relative; }

.documento-gerar summary {
  list-style: none;
  user-select: none;
}

.documento-gerar summary::-webkit-details-marker,
.documento-gerar summary::marker {
  display: none;
  content: "";
}

.documento-gerar[open] summary {
  border-color: var(--primary);
  color: var(--ink);
}

.documento-gerar form {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: 20;
  margin: 0;
  padding: 0.5rem;
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  white-space: nowrap;
}

/* Painel de campos dentro de um <details class="documento-gerar"> que já
   está aninhado num <form> maior (ex.: ação em lote do financeiro) — não dá
   pra usar outro <form> aninhado, então o painel é um <div> normal, sem o
   posicionamento flutuante de ".documento-gerar form" acima. */
.lote-form-painel {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: 20;
  min-width: 240px;
  padding: 0.75rem;
  background-color: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}

.lote-form-painel p { margin: 0 0 0.6rem; }
.lote-form-painel p:last-of-type { margin-bottom: 0.75rem; }

/* ==========================================================================
   Ação rápida (Status / Situação Unimed na listagem de clientes)
   ========================================================================== */

.quick-edit-summary { cursor: pointer; }
.quick-edit-summary:hover { filter: brightness(0.95); }
.quick-edit-summary:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Situação Unimed pode ter 0 a 5 badges — o summary precisa se comportar
   como container flex (não como o pill único que .status-badge sozinho é). */
.situacao-unimed-summary {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
}

.quick-edit-painel { min-width: 220px; }

.quick-edit-titulo {
  margin: 0 0 0.5rem;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--ink-soft);
}

.quick-edit-opcao {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 2px;
  font-size: 13.5px;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
}
.quick-edit-opcao input { width: auto; }

.quick-edit-acoes {
  margin-top: 0.6rem;
  display: flex;
  justify-content: flex-end;
}

.quick-edit-erro {
  margin: 0.5rem 0 0;
  font-size: 12.5px;
  color: var(--danger);
}

.pix-info {
  background-color: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1rem;
  margin-bottom: 0.5rem;
}

.pix-info dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25rem 0.75rem;
  margin: 0;
}

.pix-info dt {
  font-weight: 600;
  color: var(--ink-faint);
}

.pix-info dd {
  margin: 0;
  color: var(--ink);
}

.comprovante-upload-form {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.9rem 0;
}

/* Dica sob o formulário de anexar documento (upload múltiplo — ver
   DocumentoAnexadoUploadView): força quebra de linha própria em vez de
   disputar espaço com o botão dentro do mesmo flex row. */
.anexo-upload-hint {
  flex-basis: 100%;
  margin: 0;
}

/* Painel dos documentos opcionais de CPT (Cobertura Parcial Temporária) —
   destacado em âmbar pra sinalizar visualmente que é um fluxo de exceção,
   não a lista padrão de documentos gerados/anexados. */
.cpt-panel-tag {
  display: inline-block;
  margin-left: 0.4rem;
  padding: 0.15rem 0.55rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--warn-fg);
  background: var(--warn-bg);
  border-radius: 999px;
  vertical-align: middle;
}

.cpt-panel {
  padding: 1rem 1.1rem 1.1rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--amber);
  border-radius: var(--radius);
}

.cpt-panel-subtitle {
  margin: 0 0 1rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.cpt-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.9rem;
}

.cpt-card {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.9rem 1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.cpt-card:hover {
  border-color: var(--sidebar-border);
  box-shadow: var(--shadow);
}

.cpt-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.cpt-card-title {
  font-weight: 600;
  color: var(--ink);
}

.cpt-card-assinatura {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.cpt-card-acoes {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.2rem;
}

.cpt-card-acoes form {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
}

/* Upload de arquivo estilizado como botão (o <input type="file"> nativo fica
   visualmente escondido dentro do <label>, que herda o clique por estarem
   aninhados — sem precisar de JS pra abrir o seletor de arquivos). */
.file-upload {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.file-upload-label {
  position: relative;
  overflow: hidden;
}

.file-upload-label input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.file-upload-nome {
  font-size: 0.78rem;
  color: var(--ink-faint);
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ==========================================================================
   Dashboard
   ========================================================================== */

.dashboard-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 22px;
  flex-wrap: wrap;
}

.periodo-switch {
  display: flex;
  gap: 4px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 4px;
}

.periodo-switch a {
  padding: 7px 14px;
  border-radius: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-soft);
  text-decoration: none;
}
.periodo-switch a:hover { color: var(--ink); text-decoration: none; }
.periodo-switch a.active { background: var(--primary); color: #FFF; }

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 18px;
}

.kpi-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
}

.kpi-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.kpi-label { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }

.kpi-icon {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: 700;
  background: var(--primary-bg);
  color: var(--primary-dk);
  flex-shrink: 0;
}
.kpi-icon.is-ok    { background: var(--ok-bg);   color: var(--ok-fg); }
.kpi-icon.is-warn  { background: var(--warn-bg); color: var(--warn-fg); }
.kpi-icon.is-amber { background: rgba(232, 197, 115, 0.16); color: var(--amber); }

.kpi-value {
  font-family: var(--font-display);
  font-size: 27px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.4px;
}

.kpi-delta { font-size: 12px; margin-top: 6px; font-weight: 600; }
.kpi-delta.is-up   { color: var(--ok-fg); }
.kpi-delta.is-down { color: var(--bad-fg); }
.kpi-delta .kpi-delta-sufixo { color: var(--ink-faint); font-weight: 400; }

/* ---------- Cards de estatística do dashboard principal (topo) ----------
   Cards escuros com "blobs" decorativos (gradientes radiais em vez de SVG —
   mesmo efeito visual do componente de referência, sem repetir markup por
   card). Classe própria (.stat-*), não reaproveita .kpi-* — essas continuam
   servindo o dashboard de Comissões (fundo claro), que não muda aqui. */
.stat-grid {
  display: grid;
  /* auto-fit em vez de repeat(N, 1fr) fixo: acomoda os 6 cards de hoje (ou
     mais no futuro) sem precisar de um breakpoint manual por quantidade —
     cada card nunca fica menor que 190px, encolhe o nº de colunas sozinho. */
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 16px;
  margin-bottom: 18px;
}

.stat-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px 20px;
  color: #fff;
}

.stat-card::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 90% 12%, rgba(255,255,255,0.16) 0%, transparent 42%),
    radial-gradient(circle at 108% 55%, rgba(255,255,255,0.11) 0%, transparent 46%),
    radial-gradient(circle at 78% 95%, rgba(255,255,255,0.07) 0%, transparent 36%);
}

.stat-card > * { position: relative; z-index: 1; }

.stat-title { font-size: 12.5px; font-weight: 600; color: rgba(255,255,255,0.85); }

.stat-value-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }

.stat-value {
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 700;
  letter-spacing: -0.4px;
  color: #fff;
}

.stat-badge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  background: rgba(255,255,255,0.18);
  color: #fff;
}
.stat-badge.is-down { background: rgba(0,0,0,0.22); }

.stat-caption {
  font-size: 11.5px;
  color: rgba(255,255,255,0.75);
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid rgba(255,255,255,0.18);
}
.stat-caption strong { color: #fff; font-weight: 600; }

/* Card "Perdas" (desistência/declínio): 2 números lado a lado em vez de 1
   valor + badge, já que não há um "vs mês anterior" fazendo sentido aqui
   (é contagem de status atual, não série temporal). */
.stat-perdas-row { display: flex; gap: 22px; margin-top: 12px; }
.stat-perdas-item { display: flex; flex-direction: column; }
.stat-perdas-valor { font-family: var(--font-display); font-size: 22px; font-weight: 700; }
.stat-perdas-label { font-size: 11px; color: rgba(255,255,255,0.8); margin-top: 2px; }

@media (max-width: 460px) {
  .stat-grid { grid-template-columns: 1fr; }
}

/* ---------- "Vidas por vigência" (substitui o antigo "Vidas por mês") ----------
   Número grande + legenda acima do gráfico, mesma hierarquia do componente
   de referência pedido — sem o badge de "% vs mês anterior" dele: vigência é
   uma distribuição da carteira atual, não uma série temporal com "mês
   anterior" pra comparar (ver comentário no card já removido). */
.vigencia-chart-stat { margin-bottom: 14px; }
.vigencia-chart-valor {
  display: block;
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.5px;
}
.vigencia-chart-legenda {
  display: block;
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-top: 2px;
}

/* Sem linha de base sob as barras — visual mais limpo, próximo do
   componente de referência (que usa recharts sem eixo/grid visível). */
.bar-chart-clean { border-bottom: none; }

.dashboard-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 16px;
  align-items: start;
}

.dashboard-grid.single-side { grid-template-columns: 1.6fr 1fr; }

/* Ranking de planos e de vendedores lado a lado, largura igual — ficam
   logo abaixo do "Pulso de vendas", em vez de empilhados numa coluna. */
.dashboard-grid-rankings { grid-template-columns: 1fr 1fr; }
.dashboard-grid.single-col { grid-template-columns: 1fr; }

.pulso-venda-body { display: flex; align-items: center; gap: 14px; }

.pulso-venda-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--primary-bg);
  color: var(--primary-dk);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 16px;
  flex-shrink: 0;
}

.pulso-venda-info { min-width: 0; }

.pulso-venda-tempo {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.3px;
}

.pulso-venda-nome {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pulso-venda-detalhe {
  font-size: 11.5px;
  color: var(--ink-faint);
  margin-top: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dashboard-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px 22px;
}

.dashboard-card-title {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 2px;
}

.dashboard-card-subtitle {
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-bottom: 16px;
}

.bar-chart {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  height: 180px;
  border-bottom: 1px solid var(--line-subtle);
}

.bar-chart-col {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  height: 100%;
}

.bar-chart-value { font-size: 12px; font-weight: 700; color: var(--ink-soft); }

.bar-chart-bar {
  width: 100%;
  max-width: 42px;
  background: var(--primary);
  border-radius: 6px 6px 2px 2px;
  transform-origin: bottom;
}

/* Resultado líquido ADM negativo num mês (Painel de Comissões) — mesma
   barra, cor de alerta em vez da cor primária. */
.bar-chart-bar.is-negativo { background: var(--danger); }

.bar-chart-labels {
  display: flex;
  gap: 10px;
  margin-top: 8px;
}
.bar-chart-labels span {
  flex: 1;
  text-align: center;
  font-size: 11.5px;
  color: var(--ink-faint);
  font-weight: 600;
}

.rank-list { display: flex; flex-direction: column; gap: 14px; }

.rank-row-top { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 5px; }
.rank-row-nome { font-weight: 600; color: var(--ink); }
.rank-row-valor { color: var(--ink-soft); font-weight: 600; }

.rank-bar-track {
  height: 7px;
  background: var(--line-subtle);
  border-radius: 99px;
  overflow: hidden;
}
.rank-bar-fill {
  height: 100%;
  background: var(--primary);
  border-radius: 99px;
}

.vendedor-rank-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line-subtle);
}
.vendedor-rank-row:last-child { border-bottom: none; }

.vendedor-rank-pos {
  width: 20px;
  font-size: 13px;
  font-weight: 800;
  color: var(--ink-faint);
  flex-shrink: 0;
}
.vendedor-rank-row:nth-child(1) .vendedor-rank-pos { color: var(--rank-gold); }
.vendedor-rank-row:nth-child(2) .vendedor-rank-pos { color: var(--ink-soft); }
.vendedor-rank-row:nth-child(3) .vendedor-rank-pos { color: var(--rank-bronze); }

.vendedor-rank-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--primary-bg);
  color: var(--primary-dk);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 12.5px;
  flex-shrink: 0;
}

.vendedor-rank-nome {
  flex: 1;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vendedor-rank-receita { font-size: 11.5px; color: var(--ink-faint); }
.vendedor-rank-vidas { font-size: 14px; font-weight: 800; color: var(--ink); }

.dashboard-empty { color: var(--ink-faint); font-size: 13px; padding: 24px 0; text-align: center; }

/* ---------- Ranking de vendedores: pódio + lista paginada ----------
   Pódio mostra só o top 3 (2º/1º/3º, 1º elevado ao centro via `order`);
   a lista embaixo é o ranking completo, paginado no servidor (Paginator
   em app/views.py, mesmo padrão de ?page= já usado em lista_clientes). */

.leaderboard-podio {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 18px;
  padding-top: 4px;
  margin-bottom: 26px;
}

.leaderboard-podio-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 108px;
  text-align: center;
}
.leaderboard-podio-item[data-posicao="1"] { order: 2; }
.leaderboard-podio-item[data-posicao="2"] { order: 1; }
.leaderboard-podio-item[data-posicao="3"] { order: 3; }

.leaderboard-podio-medal {
  font-size: 11px;
  font-weight: 800;
  color: var(--ink-faint);
  margin-bottom: 6px;
}
.leaderboard-podio-item[data-posicao="1"] .leaderboard-podio-medal { color: var(--rank-gold); }
.leaderboard-podio-item[data-posicao="2"] .leaderboard-podio-medal { color: var(--ink-soft); }
.leaderboard-podio-item[data-posicao="3"] .leaderboard-podio-medal { color: var(--rank-bronze); }

.leaderboard-podio-avatar {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--primary-bg);
  color: var(--primary-dk);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 17px;
  box-shadow: 0 0 0 2px var(--line);
}
.leaderboard-podio-item[data-posicao="1"] .leaderboard-podio-avatar {
  width: 66px;
  height: 66px;
  font-size: 20px;
  box-shadow: 0 0 0 2px var(--rank-gold);
}
.leaderboard-podio-item[data-posicao="2"] .leaderboard-podio-avatar { box-shadow: 0 0 0 2px var(--ink-soft); }
.leaderboard-podio-item[data-posicao="3"] .leaderboard-podio-avatar { box-shadow: 0 0 0 2px var(--rank-bronze); }

.leaderboard-podio-nome {
  margin-top: 10px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.leaderboard-podio-valor { font-size: 11px; color: var(--ink-faint); margin-top: 2px; }

.leaderboard-podio-bar {
  width: 100%;
  margin-top: 10px;
  border-radius: 6px 6px 0 0;
  background: var(--primary-bg);
}
.leaderboard-podio-item[data-posicao="1"] .leaderboard-podio-bar { height: 54px; background: var(--rank-gold); }
.leaderboard-podio-item[data-posicao="2"] .leaderboard-podio-bar { height: 36px; background: var(--ink-soft); }
.leaderboard-podio-item[data-posicao="3"] .leaderboard-podio-bar { height: 24px; background: var(--rank-bronze); }

.leaderboard-list { display: flex; flex-direction: column; }

/* Posição na lista (embaixo do pódio): cor neutra por padrão, só ganha
   ouro/prata/bronze se a linha for de fato o 1º/2º/3º globalmente — via
   atributo, não :nth-child (que erraria a cor no topo da página 2+, já
   que ali a 1ª linha do DOM não é a 1ª colocação real). Classe própria
   (.leaderboard-pos), não reaproveita .vendedor-rank-pos, pra não mexer
   na coloração por :nth-child já usada no ranking do dashboard_comissoes. */
.leaderboard-pos {
  width: 24px;
  font-size: 13px;
  font-weight: 800;
  color: var(--ink-faint);
  flex-shrink: 0;
}
.leaderboard-pos[data-posicao="1"] { color: var(--rank-gold); }
.leaderboard-pos[data-posicao="2"] { color: var(--ink-soft); }
.leaderboard-pos[data-posicao="3"] { color: var(--rank-bronze); }

.leaderboard-row.is-voce {
  background: var(--primary-bg);
  border-radius: var(--radius-sm);
  margin: 0 -10px;
  padding-left: 10px;
  padding-right: 10px;
}

.leaderboard-voce-tag {
  display: inline-block;
  margin-left: 5px;
  padding: 1px 7px;
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--primary-dk);
  background: var(--surface);
  border: 1px solid var(--primary);
  border-radius: 99px;
  vertical-align: middle;
}

@media (max-width: 560px) {
  .leaderboard-podio { gap: 8px; }
  .leaderboard-podio-item { width: 88px; }
}

/* ==========================================================================
   Responsivo
   ========================================================================== */

@media (max-width: 900px) {
  /* Estrutura do drawer (.app, .sidebar, .sidebar-overlay, .mobile-topbar)
     fica no bloco "Mobile: drawer off-canvas" (ver acima, perto de
     .sidebar) — aqui só o resto do responsivo que não é sidebar. */

  /* Gutter lateral de 16px no tablet/celular (32px no desktop). */
  .main { padding: var(--sp-5) var(--sp-4) var(--sp-6); }

  .avatar-modal { max-width: calc(100% - 2rem); }
  .sf-modal { max-width: calc(100% - 2rem); }

  .app-footer { padding: 14px; }

  .search-bar { flex-wrap: wrap; }
  .lote-actions { width: 100%; }
  .lote-actions .btn { flex: 1; justify-content: center; }

  .detail-card dl { grid-template-columns: 1fr; gap: 0.2rem 0; }
  .detail-card dt { margin-top: 0.6rem; }

  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .dashboard-grid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
  .nav-link, .clickable-row, .btn { transition: none; }
}

/* ==========================================================================
   Formulário de Cliente em seções (cliente_form.html / editar_cliente.html)
   Namespace .cf-* — deliberadamente à parte de .form-card/.card (usados por
   mais 13 outras telas do sistema, de login a plano_form) pra essa reforma
   não vazar pra nenhuma delas. Reaproveita tokens (--primary, --radius,
   --shadow etc.) e os estilos globais de input/select/textarea já
   existentes — só a moldura ao redor dos campos é nova.
   ========================================================================== */

.cf-shell { max-width: 900px; margin: 0 auto; display: grid; grid-template-columns: 208px 1fr; gap: 24px; align-items: start; }

.cf-header { margin-bottom: 4px; }
.cf-eyebrow { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--primary-dk); margin-bottom: 6px; }
.cf-title { font-size: 24px; }
.cf-subtitle { color: var(--ink-soft); font-size: 13.5px; margin-top: 5px; max-width: 60ch; }

.cf-rail { position: sticky; top: 20px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow); padding: 14px; }
.cf-rail-title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--ink-faint); padding: 0 8px 10px; }
.cf-rail a { display: flex; align-items: center; gap: 9px; padding: 8px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 500; color: var(--ink-soft); text-decoration: none; }
.cf-rail a:hover { background: var(--surface-2); color: var(--ink); }
.cf-rail a.is-active { background: var(--primary-bg); color: var(--primary-dk); font-weight: 600; }
.cf-rail a svg { flex-shrink: 0; opacity: .85; }

.cf-section { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 22px 24px 24px; margin-bottom: 18px; scroll-margin-top: 20px; }
.cf-section-head { display: flex; align-items: center; gap: 11px; margin-bottom: 18px; }
.cf-section-icon { width: 34px; height: 34px; border-radius: 9px; background: var(--primary-bg); color: var(--primary-dk);
  display: grid; place-items: center; flex-shrink: 0; }
.cf-section-head h3 { font-size: 16px; margin: 0; }
.cf-section-hint { color: var(--ink-faint); font-size: 12.5px; margin-top: 1px; }

.cf-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 14px 18px; }
.cf-grid .cf-span-2 { grid-column: span 2; }
.cf-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cf-field label { margin: 0; font-size: 12.5px; font-weight: 600; color: var(--ink-soft); }
.cf-field label .cf-opt { font-weight: 400; color: var(--ink-faint); }
.cf-field label .cf-req { color: var(--danger, #f87171); font-weight: 700; }
.cf-field[hidden] { display: none; }
.cf-field .field-hint { margin: 0; }

@media (max-width: 900px) {
  .cf-shell { grid-template-columns: 1fr; }
  .cf-rail { position: static; }
  .cf-grid .cf-span-2 { grid-column: span 1; }
}

.cf-actionbar { position: sticky; bottom: 14px; display: flex; justify-content: flex-end; gap: 10px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12); padding: 12px 18px; margin-top: 6px; z-index: 5; }

.cf-vidas-contador { color: var(--ink-soft); }
.cf-vidas-contador strong { color: var(--ink); }

/* ==========================================================================
   Detalhe de Cliente reorganizado (detalhe_cliente.html) — namespace .cd-*,
   separado de .card/.detail-card (13 outras telas do sistema) pelo mesmo
   motivo do .cf-* acima.
   ========================================================================== */

/* Hierarquia (redesign fase 1): header → resumo operacional → dados/
   contrato → financeiro → demais detalhes. */
.cd-shell { max-width: 1360px; margin: 0 auto; }

/* "← Clientes" — navegação de volta como breadcrumb discreto, sem
   competir com as ações do header (antes era um botão "Voltar"). */
.cd-breadcrumb {
  display: inline-flex; align-items: center; gap: 6px;
  margin-bottom: var(--sp-3);
  font-size: 12.5px; font-weight: 600; color: var(--innov-text-secondary);
}
.cd-breadcrumb:hover { color: var(--innov-text); text-decoration: none; }

/* Header do cliente: card com uma luz índigo muito difusa atrás do
   avatar (não é banner — some no resto do card). */
.cd-header {
  position: relative;
  display: flex; justify-content: space-between; align-items: center; gap: var(--sp-5);
  flex-wrap: wrap;
  padding: var(--sp-5);
  margin-bottom: var(--sp-4);
  background-color: var(--innov-surface);
  background-image: radial-gradient(420px 220px at 44px 50%, rgba(99, 119, 255, 0.13), transparent 70%);
  border: 1px solid var(--innov-border);
  border-radius: var(--innov-radius-lg);
  box-shadow: var(--innov-shadow-sm);
}
.cd-id-row { display: flex; gap: var(--sp-4); align-items: center; min-width: 0; }
.cd-avatar {
  width: 56px; height: 56px; border-radius: 16px; flex-shrink: 0;
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: 22px;
  color: var(--innov-primary-text);
  background: linear-gradient(145deg, rgba(99, 119, 255, 0.24), rgba(45, 212, 191, 0.10));
  border: 1px solid rgba(99, 119, 255, 0.35);
  box-shadow: 0 10px 28px -10px rgba(99, 119, 255, 0.65);
}
.cd-id-text { min-width: 0; }
.cd-name {
  font-family: var(--font-display); font-size: 22px; font-weight: 700; letter-spacing: -0.2px;
  color: var(--innov-text); margin: 0; overflow-wrap: anywhere;
}
.cd-meta {
  color: var(--innov-text-secondary); font-size: 13px; margin-top: var(--sp-1);
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
}
.cd-meta-sep { color: var(--innov-text-muted); }
/* Rótulo CPF/CNPJ: o mesmo header serve PF e PJ — o documento é
   identificado pelo tipo, não deduzido do tamanho do número. */
.cd-doc-label {
  font-size: 10px; font-weight: 700; letter-spacing: 0.8px;
  padding: 1px 6px; border-radius: 5px;
  color: var(--innov-text-secondary); background: var(--innov-neutral-soft);
}
.cd-doc { font-variant-numeric: tabular-nums; color: var(--innov-text); font-weight: 500; }
.cd-badges { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-top: var(--sp-2); }
.cd-actions { display: flex; gap: var(--sp-2); flex-shrink: 0; flex-wrap: wrap; align-items: center; }

/* Menu "Mais ações" — <details> nativo: abre/fecha e é acessível por
   teclado sem JS; o JS da página só fecha ao clicar fora / Esc. É onde
   mora o "Excluir": destrutivo não fica vermelho permanente no header. */
.menu { position: relative; }
.menu > summary { list-style: none; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20;
  min-width: 200px; padding: 6px;
  background: var(--innov-surface-overlay);
  border: 1px solid var(--innov-border-strong);
  border-radius: var(--innov-radius-md);
  box-shadow: var(--innov-shadow-md);
}
.menu-item {
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%; padding: 8px 10px; border-radius: var(--innov-radius-sm);
  font-size: 13.5px; font-weight: 500; color: var(--innov-text);
}
.menu-item:hover { background: var(--innov-surface-hover); text-decoration: none; }
.menu-item.is-danger { color: var(--innov-danger); }
.menu-item.is-danger:hover { background: var(--innov-danger-soft); }
.menu-sep { height: 1px; margin: 6px 4px; background: var(--innov-border); }

/* Resumo operacional: responde "qual a situação deste cliente?" numa
   linha só, antes dos detalhes. */
.cd-summary {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-bottom: var(--sp-4);
  background: var(--innov-surface);
  border: 1px solid var(--innov-border);
  border-radius: var(--innov-radius-md);
  overflow: hidden;
}
/* Divisórias por borda esquerda/superior com margem -1px: a primeira
   coluna/linha de cada quebra cai fora da caixa e é cortada pelo
   overflow:hidden — sobra só a divisória ENTRE itens, em qualquer nº de
   colunas que o auto-fit escolher. */
.cd-summary-item {
  padding: 14px 20px; min-width: 0;
  border-left: 1px solid var(--innov-border); margin-left: -1px;
  border-top: 1px solid var(--innov-border); margin-top: -1px;
}
.cd-summary-label {
  display: block; font-size: 10.5px; font-weight: 600; letter-spacing: 0.9px; text-transform: uppercase;
  color: var(--innov-text-muted); margin-bottom: 4px;
}
.cd-summary-value {
  display: block; font-size: 14.5px; font-weight: 600; color: var(--innov-text);
  font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cd-summary-value.is-empty { color: var(--innov-text-muted); font-weight: 500; }

.cd-stepper-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 20px 26px 18px; margin-bottom: 20px; }
.cd-stepper-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 16px; flex-wrap: wrap; gap: 6px; }
.cd-stepper-head h3 { font-size: 14.5px; margin: 0; }
.cd-stepper-head span { font-size: 12px; color: var(--ink-faint); }

.cd-stepper { display: flex; }
.cd-step { flex: 1; position: relative; padding-right: 18px; }
.cd-step:last-child { flex: 0 0 auto; padding-right: 0; min-width: 150px; }
.cd-step-line { position: absolute; top: 15px; left: calc(50% + 15px); right: calc(-50% + 15px); height: 2px; background: var(--line); }
.cd-step:last-child .cd-step-line { display: none; }
.cd-step.is-done .cd-step-line { background: var(--ok-fg); }
.cd-step-dot { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; margin-bottom: 9px;
  background: var(--muted-bg); color: var(--muted-fg); border: 2px solid var(--surface); position: relative; z-index: 1; font-weight: 700; font-size: 12.5px; }
.cd-step.is-done .cd-step-dot { background: var(--ok-fg); color: #fff; }
.cd-step.is-current .cd-step-dot { background: var(--primary); color: #fff; box-shadow: 0 0 0 4px var(--primary-bg); }
.cd-step.is-recusado .cd-step-dot { background: var(--bad-fg); color: #fff; }
.cd-step-label { font-size: 12.5px; font-weight: 600; color: var(--ink); }
.cd-step-sub { font-size: 11px; color: var(--ink-faint); margin-top: 2px; }
.cd-step.is-current .cd-step-label { color: var(--primary-dk); }
.cd-step.is-recusado .cd-step-label { color: var(--bad-fg); }

@media (max-width: 720px) {
  .cd-stepper { flex-direction: column; gap: 14px; }
  .cd-step-line { display: none; }
  .cd-step:last-child { min-width: 0; }
}

/* Cards de dados em grade 2×2 (dados pessoais | plano & contrato;
   contato | documentos). Altura por linha da grade, nunca fixa: card vazio
   mostra só uma linha de "não cadastrado" em vez de um bloco enorme vazio. */
.cd-info-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-4); margin-bottom: var(--sp-4);
  /* start (não stretch): sem isso a grade iguala a altura da linha e o
     card vazio herda a altura do vizinho cheio — exatamente o "bloco
     enorme vazio" que o redesign quer eliminar. */
  align-items: start;
}

.cd-info-card {
  background: var(--innov-surface); border: 1px solid var(--innov-border); border-radius: var(--innov-radius-md);
  box-shadow: var(--innov-shadow-sm); padding: 18px 20px;
}
.cd-info-card-head { display: flex; align-items: center; gap: 10px; margin-bottom: var(--sp-4); }
.cd-info-card-icon {
  width: 28px; height: 28px; border-radius: 8px; flex-shrink: 0; display: grid; place-items: center;
  background: var(--innov-primary-soft); color: var(--innov-primary-text);
}
.cd-info-card h4 { font-size: 13.5px; font-weight: 600; margin: 0; color: var(--innov-text); }
.cd-info-card .cd-edit-link {
  margin-left: auto; font-size: 12px; font-weight: 600; white-space: nowrap; color: var(--innov-text-secondary);
}
.cd-info-card .cd-edit-link:hover { color: var(--innov-primary-text); }
/* Labels recuados, valores claros e de peso médio (nem tudo em bold). */
.cd-info-dl { display: grid; grid-template-columns: minmax(110px, max-content) 1fr; gap: 9px 18px; margin: 0; font-size: 13px; }
.cd-info-dl dt { color: var(--innov-text-muted); font-weight: 500; }
.cd-info-dl dd { margin: 0; color: var(--innov-text); font-weight: 500; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.cd-empty { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin: 0; font-size: 13px; color: var(--innov-text-muted); }
.cd-empty a { font-size: 12.5px; font-weight: 600; }

.cd-section {
  background: var(--innov-surface); border: 1px solid var(--innov-border); border-radius: var(--innov-radius-md);
  box-shadow: var(--innov-shadow-sm); padding: 20px 22px 22px; margin-bottom: var(--sp-4); scroll-margin-top: var(--sp-5);
}
.cd-section-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: var(--sp-4); flex-wrap: wrap; }
.cd-section-head-left { display: flex; align-items: center; gap: 10px; }
.cd-section-icon {
  width: 30px; height: 30px; border-radius: 8px; flex-shrink: 0; display: grid; place-items: center;
  background: var(--innov-primary-soft); color: var(--innov-primary-text);
}
.cd-section h3 { font-size: 15px; font-weight: 600; margin: 0; color: var(--innov-text); }
.cd-section-count { font-size: 12px; color: var(--innov-text-muted); font-weight: 500; white-space: nowrap; }
.cd-subsection-title {
  font-size: 11px; font-weight: 600; letter-spacing: 0.8px; text-transform: uppercase;
  color: var(--innov-text-muted); margin: var(--sp-5) 0 var(--sp-2);
}

/* ---------- Bloco Financeiro (atalho do /comissoes/financeiro/) ----------
   Card "hero" do detalhe: um degrau acima dos outros (raised) + electric
   edge no topo. Os tiles por dentro descem pro tom do card comum (poço),
   então separam do fundo pela luminosidade, sem borda colorida. */
.cd-fin { background: var(--innov-surface-raised); border-color: var(--innov-border-strong); }
.cd-fin .table-wrap { background: var(--innov-surface); box-shadow: none; }
.cd-fin thead th { background: var(--innov-surface-raised); }

.cd-fin-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: var(--sp-3); }
/* --tone define a cor do acento de cada tile (barra curta no topo + dot
   do rótulo + valor quando faz sentido) — a cor nunca pinta o tile todo. */
.cd-fin-kpi {
  --tone: var(--innov-primary-bright);
  position: relative;
  display: flex; flex-direction: column; gap: 6px;
  padding: 16px 18px;
  background: var(--innov-surface);
  border: 1px solid var(--innov-border);
  border-radius: var(--innov-radius-md);
}
.cd-fin-kpi::before {
  content: ''; position: absolute; top: -1px; left: 18px; width: 28px; height: 2px; border-radius: 0 0 2px 2px;
  background: var(--tone);
}
.cd-fin-kpi.is-primary { --tone: var(--innov-primary-bright); }
.cd-fin-kpi.is-accent  { --tone: var(--innov-accent); }
.cd-fin-kpi.is-warn    { --tone: var(--innov-warning); }
.cd-fin-kpi.is-neutral { --tone: var(--innov-text-muted); }
.cd-fin-kpi-label {
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.8px; text-transform: uppercase; color: var(--innov-text-secondary);
}
.cd-fin-kpi-label::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--tone); flex-shrink: 0; }
.cd-fin-kpi-value {
  font-family: var(--font-display); font-size: 23px; font-weight: 700; letter-spacing: -0.3px;
  color: var(--innov-text); font-variant-numeric: tabular-nums; line-height: 1.2;
}
.cd-fin-kpi-sub { font-size: 12px; color: var(--innov-text-secondary); }
.cd-fin-progress { height: 6px; border-radius: 99px; background: rgba(148, 172, 212, 0.14); overflow: hidden; margin: 2px 0; }
.cd-fin-progress > span { display: block; height: 100%; background: var(--innov-accent); border-radius: inherit; }
.cd-fin-implantacao {
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  font-size: 12.5px; color: var(--innov-text-secondary); margin: var(--sp-4) 0 0;
}
.cd-fin-implantacao strong { color: var(--innov-text); font-weight: 600; }
.cd-fin-when { font-size: 11px; color: var(--innov-text-muted); margin-top: 3px; }

@media (max-width: 900px) {
  .cd-info-grid { grid-template-columns: 1fr; }
  .cd-header { padding: var(--sp-4); }
  .cd-actions { width: 100%; }
  .cd-actions > .btn { flex: 1; }
}
@media (max-width: 560px) {
  .cd-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cd-info-dl { grid-template-columns: 1fr; gap: 2px 0; }
  .cd-info-dl dd { margin-bottom: 8px; }
  .cd-name { font-size: 19px; }
  .cd-section { padding: 16px; }
  .cd-fin-kpis { grid-template-columns: 1fr; }
}
/* ==========================================================================
   Consulta de Boletos (financeiro/boletos_service.py) — busca por CPF ao
   vivo na Asaas. Namespace .bl-* isolado do resto (.cd-*/.sf-*), só
   reaproveita primitivas já existentes (.card, .status-badge, .table-wrap,
   .documento-row) onde fazem sentido.
   ========================================================================== */

.bl-toolbar-actions { display: flex; gap: 8px; padding: 0 16px 14px; }

.bl-summary-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
.bl-summary-head h3 { margin: 0; font-size: 15px; }

.bl-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
  margin-top: 14px;
}
.bl-stat {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
}
.bl-stat-label { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }
.bl-stat-value { font-size: 21px; font-weight: 700; font-family: var(--font-display); margin-top: 3px; font-variant-numeric: tabular-nums; }
.bl-stat-total      { border-left-color: var(--primary); }
.bl-stat-aberto      { border-left-color: var(--warn-fg); }
.bl-stat-vencido    { border-left-color: var(--bad-fg); }
.bl-stat-finalizado { border-left-color: var(--ok-fg); }

.bl-prioritarios { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; margin: 16px 0; }
.bl-prioritarios .card { margin: 0; }
.bl-prioritarios h4 { margin: 0 0 10px; font-size: 13px; }

.bl-por-pagina { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-soft); }
.bl-por-pagina a { padding: 2px 7px; border-radius: 5px; }
.bl-por-pagina a.active { background: var(--primary-bg); color: var(--primary-dk); font-weight: 700; }
.bl-resultado-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; margin: 20px 0 10px; }
.bl-resultado-head h2 { margin: 0; font-size: 16px; }
.bl-contagem { font-size: 12.5px; color: var(--ink-faint); }

/* ==========================================================================
   Comissões — dashboard de conciliação e financeiro (comissoes/views.py)
   ========================================================================== */

.quadrante-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 16px;
}
.quadrante-card {
  display: block;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px 18px;
  text-decoration: none;
  color: inherit;
  transition: transform .12s ease, box-shadow .12s ease;
}
.quadrante-card:hover { transform: translateY(-1px); border-color: var(--innov-border-strong); text-decoration: none; }
.quadrante-tom-info    { border-left-color: var(--primary); }
.quadrante-tom-alerta  { border-left-color: var(--bad-fg); }
.quadrante-tom-neutro  { border-left-color: var(--warn-fg); }
.quadrante-tom-sucesso { border-left-color: var(--ok-fg); }

.quadrante-titulo { font-size: 12.5px; font-weight: 700; color: var(--ink-soft); text-transform: uppercase; letter-spacing: .03em; }
.quadrante-valor { font-family: var(--font-display); font-size: 24px; font-weight: 700; margin-top: 8px; color: var(--ink); }
.quadrante-quantidade { font-size: 12.5px; color: var(--ink-faint); margin-top: 2px; }
.quadrante-descricao { font-size: 12px; color: var(--ink-faint); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }

/* Agrupamento por cliente (financeiro) — <details>/<summary> nativo, sem
   JS: some com uma tabela gigante sem contexto (pedido #36). */
.cliente-grupo {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-top: 12px;
  overflow: hidden;
}
.cliente-grupo-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 14px 18px;
  cursor: pointer;
  font-weight: 600;
  color: var(--innov-text);
  list-style: none;
  transition: background-color var(--innov-dur) var(--innov-ease);
}
.cliente-grupo-summary:hover { background: rgba(148, 172, 212, 0.04); }
.cliente-grupo-summary::-webkit-details-marker { display: none; }
.cliente-grupo-summary::before {
  content: "▸";
  margin-right: 8px;
  color: var(--ink-faint);
  transition: transform .12s ease;
}
.cliente-grupo[open] .cliente-grupo-summary::before { transform: rotate(90deg); }
.cliente-grupo-nome { flex: 1; }
.cliente-grupo-total { font-family: var(--font-display); font-weight: 700; color: var(--ink); }
/* Só a divisória de cima: as laterais/base já são a borda do próprio
   .cliente-grupo — antes ficava borda dupla dentro do card. */
.cliente-grupo .table-wrap { border: none; border-top: 1px solid var(--line); border-radius: 0; box-shadow: none; }

/* ==========================================================================
   Componentes "Eclipse" compartilhados (redesign fase 1)
   ========================================================================== */

/* Electric edge — assinatura visual do Innov Tech: filete índigo → teal
   no topo do card + um brilho curto logo abaixo dele. Uso RESTRITO a
   componentes estratégicos (hoje: bloco Financeiro do detalhe do cliente);
   aplicar em todo card diluiria a assinatura. */
.electric-edge { position: relative; overflow: hidden; }
.electric-edge::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 2px;
  background: var(--innov-edge);
  pointer-events: none;
}
.electric-edge::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 90px;
  background: radial-gradient(60% 90px at 20% 0, rgba(99, 119, 255, 0.12), transparent 70%);
  pointer-events: none;
}
.electric-edge > * { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  .btn:hover, .btn-primary:hover { transform: none; }
}

/* ==========================================================================
   Central do vendedor (vendedores/templates/detalhe_vendedor.html + _vendedor_*)
   Reaproveita .cd-* (header, seções, tiles .cd-fin-kpi, menu, electric
   edge) do detalhe do cliente — aqui só o que é próprio desta página.
   ========================================================================== */

.vd-h2 { font-size: 15px; font-weight: 600; margin: 0; color: var(--innov-text); }

/* 4 KPIs no desktop, 2 no tablet, 1 no celular. */
.vd-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-3); margin-bottom: var(--sp-4); }
.vd-kpis .cd-fin-kpi { background: var(--innov-surface); box-shadow: var(--innov-shadow-sm); }
.vd-kpi-span { grid-column: span 3; }
.cd-fin-kpi-value.is-empty { font-size: 17px; color: var(--innov-text-secondary); }

.vd-split { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-5); }
.vd-split-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cd-subsection-title.vd-first { margin-top: 0; }
.cd-subsection-title small { text-transform: none; letter-spacing: 0; font-weight: 500; margin-left: var(--sp-2); }

.vd-note { font-size: 12px; color: var(--innov-text-muted); margin: 0 0 var(--sp-3); }
.vd-note.is-warn, .vd-foot .is-warn { color: var(--innov-warning); }

/* Lista com barra (situação/operadora) — barra = proporção, número sempre
   em texto ao lado (a barra nunca é a única informação). */
.vd-bars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-3); }
.vd-bar-row { display: grid; grid-template-columns: 1fr auto; gap: 4px var(--sp-3); align-items: baseline; }
.vd-bar-label { font-size: 13px; color: var(--innov-text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.vd-bar-value { font-size: 13px; font-weight: 600; color: var(--innov-text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.vd-bar-value small { font-weight: 500; color: var(--innov-text-muted); }
.vd-bar-track { grid-column: 1 / -1; height: 5px; border-radius: 99px; background: rgba(148, 172, 212, 0.12); overflow: hidden; }
.vd-bar-fill { display: block; height: 100%; border-radius: inherit; background: var(--innov-primary-bright); }
.vd-bar-fill.is-accent { background: var(--innov-accent); }

.vd-facts { margin: 0 0 var(--sp-3); display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.vd-facts div { min-width: 0; }
.vd-facts dt { font-size: 11px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase; color: var(--innov-text-muted); }
.vd-facts dd { margin: 2px 0 0; font-size: 16px; font-weight: 600; color: var(--innov-text); font-variant-numeric: tabular-nums; }

/* Lista de valores (quadrantes / fluxo) */
.vd-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--innov-border); border-radius: var(--innov-radius-md); background: var(--innov-surface); overflow: hidden; }
.vd-list > li + li { border-top: 1px solid var(--innov-border); }
.vd-list-row { display: flex; align-items: center; gap: var(--sp-3); padding: 11px 14px; color: var(--innov-text); }
a.vd-list-row { transition: background-color var(--innov-dur) var(--innov-ease); }
a.vd-list-row:hover { background: rgba(148, 172, 212, 0.05); text-decoration: none; }
.vd-list-row.is-muted { color: var(--innov-text-muted); }
.vd-list-label { flex: 1; min-width: 0; font-size: 13px; font-weight: 500; }
.vd-list-label small { display: block; font-size: 11.5px; font-weight: 400; color: var(--innov-text-muted); }
.vd-list-value { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.vd-tom { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--innov-text-muted); }
.vd-tom-info { background: var(--innov-primary-bright); }
.vd-tom-alerta { background: var(--innov-danger); }
.vd-tom-neutro { background: var(--innov-warning); }
.vd-tom-sucesso { background: var(--innov-success); }

/* Aviso operacional factual (recebido e não repassado) — discreto. */
.vd-alert {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px;
  margin: 0 0 var(--sp-4); padding: 10px 14px; font-size: 13px;
  color: var(--innov-text-secondary);
  background: var(--innov-primary-soft); border: 1px solid rgba(99, 119, 255, 0.25); border-radius: var(--innov-radius-sm);
}
.vd-alert strong { color: var(--innov-text); }

/* Gráfico de colunas em CSS puro (sem biblioteca): alturas calculadas no
   backend (resumo_service.serie_mensal). */
.vd-legend { display: inline-flex; align-items: center; gap: 6px; }
.vd-dot { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-left: 6px; }
.vd-dot.is-gerada, .vd-chart-bar.is-gerada { background: var(--innov-primary-bright); }
.vd-dot.is-paga, .vd-chart-bar.is-paga { background: var(--innov-accent); }
.vd-chart {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-4) var(--sp-2); background: var(--innov-surface);
  border: 1px solid var(--innov-border); border-radius: var(--innov-radius-md);
}
.vd-chart-col { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.vd-chart-bars { height: 120px; width: 100%; display: flex; align-items: flex-end; justify-content: center; gap: 3px; }
.vd-chart-bar { width: min(14px, 40%); min-height: 0; border-radius: 3px 3px 0 0; }
.vd-chart-label { font-size: 10.5px; color: var(--innov-text-muted); white-space: nowrap; }

.vd-foot { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: var(--sp-4); font-size: 12.5px; color: var(--innov-text-secondary); }
.vd-foot a { margin-left: auto; font-weight: 600; }

/* Filtros das tabelas (busca + selects inline) */
.vd-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.vd-toolbar input[type="search"] { flex: 1 1 280px; width: auto; }
.vd-toolbar select { flex: 0 1 220px; width: auto; }

.vd-cliente-link { font-weight: 600; color: var(--innov-text); }
.vd-cliente-link:hover { color: var(--innov-primary-text); }
.vd-comissao-cell { display: flex; flex-direction: column; color: var(--innov-text); line-height: 1.35; }
.vd-comissao-cell strong { font-variant-numeric: tabular-nums; }
.vd-comissao-cell span { font-size: 11.5px; color: var(--innov-text-muted); }
.vd-comissao-cell:hover { text-decoration: none; }
.vd-comissao-cell:hover strong { color: var(--innov-primary-text); }
.vd-range { font-size: 12px; color: var(--innov-text-muted); margin: var(--sp-3) 0 0; }

/* Chip "filtrado por vendedor" (Extratos/Adiantamentos, vindo da central) */
.filtro-chip {
  display: inline-block; margin: 0 0 var(--sp-3); padding: 4px 10px; font-size: 12.5px;
  color: var(--innov-text-secondary); background: var(--innov-primary-soft); border-radius: var(--innov-radius-pill);
}
.filtro-chip strong { color: var(--innov-text); }

@media (max-width: 1100px) {
  .vd-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .vd-kpi-span { grid-column: span 1; }
  .vd-split { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 720px) {
  .vd-split, .vd-split-2 { grid-template-columns: 1fr; }
  .vd-chart { grid-template-columns: repeat(6, minmax(0, 1fr)); row-gap: var(--sp-4); }
}
@media (max-width: 560px) {
  .vd-kpis { grid-template-columns: 1fr; }
  .vd-facts { grid-template-columns: 1fr 1fr; }
}
/* Cabeçalho longo quebra em 2 linhas em vez de alargar a tabela inteira;
   nome do cliente com largura mínima (não vira coluna de 1 palavra). */
thead th.th-wrap { white-space: normal; min-width: 92px; line-height: 1.3; }
td.vd-cell-cliente { white-space: normal; min-width: 170px; max-width: 260px; }

/* Extrato no recorte de UM vendedor (comissoes_extrato_detalhe.html /
   comissoes_extratos.html com ?vendedor= ou papel Vendedor): subtotal do
   vendedor em destaque, total do extrato inteiro recuado e rotulado. */
.extrato-recorte { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.extrato-recorte .cd-fin-kpi { background: var(--innov-surface); }
.extrato-recorte-destaque { border-color: color-mix(in srgb, var(--innov-accent) 40%, transparent); }
.extrato-recorte-destaque .cd-fin-kpi-value { font-size: 26px; }
.extrato-total-secundario { font-size: 18px; color: var(--innov-text-secondary); }
.extrato-pagar-nota { font-size: 12.5px; }
td.vd-destaque { color: var(--innov-accent); }
@media (max-width: 900px) { .extrato-recorte { grid-template-columns: 1fr; } }
