/* module-page.css — design system Nexus OS */
*{margin:0;padding:0;box-sizing:border-box}

/* ═════════════════════════════════════════════════════════
   Sprint Polish v2.3 — NN: Light theme
   Override de tokens quando [data-theme="light"] no <html> ou <body>.
   Cores semânticas (money/hot/warn/up/down) preservam identidade —
   só os backgrounds e textos invertem. Aplicado antes dos defaults
   pra :root vencer quando dark.
   ═════════════════════════════════════════════════════════ */
:root[data-theme="light"],
[data-theme="light"]{
  /* Surfaces — inversão completa */
  --bg:#fafafa; --bg-2:#ffffff; --bg-3:#f3f4f6; --bg-4:#e5e7eb;
  --text:#111827; --muted:#4b5563; --dim:#9ca3af;

  /* Borders mais visíveis no claro */
  --border:#e5e7eb; --border-2:#d1d5db; --border-3:#9ca3af;

  /* Brand mantém — mas accent-soft e accent-glow ajustados */
  --accent:#0091e8;          /* leve sombra mais escura pra ler em fundo claro */
  --accent-2:#00b8d9;
  --accent-glow:rgba(0,145,232,.18);
  --accent-soft:rgba(0,145,232,.08);

  /* Semantic preservam identidade mas com tons ajustados pra contraste */
  --up:#15803d;              /* verde-saúde mais escuro pra contraste em branco */
  --up-soft:rgba(21,128,61,.1);
  --warn:#b45309;            /* amarelo->âmbar escuro */
  --warn-soft:rgba(180,83,9,.1);
  --down:#dc2626;
  --down-soft:rgba(220,38,38,.1);
  --money:#059669;           /* verde-money escuro */
  --money-soft:rgba(5,150,105,.1);
  --money-glow:rgba(5,150,105,.18);
  --hot:#dc2626;
  --hot-soft:rgba(220,38,38,.1);

  /* Gradient sutil pro tema claro */
  --gradient:linear-gradient(135deg, #0091e8 0%, #00b8d9 100%);
  --gradient-soft:linear-gradient(135deg, rgba(0,145,232,.10) 0%, rgba(0,184,217,.04) 100%);

  /* Aside fica mais clarinho */
  color-scheme:light;
}

/* Sombras adaptativas — no light ficam mais sutis */
[data-theme="light"] .kpi-card:hover,
[data-theme="light"] .metric-card:hover,
[data-theme="light"] .stat-card:hover,
[data-theme="light"] .stat-box:hover,
[data-theme="light"] .pulse-box:hover{
  box-shadow:0 6px 16px rgba(0,0,0,.08);
}
[data-theme="light"] .kpi-card.kpi-money:hover,
[data-theme="light"] .metric-card.money:hover{
  box-shadow:0 6px 16px rgba(5,150,105,.18);
}

/* Empty/skeleton mais discretos */
[data-theme="light"] .nx-empty{ background:var(--bg-2); }
[data-theme="light"] .nx-skeleton{
  background:linear-gradient(90deg, #f3f4f6 0%, #e5e7eb 50%, #f3f4f6 100%);
  background-size:200% 100%;
}

/* Phase-card no light */
[data-theme="light"] .phase-card:hover{
  box-shadow:0 6px 18px rgba(0,145,232,.15);
}

/* Outline focus mais contrastado */
[data-theme="light"] *:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:2px;
}

/* Transição suave ao alternar tema */
html,
[data-theme] body,
[data-theme] aside,
[data-theme] main{
  transition:background-color .2s ease, color .2s ease;
}

:root{
  /* ═════════ COLOR TOKENS ═════════ */
  --bg:#0a0a0a; --bg-2:#141414; --bg-3:#1c1c1c; --bg-4:#262626;
  --text:#e8e8e8; --muted:#888; --dim:#777;

  /* Brand */
  --accent:#0099ff;
  --accent-2:#00d4ff;
  --accent-glow:rgba(0,153,255,.25);
  --accent-soft:rgba(0,153,255,.08);

  /* Semantic */
  --up:#22c55e;
  --up-soft:rgba(34,197,94,.12);
  --warn:#ffb000;
  --warn-soft:rgba(255,176,0,.12);
  --down:#ff3838;
  --down-soft:rgba(255,56,56,.12);

  /* Money / Sales — Sprint 1 Nexus v2 (item T do DataProspect roadmap).
     Verde-dinheiro distinto do --up (verde-sucesso/saúde). Usar em:
     - Cards de receita, MRR, ticket médio, pipeline value
     - KPIs de conversão (taxa de fechamento, lead→cliente)
     - Badges de leads quentes (intent score >80)
     Hierarquia visual: azul=info, verde-dinheiro=$$$, verde-up=saúde,
     amarelo=alerta, vermelho=perigo. */
  --money:#00d4aa;
  --money-soft:rgba(0,212,170,.12);
  --money-glow:rgba(0,212,170,.25);
  --hot:#ff5c2e;            /* Lead quente — laranja intenso */
  --hot-soft:rgba(255,92,46,.12);

  /* Borders */
  --border:#222; --border-2:#333; --border-3:#444;

  /* Gradients */
  --gradient:linear-gradient(135deg, #0099ff 0%, #00d4ff 100%);
  --gradient-soft:linear-gradient(135deg, rgba(0,153,255,.12) 0%, rgba(0,212,255,.04) 100%);

  /* ═════════ SPACING TOKENS (escala 4px) ═════════ */
  --space-1:4px;
  --space-2:8px;
  --space-3:12px;
  --space-4:16px;
  --space-5:20px;
  --space-6:24px;
  --space-8:32px;
  --space-10:40px;
  --space-12:48px;
  --space-16:64px;

  /* ═════════ TYPOGRAPHY TOKENS ═════════ */
  --text-xs:11px;
  --text-sm:12px;
  --text-base:13px;
  --text-md:14px;
  --text-lg:16px;
  --text-xl:20px;
  --text-2xl:24px;
  --text-3xl:32px;

  --weight-regular:400;
  --weight-medium:500;
  --weight-semibold:600;
  --weight-bold:700;
  --weight-black:900;

  --font-sans:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  --font-mono:'JetBrains Mono','Courier New',monospace;

  /* ═════════ RADIUS TOKENS ═════════ */
  --radius-sm:3px;
  --radius-md:6px;
  --radius-lg:8px;
  --radius-xl:12px;
  --radius-pill:99px;

  /* ═════════ SHADOW TOKENS ═════════ */
  --shadow-sm:0 1px 2px rgba(0,0,0,.3);
  --shadow-md:0 4px 12px rgba(0,0,0,.4);
  --shadow-lg:0 8px 24px rgba(0,0,0,.5);
  --shadow-glow:0 0 24px rgba(0,153,255,.15);

  /* ═════════ MOTION TOKENS ═════════ */
  --transition-fast:.12s ease;
  --transition-base:.15s ease;
  --transition-slow:.3s ease;
}

body{
  background:var(--bg); color:var(--text);
  font-family:var(--font-sans);
  font-size:var(--text-md);
  min-height:100vh;
  display:grid; grid-template-columns:240px 1fr;
}

/* ─── A11y utilities ─────────────────────────────────── */
.sr-only{
  position:absolute; width:1px; height:1px; padding:0; overflow:hidden;
  clip:rect(0,0,0,0); white-space:nowrap; border:0;
}
/* Skip-link: primeiro tab-stop da página, escondido até receber foco. */
.skip-link{
  position:fixed; top:-120px; left:12px; z-index:10000;
  background:var(--accent); color:#fff; padding:10px 16px;
  border-radius:8px; font-size:14px; font-weight:600;
  text-decoration:none; transition:top .15s ease;
}
.skip-link:focus{ top:12px; outline:2px solid #fff; outline-offset:2px; }
*:focus-visible{outline:2px solid var(--accent); outline-offset:2px;}

/* ─── Sidebar ───────────────────────────────────────── */
aside{
  background:var(--bg-2);
  border-right:1px solid var(--border);
  padding:var(--space-6) 0;
  position:sticky; top:0; height:100vh; overflow-y:auto;
}
.brand{padding:0 var(--space-5) var(--space-5); border-bottom:1px solid var(--border); margin-bottom:var(--space-4);}
.brand h1{
  font-size:18px; font-weight:var(--weight-black); letter-spacing:-.5px;
  font-family:var(--font-mono);
}
.brand h1 span{color:var(--accent)}
.brand .v{font-size:10px; color:var(--dim); margin-top:2px; letter-spacing:1px;}
.nav-section{margin-bottom:var(--space-5);}
.nav-label{
  padding:0 var(--space-5) var(--space-2); font-size:10px; color:var(--dim);
  letter-spacing:1.5px; text-transform:uppercase;
  font-family:var(--font-mono);
}
/* Sprint 4 Y: Fases numeradas — "FASE 0N · Label" com prefixo destacado */
.nav-section-phase .nav-label{
  display:flex; align-items:center; gap:6px;
  color:var(--text); font-size:11px; letter-spacing:1px;
}
.nav-section-phase .nav-phase-num{
  background:var(--accent-soft); color:var(--accent);
  padding:2px 7px; border-radius:99px;
  font-size:9px; font-weight:700; letter-spacing:1.2px;
  border:1px solid var(--accent-soft);
}
.nav-section-phase .nav-phase-desc{
  padding:0 var(--space-5) var(--space-2);
  font-size:10px; color:var(--muted); font-style:italic;
  margin-top:-4px; line-height:1.3;
}
.nav-item{
  display:flex; align-items:center; gap:10px;
  padding:var(--space-2) var(--space-5); color:var(--muted); cursor:pointer;
  text-decoration:none; font-size:var(--text-base);
  border-left:3px solid transparent;
  transition:all var(--transition-base);
}
.nav-item:hover{background:var(--bg-3); color:var(--text)}
.nav-item.active{background:var(--bg-3); color:var(--accent); border-left-color:var(--accent);}
.nav-icon{
  width:16px; height:16px; flex-shrink:0;
  display:inline-flex; align-items:center; justify-content:center;
  color:currentColor;
}
.nav-icon svg{width:16px; height:16px; stroke-width:1.75;}
.nav-text{display:flex; flex-direction:column; gap:1px; line-height:1.2; min-width:0;}
.nav-label-text{font-size:var(--text-base);}
.nav-desc{font-size:10.5px; color:var(--muted); opacity:.7; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;}
.nav-item:hover .nav-desc{opacity:1;}
.nav-item.active .nav-desc{color:var(--text); opacity:.8;}

/* ─── Sidebar collapsible group ─────────────────────── */
.nav-collapse-toggle{
  width:100%; background:transparent; border:none; cursor:pointer;
  padding:0 var(--space-5) var(--space-2); display:flex; justify-content:space-between; align-items:center;
  color:var(--dim); font-size:10px; letter-spacing:1.5px; text-transform:uppercase;
  font-family:var(--font-mono); transition:color var(--transition-base);
}
.nav-collapse-toggle:hover{color:var(--text);}
.nav-collapse-arrow{font-size:10px; opacity:.6;}
.nav-collapse-body{display:none;}
.nav-section-collapsible.open .nav-collapse-body{display:block;}
.nav-subgroup-label{
  padding:14px var(--space-5) 4px; font-size:9px; color:var(--muted); opacity:.6;
  letter-spacing:1px; text-transform:uppercase;
  font-family:var(--font-mono);
  border-top:1px solid rgba(255,255,255,.04); margin-top:6px;
}
.nav-subgroup-label:first-child{border-top:none; margin-top:0;}

/* ─── Main ──────────────────────────────────────────── */
main{padding:var(--space-6) var(--space-8); max-width:1200px;}
.page-header{
  margin-bottom:var(--space-8); padding-bottom:var(--space-4);
  border-bottom:1px solid var(--border);
  display:flex; justify-content:space-between; align-items:flex-start; gap:var(--space-4);
}
.page-header h2{font-size:var(--text-2xl); font-weight:var(--weight-bold); margin-bottom:var(--space-1);}
.page-header p{color:var(--muted); font-size:var(--text-base); max-width:600px;}
.page-actions{display:flex; gap:var(--space-2); flex-shrink:0;}

/* ─── Section ────────────────────────────────────────── */
section.s{margin-bottom:var(--space-8);}
.section-head{
  display:flex; justify-content:space-between; align-items:baseline;
  margin-bottom:14px;
}
.section-title{
  font-size:var(--text-xs); color:var(--muted); letter-spacing:1.5px;
  text-transform:uppercase; font-family:var(--font-mono);
  display:inline-flex; align-items:center; gap:6px;
}
.section-title svg{width:14px; height:14px; stroke-width:1.75;}

/* ─── Cards ──────────────────────────────────────────── */
.card{
  background:var(--bg-2); border:1px solid var(--border);
  border-radius:var(--radius-lg); padding:var(--space-5);
}
.card-title{font-size:var(--text-md); font-weight:var(--weight-semibold); margin-bottom:var(--space-3);}

/* ─── KPI Card (componente novo — usado em financial, pixel, drill, instagram) ─── */
.kpi-grid{
  display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));
  gap:var(--space-3); margin-bottom:var(--space-4);
}
.kpi-card{
  background:var(--bg-2); border:1px solid var(--border);
  border-radius:var(--radius-lg); padding:var(--space-5);
  text-align:center;
}
.kpi-card-label{
  font-size:var(--text-xs); color:var(--muted); opacity:.7;
  text-transform:uppercase; letter-spacing:.05em;
  margin-bottom:6px;
}
.kpi-card-value{
  font-size:var(--text-2xl); font-weight:var(--weight-bold);
  color:var(--text); line-height:1.1;
  font-variant-numeric:tabular-nums;
}
.kpi-card-value.sm{font-size:var(--text-lg);}
.kpi-card-value.lg{font-size:var(--text-3xl);}
.kpi-card-hint{
  font-size:var(--text-xs); color:var(--muted); opacity:.7;
  margin-top:4px;
}
.kpi-card.accent{border-left:3px solid var(--accent);}
.kpi-card.up{border-left:3px solid var(--up);}
.kpi-card.warn{border-left:3px solid var(--warn);}
.kpi-card.down{border-left:3px solid var(--down);}

/* ─── Form ───────────────────────────────────────────── */
.form-grid{
  display:grid; grid-template-columns:1fr 1fr; gap:var(--space-4);
}
.form-grid.full{grid-template-columns:1fr;}
.field{display:flex; flex-direction:column; gap:6px;}
.field label{
  font-size:var(--text-xs); color:var(--muted); font-weight:var(--weight-semibold);
  letter-spacing:.5px;
}
.field input, .field textarea, .field select{
  padding:10px var(--space-3);
  background:var(--bg-3);
  border:1px solid var(--border-2);
  border-radius:var(--radius-md);
  color:var(--text);
  font-family:inherit; font-size:var(--text-md);
  transition:all var(--transition-base); outline:none;
}
.field textarea{min-height:80px; resize:vertical;}
.field input:focus, .field textarea:focus, .field select:focus{
  border-color:var(--accent);
  box-shadow:0 0 0 2px var(--accent-glow);
}
.field-help{font-size:var(--text-xs); color:var(--dim);}
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"]{
  border-color:var(--down);
}

/* ─── Buttons ────────────────────────────────────────── */
.btn{
  background:transparent; color:var(--muted);
  border:1px solid var(--border-2); padding:var(--space-2) 14px;
  border-radius:var(--radius-md); cursor:pointer; font-size:var(--text-sm);
  font-family:inherit; transition:all var(--transition-base);
  display:inline-flex; align-items:center; gap:6px;
  text-decoration:none;
}
.btn:hover{color:var(--text); border-color:var(--accent);}
.btn-primary{
  background:var(--gradient);
  color:#000; font-weight:var(--weight-bold);
  border:none;
}
.btn-primary:hover{
  transform:translateY(-1px);
  box-shadow:var(--shadow-md), var(--shadow-glow);
  color:#000;
}
.btn-primary:disabled{opacity:.5; cursor:not-allowed; transform:none;}
.btn-danger{color:var(--down); border-color:rgba(255,56,56,.3);}
.btn-danger:hover{border-color:var(--down); background:var(--down-soft);}
.btn-icon{padding:6px var(--space-2);}

/* ─── Output area ────────────────────────────────────── */
.output{
  background:var(--bg-3);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  padding:var(--space-4);
  font-family:var(--font-mono);
  font-size:var(--text-sm);
  white-space:pre-wrap;
  max-height:400px; overflow:auto;
  color:var(--text);
}
.output.success{border-color:rgba(0,153,255,.4);}
.output.error{border-color:rgba(255,56,56,.4); color:var(--down);}

/* ─── Badge / Pill ───────────────────────────────────── */
.badge, .pill{
  display:inline-flex; align-items:center; gap:6px;
  padding:3px var(--space-2); border-radius:var(--radius-sm);
  font-size:10px; font-weight:var(--weight-bold);
  font-family:var(--font-mono);
  letter-spacing:.5px; text-transform:uppercase;
}
.badge.up, .pill.up{background:var(--up-soft); color:var(--up);}
.badge.accent, .pill.accent{background:var(--accent-soft); color:var(--accent);}
.badge.warn, .pill.warn{background:var(--warn-soft); color:var(--warn);}
.badge.down, .pill.down{background:var(--down-soft); color:var(--down);}
.badge.muted, .pill.muted{background:var(--bg-3); color:var(--muted);}

/* ─── Tables ─────────────────────────────────────────── */
table, .data-table{width:100%; border-collapse:collapse;}
.data-table{
  background:var(--bg-2); border:1px solid var(--border);
  border-radius:var(--radius-lg); overflow:hidden;
}
table th, table td, .data-table th, .data-table td{
  padding:10px var(--space-3); text-align:left;
  border-bottom:1px solid var(--border);
  font-size:var(--text-base);
}
table th, .data-table th{
  font-size:10px; color:var(--muted); font-weight:var(--weight-bold);
  text-transform:uppercase; letter-spacing:1px;
  font-family:var(--font-mono);
  background:var(--bg-3);
}
table tr:last-child td, .data-table tr:last-child td{border-bottom:none;}
.data-table tr:hover td{background:var(--bg-3);}
.text-right{text-align:right;}
.text-center{text-align:center;}
.tabular{font-variant-numeric:tabular-nums;}

/* ═════════════════════════════════════════════════════════
   Sprint Visual v2.1 — HH: Typography utilities
   Classes canônicas pra hierarquia consistente em todos os módulos.
   Substitui font-size hardcoded por classes semânticas.
   ═════════════════════════════════════════════════════════ */

/* Hierarquia de títulos — semântico, usar em h1/h2/h3 ou div */
.nx-h1{
  font-size:clamp(28px, 4vw, 40px);
  font-weight:var(--weight-black);
  letter-spacing:-1px; line-height:1.15;
}
.nx-h2{
  font-size:var(--text-2xl); /* 24px */
  font-weight:var(--weight-bold);
  letter-spacing:-.3px; line-height:1.2;
}
.nx-h3{
  font-size:var(--text-xl); /* 20px */
  font-weight:var(--weight-semibold);
  letter-spacing:-.2px; line-height:1.25;
}
.nx-h4{
  font-size:var(--text-lg); /* 16px */
  font-weight:var(--weight-semibold);
  line-height:1.3;
}

/* Tamanhos de texto — pareados com os tokens */
.nx-text-xs{font-size:var(--text-xs); line-height:1.4;}
.nx-text-sm{font-size:var(--text-sm); line-height:1.45;}
.nx-text-base{font-size:var(--text-base); line-height:1.5;}
.nx-text-md{font-size:var(--text-md); line-height:1.5;}
.nx-text-lg{font-size:var(--text-lg); line-height:1.45;}
.nx-text-xl{font-size:var(--text-xl); line-height:1.4;}
.nx-text-2xl{font-size:var(--text-2xl); line-height:1.3;}
.nx-text-3xl{font-size:var(--text-3xl); line-height:1.2;}

/* Pesos — usar quando o size já tá ok mas precisa mudar peso */
.nx-weight-regular{font-weight:var(--weight-regular);}
.nx-weight-medium{font-weight:var(--weight-medium);}
.nx-weight-semibold{font-weight:var(--weight-semibold);}
.nx-weight-bold{font-weight:var(--weight-bold);}
.nx-weight-black{font-weight:var(--weight-black);}

/* Cores de texto semânticas */
.nx-text-muted{color:var(--muted);}
.nx-text-dim{color:var(--dim);}
.nx-text-up{color:var(--up);}
.nx-text-warn{color:var(--warn);}
.nx-text-down{color:var(--down);}

/* Família de fontes */
.nx-font-mono{font-family:var(--font-mono);}
.nx-font-sans{font-family:var(--font-sans);}

/* Microcopy: labels uppercase tipo "RECEITA HOJE" */
.nx-label{
  font-size:var(--text-xs); color:var(--muted);
  text-transform:uppercase; letter-spacing:.06em;
  font-weight:var(--weight-semibold);
  font-family:var(--font-mono);
}

/* Body text padrão (parágrafos) */
.nx-prose{
  font-size:var(--text-md);
  line-height:1.6; color:var(--text);
  max-width:65ch;
}
.nx-prose p{margin-bottom:var(--space-3);}
.nx-prose p:last-child{margin-bottom:0;}

/* Aplicação default em tags semânticas — só se não tiverem classe customizada.
   Faz hierarquia funcionar mesmo em HTML antigo sem opt-in. */
main h1:not([class]):not([class=""]) ,
main > h1{font-size:clamp(28px, 4vw, 40px); font-weight:var(--weight-black); letter-spacing:-1px;}
main h2:not([class]):not([class=""]):not(.page-header *),
main > section > h2{font-size:var(--text-2xl); font-weight:var(--weight-bold); letter-spacing:-.3px; margin-bottom:var(--space-3);}
main h3:not([class]):not([class=""]),
main > section > h3{font-size:var(--text-xl); font-weight:var(--weight-semibold); margin-bottom:var(--space-2);}
main h4:not([class]):not([class=""]){font-size:var(--text-lg); font-weight:var(--weight-semibold); margin-bottom:var(--space-2);}

/* ─── API docs inline ────────────────────────────────── */
.api-doc{
  background:var(--bg-3);
  border:1px solid var(--border);
  border-left:3px solid var(--accent);
  border-radius:var(--radius-md);
  padding:var(--space-3) var(--space-4);
  margin-bottom:var(--space-2);
  font-family:var(--font-mono);
  font-size:var(--text-sm);
}
.api-method{
  display:inline-block; padding:2px 6px;
  background:var(--gradient-soft); color:var(--accent);
  border-radius:var(--radius-sm); margin-right:var(--space-2);
  font-weight:var(--weight-bold); font-size:10px;
}
.api-method.post{color:var(--accent);}
.api-method.get{color:var(--up);}
.api-method.delete{color:var(--down);}
.api-path{color:var(--text);}
.api-desc{color:var(--muted); font-size:var(--text-xs); margin-top:4px; font-family:var(--font-sans);}

/* ─── Empty state ────────────────────────────────────── */
.empty{
  padding:var(--space-10); text-align:center; color:var(--muted); font-size:var(--text-base);
}
.empty-icon{
  width:48px; height:48px; margin:0 auto var(--space-3);
  opacity:.4;
  display:flex; align-items:center; justify-content:center;
}
.empty-icon svg{width:32px; height:32px; stroke-width:1.5;}
.empty-title{font-size:var(--text-md); color:var(--text); margin-bottom:6px; font-weight:var(--weight-medium);}
.empty-hint{font-size:var(--text-sm); color:var(--dim); max-width:340px; margin:0 auto;}

/* ─── Spinner ────────────────────────────────────────── */
.spinner{
  display:inline-block; width:14px; height:14px;
  border:2px solid var(--bg-4);
  border-top-color:var(--accent);
  border-radius:50%;
  animation:spin .8s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg);}}

/* ─── Loading rico em botão (NEXUS.showSpinner com steps + timer + barra) ─ */
.btn.nx-loading,
button.nx-loading{
  position:relative;
  overflow:hidden;
  cursor:wait !important;
  opacity:1;
  font-weight:var(--weight-semibold);
}
.nx-spin{
  display:inline-block; width:16px; height:16px;
  border:2.5px solid rgba(255,255,255,.3);
  border-top-color:currentColor;
  border-radius:50%;
  animation:spin .7s linear infinite;
  vertical-align:middle;
  margin-right:10px;
  flex-shrink:0;
}
.nx-spin-text{
  display:inline-block;
  transition:opacity .15s ease;
  vertical-align:middle;
  font-size:14px;
  font-weight:var(--weight-semibold);
  letter-spacing:.1px;
}
.nx-spin-timer{
  display:inline-block;
  margin-left:10px;
  padding:3px 10px;
  background:rgba(0,0,0,.4);
  color:#fff;
  border-radius:99px;
  font-size:12px;
  font-variant-numeric:tabular-nums;
  font-family:'JetBrains Mono', ui-monospace, monospace;
  font-weight:var(--weight-bold);
  vertical-align:middle;
  opacity:1;
  letter-spacing:.3px;
}
.nx-spin-bar{
  position:absolute;
  left:0; right:0; bottom:0;
  height:4px;
  background:linear-gradient(90deg, transparent 0%, currentColor 50%, transparent 100%);
  opacity:.85;
  animation:nx-bar-slide 1.6s linear infinite;
  pointer-events:none;
}
@keyframes nx-bar-slide{
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

/* ─── Modal / Dialog (componente novo) ─────────────────── */
.modal-overlay{
  position:fixed; inset:0;
  background:rgba(0,0,0,.7);
  display:flex; align-items:center; justify-content:center;
  z-index:1000; padding:var(--space-4);
  animation:fadeIn .2s ease;
}
.modal{
  background:var(--bg-2);
  border:1px solid var(--border-2);
  border-radius:var(--radius-xl);
  padding:var(--space-6);
  max-width:520px; width:100%;
  max-height:90vh; overflow-y:auto;
  box-shadow:var(--shadow-lg);
}
.modal-header{
  display:flex; justify-content:space-between; align-items:flex-start;
  margin-bottom:var(--space-4); gap:var(--space-3);
}
.modal-title{font-size:var(--text-lg); font-weight:var(--weight-semibold);}
.modal-subtitle{font-size:var(--text-sm); color:var(--muted); margin-top:2px;}
.modal-body{font-size:var(--text-base); color:var(--text); margin-bottom:var(--space-5);}
.modal-actions{
  display:flex; gap:var(--space-2); justify-content:flex-end;
  margin-top:var(--space-4);
}
.modal-close{
  background:transparent; border:none; cursor:pointer;
  color:var(--muted); font-size:18px; padding:4px var(--space-2);
  transition:color var(--transition-base);
}
.modal-close:hover{color:var(--text);}
@keyframes fadeIn{from{opacity:0;}to{opacity:1;}}

/* ─── Toast / Notification (componente novo) ───────────── */
.toast-container{
  position:fixed; bottom:var(--space-5); right:var(--space-5);
  display:flex; flex-direction:column; gap:var(--space-2);
  z-index:1100; pointer-events:none;
}
.toast{
  background:var(--bg-2); border:1px solid var(--border-2);
  border-radius:var(--radius-md); padding:var(--space-3) var(--space-4);
  font-size:var(--text-base); color:var(--text);
  min-width:240px; max-width:380px;
  pointer-events:auto;
  animation:slideIn .25s ease;
  box-shadow:var(--shadow-md);
}
.toast.success{border-left:3px solid var(--up);}
.toast.warn{border-left:3px solid var(--warn);}
.toast.error{border-left:3px solid var(--down);}
.toast.info{border-left:3px solid var(--accent);}
@keyframes slideIn{
  from{opacity:0; transform:translateX(20px);}
  to{opacity:1; transform:translateX(0);}
}

/* ─── Quote bubble (chat estilo, usado em concierge.html) ─── */
.quote-bubble{
  padding:var(--space-3) var(--space-4);
  border-radius:var(--radius-md);
  border-left:2px solid var(--border-3);
  background:rgba(255,255,255,.02);
  margin-top:var(--space-2);
  font-size:var(--text-base);
  white-space:pre-wrap;
}
.quote-bubble.user{border-left-color:var(--accent); background:var(--accent-soft);}
.quote-bubble.assistant{border-left-color:var(--muted); background:rgba(255,255,255,.03);}
.quote-bubble-label{
  font-size:10px; opacity:.6; margin-bottom:4px;
  text-transform:uppercase; letter-spacing:.05em;
}

/* ─── Sprint 1 Nexus v2 (T+U): hero stats + utility money ──────────────── */
/* Hero stats numerão — barra de 3 stats macro acima da dobra */
.hero-stats{
  display:grid; grid-template-columns:repeat(3, 1fr); gap:var(--space-3);
  margin-bottom:var(--space-6); padding:var(--space-5);
  background:var(--bg-2); border:1px solid var(--border);
  border-radius:var(--radius-lg);
}
.hero-stats .hero-stat{
  display:flex; flex-direction:column; gap:4px; min-width:0;
}
.hero-stats .hero-stat .num{
  font-size:clamp(28px, 4vw, 42px);
  font-weight:700; letter-spacing:-0.02em;
  color:var(--accent); line-height:1.05;
  font-variant-numeric:tabular-nums;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.hero-stats .hero-stat .num.money{ color:var(--money); }
.hero-stats .hero-stat .num.hot{ color:var(--hot); }
.hero-stats .hero-stat .label{
  font-size:13px; color:var(--muted);
  text-transform:uppercase; letter-spacing:.3px;
}
.hero-stats .hero-stat .delta{
  font-size:11px; margin-top:2px;
  display:inline-flex; align-items:center; gap:3px;
}
.hero-stats .hero-stat .delta.up{ color:var(--up); }
.hero-stats .hero-stat .delta.down{ color:var(--down); }
@media (max-width:600px){
  .hero-stats{ grid-template-columns:1fr; padding:var(--space-4); }
  .hero-stats .hero-stat .num{ font-size:28px; }
}

/* Money / Hot utilities — pra reaproveitar em cards diversos (kpi, traffic, hive…)
   Sprint Visual v2.1 (item DD): corrigido seletor `.kpi-value` → `.kpi-card-value`
   que é a classe real usada nos módulos. Antes o token estava órfão. */
.text-money{ color:var(--money) !important; }
.bg-money{ background:var(--money-soft); }
.border-money{ border-color:var(--money); }

/* KPI card variants — left-border + colored value, padrão dos .kpi-card.up/accent */
.kpi-card.kpi-money{ border-left:3px solid var(--money); }
.kpi-card.kpi-money .kpi-card-value{ color:var(--money); }
.kpi-card.kpi-hot{ border-left:3px solid var(--hot); }
.kpi-card.kpi-hot .kpi-card-value{ color:var(--hot); }

/* Stat-num variants (billing/vending usam <div class="stat-num"> em vez de .kpi-card-value) */
.stat-num.money{ color:var(--money); }
.stat-num.hot{ color:var(--hot); }

/* Backward-compat com seletor antigo (caso algum HTML legado use .kpi-value) */
.kpi-card.kpi-money .kpi-value{ color:var(--money); }
.kpi-card.kpi-hot .kpi-value{ color:var(--hot); }

/* Funil de conversão visual — Sprint 2 Nexus v2 (item V) ───────────────── */
.funnel-chart{
  display:flex; flex-direction:column; gap:14px;
  padding:var(--space-5); background:var(--bg-2);
  border:1px solid var(--border); border-radius:var(--radius-lg);
}
.funnel-step{ display:flex; flex-direction:column; gap:4px; }
.funnel-step .funnel-bar{
  display:flex; align-items:center; justify-content:space-between;
  padding:14px 18px; border-radius:var(--radius);
  min-width:140px; transition:width .4s ease;
  border:1px solid var(--border-2);
  background:var(--bg-3);
  position:relative; overflow:hidden;
}
.funnel-step .funnel-bar::before{
  content:''; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, currentColor 200%);
  opacity:.08; pointer-events:none;
}
.funnel-step.neutral .funnel-bar{ color:var(--accent); border-color:var(--accent); background:var(--accent-soft); }
.funnel-step.good    .funnel-bar{ color:var(--money);  border-color:var(--money);  background:var(--money-soft); }
.funnel-step.warn    .funnel-bar{ color:var(--warn);   border-color:var(--warn);   background:var(--warn-soft); }
.funnel-step.bad     .funnel-bar{ color:var(--down);   border-color:var(--down);   background:var(--down-soft); }
.funnel-bar-label{ font-weight:600; color:var(--text); font-size:14px; z-index:1; }
.funnel-bar-count{ font-weight:700; font-size:18px; font-variant-numeric:tabular-nums; z-index:1; }
.funnel-step .funnel-conv{
  font-size:11px; color:var(--muted); padding-left:18px;
}
.funnel-step .conv-pct{ color:var(--text); font-weight:600; }
.funnel-step.bad .drop-pct{ color:var(--down); font-weight:600; }
@media (max-width:600px){
  .funnel-chart{ padding:var(--space-3); }
  .funnel-step .funnel-bar{ padding:10px 12px; }
  .funnel-bar-label{ font-size:12px; }
  .funnel-bar-count{ font-size:14px; }
}

/* Lead temperature badges (preparação pra item P/X da Sprint 2) */
.lead-temp{ display:inline-flex; align-items:center; gap:3px; font-size:11px; padding:2px 8px; border-radius:99px; font-weight:600; }
.lead-temp.hot{  background:var(--hot-soft);  color:var(--hot);  border:1px solid var(--hot); }
.lead-temp.warm{ background:var(--warn-soft); color:var(--warn); border:1px solid var(--warn); }
.lead-temp.cold{ background:var(--bg-3); color:var(--muted); border:1px solid var(--border); }

/* ─── Mobile-first improvements (Pacote 5 - I) ──────────── */
@media (max-width:900px){
  body{grid-template-columns:1fr;}
  aside{
    /* Hamburguer-collapsível em mobile (toggle por botão flutuante) */
    position:fixed; top:0; left:0; height:100vh; width:280px; z-index:200;
    transform:translateX(-100%); transition:transform .25s ease;
    border-right:1px solid var(--border); padding:var(--space-3) 0;
    overflow-y:auto;
  }
  aside.mobile-open{ transform:translateX(0); box-shadow:0 0 30px rgba(0,0,0,.5); }
  body::before {
    /* Backdrop quando menu aberto */
    content:''; position:fixed; inset:0; z-index:199; background:rgba(0,0,0,.5);
    opacity:0; pointer-events:none; transition:opacity .2s;
  }
  body.menu-open::before { opacity:1; pointer-events:auto; }
  main{ padding:var(--space-4) var(--space-3) var(--space-6); padding-top:60px; }
  .mobile-menu-toggle {
    display:flex !important;
    position:fixed; top:12px; left:12px; z-index:201;
    width:42px; height:42px; align-items:center; justify-content:center;
    background:var(--bg-2); border:1px solid var(--border); border-radius:8px;
    cursor:pointer; color:var(--text); font-size:20px;
  }
  .form-grid{grid-template-columns:1fr;}
  .page-header{flex-direction:column; align-items:flex-start;}
  .page-actions{flex-wrap:wrap; gap:6px; width:100%;}
  .page-actions .btn{flex:1; min-width:120px; font-size:13px;}
  .kpi-grid{grid-template-columns:repeat(2, 1fr); gap:8px;}
  .kpi-value{font-size:22px;}
  .kpi-card{padding:14px;}
  /* tap targets ≥44px (WCAG) */
  button, .btn, a.btn, input[type="checkbox"]+label{min-height:44px;}
  /* tabelas viram lista vertical */
  table.responsive thead{display:none;}
  table.responsive tr{display:block; padding:10px; border-bottom:1px solid var(--border);}
  table.responsive td{display:flex; justify-content:space-between; padding:4px 0;}
  table.responsive td:before{content:attr(data-label); font-weight:600; color:var(--muted);}
}
@media (max-width:600px){
  .kpi-grid{grid-template-columns:1fr;}
  main{padding:var(--space-3) var(--space-3) var(--space-5); padding-top:60px;}
  .modal-card{margin:8px; max-height:calc(100vh - 16px);}
}

/* ─── Item K (2026-05-20): mobile-first polish — bottom nav + sininho fullscreen ─ */
/* Bottom nav fixo: 4 atalhos críticos visíveis sem hamburger */
@media (max-width:768px){
  #nx-bottom-nav{
    display:flex !important;
    position:fixed; bottom:0; left:0; right:0; z-index:150;
    background:rgba(10,10,10,.96); backdrop-filter:blur(12px);
    border-top:1px solid var(--border);
    padding:8px 0; padding-bottom:max(8px, env(safe-area-inset-bottom));
    justify-content:space-around;
  }
  #nx-bottom-nav a{
    display:flex; flex-direction:column; align-items:center; gap:3px;
    flex:1; padding:4px 0; color:var(--muted);
    text-decoration:none; font-size:10px; font-weight:600;
    text-transform:uppercase; letter-spacing:.3px;
    min-height:auto; /* override do tap-target 44px global */
  }
  #nx-bottom-nav a svg{width:22px; height:22px;}
  #nx-bottom-nav a[aria-current="page"]{color:var(--accent);}
  /* Espaço extra no fim do main pra não ficar atrás do bottom nav */
  main{padding-bottom:84px !important;}
}
@media (min-width:769px){
  #nx-bottom-nav{display:none !important;}
}

/* Sininho dropdown vira fullscreen em telas pequenas — mais espaço pra ler notif */
@media (max-width:480px){
  #nx-notif-dropdown{
    position:fixed !important;
    top:60px !important; right:8px !important; left:8px !important;
    width:auto !important; max-width:none !important;
    max-height:calc(100vh - 80px) !important;
  }
  #nx-notif-list{ max-height:calc(100vh - 200px) !important; }
}
.mobile-menu-toggle{display:none;}

/* ═════════════════════════════════════════════════════════
   Sprint Visual v2.1 — JJ: Onboarding tour
   Tour guiado com overlay + tooltip apontando pro elemento.
   Custom (sem libs), persistido em workspace_settings.onboarding.tour_completed.
   API: NEXUS.startTour(steps), NEXUS.endTour().
   ═════════════════════════════════════════════════════════ */
.nx-tour-overlay{
  position:fixed; inset:0; z-index:9998;
  background:rgba(0,0,0,.55);
  backdrop-filter:blur(2px);
  animation:nx-fade-in .25s ease-out;
}
.nx-tour-cutout{
  position:fixed; z-index:9999;
  border-radius:var(--radius-lg);
  box-shadow:0 0 0 9999px rgba(0,0,0,.55),
             0 0 0 4px var(--accent-glow),
             0 0 28px var(--accent);
  pointer-events:none;
  transition:all .35s cubic-bezier(.22, 1, .36, 1);
}
.nx-tour-tooltip{
  position:fixed; z-index:10000;
  background:var(--bg-2);
  border:1px solid var(--accent);
  border-radius:var(--radius-lg);
  padding:var(--space-5);
  width:340px; max-width:calc(100vw - 32px);
  box-shadow:0 18px 50px rgba(0,0,0,.5),
             0 0 24px var(--accent-glow);
  animation:nx-fade-up .3s ease-out;
}
.nx-tour-tooltip .nx-tour-step{
  font-size:var(--text-xs); color:var(--accent);
  text-transform:uppercase; letter-spacing:1px;
  font-family:var(--font-mono); font-weight:700;
  margin-bottom:var(--space-2);
}
.nx-tour-tooltip h4{
  font-size:var(--text-lg); font-weight:var(--weight-bold);
  margin:0 0 var(--space-2); color:var(--text);
}
.nx-tour-tooltip p{
  font-size:var(--text-base); color:var(--muted);
  line-height:1.55; margin:0 0 var(--space-4);
}
.nx-tour-actions{
  display:flex; justify-content:space-between; align-items:center;
  gap:var(--space-3);
}
.nx-tour-skip{
  background:transparent; border:none; cursor:pointer;
  color:var(--dim); font-size:var(--text-sm);
  padding:6px 10px; text-decoration:underline;
}
.nx-tour-skip:hover{color:var(--muted);}
.nx-tour-nav{display:flex; gap:var(--space-2);}
.nx-tour-btn{
  padding:8px 16px; border-radius:var(--radius-md);
  font-size:var(--text-sm); font-weight:var(--weight-semibold);
  cursor:pointer; border:none;
  transition:all var(--transition-base);
}
.nx-tour-btn.next{
  background:var(--gradient); color:#000;
  box-shadow:0 4px 14px var(--accent-glow);
}
.nx-tour-btn.next:hover{transform:translateY(-1px); box-shadow:0 6px 20px var(--accent);}
.nx-tour-btn.prev{
  background:var(--bg-3); color:var(--text);
  border:1px solid var(--border-2);
}
.nx-tour-btn.prev:hover{border-color:var(--accent); color:var(--accent);}
.nx-tour-progress{
  display:flex; gap:4px; margin-top:var(--space-3);
}
.nx-tour-progress-dot{
  flex:1; height:3px; border-radius:99px;
  background:var(--bg-3);
  transition:background var(--transition-base);
}
.nx-tour-progress-dot.done{ background:var(--accent); }
@keyframes nx-fade-in{
  from{ opacity:0; }
  to{ opacity:1; }
}
@media (max-width:600px){
  .nx-tour-tooltip{ width:calc(100vw - 24px); left:12px !important; }
}

/* ═════════════════════════════════════════════════════════
   Sprint Visual v2.1 — OO: Print-friendly CSS
   Permite Ctrl+P virar PDF de relatório limpo: esconde chrome,
   inverte cores pra economizar tinta, evita quebra ruim de cards.
   ═════════════════════════════════════════════════════════ */
@media print{
  /* Esconder cromo do app */
  aside, #sidebar, .page-actions, .btn,
  #nx-bottom-nav, #nx-notif-bell, #nx-notif-dropdown,
  .mobile-menu-toggle, .nav-collapse-toggle,
  .api-doc, .section-action,
  [data-print="hide"]{
    display:none !important;
  }

  /* Layout single column, sem grid */
  body{
    background:#fff !important;
    color:#000 !important;
    display:block !important;
    font-size:11pt;
  }
  main{
    padding:0 !important; max-width:100% !important;
    margin:0 !important;
  }

  /* Cores acessíveis em papel */
  .page-header h2, h1, h2, h3{
    color:#000 !important;
    page-break-after:avoid;
  }
  .page-header p, p, .muted{ color:#333 !important; }
  .page-header{
    border-bottom:2px solid #000 !important;
    padding-bottom:8px !important; margin-bottom:16px !important;
  }

  /* Cards/sections: preto no branco, borda fina, sem shadow */
  .kpi-card, .metric-card, .stat-card, .stat-box,
  .pulse-box, .card, section.s, .nx-empty,
  .funnel-chart, .nx-skeleton-card{
    background:#fff !important;
    border:1px solid #ccc !important;
    box-shadow:none !important;
    color:#000 !important;
    page-break-inside:avoid;
    break-inside:avoid;
  }

  /* Money/hot preservam cor (mas escurece um pouco pra ler em papel) */
  .text-money, .stat-num.money, .stat-num.green,
  .metric-value.money, .kpi-card.kpi-money .kpi-card-value,
  .pulse-num.money, .pprice, .lead-price,
  .hero-stat .num.money{ color:#008860 !important; }

  .text-hot, .stat-num.hot, .metric-value.hot,
  .kpi-card.kpi-hot .kpi-card-value, .pulse-num.hot,
  .hero-stat .num.hot{ color:#cc4422 !important; }

  /* Tabelas mais limpas */
  table{ border-collapse:collapse !important; width:100% !important; }
  th, td{
    border:1px solid #ccc !important;
    padding:6px 8px !important;
    color:#000 !important;
  }
  th{ background:#f0f0f0 !important; font-weight:700; }

  /* Cabeçalho de página de relatório (mostra só no print) */
  .print-header{
    display:block !important;
    border-bottom:3px solid #000;
    padding:0 0 12px; margin-bottom:16px;
  }
  .print-header h1{ font-size:18pt; margin:0 0 4px; }
  .print-header .meta{ font-size:9pt; color:#666; }

  /* Evita órfãs/viúvas */
  p, li{ orphans:3; widows:3; }

  /* Imprime URL de links */
  a[href]:after{
    content:" (" attr(href) ")";
    font-size:8pt; color:#666;
    word-wrap:break-word;
  }
  a[href^="#"]:after,
  a[href^="javascript:"]:after,
  .btn[href]:after{ content:""; }

  /* Skeleton/spinner: não mostrar em print */
  .nx-skeleton, .nx-spinner, .nx-spinner-block{
    display:none !important;
  }

  /* Page break manual */
  .page-break-before{ page-break-before:always; }
  .page-break-after{ page-break-after:always; }
  .page-break-avoid{ page-break-inside:avoid; }

  /* Margens de página */
  @page{
    margin:1.5cm 1.2cm;
    size:A4;
  }
}

.print-header{ display:none; } /* só aparece em @media print */

/* ═════════════════════════════════════════════════════════
   Sprint Visual v2.1 — GG: Microanimações
   Hover sutil em cards, count-up nos KPIs, entrada de página suave.
   Tudo CSS puro + IntersectionObserver, zero libs.
   Respeita prefers-reduced-motion.
   ═════════════════════════════════════════════════════════ */

/* Hover lift em cards (uniformiza o que estava espalhado) */
.kpi-card,
.metric-card,
.stat-card,
.stat-box,
.pulse-box,
.nx-skeleton-card,
.section-card,
.card{
  transition:transform var(--transition-base),
             border-color var(--transition-base),
             box-shadow var(--transition-base);
}
.kpi-card:hover,
.metric-card:hover,
.stat-card:hover,
.stat-box:hover,
.pulse-box:hover{
  transform:translateY(-2px);
  border-color:var(--border-2);
  box-shadow:0 6px 20px rgba(0,0,0,.18);
}

/* Variante específica: card money ganha glow sutil verde-$ no hover */
.kpi-card.kpi-money:hover,
.metric-card.money:hover{
  box-shadow:0 6px 20px var(--money-glow);
  border-color:var(--money);
}
.kpi-card.kpi-hot:hover,
.metric-card.hot:hover{
  box-shadow:0 6px 20px rgba(255,92,46,.25);
  border-color:var(--hot);
}

/* Count-up animation — número conta de 0 ao valor real em ~800ms.
   Aplicado via JS (NEXUS.countUp) ao elemento. Esses estilos preparam o terreno. */
.nx-countup{
  font-variant-numeric:tabular-nums; /* evita "pular" largura quando dígitos mudam */
  display:inline-block;
}
.nx-countup.nx-countup-running{
  opacity:.95;
}

/* Page enter animation — section/main fade-up suave quando carrega */
@keyframes nx-fade-up{
  from{ opacity:0; transform:translateY(8px); }
  to{ opacity:1; transform:translateY(0); }
}
main > section,
main > .page-header{
  animation:nx-fade-up .35s ease-out backwards;
}
main > section:nth-child(1){ animation-delay:0s; }
main > section:nth-child(2){ animation-delay:.05s; }
main > section:nth-child(3){ animation-delay:.1s; }
main > section:nth-child(4){ animation-delay:.15s; }
main > section:nth-child(5){ animation-delay:.2s; }
main > section:nth-child(6){ animation-delay:.25s; }
main > section:nth-child(7){ animation-delay:.3s; }

/* Item enter — cards em grid aparecem em cascata */
.kpi-grid > .kpi-card,
.metrics-grid > .metric-card,
.stat-row > .stat-card,
.stat-row > .stat-box{
  animation:nx-fade-up .4s ease-out backwards;
}
.kpi-grid > .kpi-card:nth-child(1),
.metrics-grid > .metric-card:nth-child(1),
.stat-row > *:nth-child(1){ animation-delay:.05s; }
.kpi-grid > .kpi-card:nth-child(2),
.metrics-grid > .metric-card:nth-child(2),
.stat-row > *:nth-child(2){ animation-delay:.1s; }
.kpi-grid > .kpi-card:nth-child(3),
.metrics-grid > .metric-card:nth-child(3),
.stat-row > *:nth-child(3){ animation-delay:.15s; }
.kpi-grid > .kpi-card:nth-child(4),
.metrics-grid > .metric-card:nth-child(4),
.stat-row > *:nth-child(4){ animation-delay:.2s; }

/* Botões com micro-feedback no clique */
.btn{
  transition:transform var(--transition-fast),
             background var(--transition-base),
             border-color var(--transition-base),
             box-shadow var(--transition-base);
}
.btn:active{ transform:scale(.97); }

/* Nav-item — leve translateX no hover pra dar feedback de direção */
.nav-item{
  position:relative;
}
.nav-item:hover{ padding-left:calc(var(--space-5) + 2px); }

/* Respeita acessibilidade — usuários com prefers-reduced-motion ficam imunes */
@media (prefers-reduced-motion:reduce){
  *,
  *::before,
  *::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  .nav-item:hover{ padding-left:var(--space-5); }
}

/* ═════════════════════════════════════════════════════════
   Sprint Visual v2.1 — EE + FF: Empty states + Loading skeletons
   Componentes globais reusáveis em qualquer módulo. Substituem:
   - "Carregando…" texto puro → .nx-skeleton (shimmer animado)
   - "Nenhum X encontrado" cru → .nx-empty (ilustração + CTA)
   ═════════════════════════════════════════════════════════ */

/* ─── Empty state ──────────────────────────────────────── */
.nx-empty{
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:var(--space-3); padding:var(--space-10) var(--space-5);
  text-align:center; color:var(--muted);
  background:var(--bg-2); border:1px dashed var(--border-2);
  border-radius:var(--radius-lg);
  min-height:200px;
}
.nx-empty-icon{
  width:64px; height:64px; border-radius:50%;
  background:var(--bg-3); border:1px solid var(--border);
  display:flex; align-items:center; justify-content:center;
  color:var(--dim); margin-bottom:var(--space-2);
}
.nx-empty-icon svg{ width:28px; height:28px; stroke-width:1.5; }
.nx-empty-title{
  font-size:var(--text-md); font-weight:var(--weight-semibold);
  color:var(--text); margin:0;
}
.nx-empty-hint{
  font-size:var(--text-sm); color:var(--muted);
  max-width:380px; line-height:1.5; margin:0;
}
.nx-empty-cta{ margin-top:var(--space-3); }

/* Variantes semânticas */
.nx-empty.nx-empty-success .nx-empty-icon{ background:var(--up-soft); color:var(--up); border-color:var(--up); }
.nx-empty.nx-empty-money .nx-empty-icon{ background:var(--money-soft); color:var(--money); border-color:var(--money); }
.nx-empty.nx-empty-warn .nx-empty-icon{ background:var(--warn-soft); color:var(--warn); border-color:var(--warn); }
.nx-empty.nx-empty-error .nx-empty-icon{ background:var(--down-soft); color:var(--down); border-color:var(--down); }

/* Inline (pra usar dentro de tabelas/cards menores) */
.nx-empty.nx-empty-inline{
  min-height:120px; padding:var(--space-6) var(--space-4);
}
.nx-empty.nx-empty-inline .nx-empty-icon{ width:44px; height:44px; }
.nx-empty.nx-empty-inline .nx-empty-icon svg{ width:20px; height:20px; }

/* ─── Loading skeleton ─────────────────────────────────── */
@keyframes nx-shimmer{
  0%{ background-position:-200% 0; }
  100%{ background-position:200% 0; }
}
.nx-skeleton{
  background:linear-gradient(90deg,
    var(--bg-2) 0%,
    var(--bg-3) 50%,
    var(--bg-2) 100%);
  background-size:200% 100%;
  animation:nx-shimmer 1.5s ease-in-out infinite;
  border-radius:var(--radius-md);
  display:block;
}
.nx-skeleton.nx-skeleton-text{ height:14px; margin:6px 0; }
.nx-skeleton.nx-skeleton-text.sm{ height:10px; }
.nx-skeleton.nx-skeleton-text.lg{ height:18px; }
.nx-skeleton.nx-skeleton-title{ height:24px; width:60%; margin:8px 0 16px; }
.nx-skeleton.nx-skeleton-line-50{ width:50%; }
.nx-skeleton.nx-skeleton-line-70{ width:70%; }
.nx-skeleton.nx-skeleton-line-90{ width:90%; }

/* Card skeleton: usar em grids de cards (KPI, lista de items, etc) */
.nx-skeleton-card{
  background:var(--bg-2); border:1px solid var(--border);
  border-radius:var(--radius-lg); padding:var(--space-5);
  display:flex; flex-direction:column; gap:var(--space-2);
}
.nx-skeleton-card .nx-skeleton{ background-color:var(--bg-3); }

/* Row skeleton: pra tabelas */
.nx-skeleton-row{
  display:flex; gap:var(--space-3); padding:var(--space-3) 0;
  border-bottom:1px solid var(--border);
}
.nx-skeleton-row .nx-skeleton{ flex:1; height:16px; }

/* Spinner global (substitui texto "Carregando…") */
.nx-spinner{
  display:inline-block; width:18px; height:18px;
  border:2px solid var(--bg-3); border-top-color:var(--accent);
  border-radius:50%; animation:nx-spin .8s linear infinite;
  vertical-align:middle;
}
.nx-spinner.lg{ width:32px; height:32px; border-width:3px; }
.nx-spinner.sm{ width:14px; height:14px; border-width:1.5px; }
.nx-spinner-block{
  display:flex; align-items:center; justify-content:center; gap:var(--space-2);
  padding:var(--space-8) var(--space-4);
  color:var(--muted); font-size:var(--text-sm);
}
@keyframes nx-spin{ to{ transform:rotate(360deg); } }
