/* ==========================================================================
   PAINELL — DESIGN SYSTEM (multi-tenant)
   --------------------------------------------------------------------------
   ERP/CRM admin panel. Densidade alta, visual moderno e profissional.

   As variáveis de BRANDING (--fundoMenu, --corAtiva, --bt-*-..., --familyFont,
   etc.) são injetadas POR TENANT via core/theme.php -> renderThemeVars().
   Este arquivo NÃO chumba cores de marca: consome via var(--*) e DERIVA os
   tons (hover/borda/foco) com color-mix(), com fallback estático.

   Sumário:
     1. Tokens base (cores neutras, espaçamento, raios, sombras, tipografia)
     2. Reset/base
     3. Tipografia & utilitários
     4. Botões
     5. Formulários
     6. Cards / painéis
     7. Badges / tags
     8. Alerts
     9. Breadcrumbs
    10. Tabelas (+ harmonização DataTables/Bootstrap)
    11. Layout do painel: sidebar, topbar, conteúdo
    12. Login
    13. Responsivo
   ========================================================================== */

/* ==========================================================================
   1. TOKENS BASE
   - Branding vem de :root injetado pelo PHP (renderThemeVars).
   - Aqui ficam os fallbacks dessas variáveis (caso o <style> não carregue)
     e TODOS os tokens derivados/neutros que não dependem do tenant.
   ========================================================================== */
:root{
  /* ---- Fallbacks do branding (sobrescritos por renderThemeVars; default = verde N26 #008177) ---- */
  --fundoMenu:#0b4d47; --cor_text_login:#dbeae7; --corSubmenuA:#7a7a7a;
  --cor_formLabel:#26463f; --cor_form:#2b2f38; --corAtiva:#008177;
  --corAtivaBorderLine:#008177; --corTxtMenu:#FCFCFC; --corMarcadoresSubmenu:#d7e8e5;
  --familyFont:'Plus Jakarta Sans', 'IBM Plex Sans', system-ui, sans-serif; --fontWeightBase:400;
  --tam_formLabel:15px; --fontSizeMenu:14px; --fontSizeSubmenu:12px; --size_legendForm:22px;
  --bt-success-color:#3E3B3C; --bt-success-background:#DEFF8B; --bt-success-border:#DEFF8B;
  --bt-info-color:#fff; --bt-info-background:#597EB7; --bt-info-border:#4B71AC;
  --bt-warning-color:#3E3B3C; --bt-warning-background:#fff18b; --bt-warning-border:#fff18b;
  --bt-danger-color:#fff; --bt-danger-background:#CC6463; --bt-danger-border:#C65150;
  --bt-go-color:#000; --bt-go-background:#F0C30E; --bt-go-border:#F39B08;
  --chartColors:#3d485c,#4c5a73,#5c6c89,#6d7f9e,#8493ad,#9aa7bc,#b1bbcb,#c8cfda;
  --logo-login:none; --logo-menu:none; --logo-marca:none;

  /* ---- Cores neutras (cinzas do UI, independem do tenant) ---- */
  /* ===== Minimalismo Nubank: branco no FUNDO, cinza nas SUPERFÍCIES/elementos ===== */
  --c-bg:           #ffffff;   /* fundo da área = BRANCO */
  --c-surface:      #f3f4f6;   /* cards/superfícies/elementos = cinza claro (elevação por COR, não sombra) */
  --c-surface-2:    #e9eaef;   /* hover/secundário = cinza um pouco mais */
  --c-brand-dark:   color-mix(in srgb, var(--corAtiva) 26%, #0d0612);   /* fundo escuro tematizado pela marca (login, modos imersivos) */
  --c-border:       #e2e6ee;   /* bordas padrão */
  --c-border-strong:#cdd3e0;
  --c-text:         #2b2f38;   /* texto principal — ~12.3:1 no branco */
  --c-text-muted:   #6b7280;   /* texto secundário — ~4.8:1 (AA) */
  /* A11Y: text-soft carrega TEXTO real (hints, .kpi-sub, .meta) → precisa passar AA.
     Era #97a0af (~2.6:1, reprovava). Agora ~4.6:1. Placeholder transitório usa
     --c-placeholder (segue claro de propósito: campo vazio não pode parecer preenchido). */
  --c-text-soft:    #6e7686;   /* hints/legendas (texto real) — ~4.6:1 (AA) */
  --c-placeholder:  #97a0af;   /* placeholder/affixo (transitório, exceção AA) */
  --c-text-invert:  #ffffff;

  /* ---- Cor de marca derivada (a "acentuação" do tenant) ---- */
  --c-accent:        var(--corAtiva);
  --c-accent-line:   var(--corAtivaBorderLine);
  /* tom suave do accent p/ fundos (fallback = accent translúcido via rgba não dá em var; usamos color-mix) */
  --c-accent-soft:   color-mix(in srgb, var(--corAtiva) 12%, #ffffff);
  --c-accent-hover:  color-mix(in srgb, var(--corAtiva) 86%, #000000);

  /* ---- Feedback semântico (UI states, neutros do sistema) ---- */
  /* feedback semântico — tons suaves/dessaturados (Nubank), legíveis em botão e badge */
  --c-success:#388f61; --c-success-bg:#e9f6ef;
  --c-info:   #4170af; --c-info-bg:   #ecf1f8;
  --c-warning:#ab8036; --c-warning-bg:#f6f0e4;
  --c-danger: #c4454b; --c-danger-bg: #f9ecec;

  /* ---- Tipografia: escala derivada ---- */
  /* A11Y: escala em REM (base 16px do root) — respeita o zoom/aumento de texto
     do navegador (px ignora). Escala "ampla" (2026-06): corpo 15px, mais legível
     no uso o dia inteiro (era 13). 1rem=16px:
     13→.8125 · 14→.875 · 15→.9375 · 16→1 · 17→1.0625 · 18→1.125 · 24→1.5 · 30→1.875 */
  --font-sans: var(--familyFont);
  --fs-xs: .8125rem; --fs-sm: .875rem; --fs-base: .9375rem; --fs-md: 1rem;
  --fs-lg: 1.0625rem; --fs-xl: 1.125rem; --fs-2xl: 1.5rem; --fs-3xl: 1.875rem;
  --lh-tight: 1.25; --lh-base: 1.5;
  --fw-normal: var(--fontWeightBase, 400); --fw-medium: 500; --fw-semibold: 600; --fw-bold: 700;

  /* ---- Espaçamento (escala 4px) ---- */
  --sp-0:0; --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px;
  --sp-5:20px; --sp-6:24px; --sp-7:32px; --sp-8:40px; --sp-9:48px;

  /* ---- Raios ---- */
  --r-xs:4px; --r-sm:6px; --r-md:8px; --r-lg:12px; --r-pill:999px;

  /* ---- Sombras (flat: só overlay/menu suspenso tem sombra) ---- */
  --sh-xs: none;
  --sh-sm: none;
  --sh-md: none;
  --sh-lg: 0 10px 30px rgba(16,24,40,.14);   /* mantida: dropdowns / runWindow / overlays */
  --sh-focus: 0 0 0 3px color-mix(in srgb, var(--corAtiva) 35%, transparent);

  /* ---- Layout ---- */
  --sidebar-w: 248px;
  --sidebar-w-collapsed: 64px;
  --topbar-h: 64px;

  --transition: .16s ease;

  /* ---- z-index: escala de empilhamento (use os tokens, não números mágicos) ---- */
  --z-sticky:    20;      /* cabeçalhos/sidebar grudados ao rolar */
  --z-dropdown:  60;      /* menus suspensos / popovers */
  --z-backdrop:  1100;    /* véu escuro de um overlay LOCAL (gaveta off-canvas) */
  --z-overlay:   1200;    /* gaveta/painel local por cima do véu */
  --z-toast:     9000;    /* confirmações flutuantes (auto-save, flash) */
  --z-modal:     10000;   /* runWindow / modal global (casca) */
}

/* ----------------------------------------------------------------------------
   Tipografia no CELULAR (≤680px): no telefone damos uma folga extra sobre a
   escala base (corpo 15→16, pequenos +1) p/ leitura e alvo de toque, e SEGURAMOS
   o display gigante (--fs-3xl 30→28). Como o painel consome var(--fs-*), TODAS as
   telas crescem juntas, sem tocar tela por tela. Mantém rem (respeita o zoom).
   O MENU acompanha junto: --fontSizeMenu/Submenu = var(--fs-md)/var(--fs-sm)
   (theme.php), então sobem com a escala aqui sem nada a tocar neste bloco.
   --------------------------------------------------------------------------- */
@media (max-width:680px){
  :root{
    --fs-xs: .875rem;    /* 13 → 14 */
    --fs-sm: .9375rem;   /* 14 → 15 */
    --fs-base: 1rem;     /* 15 → 16 */
    --fs-md: 1rem;       /* 16 → 16 */
    --fs-lg: 1.125rem;   /* 17 → 18 */
    --fs-xl: 1.25rem;    /* 18 → 20 */
    --fs-2xl: 1.5rem;    /* 24 → 24 */
    --fs-3xl: 1.75rem;   /* 30 → 28 (segura o display no telefone) */
  }
  /* iOS Safari só NÃO dá zoom ao focar um campo se a fonte for ≥16px */
  .form-control,.ds-input,.ds-select,.ds-textarea,.list-q,.list-search input{ font-size:16px; }
}

/* ==========================================================================
   2. RESET / BASE
   ========================================================================== */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body{
  margin:0;
  font-family:var(--font-sans);
  font-weight:var(--fw-normal);
  font-size:var(--fs-base);
  line-height:var(--lh-base);
  color:var(--c-text);
  background:var(--c-bg);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img{ max-width:100%; display:block; }
a{ color:var(--c-accent); text-decoration:none; transition:color var(--transition); }
a:hover{ color:var(--c-accent-hover); }
hr{ border:0; border-top:1px solid var(--c-border); margin:var(--sp-4) 0; }

/* Foco acessível global: anel visível só p/ navegação por teclado */
:focus-visible{ outline:none; box-shadow:var(--sh-focus); border-radius:var(--r-xs); }

/* ==========================================================================
   3. TIPOGRAFIA & UTILITÁRIOS
   ========================================================================== */
h1,h2,h3,h4,h5,h6{ margin:0 0 var(--sp-3); font-weight:var(--fw-semibold); line-height:var(--lh-tight); color:var(--c-text); }
h1{ font-size:var(--fs-3xl); } h2{ font-size:var(--fs-2xl); } h3{ font-size:var(--fs-xl); }
h4{ font-size:var(--fs-lg); } h5{ font-size:var(--fs-md); } h6{ font-size:var(--fs-sm); }
p{ margin:0 0 var(--sp-3); }
small,.text-sm{ font-size:var(--fs-sm); }
.text-muted{ color:var(--c-text-muted); }
.text-soft{ color:var(--c-text-soft); }
.text-accent{ color:var(--c-accent); }
.fw-medium{ font-weight:var(--fw-medium); } .fw-semibold{ font-weight:var(--fw-semibold); } .fw-bold{ font-weight:var(--fw-bold); }
.u-uppercase{ text-transform:uppercase; letter-spacing:.04em; }
.u-truncate{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* A11Y: nome acessível só p/ leitor de tela (botão só-ícone, contexto de ação).
   Some visualmente sem virar tooltip (use no lugar de title — veja runTitle). */
.sr-only{ position:absolute!important; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }
/* fica visível ao receber foco por teclado (ex.: link "pular para o conteúdo") */
.sr-only-focusable:focus,.sr-only-focusable:focus-visible{ position:static!important; width:auto; height:auto; margin:0; overflow:visible; clip:auto; clip-path:none; white-space:normal; }
.u-flex{ display:flex; } .u-items-center{ align-items:center; } .u-justify-between{ justify-content:space-between; }
.u-gap-1{ gap:var(--sp-1); } .u-gap-2{ gap:var(--sp-2); } .u-gap-3{ gap:var(--sp-3); }
.u-mt-2{ margin-top:var(--sp-2); } .u-mt-4{ margin-top:var(--sp-4); }
.u-mb-2{ margin-bottom:var(--sp-2); } .u-mb-4{ margin-bottom:var(--sp-4); }

/* Legenda de formulário (size_legendForm é do tenant) */
.ds-legend{
  font-size:var(--size_legendForm);
  font-weight:var(--fw-semibold);
  color:var(--cor_formLabel);
  margin:0 0 var(--sp-4);
  display:flex; align-items:center; gap:var(--sp-2);
}

/* ==========================================================================
   4. BOTÕES
   - 5 variantes temáveis (success/info/warning/danger/go) + neutro.
   - Tamanhos sm/md. Estados hover/active/disabled/loading.
   - As cores das variantes vêm das vars --bt-*-color/-background/-border.
   ========================================================================== */
.btn{
  --_c: var(--c-text);
  --_bg: var(--c-surface);
  --_bd: var(--c-border-strong);
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  font-family:inherit; font-size:var(--fs-md); font-weight:var(--fw-medium); line-height:1;
  padding:9px 16px; min-height:38px;
  color:var(--_c); background:var(--_bg);
  border:1px solid var(--_bd); border-radius:var(--r-pill);   /* PÍLULA: padrão de todos os botões (Nubank). Hover pinta o fundo do próprio botão = já arredondado. */
  cursor:pointer; user-select:none; white-space:nowrap;
  transition:filter var(--transition), box-shadow var(--transition), background var(--transition), transform .05s ease;
}
.btn:hover{ filter:brightness(.95); color:var(--_c); }   /* reafirma a cor: senão o a:hover global (cor de link) some o texto de um <a class="btn"> */
.btn:active{ transform:translateY(1px); }
.btn:focus-visible{ box-shadow:var(--sh-focus); }
.btn[disabled],.btn.is-disabled{ opacity:.55; cursor:not-allowed; filter:none; transform:none; }

/* Tamanhos */
.btn-sm{ padding:6px 12px; min-height:32px; font-size:var(--fs-sm); }
.btn-md{ padding:9px 16px; min-height:38px; }
.btn-lg{ padding:12px 22px; min-height:46px; font-size:var(--fs-lg); }
.btn-block{ display:flex; width:100%; }
/* SÓ-ÍCONE = CÍRCULO PERFEITO: largura == altura nos dois tamanhos. NÃO usar só
   min-height (a largura 32 do btn-sm com altura 38 vira cápsula vertical/oval). */
.btn-icon{ padding:0; width:38px; height:38px; min-height:0; }
.btn-icon.btn-sm{ width:32px; height:32px; min-height:0; }   /* min-height:0 (especificidade 0,2,0) vence o @media .btn-sm{min-height:38} — senão vira 32×38 oval no mobile */

/* Variantes temáveis (mapeiam as vars do tenant) */
.btn-success{ --_c:var(--bt-success-color); --_bg:var(--bt-success-background); --_bd:var(--bt-success-border); }
.btn-info{    --_c:var(--bt-info-color);    --_bg:var(--bt-info-background);    --_bd:var(--bt-info-border); }
.btn-warning{ --_c:var(--bt-warning-color); --_bg:var(--bt-warning-background); --_bd:var(--bt-warning-border); }
.btn-danger{  --_c:var(--bt-danger-color);  --_bg:var(--bt-danger-background);  --_bd:var(--bt-danger-border); }
.btn-go{      --_c:var(--bt-go-color);      --_bg:var(--bt-go-background);      --_bd:var(--bt-go-border); }

/* Botão de acento (usa a cor ativa da marca) */
.btn-accent{ --_c:#fff; --_bg:var(--corAtiva); --_bd:var(--corAtiva); }

/* Neutro / secundário / ghost / link */
.btn-neutral{ --_c:var(--c-text); --_bg:var(--c-surface); --_bd:var(--c-border-strong); }
.btn-ghost{ --_c:var(--c-text-muted); --_bg:transparent; --_bd:transparent; }
.btn-ghost:hover{ background:var(--c-surface-2); filter:none; }
.btn-link{ --_c:var(--c-accent); --_bg:transparent; --_bd:transparent; padding-left:4px; padding-right:4px; }
.btn-link:hover{ text-decoration:underline; filter:none; }

/* --------------------------------------------------------------------------
   AÇÕES (REGRA NUBANK NOVA) — hierarquia por ÊNFASE, não por cor.
   Só a AÇÃO DA VEZ ganha destaque; o resto fica neutro.
     • Primária (Novo/Salvar)        = ROXO sólido (accent).
     • Secundárias (Editar/Ver)      = NEUTRAS (superfície cinza).
     • Cancelar/voltar               = ghost neutro.
     • Excluir                       = NEUTRO em repouso (NÃO vermelho).
     • Vermelho SÓ no passo final de confirmação destrutiva: .btn-delete-confirm.
   As ênfases (.btn-soft/.btn-outline/.btn-text) seguem atuando sobre --act.
   Convenção de ícone:  novo=fa-plus  salvar=fa-check  editar=fa-pen
                        ver=fa-eye  excluir=fa-trash  cancelar=fa-xmark
   -------------------------------------------------------------------------- */
.btn-new    { --act:var(--corAtiva);     --_bg:var(--act); --_c:#fff; --_bd:var(--act); }       /* primária = accent sólido */
.btn-save   { --act:var(--corAtiva);     --_bg:var(--act); --_c:#fff; --_bd:var(--act); }       /* primária = accent sólido */
.btn-edit   { --act:#5b6472;             --_bg:var(--c-surface); --_c:var(--c-text); --_bd:var(--c-border-strong); } /* secundária = neutro */
.btn-view   { --act:#5b6472;             --_bg:var(--c-surface); --_c:var(--c-text); --_bd:var(--c-border-strong); } /* secundária = neutro */
.btn-delete { --act:var(--c-text-muted); --_bg:var(--c-surface); --_c:var(--c-text); --_bd:var(--c-border-strong); } /* excluir NEUTRO em repouso */
.btn-cancel { --act:var(--c-text-muted); --_bg:transparent; --_c:var(--c-text-muted); --_bd:transparent; } /* cancelar/voltar */
.btn-cancel:hover{ background:var(--c-surface-2); filter:none; }
/* passo final de confirmação destrutiva ("Tem certeza?"): AÍ SIM vermelho sólido */
.btn-delete-confirm{ --act:var(--c-danger); --_bg:var(--act); --_c:#fff; --_bd:var(--act); }

/* Ênfases — atuam sobre a cor --act da intenção (vêm depois p/ sobrescrever o sólido) */
.btn-soft{    --_bg:color-mix(in srgb, var(--act,var(--corAtiva)) 12%, #fff); --_c:var(--act,var(--corAtiva)); --_bd:transparent; }
.btn-soft:hover{ filter:none; background:color-mix(in srgb, var(--act,var(--corAtiva)) 18%, #fff); }
.btn-outline{ --_bg:transparent; --_c:var(--act,var(--corAtiva)); --_bd:var(--act,var(--c-border-strong)); }
.btn-outline:hover{ filter:none; background:color-mix(in srgb, var(--act,var(--corAtiva)) 9%, transparent); }
.btn-text{    --_bg:transparent; --_c:var(--act,var(--corAtiva)); --_bd:transparent; padding-left:8px; padding-right:8px; }
.btn-text:hover{ filter:none; background:color-mix(in srgb, var(--act,var(--corAtiva)) 9%, transparent); }

/* --------------------------------------------------------------------------
   ÍCONE DE CARD / AÇÃO — bolinha branca com o glifo dentro. REGRA NUBANK NOVA:
   o ícone NÃO carrega cor de intenção. Só DOIS estados:
     • NEUTRO (padrão) = glifo GRAFITE (--c-text) sobre a bolinha branca.
     • PRIORIDADE (.ico-accent / .ico-priority) = bolinha LAVANDA + glifo ROXO,
       reservado à AÇÃO PRINCIPAL do bloco (ex.: Novo/Criar). Um por grupo.
   As antigas variantes semânticas (ico-new/edit/delete/config/warning/…) ficam
   por COMPAT, mas TODAS resolvem para o neutro grafite — a cor saiu dos ícones. */
.ico-badge{ width:44px; height:44px; border-radius:50%; background:#fff; color:var(--c-text); display:inline-flex; align-items:center; justify-content:center; font-size:19px; flex:0 0 auto; }
.ico-badge.ico-sm{ width:34px; height:34px; font-size:15px; }
.ico-badge.ico-lg{ width:52px; height:52px; font-size:22px; }
/* compat: qualquer intenção antiga = NEUTRO grafite (sem cor) */
.ico-new,.ico-edit,.ico-view,.ico-delete,.ico-warning,.ico-config,
.ico-success,.ico-info,.ico-danger{ color:var(--c-text); }
/* ÚNICA exceção: ÍCONE DE PRIORIDADE (ação principal) = lavanda + roxo */
.ico-accent,.ico-priority{ background:var(--c-accent-soft); color:var(--corAtiva); }

/* Loading */
.btn.is-loading{ color:transparent !important; pointer-events:none; position:relative; }
.btn.is-loading::after{
  content:""; position:absolute; width:15px; height:15px; border-radius:50%;
  border:2px solid currentColor; border-top-color:transparent;
  color:var(--_c); animation:ds-spin .6s linear infinite;
}
@keyframes ds-spin{ to{ transform:rotate(360deg); } }

/* Estado "ocupado" para alvos que não são .btn (links de ação, ícones de linha):
   spinner discreto no lugar do conteúdo. Aplicado por ds-busy.js (aria-busy). */
[aria-busy="true"]:not(.btn):not(.refresh-status){ position:relative; pointer-events:none; }
/* .start-card fica de fora: cards de navegação têm o próprio spinner no ícone
   (ver start.php). Sem isto, a rede ampla abaixo pintava um 2º spinner no MEIO
   do card e sumia o texto ao clicar — visual poluído. */
.is-loading:not(.btn):not(.refresh-status):not(.start-card){ color:transparent !important; }
.is-loading:not(.btn):not(.refresh-status):not(.start-card)::after{
  content:""; position:absolute; top:50%; left:50%; width:14px; height:14px; margin:-7px 0 0 -7px;
  border-radius:50%; border:2px solid var(--corAtiva); border-top-color:transparent;
  animation:ds-spin .6s linear infinite;
}

/* BARRA DE PROGRESSO DE NAVEGAÇÃO (casca) — faixa fina no topo enquanto o
   conteúdo troca de tela; mata a sensação de "congelou". Controlada por ds-busy.js. */
.ds-nav-progress{ position:fixed; top:0; left:0; right:0; height:3px; z-index:var(--z-toast,9000);
  pointer-events:none; opacity:0; transition:opacity .2s ease; }
.ds-nav-progress.on{ opacity:1; }
.ds-nav-progress.done{ opacity:0; transition:opacity .3s ease .12s; }
.ds-nav-progress > i{ display:block; height:100%; width:0;
  background:linear-gradient(90deg, color-mix(in srgb,var(--corAtiva) 55%,#fff), var(--corAtiva));
  box-shadow:0 0 8px color-mix(in srgb,var(--corAtiva) 60%,transparent);
  transition:width .18s cubic-bezier(.16,1,.3,1); }
@media (prefers-reduced-motion:reduce){ .ds-nav-progress > i{ transition:none; } }

/* SKELETON (placeholder de carregamento) — use no lugar de spinner em áreas de
   conteúdo. .skel = bloco; modificadores de forma; herda o raio do contexto. */
.skel{ position:relative; overflow:hidden; background:var(--c-surface-2); border-radius:var(--r-sm); }
.skel::after{ content:""; position:absolute; inset:0; transform:translateX(-100%);
  background:linear-gradient(90deg, transparent, color-mix(in srgb,#fff 55%,transparent), transparent);
  animation:ds-shimmer 1.2s infinite; }
.skel-line{ height:12px; border-radius:var(--r-pill); }
.skel-title{ height:20px; border-radius:var(--r-sm); }
.skel-input{ height:38px; border-radius:var(--r-md); }
@keyframes ds-shimmer{ to{ transform:translateX(100%); } }
@media (prefers-reduced-motion:reduce){ .skel::after{ animation:none; } }

/* Grupo de botões */
.btn-group{ display:inline-flex; }
.btn-group .btn{ border-radius:0; margin-left:-1px; }
.btn-group .btn:first-child{ border-radius:var(--r-sm) 0 0 var(--r-sm); margin-left:0; }
.btn-group .btn:last-child{ border-radius:0 var(--r-sm) var(--r-sm) 0; }

/* o atributo hidden SEMPRE esconde (vence o display:inline-flex de .badge etc.) */
[hidden]{ display:none !important; }

/* Botão só-ícone (quadrado): ações compactas em cabeçalhos de listagem/kanban
   (Novo, Filtro). Use .btn + intenção (.btn-new/.btn-view/…) + .btn-icon.
   Badge de contagem e caret do dropdown ficam ancorados no canto. */
.btn-icon{ width:38px; height:38px; min-height:0; padding:0; justify-content:center; position:relative; flex:0 0 auto; align-self:center; aspect-ratio:1; }
.btn-icon > .badge,.btn-icon > .badge-accent{ position:absolute; top:-5px; right:-5px; min-width:16px; height:16px; padding:0 4px; font-size:10px; line-height:16px; border-radius:var(--r-pill); }
.btn-icon > .fa-caret-down{ position:absolute; bottom:3px; right:4px; font-size:9px; opacity:.85; }

/* ==========================================================================
   5. FORMULÁRIOS
   ========================================================================== */
.form-group{ margin-bottom:var(--sp-4); }
.form-row{ display:flex; flex-wrap:wrap; gap:var(--sp-4); }
.form-row > .form-group{ flex:1 1 220px; margin-bottom:0; }
/* FORM em painel (runWindow): SEM caixa — campos soltos no branco (minimalista).
   Vale p/ todo form que usa .form-wrap > .card. O respiro vertical entre campos
   é por tela (.form-row local), padrão ~26-28px. */
.form-wrap > .card{ background:transparent; border:0; box-shadow:none; border-radius:0; margin:0; }
.form-wrap > .card > .card-body{ padding:0; }

.form-label,
label.ds-label{
  display:block;
  font-size:var(--tam_formLabel);
  font-weight:var(--fw-medium);
  color:var(--cor_formLabel);
  margin-bottom:6px;
}
.form-label .req{ color:var(--c-danger); margin-left:2px; }
.form-hint{ display:block; font-size:var(--fs-xs); color:var(--c-text-soft); margin-top:4px; }

.form-control,
input.ds-input, select.ds-select, textarea.ds-textarea,
input[type=text].ds, input[type=email].ds, input[type=password].ds,
input[type=number].ds, input[type=date].ds{
  display:block; width:100%;
  font-family:inherit; font-size:var(--fs-md); line-height:1.4;
  color:var(--cor_form);
  background:transparent;   /* funde com o fundo (underline puro) */
  padding:9px 2px; min-height:38px;
  /* minimalista: só a linha de baixo, sem caixa nem radius */
  border:0; border-bottom:1px solid var(--c-border-strong);
  border-radius:0;
  transition:border-color var(--transition), box-shadow var(--transition);
  appearance:none;
}
textarea.form-control,.ds-textarea{ min-height:96px; resize:vertical; }
.form-control::placeholder{ color:var(--c-placeholder); }
.form-control:hover{ border-color:var(--c-border-strong); }
.form-control:focus,
.ds-input:focus,.ds-select:focus,.ds-textarea:focus{
  outline:none;
  border-bottom-color:var(--corAtiva);
  border-bottom-width:2px;
  padding-bottom:8px;   /* compensa o +1px da borda p/ o conteúdo não pular */
  box-shadow:none;
}
/* readonly/disabled: mantém o underline (SEM caixa cinza) — só texto apagado + cursor */
.form-control[disabled],.form-control[readonly]{ background:transparent; color:var(--c-text-muted); cursor:not-allowed; border-bottom-style:dashed; }
/* autofill do Chrome: preserva o visual underline (sem o fundo amarelo/claro do navegador) */
.form-control:-webkit-autofill,
.form-control:-webkit-autofill:hover,
.form-control:-webkit-autofill:focus,
.form-control:-webkit-autofill:active{
  -webkit-text-fill-color:var(--cor_form); caret-color:var(--cor_form);
  -webkit-box-shadow:0 0 0 1000px var(--c-surface) inset;
  transition:background-color 9999s ease-in-out 0s;
}

/* Select com caret */
select.form-control,.ds-select{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center;
  padding-right:34px;
}

/* Input com ícone (prefixo/sufixo) */
.input-affix{ position:relative; display:flex; align-items:center; }
.input-affix .form-control{ padding-left:26px; }
.input-affix .affix-ico{ position:absolute; left:2px; color:var(--c-placeholder); pointer-events:none; display:flex; }

/* Campo conectado a API — raio cinza discreto à direita; o tooltip vem do runTitle (title nativo).
   Markup: <div class="field-api"><input class="form-control"><i class="fa fa-bolt api-flag" title="…"></i></div>
   Estados aplicados por JS na consulta: .is-busy (consultando, gira) · .is-done (preenchido). */
.field-api{ position:relative; display:flex; align-items:center; width:100%; }
.field-api .form-control{ flex:1 1 auto; min-width:0; padding-right:22px; }
.field-api .api-flag{ position:absolute; right:2px; color:var(--c-text-soft); display:flex; cursor:help; line-height:1; transition:color var(--transition); }
.field-api .api-flag.is-busy{ color:var(--corAtiva); animation:ds-spin .7s linear infinite; }
.field-api .api-flag.is-done{ color:var(--c-success); }

/* Validação (linha de baixo colorida, sem glow) */
.form-control.is-invalid,.has-error .form-control{ border-bottom-color:var(--c-danger); border-bottom-width:2px; }
.form-control.is-invalid:focus{ border-bottom-color:var(--c-danger); box-shadow:none; }
.form-control.is-valid,.has-success .form-control{ border-bottom-color:var(--c-success); border-bottom-width:2px; }
.invalid-feedback{ display:block; color:var(--c-danger); font-size:var(--fs-xs); margin-top:4px; }
.valid-feedback{ display:block; color:var(--c-success); font-size:var(--fs-xs); margin-top:4px; }

/* ReqGroup — grupo "um ou outro" obrigatório (campo OU campo). Lib: /assets/js/reqgroup.js (data-ou).
   O alvo (.ou-mark) marca cada campo do grupo; ao preencher um, os demais apagam (.off). */
.ou-mark{ font-size:10px; color:var(--corAtiva); opacity:.75; margin-left:4px; cursor:help; }
.ou-mark.off{ opacity:.2; }
.form-group.ou-falta .form-control,
.form-group.ou-falta .ds-input,
.form-group.ou-falta .ds-select{ border-color:var(--c-warning); border-bottom-color:var(--c-warning); }
.form-group.ou-falta .ou-mark{ color:var(--c-warning); opacity:1; }

/* Checkbox / radio custom */
.ds-check{ display:inline-flex; align-items:center; gap:8px; cursor:pointer; font-size:var(--fs-md); user-select:none; }
.ds-check input[type=checkbox],.ds-check input[type=radio]{
  appearance:none; -webkit-appearance:none; width:18px; height:18px; margin:0;
  border:1.5px solid var(--c-border-strong); background:var(--c-surface);
  display:grid; place-content:center; cursor:pointer; transition:var(--transition);
}
.ds-check input[type=checkbox]{ border-radius:var(--r-xs); }
.ds-check input[type=radio]{ border-radius:50%; }
.ds-check input:focus-visible{ box-shadow:var(--sh-focus); }
.ds-check input:checked{ background:var(--corAtiva); border-color:var(--corAtiva); }   /* marcado = cor primária */
.ds-check input[type=checkbox]:checked::after{
  content:""; width:5px; height:9px; border:2px solid #fff; border-top:0; border-left:0;
  transform:rotate(45deg) translate(-1px,-1px);
}
.ds-check input[type=radio]:checked::after{ content:""; width:7px; height:7px; border-radius:50%; background:#fff; }

/* Toggle switch */
.ds-switch{ position:relative; display:inline-flex; align-items:center; gap:8px; cursor:pointer; }
.ds-switch input{ position:absolute; opacity:0; width:0; height:0; }
.ds-switch .track{ width:38px; height:21px; border-radius:var(--r-pill); background:var(--c-border-strong); transition:var(--transition); position:relative; }
.ds-switch .track::after{ content:""; position:absolute; top:2px; left:2px; width:17px; height:17px; border-radius:50%; background:#fff; box-shadow:var(--sh-xs); transition:var(--transition); }
.ds-switch input:checked + .track{ background:var(--corAtiva); }   /* ligado = cor primária */
.ds-switch input:checked + .track::after{ transform:translateX(17px); }
.ds-switch input:focus-visible + .track{ box-shadow:var(--sh-focus); }

/* ==========================================================================
   5.1 FORMULÁRIO EM PAINEL (CAPA-PERFIL + ABAS-PASTA) — padrão de cadastro/edição
   Para telas de form que abrem em runWindow (modal lateral). Referência viva: modulos/cpfj/form.php.
   Compõe:
     .form-cover            capa escura (cor-de-marca). Dentro:
        .fc-id > .fc-avatar(.is-pj) [upload + .fc-cam hover] + .fc-titles(.fc-eyebrow + h1[.is-ph])
        .fc-prog (progresso) · .fc-x (fechar) · opcional: .rel-seg (segmentado sobre o escuro)
     .form-tabs             ABAS-PASTA: barra = extensão escura da capa; aba .active = língua BRANCA
     .form-body / .tab-pane(.active) / .form-grid (12 col) / .form-head+.fh-main+.form-photo / .form-foot
     .rel-seg > .rel-tg     SEGMENTADO multi-seleção (claro no corpo; branco sobre a capa escura)
     .dropzone > .dz-ico/.dz-txt/.dz-hint   área de arrastar-e-soltar arquivos

   AVISO/ALERTA dentro do form (.alert) — LOCAL CORRETO:
     SEMPRE dentro de .form-body, no TOPO (antes de .form-grid / do grid de conteúdo), margem
     só vertical (ex.: style="margin:0 0 16px"). Quando há abas, fica ABAIXO da .form-tabs.
     NUNCA colocar o .alert ENTRE .form-cover e .form-tabs (nem entre a capa e o <form>): a barra
     de abas é a EXTENSÃO ESCURA da capa — um box claro no meio CORTA essa continuidade e "mata"
     o cabeçalho. (Forms sem abas, ex. combustível: idem — aviso no topo do corpo, não acima da capa.)
   ========================================================================== */
/* ----- CAPA-PERFIL: avatar (upload) + eyebrow + título (pode ser preenchido ao vivo) ----- */
/* glow radial sutil da marca no topo-esquerdo (profundidade "Nubank"), sobre a base escura */
.form-cover{ position:relative; color:#fff; padding:38px 32px 32px;
  background:
    radial-gradient(120% 130% at 12% -25%, color-mix(in srgb, var(--corAtiva) 30%, transparent) 0%, transparent 60%),
    var(--c-brand-dark); }
.form-cover .fc-id{ display:flex; align-items:center; gap:22px; }
.form-cover h1{ margin:0; color:#fff; font-size:var(--fs-3xl); font-weight:var(--fw-bold); letter-spacing:-.02em; line-height:1.25; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.form-cover h1.is-ph{ opacity:.5; font-weight:var(--fw-semibold); }      /* placeholder enquanto não há nome */
.fc-eyebrow{ display:block; font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:.08em; color:rgba(255,255,255,.72); margin-bottom:2px; }
.fc-titles{ min-width:0; }
/* avatar: clica p/ enviar imagem, hover mostra a câmera. PF = redondo; empresa = .is-pj (quadrado arred.) */
.fc-avatar{ position:relative; flex:0 0 auto; width:90px; height:90px; border-radius:50%; cursor:pointer; overflow:hidden;
  background:rgba(255,255,255,.14); border:2px solid rgba(255,255,255,.38); display:flex; align-items:center; justify-content:center;
  color:#fff; transition:border-color .15s; }
.fc-avatar.is-pj{ border-radius:18px; }
.fc-avatar:hover{ border-color:#fff; }
.fc-avatar img{ width:100%; height:100%; object-fit:cover; }
.fc-avatar > i{ font-size:36px; opacity:.92; }
.fc-avatar .fc-cam{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; background:rgba(0,0,0,.42); color:#fff; font-size:18px; opacity:0; transition:opacity .15s; }
.fc-avatar:hover .fc-cam{ opacity:1; }
.form-cover .fc-prog{ margin-top:20px; height:5px; width:min(420px,55%); background:rgba(255,255,255,.20); border-radius:6px; overflow:hidden; }
.form-cover .fc-prog i{ display:block; height:100%; width:0; background:#fff; border-radius:6px; transition:width .3s; }
.form-cover .fc-x{ position:absolute; top:24px; right:26px; width:44px; height:44px; border-radius:50%; border:0; cursor:pointer;
  background:rgba(255,255,255,.16); color:#fff; font-size:16px; display:flex; align-items:center; justify-content:center; transition:background .15s; }
.form-cover .fc-x:hover{ background:rgba(255,255,255,.30); }
/* botão "?" — reabre a introdução do form (introCover/window.formIntroReabrir); irmão do fechar, à esquerda dele */
.form-cover .fc-help{ position:absolute; top:24px; right:78px; width:44px; height:44px; border-radius:50%; border:0; cursor:pointer;
  background:rgba(255,255,255,.16); color:#fff; font-size:16px; display:flex; align-items:center; justify-content:center; transition:background .15s; }
.form-cover .fc-help:hover{ background:rgba(255,255,255,.30); }
/* CLUSTER de ações da capa (quando há mais de uma opção: copiar/ver/ajuda/fechar).
   Container flex ancorado à direita; cada botão tem o MESMO tamanho/estilo do .fc-x
   (consistência entre telas — orçamento, locação, etc.). O fechar é o último (direita)
   e leva data-rw-close p/ o runWindow esconder o próprio X. */
.form-cover .fc-tools{ position:absolute; top:24px; right:26px; display:flex; gap:8px; z-index:3; }
.form-cover .fc-tool{ width:44px; height:44px; border-radius:50%; border:0; cursor:pointer;
  background:rgba(255,255,255,.16); color:#fff; font-size:16px; display:flex; align-items:center; justify-content:center; transition:background .15s; }
.form-cover .fc-tool:hover{ background:rgba(255,255,255,.30); }

/* ----- ABAS-PASTA: a barra é a extensão ESCURA da capa; a aba ATIVA é uma língua BRANCA que emenda no conteúdo ----- */
.form-tabs{ display:flex; flex-wrap:nowrap; gap:4px; padding:0 24px; background:var(--c-brand-dark); overflow-x:auto; scrollbar-width:thin; scrollbar-color:transparent transparent; }
.form-tabs::-webkit-scrollbar{ height:5px; }
.form-tabs::-webkit-scrollbar-thumb{ background:transparent; border-radius:8px; }
.form-tabs:hover::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.20); }
.form-tabs button{ flex:0 0 auto; background:transparent; border:0; cursor:pointer; font-size:var(--fs-md); color:rgba(255,255,255,.72);
  padding:12px 18px; border-radius:10px 10px 0 0; transition:background .12s,color .12s; white-space:nowrap; }
.form-tabs button:hover{ color:#fff; background:rgba(255,255,255,.10); }
.form-tabs button.active,
.form-tabs button.active:hover{ background:var(--c-bg); color:var(--c-text); font-weight:var(--fw-semibold); }

.form-body{ padding:18px 30px 28px; }
.tab-pane{ display:none; } .tab-pane.active{ display:block; }
/* align-items:START — campos alinham pelo TOPO (label). Com 'end', um campo que ganha
   texto de ajuda (.field-hint) ficava mais alto e empurrava os vizinhos pra cima,
   "estourando" o alinhamento da linha. start resolve em definitivo (vale p/ toda a ferramenta). */
.form-grid{ display:grid; grid-template-columns:repeat(12,1fr); gap:28px 16px; align-items:start; }
.form-head{ display:flex; gap:24px; align-items:flex-start; }
.form-head .fh-main{ flex:1; min-width:0; }
.form-photo{ flex:0 0 auto; width:112px; text-align:center; }
.form-photo .foto-box{ width:112px; height:112px; border-radius:14px; background:var(--c-surface); border:1px solid var(--c-border);
  display:flex; align-items:center; justify-content:center; color:#9aa3b0; font-size:30px; cursor:pointer; overflow:hidden; transition:border-color .15s; }
.form-photo .foto-box:hover{ border-color:var(--corAtiva); }
.form-photo .foto-box img{ width:100%; height:100%; object-fit:cover; }
/* RODAPÉ DE AÇÃO (canônico) — vale p/ FORMS (.form-foot) E painéis de config (.cfg-foot/.ed-foot
   são ALIASES do MESMO componente; não duplicar CSS local). Fixo na base do painel (sticky),
   ações à direita, separado por uma linha. Um <span> filho vira espaçador (empurra as ações
   p/ a direita). No celular vira uma BOTTOM ACTION BAR fixa — ver §5.1 @media(max-width:560px). */
.form-foot, .cfg-foot, .ed-foot{ display:flex; align-items:center; justify-content:flex-end; gap:8px;
  position:sticky; bottom:0; z-index:var(--z-sticky);
  padding:14px 24px; background:var(--c-bg); border-top:1px solid var(--c-border); }
.form-foot > span, .cfg-foot > span, .ed-foot > span{ flex:1; }   /* espaçador opcional */

/* ----- SEGMENTADO multi-seleção em PÍLULA (track arredondado; ativo = pílula "encaixada"/inset).
   Claro = corpo (ativo roxo); escuro = dentro da capa (ativo branco). Formato na base, cor por variante. ----- */
.rel-seg{ display:inline-flex; flex-wrap:wrap; gap:4px; background:var(--c-surface); border:1px solid var(--c-border); border-radius:var(--r-pill); padding:4px; }
.rel-tg{ display:inline-flex; align-items:center; gap:7px; padding:8px 15px; border-radius:var(--r-pill); cursor:pointer; color:var(--c-text-muted);
  font-size:var(--fs-sm); font-weight:var(--fw-semibold); white-space:nowrap; transition:background .12s,color .12s; user-select:none; }
.rel-tg input{ position:absolute; opacity:0; width:0; height:0; }
.rel-tg i{ font-size:13px; opacity:.85; }
.rel-tg:hover{ color:var(--corAtiva); }
.rel-tg:has(input:checked){ background:var(--corAtiva); color:#fff; margin:5px 0; padding:4px 15px; }   /* ativo = pílula inset (menor, centrada no track) */
.rel-tg:has(input:checked) i, .rel-tg input:checked ~ i{ opacity:1; }
/* variante sobre a capa escura: track translúcido; INATIVO = só texto (sem chip);
   fundo aparece SÓ no hover e no ativo (branco) */
.form-cover .rel-seg{ background:rgba(255,255,255,.10); border:0; margin:26px 0 0; }
.form-cover .rel-tg{ color:#fff; }
.form-cover .rel-tg:hover{ background:rgba(255,255,255,.14); }
.form-cover .rel-tg:has(input:checked){ background:#fff; color:var(--c-text); }

/* ----- DROPZONE (arrastar-e-soltar arquivos; clicar também abre o seletor) ----- */
.dropzone{ display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
  border:2px dashed var(--c-border-strong); border-radius:14px; padding:40px 20px; cursor:pointer;
  background:var(--c-surface); color:var(--c-text-muted); transition:border-color .15s,background .15s,color .15s; }
.dropzone:hover{ border-color:var(--corAtiva); color:var(--corAtiva); }
.dropzone.dragover{ border-color:var(--corAtiva); background:color-mix(in srgb,var(--corAtiva) 8%,var(--c-surface)); color:var(--corAtiva); }
.dropzone .dz-ico{ font-size:32px; margin-bottom:10px; opacity:.85; }
.dropzone .dz-txt{ font-size:var(--fs-md); }
.dropzone .dz-txt b{ color:var(--c-text); font-weight:var(--fw-semibold); }
.dropzone:hover .dz-txt b,.dropzone.dragover .dz-txt b{ color:var(--corAtiva); }
.dropzone .dz-hint{ font-size:var(--fs-xs); color:var(--c-text-soft); margin-top:6px; }

@media (max-width:760px){
  .form-grid{ grid-template-columns:repeat(2,1fr); }
  .form-grid .form-group{ grid-column:span 2 !important; }
  .form-head{ align-items:flex-start; gap:16px; }
  .form-photo{ width:auto; }
  .form-photo .foto-box{ width:96px; height:96px; margin:0; }
}
@media (max-width:560px){
  .form-cover{ padding:28px 18px 24px; }
  .form-cover h1{ font-size:var(--fs-2xl); }
  .fc-avatar{ width:70px; height:70px; } .fc-avatar > i{ font-size:28px; }
  /* celular: relacionamento em GRID (2 colunas), sem fundo de container */
  .form-cover .rel-seg{ margin-top:20px; width:100%; display:grid; grid-template-columns:repeat(2,1fr); gap:6px; padding:0; background:transparent; }
  .form-cover .rel-tg{ justify-content:flex-start; }
  .form-cover .rel-tg:has(input:checked){ margin:0; padding:8px 15px; }   /* grid uniforme: sem o "inset" do desktop */
  .form-cover .fc-x{ top:18px; right:16px; width:40px; height:40px; }
  .form-cover .fc-help{ top:18px; right:62px; width:40px; height:40px; }
  .form-cover .fc-tools{ top:18px; right:16px; gap:6px; }
  .form-cover .fc-tool{ width:40px; height:40px; }
  .form-tabs{ padding:0 12px; }
  .form-body{ padding:16px; }
  /* RODAPÉ DE AÇÕES travado na BASE DA TELA no celular (bottom action bar de app):
     position:FIXED — gruda na base SEMPRE, form curto ou longo. (sticky só grudava quando
     havia scroll, então em form curto — ex.: patrimônio — o rodapé "subia" pro meio da tela;
     fixed elimina essa inconsistência.) O conteúdo (.form-body) reserva espaço embaixo p/ o
     último campo não ficar atrás do rodapé. O Salvar NUNCA fica atrás da barra do navegador.
     LADO A LADO (não empilha à toa): o caso comum é [Cancelar][Salvar] — as secundárias ficam
     COMPACTAS (do tamanho do texto) e a ação principal (.btn-save) DOMINA a linha, virando o
     alvo do polegar: [Cancelar][      Salvar      ]. Só quando há 3+ botões largos (Ver
     parcelas / Alterar registro) que não cabem, o flex-wrap quebra e o Salvar (order:9) desce
     FULL-WIDTH. Correção no DS, vale p/ todo form do painel — não por tela. */
  .form-foot, .cfg-foot, .ed-foot{ position:fixed; left:0; right:0; bottom:0; z-index:var(--z-sticky); margin:0;
    padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px)); flex-wrap:wrap; gap:10px 8px;
    background:var(--c-bg); border-top:1px solid var(--c-border); }
  .form-foot > span, .cfg-foot > span, .ed-foot > span{ display:none; }   /* o espaçador do desktop não se aplica no celular */
  .form-foot .btn, .cfg-foot .btn, .ed-foot .btn{ flex:0 1 auto; justify-content:center; white-space:nowrap; min-width:0; }
  .form-foot .btn-save, .cfg-foot .btn-save, .ed-foot .btn-save{ flex:1 1 auto; order:9; }  /* ação principal: cresce e domina; cai p/ baixo só se não couber */
  /* reserva UNIVERSAL p/ o conteúdo não ficar atrás do rodapé fixo — independe do nome do corpo
     (.form-body, .cfg-body, .ed-body, etc.): o padding no <body> empurra o fim do scroll acima da barra.
     Esta é a reserva-BASE (fallback): rodapé com hint/3+ botões quebra linha e fica MAIS ALTO que 80px —
     o assets/js/foot-space.js mede a altura real e ajusta o padding do body (inline vence esta regra). */
  body:has(.form-foot), body:has(.cfg-foot), body:has(.ed-foot){ padding-bottom:calc(80px + env(safe-area-inset-bottom,0px)); }
}
@media (max-width:480px){
  .form-grid{ grid-template-columns:1fr; }
  .form-grid .form-group{ grid-column:span 1 !important; }
}

/* ==========================================================================
   5.1.b APP-SHELL DO PAINEL DE FORMULÁRIO (desktop ≥561px) — rodapé na base
   --------------------------------------------------------------------------
   PROBLEMA: o rodapé (.form-foot/.cfg-foot/.ed-foot) é position:sticky;bottom:0
   — só encosta na base QUANDO há scroll. Form curto (poucos campos) não rola,
   então o rodapé "subia" pro meio do painel, deixando um vazio embaixo.
   SOLUÇÃO (sem overflow container, p/ NÃO recortar os dropdowns ABSOLUTOS do
   buscaPicker/selectSearch que vivem dentro do corpo): o body do painel vira
   COLUNA flex com min-height:100dvh; o wrapper (o <form> que contém o rodapé,
   ou .*-wrap) cresce; o rodapé recebe margin-top:auto → vai pra BASE em form
   curto e, como continua sticky, fica GRUDADO na base também em form longo (o
   conteúdo rola por baixo, no scroll natural do body, sem ser clipado). O
   respiro do último campo já vem do padding-bottom:28px do .form-body.
   PRÉ-REQUISITO de markup: o rodapé deve ser IRMÃO do corpo (.form-body etc.),
   nunca aninhado dentro dele. (No celular ≤560px o rodapé já é fixed — §5.1.) */
@media (min-width:561px){
  body:has(.form-foot), body:has(.cfg-foot), body:has(.ed-foot){
    margin:0; display:flex; flex-direction:column; min-height:100dvh; }
  /* o wrapper que contém o rodapé cresce e vira coluna; a capa fora do form e as
     abas ficam no topo naturalmente — só o rodapé é empurrado pra base */
  body:has(.form-foot) > form:has(> .form-foot),
  body:has(.cfg-foot)  > form:has(> .cfg-foot),
  body:has(.ed-foot)   > form:has(> .ed-foot),
  body:has(.form-foot) > .form-wrap,
  body:has(.cfg-foot)  > .cfg-wrap,
  body:has(.ed-foot)   > .ed-wrap{
    flex:1 1 auto; display:flex; flex-direction:column; min-height:0; }
  /* rodapé: base em form curto (margin-top:auto) + grudado em form longo (sticky herdado de §5.1) */
  body:has(.form-foot) .form-foot,
  body:has(.cfg-foot)  .cfg-foot,
  body:has(.ed-foot)   .ed-foot{ margin-top:auto; }
  /* o widget "Avaliar esta tela" reserva 84px no body (html.fb-present) p/ telas que rolam;
     com o rodapé sticky na base ele é desnecessário e só empurraria a base — zera. Vale
     ligado/desligado: sem fb-present não há padding; o coração flutua sem mudar a altura. */
  html.fb-present body:has(.form-foot),
  html.fb-present body:has(.cfg-foot),
  html.fb-present body:has(.ed-foot){ padding-bottom:0; }
  /* …e o gatilho (fixed, canto inf. esquerdo) não pode COBRIR o texto do rodapé de ação
     (sticky, bottom:0) — ex.: "Quem recebe assina…". Sobe o coração p/ logo acima do rodapé.
     :not(.fb-moved) respeita a posição que o usuário arrastou. */
  html.fb-present body:has(.form-foot) #fbWidgetRoot .fb-fab:not(.fb-moved),
  html.fb-present body:has(.cfg-foot)  #fbWidgetRoot .fb-fab:not(.fb-moved),
  html.fb-present body:has(.ed-foot)   #fbWidgetRoot .fb-fab:not(.fb-moved){ bottom:calc(74px + env(safe-area-inset-bottom,0px)); }
}

/* ==========================================================================
   5.2 INTRODUÇÃO DE FORMULÁRIO (capa de boas-vindas na 1ª vez)
   Componente: core/intro.php -> introCover(). Capa que cobre o painel do form
   antes do preenchimento (público leigo: 1 ilustração + título grande + 1 frase
   + 1 botão "Começar"). "Viu uma vez, não vê mais" (sys_user_prefs); o botão
   .fc-help da capa reabre via window.formIntroReabrir().
   ILUSTRAÇÃO: o vetor é inlinado e o ACENTO (vermelho puro #FF0000 no arquivo ->
   currentColor) herda a cor da marca — igual à "camisa" do empty-state ([id=Accent]).
   ========================================================================== */
.form-intro{ position:fixed; inset:0; z-index:var(--z-overlay); display:flex; align-items:center; justify-content:center;
  background:var(--c-bg); padding:40px 28px calc(40px + env(safe-area-inset-bottom,0px)); text-align:center;
  overflow-y:auto;   /* telas baixas: conteúdo mais alto que a viewport ROLA (antes cortava topo/rodapé e o botão sumia) */
  opacity:0; visibility:hidden; pointer-events:none; transition:opacity .3s ease, visibility .3s ease; }
.form-intro.is-on{ opacity:1; visibility:visible; pointer-events:auto; }
/* width:100% + min-width:0 são ESSENCIAIS: sem eles, este flex item não encolhe abaixo do
   próprio conteúdo e em telas < ~440px o título/texto vazava pro lado (corte à direita em
   TODAS as intros — Feed, pessoa jurídica, etc.). Com width:100%, encolhe até a largura da
   tela e o texto quebra; o max-width só limita no desktop. */
.form-intro .fi-inner{ width:100%; min-width:0; max-width:440px; margin:auto; display:flex; flex-direction:column; align-items:center;
  transform:translateY(12px); transition:transform .35s cubic-bezier(.2,.7,.2,1); }
/* margin:auto centraliza quando cabe e, quando NÃO cabe, encosta no topo (com o padding) e rola —
   evita o bug do flexbox align-items:center que corta o topo em overflow (botão inacessível). */
.form-intro.is-on .fi-inner{ transform:none; }
/* ilustração inline TEMADA: PRETO -> currentColor (= --c-text, mesma cor do título); VERMELHO #FF0000 -> acento da marca */
.form-intro .fi-art{ display:block; margin-bottom:28px; color:var(--c-text); }
.form-intro .fi-art svg{ width:clamp(180px,42vw,280px); height:auto; display:block; }
.form-intro .fi-art [fill="#FF0000" i], .form-intro .fi-art [fill="#F00" i], .form-intro .fi-art [fill="red" i], .form-intro .fi-art [id="Accent"]{ fill:var(--corAtiva); }
.form-intro .fi-art [stroke="#FF0000" i], .form-intro .fi-art [stroke="#F00" i], .form-intro .fi-art [stroke="red" i]{ stroke:var(--corAtiva); }
/* fallback sem vetor: ícone num círculo lavanda */
.form-intro .fi-ico{ width:88px; height:88px; border-radius:50%; background:var(--c-accent-soft);
  display:flex; align-items:center; justify-content:center; margin-bottom:28px; font-size:38px; color:var(--corAtiva); }
.form-intro .fi-eyebrow{ margin:0 0 10px; font-size:var(--fs-xs); font-weight:var(--fw-semibold); letter-spacing:.12em;
  text-transform:uppercase; color:var(--c-text-muted); }
/* max-width:100% + overflow-wrap são ESSENCIAIS: .fi-step é flex column com align-items:center,
   então os filhos de texto ganham largura max-content (o título inteiro numa linha só) e
   vazavam pro lado em telas estreitas. Travar em 100% força a quebra dentro do .fi-inner. */
.form-intro .fi-title{ margin:0; max-width:100%; overflow-wrap:break-word; font-size:var(--fs-3xl); font-weight:var(--fw-bold); letter-spacing:-.02em; line-height:1.15; color:var(--c-text); }
.form-intro .fi-text{ margin:14px 0 0; max-width:100%; overflow-wrap:break-word; font-size:var(--fs-lg); line-height:1.6; color:var(--c-text-muted); }   /* grande: público leigo */
.form-intro .fi-btn{ margin-top:32px; display:inline-flex; align-items:center; gap:10px; cursor:pointer;
  padding:15px 34px; border:0; border-radius:var(--r-pill); background:var(--corAtiva); color:#fff;
  font-size:var(--fs-lg); font-weight:var(--fw-semibold); transition:filter .15s, transform .05s; }
.form-intro .fi-btn:hover{ filter:brightness(1.06); }
.form-intro .fi-btn:active{ transform:translateY(1px); }
.form-intro .fi-btn:focus-visible{ outline:none; box-shadow:var(--sh-focus); }
/* ----- modo PÁGINAS (intro estendida p/ telas complexas): passos + bolinhas + nav ----- */
.form-intro .fi-steps{ width:100%; display:flex; flex-direction:column; align-items:center; }
.form-intro .fi-step{ display:none; flex-direction:column; align-items:center; width:100%; }
.form-intro .fi-step.is-active{ display:flex; animation:fi-step-in .3s ease both; }
@keyframes fi-step-in{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }
/* troca de passo deslizando na horizontal (avançar = entra da direita; voltar = da esquerda) — toque/botão */
.form-intro .fi-steps.dir-fwd  .fi-step.is-active{ animation:fi-slide-l .28s ease both; }
.form-intro .fi-steps.dir-back .fi-step.is-active{ animation:fi-slide-r .28s ease both; }
@keyframes fi-slide-l{ from{ opacity:0; transform:translateX(30px); }  to{ opacity:1; transform:none; } }
@keyframes fi-slide-r{ from{ opacity:0; transform:translateX(-30px); } to{ opacity:1; transform:none; } }
.form-intro .fi-dots{ display:flex; gap:8px; margin-top:26px; }
.form-intro .fi-dot{ width:8px; height:8px; border-radius:999px; background:var(--c-border-strong,#cdd3e0); transition:width .2s, background .2s; }
.form-intro .fi-dot.is-on{ width:22px; background:var(--corAtiva); }
.form-intro .fi-nav{ display:flex; gap:10px; align-items:center; margin-top:22px; }
.form-intro .fi-nav .fi-next{ margin-top:0; }   /* dentro da nav, sem a margem do .fi-btn solto */
.form-intro .fi-back{ display:inline-flex; align-items:center; gap:8px; background:transparent; border:0; cursor:pointer;
  color:var(--c-text-muted); font-size:15px; font-weight:var(--fw-semibold); padding:13px 20px; border-radius:var(--r-pill); transition:background .15s, color .15s; }
.form-intro .fi-back:hover{ background:var(--c-surface); color:var(--c-text); }
.form-intro .fi-back[hidden]{ display:none; }
.form-intro .fi-skip{ margin-top:14px; background:transparent; border:0; cursor:pointer; color:var(--c-text-soft);
  font-size:var(--fs-sm); text-decoration:underline; }
.form-intro .fi-skip:hover{ color:var(--c-text-muted); }
@media (prefers-reduced-motion:reduce){ .form-intro{ transition:none; } .form-intro .fi-inner{ transition:none; transform:none; } .form-intro .fi-step.is-active, .form-intro .fi-steps.dir-fwd .fi-step.is-active, .form-intro .fi-steps.dir-back .fi-step.is-active{ animation:none; } }
/* ===========================================================================
   BOTÃO DE AJUDA "?" — componente ÚNICO (.help-dot) injetado por injetarHelp()
   (core/intro.php) para REABRIR a introdução da tela. IDENTIDADE constante em
   toda a ferramenta (mesmo círculo, mesmo tamanho, ícone fa-question, mesmo canto)
   + PELE conforme a superfície onde ancora:
     • base            = inline num cabeçalho claro (topbar do start): discreto, sem moldura.
     • .is-raised      = sobre conteúdo imprevisível (flutuante/painel): moldura + sombrinha.
     • .is-float       = fixo no canto sup. direito (telas de layout próprio).
     • .is-panel       = absoluto no painel runWindow, à esquerda do fechar.
   NÃO vale para a CAPA do form: lá o "?" (.fc-help) é irmão do × e segue o cluster
   da capa (44px translúcido) — pele própria, de propósito. */
.help-dot{ flex:none; width:38px; height:38px; border-radius:50%; border:0; cursor:pointer; padding:0;
  display:inline-flex; align-items:center; justify-content:center; font-size:16px; line-height:1;
  background:transparent; color:var(--c-text-muted);
  transition:background .15s, color .15s, border-color .15s; }
.help-dot:hover{ background:var(--c-surface-2); color:var(--c-text); }
.help-dot:focus-visible{ outline:2px solid var(--corAtiva); outline-offset:2px; }
.help-dot.is-raised{ border:1px solid var(--c-border); background:var(--c-surface); box-shadow:0 2px 8px rgba(0,0,0,.08); }
.help-dot.is-raised:hover{ background:var(--c-accent-soft); color:var(--corAtiva); border-color:transparent; }
.help-dot.is-float{ position:fixed; top:14px; right:16px; z-index:40; }
.help-dot.is-panel{ position:absolute; top:16px; right:64px; z-index:5; }
@media (max-width:680px){
  .help-dot{ width:34px; height:34px; font-size:15px; }
  .help-dot.is-float{ top:10px; right:10px; }
}

/* ==========================================================================
   6. CARDS / PAINÉIS
   ========================================================================== */
.card,.ds-card{
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-sm);
  margin-bottom:var(--sp-4);
}
.card-header,.ds-card .card-header{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-3);
  padding:var(--sp-4) var(--sp-5);
  border-bottom:1px solid var(--c-border);
}
.card-header h3,.card-header h4{ margin:0; }
.card-body,.ds-card .card-body{ padding:var(--sp-5); }
.card-footer{ padding:var(--sp-4) var(--sp-5); border-top:1px solid var(--c-border); background:var(--c-surface-2); border-radius:0 0 var(--r-lg) var(--r-lg); }
.card-accent{ border-top:3px solid var(--corAtiva); }

/* Card de métrica (dashboards) */
.stat-card{ display:flex; flex-direction:column; gap:var(--sp-1); padding:var(--sp-5); }
.stat-card .stat-label{ font-size:var(--fs-sm); color:var(--c-text-muted); text-transform:uppercase; letter-spacing:.04em; }
.stat-card .stat-value{ font-size:var(--fs-3xl); font-weight:var(--fw-bold); color:var(--c-text); line-height:1.1; }
.stat-card .stat-delta{ font-size:var(--fs-sm); font-weight:var(--fw-medium); }
.stat-card .stat-delta.up{ color:var(--c-success); } .stat-card .stat-delta.down{ color:var(--c-danger); }

/* telas "start" (hubs de atalho): são navegação, não conteúdo — sem seleção de texto */
.start-wrap{ -webkit-user-select:none; user-select:none; }

/* TÍTULO DE SEÇÃO (telas start/dashboard) — separador COESO e ÚNICO, SEM ÍCONE (Nubank).
   Use <h2 class="sec-title">Texto</h2> — mesmo estilo em TODAS as telas start. Contador/
   subtítulo opcional: <span class="count">…</span>. NÃO redefina por tela nem ponha ícone. */
.sec-title{ margin:28px 0 14px; font-size:var(--fs-lg); font-weight:var(--fw-semibold); color:var(--c-text); letter-spacing:-.01em; line-height:var(--lh-tight); }
.sec-title:first-child{ margin-top:0; }
.sec-title .count{ margin-left:8px; font-size:var(--fs-sm); font-weight:var(--fw-normal); color:var(--c-text-soft); letter-spacing:0; }

/* STATUS DE ATUALIZAÇÃO (dashboards) — "atualizado há X" + ícone, TUDO clicável (refaz a
   consulta). O texto vai num <span> DENTRO; o ícone vem DEPOIS. Gira no hover (affordance)
   e durante o carregamento (.is-loading). NÃO é um botão "atualizar" separado.
   Uso: <a class="refresh-status" onclick="…"><span id="cacheInfo"></span><i class="fa fa-refresh"></i></a> */
/* BADGE "atualizado há X" (pill, desktop + mobile). A COR escala com a IDADE do cache
   (6h): cinza quando fresco → âmbar no meio → vermelho perto do limite (defasado).
   As classes .is-aging / .is-stale são aplicadas por refreshAge() (start-actions.js). */
.refresh-status{ display:inline-flex; align-items:center; gap:6px; cursor:pointer; text-decoration:none;
  background:var(--c-surface-2); color:var(--c-text-muted); padding:5px 11px; border-radius:var(--r-pill);
  font-size:var(--fs-xs); white-space:nowrap; transition:background var(--transition), color var(--transition); }
.refresh-status:hover{ color:var(--c-text); }
.refresh-status.is-aging{ background:var(--c-warning-bg); color:var(--c-warning); }   /* meio do período (~3–5h) */
.refresh-status.is-stale{ background:var(--c-danger-bg);  color:var(--c-danger); }    /* perto das 6h: muito defasado */
.refresh-status i{ font-size:12px; transition:transform .45s cubic-bezier(.16,1,.3,1); }
.refresh-status:hover i{ transform:rotate(-180deg); }
.refresh-status.is-loading{ pointer-events:none; }
.refresh-status.is-loading i{ animation:ds-spin .7s linear infinite; }

/* Card de atalho (telas "start"): ícone semântico (.ico-badge) + título + descrição.
   A cor do ícone segue a intenção: Novo=ico-new(verde), abrir/listar/navegar=ico-view(neutro),
   configurar=ico-accent(roxo). "Em breve" usa .is-soon ou .soon.
   COMPONENTE ÚNICO — use .start-card (canônico) ou .shortcut-card (alias). NÃO redefina
   o card localmente nas telas; só o .start-grid (largura das colunas) fica local por hub. */
.start-card,
.shortcut-card{
  position:relative;
  display:flex; flex-direction:column; gap:var(--sp-2);
  background:var(--c-surface); border:1px solid var(--c-border); border-radius:var(--r-lg);
  padding:var(--sp-5); cursor:pointer; text-decoration:none; color:inherit;
  transition:border-color var(--transition), box-shadow var(--transition), transform .05s ease;
}
.start-card:hover,
.shortcut-card:hover{ border-color:color-mix(in srgb,var(--corAtiva) 38%,var(--c-border)); box-shadow:var(--sh-sm); }
.start-card:active,
.shortcut-card:active{ transform:translateY(1px); }
.start-card h3,
.shortcut-card h3{ margin:6px 0 0; font-size:var(--fs-lg); }
.start-card p,
.shortcut-card p{ margin:0; color:var(--c-text-muted); font-size:var(--fs-sm); }
.start-card .meta,
.shortcut-card .meta{ margin-top:auto; padding-top:var(--sp-2); color:var(--c-text-soft); font-size:var(--fs-xs); }
.start-card.is-soon, .start-card.soon,
.shortcut-card.is-soon, .shortcut-card.soon{ opacity:.55; cursor:default; }
.start-card.is-soon:hover, .start-card.soon:hover,
.shortcut-card.is-soon:hover, .shortcut-card.soon:hover{ border-color:var(--c-border); box-shadow:none; transform:none; }
/* botão de desafixar no card de relatório fixado (repFixadosCards -> start do módulo); aparece no hover */
.start-card.rel-fixado .rel-unpin{
  position:absolute; top:8px; right:8px; width:28px; height:28px; padding:0;
  border:0; border-radius:50%; background:transparent; color:var(--c-text-soft);
  display:none; align-items:center; justify-content:center; font-size:12px; cursor:pointer;
  transition:background var(--transition), color var(--transition);
}
.start-card.rel-fixado:hover .rel-unpin{ display:flex; }
.start-card.rel-fixado .rel-unpin:hover{ background:var(--c-surface-2); color:var(--c-danger); }
@media (max-width:680px){ .start-card.rel-fixado .rel-unpin{ display:none; } }   /* no toque, gerencia na lista */

/* KPI (dashboards): ícone semântico + label + valor. Use .ico-badge p/ o ícone.
   Hover de realce opcional: defina --kc no card (ex.: .meu-kpi{--kc:#27ae60}) p/ a cor da borda;
   sem --kc, cai na cor da marca. Aceita rótulo/valor como .kpi-label/.kpi-value OU .lbl/.val. */
.kpi-card{
  display:flex; align-items:center; gap:var(--sp-3);
  background:var(--c-surface); border:1px solid var(--c-border); border-radius:var(--r-lg); padding:var(--sp-4) var(--sp-5);
  transition:border-color var(--transition);
}
.kpi-card:hover{ border-color:color-mix(in srgb, var(--kc, var(--corAtiva)) 45%, var(--c-border)); }
.kpi-card .kpi-info{ min-width:0; }
.kpi-card .kpi-label{ color:var(--c-text-muted); font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:.04em; font-weight:var(--fw-semibold); }
.kpi-card .kpi-value{ font-size:var(--fs-2xl); font-weight:var(--fw-bold); color:var(--c-text); line-height:1.15; font-variant-numeric:tabular-nums; }
.kpi-card .kpi-sub{ color:var(--c-text-soft); font-size:var(--fs-xs); margin-top:2px; }

/* ==========================================================================
   7. BADGES / TAGS
   ========================================================================== */
.badge,.tag{
  display:inline-flex; align-items:center; gap:4px;
  font-size:var(--fs-xs); font-weight:var(--fw-semibold); line-height:1;
  padding:4px 9px; border-radius:var(--r-pill);
  background:var(--c-surface-2); color:var(--c-text-muted); border:1px solid var(--c-border);
}
.badge-accent{ background:var(--c-accent-soft); color:var(--corAtiva); border-color:transparent; }
.badge-success{ background:var(--c-success-bg); color:var(--c-success); border-color:transparent; }
.badge-info{ background:var(--c-info-bg); color:var(--c-info); border-color:transparent; }
.badge-warning{ background:var(--c-warning-bg); color:var(--c-warning); border-color:transparent; }
.badge-danger{ background:var(--c-danger-bg); color:var(--c-danger); border-color:transparent; }
.badge-dot::before{ content:""; width:6px; height:6px; border-radius:50%; background:currentColor; }
/* Etiqueta "Exportado" — registro (frota) já lançado no financeiro. Discreta, inline na célula. */
.badge-imp{ display:inline-flex; align-items:center; gap:3px; font-size:10px; font-weight:var(--fw-semibold); line-height:1;
  color:var(--c-success); background:var(--c-success-bg); padding:2px 7px; border-radius:var(--r-pill); vertical-align:middle; margin-left:6px; }
/* Selo "Plus" — recurso pago (ex.: FIPE histórico/curva). Cor da marca, discreto. */
.plus-badge{ display:inline-flex; align-items:center; line-height:1; font-size:10px; font-weight:var(--fw-bold); letter-spacing:.06em; color:#fff; background:var(--corAtiva); padding:3px 7px; border-radius:var(--r-pill); vertical-align:middle; }

/* ==========================================================================
   8. ALERTS
   ========================================================================== */
.alert{
  display:flex; gap:var(--sp-3); align-items:flex-start;
  padding:var(--sp-3) var(--sp-4);
  border:1px solid transparent; border-left-width:3px;
  border-radius:var(--r-sm);
  font-size:var(--fs-md); margin-bottom:var(--sp-4);
}
.alert-title{ font-weight:var(--fw-semibold); margin:0 0 2px; }
.alert .alert-close{ margin-left:auto; cursor:pointer; opacity:.6; background:none; border:0; font-size:16px; line-height:1; color:inherit; }
.alert-success{ background:var(--c-success-bg); border-color:var(--c-success); color:#155d33; }
.alert-info{    background:var(--c-info-bg);    border-color:var(--c-info);    color:#1d4ed8; }
.alert-warning{ background:var(--c-warning-bg); border-color:var(--c-warning); color:#92600f; }
.alert-danger{  background:var(--c-danger-bg);  border-color:var(--c-danger);  color:#a11d24; }

/* ==========================================================================
   8.1 AVISO DE RECURSO (upsell / configurar) — barra única, ver core/upsell.php
   ========================================================================== */
.upsell-note{
  display:flex; align-items:center; flex-wrap:wrap; gap:8px 10px;
  border:1px solid transparent; border-radius:var(--r-md);
  padding:10px 12px; margin:0 0 12px;
  font-size:var(--fs-sm); line-height:1.35;
  /* informativo (configurar / pedir) = âmbar */
  background:var(--c-warning-bg); border-color:color-mix(in srgb, var(--c-warning) 35%, transparent); color:#92600f;
}
.upsell-note i{ flex:0 0 auto; font-size:15px; }
.upsell-note .un-txt{ flex:1 1 auto; min-width:140px; }
.upsell-note .un-cta{ flex:0 0 auto; font-weight:var(--fw-semibold); color:var(--c-accent); text-decoration:none; }
.upsell-note .un-cta:hover{ text-decoration:underline; }
/* comercial (contratar / sem saldo) = momento de marca (roxo), com CTA pill */
.upsell-note.is-sell{ background:var(--c-accent-soft); border-color:color-mix(in srgb, var(--corAtiva) 30%, transparent); color:var(--c-brand-dark); }
.upsell-note.is-sell > i{ color:var(--c-accent); }   /* só o ícone da esquerda; o do CTA herda o branco do pill */
.upsell-note.is-sell .un-cta{
  display:inline-flex; align-items:center; gap:6px;
  background:var(--corAtiva); color:#fff; padding:6px 12px; border-radius:var(--r-pill);
}
.upsell-note.is-sell .un-cta:hover{ text-decoration:none; filter:brightness(.97); }

/* ==========================================================================
   9. BREADCRUMBS
   ========================================================================== */
.breadcrumb{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; font-size:var(--fs-sm); color:var(--c-text-muted); margin:0 0 var(--sp-4); padding:0; list-style:none; }
.breadcrumb li{ display:flex; align-items:center; gap:6px; }
.breadcrumb li+li::before{ content:"/"; color:var(--c-text-soft); }
.breadcrumb a{ color:var(--c-text-muted); }
.breadcrumb a:hover{ color:var(--c-accent); }
.breadcrumb .active{ color:var(--c-text); font-weight:var(--fw-medium); }

/* ==========================================================================
   10. TABELAS (+ harmonização com DataTables Bootstrap)
   ========================================================================== */
.table,table.ds-table{ width:100%; border-collapse:collapse; font-size:var(--fs-md); background:var(--c-surface); }
.table th,.table td{ padding:10px 14px; text-align:left; border-bottom:1px solid var(--c-border); vertical-align:middle; }
.table thead th{
  font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:#fff;
  text-transform:uppercase; letter-spacing:.03em;
  background:var(--c-text-muted); border-bottom:0;
  white-space:nowrap;
}
.table tbody tr{ transition:background var(--transition); }
.table tbody tr:hover{ background:color-mix(in srgb, var(--corAtiva) 5%, var(--c-surface)); }
.table.table-striped tbody tr:nth-child(odd){ background:color-mix(in srgb, var(--c-text) 6%, var(--c-surface)); }
.table.table-striped tbody tr:nth-child(odd):hover{ background:color-mix(in srgb, var(--corAtiva) 7%, var(--c-surface)); }
.table.table-bordered,.table.table-bordered th,.table.table-bordered td{ border:1px solid var(--c-border); }
.table-wrap{ overflow-x:auto; border:1px solid var(--c-border); border-radius:var(--r-lg); }
.table-wrap .table th:first-child,.table-wrap .table td:first-child{ padding-left:var(--sp-5); }

/* DataTables (Bootstrap) — alinhar ao tema do painel */
.dataTables_wrapper{ font-size:var(--fs-md); color:var(--c-text); }
.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select{
  border:1px solid var(--c-border-strong); border-radius:var(--r-sm);
  padding:6px 10px; font-family:inherit; color:var(--cor_form); background:var(--c-surface);
}
.dataTables_wrapper .dataTables_filter input:focus,
.dataTables_wrapper .dataTables_length select:focus{ outline:none; border-color:var(--corAtiva); box-shadow:var(--sh-focus); }
.dataTables_wrapper .dataTables_info,
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_filter{ color:var(--c-text-muted); padding:var(--sp-3) 0; }
.dataTables_wrapper .dataTables_paginate .paginate_button{
  border-radius:var(--r-sm) !important; border:1px solid var(--c-border) !important;
  padding:5px 11px !important; margin:0 2px; color:var(--c-text-muted) !important; background:var(--c-surface) !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button.current,
.dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{
  background:var(--corAtiva) !important; border-color:var(--corAtiva) !important; color:#fff !important;
}
.dataTables_wrapper .dataTables_paginate .paginate_button:hover{
  background:var(--c-accent-soft) !important; border-color:var(--c-accent-soft) !important; color:var(--corAtiva) !important;
}
table.dataTable thead th{ border-bottom:1px solid var(--c-border-strong) !important; }
table.dataTable.no-footer{ border-bottom:1px solid var(--c-border) !important; }

/* ==========================================================================
   10.1 LISTAGEM (padrão dos módulos): cabeçalho + busca + tabela .tbl + pager.
   Centraliza o que estava repetido em cada list.php. A tela só define colunas
   e dados; o visual vem daqui. Marcação: .list-wrap > .list-head (+.list-search)
   + table.tbl.cards-mobile + .pager.
   ========================================================================== */
/* container: SEM padding lateral (barra/tabela ocupam full-width); respiro no fim */
.list-wrap{ padding:0 0 calc(48px + env(safe-area-inset-bottom,0px)); }
/* FAIXA DE AVISO no topo da listagem: de canto a canto, SEM borda nem raio (texto com respiro de 24px).
   Variantes: padrão = âmbar (aviso); .is-info (azul); .is-danger (vermelho). */
.list-wrap .list-note{ display:flex; align-items:center; gap:9px; padding:12px 24px; margin:0; font-size:var(--fs-sm);
  background:#fff7e6; color:#8a6d3b; }
.list-wrap .list-note.is-info{   background:var(--c-info-bg);   color:var(--c-info); }
.list-wrap .list-note.is-danger{ background:var(--c-danger-bg); color:var(--c-danger); }
/* cabeçalho = BARRA integrada no topo: full-width, linha embaixo, FIXA ao rolar, tudo numa fileira */
.list-head{ display:flex; align-items:center; gap:10px; padding:11px 24px; margin:0; flex-wrap:wrap;
  background:var(--c-bg); border-bottom:1px solid var(--c-border); position:sticky; top:0; z-index:5; }
.list-head h1{ margin:0; font-size:var(--fs-xl); line-height:1.2; }
.list-head .count{ color:var(--c-text-muted); font-size:var(--fs-xs); }
.list-head .spacer{ flex:1; }
.list-head .btn{ height:38px; }
/* busca GRANDE: ocupa a barra (sem caixa nem botão) e empurra as ações p/ a direita */
.list-search{ flex:1; display:flex; align-items:center; gap:8px; min-width:0; }
.list-q{ flex:1; width:100%; min-width:0; height:38px; border:0; background:transparent; outline:none; font-size:var(--fs-xl); color:var(--c-text); padding:0 2px; font-family:inherit; }
.list-q::placeholder{ color:var(--c-placeholder); }
.list-q-clear{ color:var(--c-text-soft); text-decoration:none; flex:0 0 auto; }
.list-q-clear:hover{ color:var(--c-danger); }
/* SELECT de barra/toolbar (filtro inline): pill compacto que casa com a barra.
   Use no lugar de .form-control (que é underline full-width, p/ formulário) quando o
   <select> vive numa .list-head / barra de filtros. */
.bar-select{ flex:0 0 auto; width:auto; height:38px; border:1px solid var(--c-border); border-radius:var(--r-pill);
  background:var(--c-surface); color:var(--c-text-muted); font-family:inherit; font-size:var(--fs-sm); font-weight:var(--fw-semibold);
  padding:0 32px 0 14px; cursor:pointer; appearance:none; -webkit-appearance:none; transition:border-color .14s, color .14s;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 12px center; }
.bar-select:hover{ border-color:var(--c-border-strong); color:var(--c-text); }
.bar-select:focus{ outline:none; border-color:var(--corAtiva); }
/* FILTRO EM ABAS-LINK (.flt-tabs): substitui o <select onchange="location.href=…"> nos filtros de
   listagem — dentro do iframe do shell, a navegação por SCRIPT do <select> não recarrega a lista;
   link real (clique do usuário) sempre navega. Também é mais visível (as opções ficam à mostra). */
.flt-tabs{ display:inline-flex; flex:0 0 auto; gap:2px; padding:3px; border:1px solid var(--c-border);
  border-radius:var(--r-pill); background:var(--c-surface-2, #eef0f4); max-width:100%; overflow-x:auto; }
.flt-tab{ display:inline-flex; align-items:center; white-space:nowrap; padding:6px 14px; border-radius:var(--r-pill);
  font-size:var(--fs-sm); font-weight:var(--fw-medium); color:var(--c-text-muted); text-decoration:none; transition:background .12s, color .12s; }
.flt-tab:hover{ color:var(--c-text); }
.flt-tab.on{ background:var(--c-bg); color:var(--c-text); font-weight:var(--fw-semibold); box-shadow:0 1px 2px rgba(20,20,40,.08); }

/* LISTA minimalista (Nubank): SEM caixa/sombra/cantos; tudo branco; cabeçalho claro;
   registros separados só por uma DIVISÓRIA FINA; hover sutil. */
/* separate (não collapse): o sticky do thead é confiável e bordas/shadow renderizam */
table.tbl{ width:100%; border-collapse:separate; border-spacing:0; background:transparent; }
/* linha de títulos clara e FIXA (gruda logo abaixo da barra de ~60px) */
table.tbl th{ background:var(--c-bg); color:var(--c-text-muted); text-align:left; font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:.5px; padding:10px 14px; border-bottom:1px solid var(--c-border-strong); white-space:nowrap; position:sticky; top:60px; z-index:4; }
table.tbl td{ padding:14px; border-bottom:1px solid var(--c-border); font-size:var(--fs-md); }
table.tbl tr:last-child td{ border-bottom:0; }
table.tbl tbody tr{ transition:background .12s; background:transparent; }
table.tbl tbody tr:hover{ background:color-mix(in srgb, var(--c-text) 4%, transparent); }
/* encaixe full-width: 24px de respiro só nas pontas (alinha com a barra) */
table.tbl th:first-child,table.tbl td:first-child{ padding-left:24px; }
table.tbl th:last-child,table.tbl td:last-child{ padding-right:24px; }

/* ===== TABELA DE IMPRESSÃO / RELATÓRIO (.ptbl) =====
   Componente DISTINTO da lista "Nubank" (.tbl, sem caixa): a tabela de relatório é feita
   p/ ler no papel/PDF — tem CAIXA, cabeçalho claro maiúsculo e ZEBRA. Use class="ptbl" nos
   relatórios (executar/construtor). NÃO redefina o .tbl pra isso. `.small` limita a largura.
   O bloco @media print repete o cabeçalho por página, zebra suave e evita quebrar linhas. */
table.ptbl{ width:100%; border-collapse:separate; border-spacing:0; background:#fff;
  border:1px solid var(--c-border); border-radius:var(--r-lg); overflow:hidden;
  -webkit-print-color-adjust:exact; print-color-adjust:exact; }
table.ptbl th{ background:var(--c-surface-2); color:var(--c-text); text-align:left;
  font-size:var(--fs-xs); font-weight:var(--fw-bold); text-transform:uppercase; letter-spacing:.5px;
  padding:11px 13px; border-bottom:2px solid var(--c-border-strong); white-space:nowrap;
  -webkit-print-color-adjust:exact; print-color-adjust:exact; }
table.ptbl td{ padding:10px 13px; border-bottom:1px solid var(--c-border); font-size:var(--fs-md); vertical-align:middle; }
table.ptbl tr:last-child td{ border-bottom:0; }
table.ptbl tbody tr:nth-child(even){ background:#f1f4f9; -webkit-print-color-adjust:exact; print-color-adjust:exact; }
table.ptbl td.num, table.ptbl th.num{ text-align:right; font-variant-numeric:tabular-nums; white-space:nowrap; }
table.ptbl.small{ max-width:760px; }
@media print {
  .help-dot{ display:none !important; }   /* o "?" de ajuda nunca vai pro papel */
  table.ptbl{ border:1px solid #ccc; }
  table.ptbl thead{ display:table-header-group; }   /* repete cabeçalho em CADA página impressa */
  table.ptbl th{ background:#eef1f6 !important; color:#000 !important; border-bottom:2px solid #b3bac6 !important;
    -webkit-print-color-adjust:exact; print-color-adjust:exact; }
  table.ptbl td{ border-bottom:1px solid #dde2ea !important; }
  table.ptbl tbody tr:nth-child(even){ background:#f2f5f9 !important; -webkit-print-color-adjust:exact; print-color-adjust:exact; }
  table.ptbl tr{ break-inside:avoid; page-break-inside:avoid; }
}

/* coluna ID compacta e discreta (penúltima, antes de Ações) */
.col-id{ color:var(--c-text-soft); font-variant-numeric:tabular-nums; width:1%; white-space:nowrap; }

.cell-nome{ display:flex; align-items:center; gap:10px; }
.cell-nome .avatar{ width:30px; height:30px; border-radius:50%; flex:0 0 auto; }
.cell-anx{ color:var(--c-text-soft); font-size:.85em; margin-right:5px; }            /* clipe "tem anexo" prefixando a célula */
.cell-nome .cell-anx{ flex:0 0 auto; margin:0 -3px 0 -4px; }                          /* dentro da célula de nome (flex): entre avatar e nome */

.row-actions{ white-space:nowrap; text-align:right; }
.row-actions a{ display:inline-flex; width:32px; height:32px; align-items:center; justify-content:center; border-radius:var(--r-pill); color:var(--c-text-muted); cursor:pointer; text-decoration:none; }
.row-actions a:hover{ background:var(--c-bg); color:var(--corAtiva); }
/* editar/excluir = NEUTROS (lei "cor por ênfase"): o hover cai no genérico acima
   (fundo claro + roxo), sem âmbar/vermelho. Vermelho de excluir só no confirmar. */

/* ===== ESTADO VAZIO RICO (empty-state) — ilustração "groovy" + mensagem amigável =====
   Para contextos de TELA: sem permissão, módulo ainda vazio (1ª vez), onboarding.
   Markup pelo helper PHP emptyState() (core/emptystate.php). REGRA DE OURO: a CAMISA
   do personagem é SEMPRE a cor do cliente ([id="Accent"] -> var(--corAtiva)).
   NÃO confundir com o .empty minimalista da listagem (busca/filtro sem resultado, abaixo). */
.empty-state{ display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; padding:48px 24px; }
.empty-state.is-full{ min-height:100vh; min-height:100dvh; }     /* ocupa a área toda (ex.: sem permissão) */
.empty-state-art{ width:min(340px,64vw); margin-bottom:14px; color:var(--c-text); }   /* preto do vetor (currentColor) = cor do título */
.empty-state-art svg{ width:100%; height:auto; display:block; }
/* acento na cor da marca: vetores 2-cores (#FF0000) e a "camisa" do padrão (id="Accent") */
.empty-state-art svg [fill="#FF0000" i], .empty-state-art svg [id="Accent"]{ fill:var(--corAtiva); }
.empty-state-art svg [stroke="#FF0000" i]{ stroke:var(--corAtiva); }
.empty-state-title{ margin:6px 0; font-size:var(--fs-2xl); font-weight:var(--fw-bold);
  color:var(--c-text); letter-spacing:-.01em; }
.empty-state-msg{ margin:0; max-width:440px; color:var(--c-text-muted); font-size:var(--fs-md); line-height:1.55; }
.empty-state-foot{ margin-top:22px; display:flex; gap:10px; flex-wrap:wrap; justify-content:center; }
.empty-state-note{ margin-top:16px; font-size:var(--fs-sm); color:var(--c-text-soft); }
@media (max-width:680px){ .empty-state{ padding:36px 18px; } .empty-state-art{ width:min(260px,72vw); } }
/* ACESSO RESTRITO (.empty-state.is-locked): mesmo componente, ilustração de bloqueio
   (rodízio em assets/images/bloqueio/*.svg, fallback 403.svg). Markup pelo helper
   acessoNegado() / paginaAcessoNegado() (core/emptystate.php + core/acesso.php). */

/* ESTADO VAZIO (null): minimalista — sem caixa cinza, alinhado à esquerda,
   ícone num disco suave pequeno + texto. Funciona com o markup <i class="fa ... fa-2x"></i><br><br>Texto. */
.list-wrap .empty{ padding:30px 24px; text-align:left; color:var(--c-text-soft); background:transparent; border-radius:0; font-size:var(--fs-md); line-height:1.6; }
.list-wrap .empty br{ display:none; }                       /* tira as quebras p/ ícone+texto na mesma linha */
.list-wrap .empty i{ font-size:15px; width:38px; height:38px; flex:0 0 38px; vertical-align:middle; margin-right:12px;
  display:inline-flex; align-items:center; justify-content:center; background:var(--c-surface); border-radius:50%; color:var(--c-text-muted); }
.list-wrap .empty .muted{ display:block; margin-top:6px; margin-left:50px; font-size:var(--fs-sm); }   /* sub-linha alinhada ao texto */
.list-wrap .empty .btn{ margin-left:12px; vertical-align:middle; }

.pager{ display:flex; gap:6px; align-items:center; justify-content:flex-end; margin-top:16px; flex-wrap:wrap; }
.pager a,.pager span{ min-width:34px; height:34px; display:inline-flex; align-items:center; justify-content:center; padding:0 8px; border-radius:100%; text-decoration:none; color:var(--c-text); background:var(--c-surface); border:1px solid var(--c-border); font-size:var(--fs-sm); }
.pager a:hover{ border-color:var(--corAtiva); color:var(--corAtiva); }
.pager .cur{ background:var(--corAtiva); color:#fff; border-color:var(--corAtiva); }
.pager .muted{ color:var(--c-text-soft); background:transparent; border:0; }

/* rodapé: lixeira/contagem (esq.) · paginação (dir.) — alinhado às pontas (24px) */
.list-foot{ display:flex; align-items:center; justify-content:space-between; gap:14px; margin-top:16px; padding:0 24px; flex-wrap:wrap; }
.list-foot .foot-left{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.list-foot .foot-right{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; margin-left:auto; }
.list-foot .count{ color:var(--c-text-muted); font-size:var(--fs-sm); }
.list-foot .pager{ margin:0; }
.lix-link{ display:inline-flex; align-items:center; gap:6px; color:var(--c-text-muted); font-size:var(--fs-sm); text-decoration:none; }
.lix-link:hover{ color:var(--corAtiva); }

/* ===== ORDENAÇÃO POR COLUNA (cabeçalho) =====
   O botão de ordenar só aparece ao passar o mouse no <th>; a coluna ativa o mantém
   visível (na cor da marca) indicando a direção. Some no mobile (cabeçalho vira card). */
table.tbl th.th-sortable{ padding-right:30px; }                       /* reserva espaço p/ o botão à direita */
/* o RÓTULO também ordena (clicar no nome da coluna funciona, não só na setinha) */
.th-label{ color:inherit; text-decoration:none; cursor:pointer; }
.th-label:hover{ color:var(--corAtiva); }
.th-sortbtn{ position:absolute; right:8px; top:50%; transform:translateY(-50%);
  display:inline-flex; align-items:center; justify-content:center; width:22px; height:22px;
  border-radius:var(--r-sm); color:var(--c-text-soft); background:transparent; text-decoration:none;
  opacity:0; transition:opacity .15s, color .15s, background .15s; cursor:pointer; }
.th-sortbtn i{ font-size:13px; line-height:1; }
table.tbl th.th-sortable:hover .th-sortbtn{ opacity:1; }              /* revela no hover do cabeçalho */
.th-sortbtn:hover{ color:var(--corAtiva); background:color-mix(in srgb, var(--corAtiva) 12%, transparent); }
.th-sortbtn.is-active{ opacity:1; color:var(--corAtiva); }           /* coluna ordenada: fixo na marca */
table.tbl th.th-sortable.is-sorted{ color:var(--corAtiva); }         /* rótulo da coluna ativa também tinge */

/* SCROLL INFINITO (modo ordenado): sentinel + linha de carregamento */
.list-sentinel{ height:1px; }
.list-loading{ display:flex; align-items:center; justify-content:center; gap:8px;
  padding:18px 24px; color:var(--c-text-muted); font-size:var(--fs-sm); }
.list-loading i{ animation:list-spin .8s linear infinite; }
.list-loading[hidden]{ display:none; }
@keyframes list-spin{ to{ transform:rotate(360deg); } }

/* dropdown do botão "Novo" (multi-tipo) */
.novo-wrap{ position:relative; }
.novo-menu{ position:absolute; right:0; top:calc(100% + 4px); background:var(--c-surface); border:1px solid var(--c-border); border-radius:8px; box-shadow:var(--sh-lg); min-width:210px; z-index:60; display:none; overflow:hidden; }
.novo-menu.open{ display:block; }
.novo-menu a{ display:flex; align-items:center; gap:10px; padding:11px 14px; cursor:pointer; color:var(--c-text); font-size:var(--fs-sm); }
.novo-menu a:hover{ background:var(--c-bg); color:var(--corAtiva); }

/* ORDENAR no MOBILE: o botão de ordenar por coluna só existe no celular (no desktop a
   ordenação vem do hover no cabeçalho). Abre um menu com as colunas ordenáveis. */
.sort-wrap{ position:relative; display:none; }                       /* desktop: oculto (usa o hover do <th>) */
.sort-menu{ position:absolute; right:0; top:calc(100% + 4px); background:var(--c-surface); border:1px solid var(--c-border); border-radius:10px; box-shadow:var(--sh-lg); min-width:230px; max-width:80vw; z-index:60; display:none; overflow:hidden; padding:4px 0; }
.sort-menu.open{ display:block; }
.sort-menu-tit{ padding:8px 14px 6px; font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:.5px; color:var(--c-text-soft); }
.sort-opt{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding:12px 14px; cursor:pointer; color:var(--c-text); font-size:var(--fs-sm); text-decoration:none; }
.sort-opt:hover{ background:var(--c-bg); }
.sort-opt.is-active{ color:var(--corAtiva); font-weight:var(--fw-semibold); }
.sort-clear{ display:flex; align-items:center; gap:8px; padding:11px 14px; margin-top:4px; border-top:1px solid var(--c-border); color:var(--c-text-muted); font-size:var(--fs-sm); text-decoration:none; cursor:pointer; }
.sort-clear:hover{ color:var(--corAtiva); }
@media (max-width:680px){
  .sort-wrap{ display:inline-flex; }                              /* o botão aparece só no celular */
  /* menu vira BANDEJA INFERIOR: sempre na tela (não importa onde o botão fique) e bom p/ o toque */
  .sort-menu{ position:fixed; left:10px; right:10px; bottom:10px; top:auto;
    min-width:0; max-width:none; max-height:72vh; overflow:auto; border-radius:16px; padding:6px 0 8px; }
  .sort-menu.open{ animation:sortSheetUp .18s cubic-bezier(.16,1,.3,1); }
  .sort-menu-tit{ padding:12px 18px 8px; font-size:var(--fs-sm); }
  .sort-opt, .sort-clear{ padding:15px 18px; font-size:var(--fs-md); }   /* alvos de toque maiores */
}
@keyframes sortSheetUp{ from{ transform:translateY(14px); opacity:0; } to{ transform:translateY(0); opacity:1; } }
/* backdrop da bandeja de ordenar (só no mobile, criado pelo list-sort.js) */
.sort-backdrop{ position:fixed; inset:0; z-index:59; background:rgba(15,18,28,.22); animation:sortBdIn .18s ease; }
@keyframes sortBdIn{ from{ opacity:0; } to{ opacity:1; } }

/* SELEÇÃO EM LOTE: a lixeira do registro vira o checkbox; marcar-todos + contador na barra.
   Ative com a classe .sel-mode no .list-wrap. */
.row-actions .row-sel{ display:none; width:18px; height:18px; cursor:pointer; accent-color:var(--corAtiva); vertical-align:middle; margin:0 6px; }
.sel-mode .row-actions .del{ display:none; }
.sel-mode .row-actions .row-sel{ display:inline-block; }
/* lixeira: checkbox sempre visível, SEM esconder as ações por linha (restaurar/eliminar) */
.trash-mode .row-actions .row-sel{ display:inline-block; }
.lote-all{ display:none; }                                  /* marcar-todos (na barra) */
.sel-mode .lote-all{ display:inline-flex; align-items:center; justify-content:center; }
.lote-all input{ margin:0; width:18px; height:18px; accent-color:var(--corAtiva); cursor:pointer; }
.sel-mode .lote-hide{ display:none; }                       /* filtro/novo somem no modo lote */
tr.row-on{ background:color-mix(in srgb, var(--corAtiva) 9%, var(--c-surface)) !important; }
.btn-icon.btn-delete .badge{ background:#fff; color:var(--c-danger); border:0; }   /* contador do "excluir vários" */

/* no celular o avatar do nome vai p/ a direita (combina com table.cards-mobile) */
@media (max-width:680px){
  .list-wrap .cell-nome{ width:100%; }
  .list-wrap .cell-nome .avatar{ order:2; margin-left:auto; }
  .cell-nome .avatar{ width:44px; height:44px; }   /* avatar um pouco maior no celular (toque/legibilidade) */
  /* botões só-ícone = alvo de toque 44px (.list-head .btn-icon vence o .list-head .btn{height:38px}) */
  .btn-icon{ width:44px; height:44px; }
  .list-head .btn-icon{ width:44px; height:44px; }
  .list-head{ gap:8px; padding:11px 18px; }
  .list-q{ font-size:var(--fs-md); }
  /* no card mobile a tabela não tem o respiro lateral de 24px (o card já tem o seu) */
  table.tbl th:first-child,table.tbl td:first-child{ padding-left:0; }
  table.tbl th:last-child,table.tbl td:last-child{ padding-right:0; }
  /* respiro maior no fim da página no celular (depois da paginação) */
  .list-wrap{ padding-bottom:calc(80px + env(safe-area-inset-bottom,0px)); }
}

/* ==========================================================================
   11. LAYOUT DO PAINEL: sidebar + topbar + conteúdo
   - Cores do menu vêm de --fundoMenu/--corTxtMenu/--corMarcadoresSubmenu/--corSubmenuA.
   ========================================================================== */
.app{ display:flex; min-height:100vh; min-height:100dvh; }   /* dvh: respeita as barras do navegador no mobile (não corta o fim) */

/* ---- Sidebar ---- */
.app-sidebar{
  width:var(--sidebar-w); flex:0 0 var(--sidebar-w);
  background:var(--c-brand-dark); color:var(--corTxtMenu);
  display:flex; flex-direction:column;
  position:sticky; top:0; height:100vh; height:100dvh; overflow-y:auto;
  transition:width var(--transition), flex-basis var(--transition);
  scrollbar-width:thin; scrollbar-color:transparent transparent;   /* Firefox: some até o hover */
}
/* conteúdo do menu (a "luz" que acompanhava o item ativo foi removida) */
.app-sidebar > .sidebar-brand,
.app-sidebar > .sidebar-nav{ position:relative; z-index:1; }
.app-sidebar:hover{ scrollbar-color:rgba(255,255,255,.30) transparent; }
.app-sidebar::-webkit-scrollbar{ width:6px; }
.app-sidebar::-webkit-scrollbar-track{ background:transparent; }            /* sem a faixa branca */
.app-sidebar::-webkit-scrollbar-thumb{ background:transparent; border-radius:8px; border:2px solid transparent; background-clip:padding-box; }
.app-sidebar:hover::-webkit-scrollbar-thumb{ background:rgba(255,255,255,.22); background-clip:padding-box; }
.app-sidebar::-webkit-scrollbar-thumb:hover{ background:rgba(255,255,255,.36); background-clip:padding-box; }

.sidebar-brand{
  display:flex; align-items:center; gap:var(--sp-3);
  height:var(--topbar-h); flex:0 0 var(--topbar-h);
  padding:0 var(--sp-5);
  border-bottom:1px solid rgba(255,255,255,.12);
}
.sidebar-brand .brand-logo{
  width:30px; height:30px; flex:0 0 30px; border-radius:var(--r-sm);
  background:var(--logo-marca) center/contain no-repeat, rgba(255,255,255,.15);
}
.sidebar-brand .brand-name{ font-weight:var(--fw-semibold); font-size:var(--fs-lg); color:var(--corTxtMenu); white-space:nowrap; }

.sidebar-nav{ padding:var(--sp-3) var(--sp-2); flex:1 1 auto; }
.sidebar-section{ padding:var(--sp-4) var(--sp-3) var(--sp-1); font-size:var(--fs-xs); text-transform:uppercase; letter-spacing:.06em; color:color-mix(in srgb, var(--corTxtMenu) 55%, transparent); }

.nav-item{
  display:flex; align-items:center; gap:var(--sp-3);
  padding:9px var(--sp-3); margin:1px 0;
  font-size:var(--fontSizeMenu); color:var(--corTxtMenu);
  cursor:pointer;
  border-left:3px solid transparent;
  transition:background var(--transition), color var(--transition);
}
/* ícone do menu = NEUTRO (cor do texto do menu, sem tinta de marca); item ativo fica pleno */
.nav-item .nav-ico{ width:18px; flex:0 0 18px; text-align:center; color:var(--corTxtMenu); opacity:.72; display:flex; justify-content:center; transition:width .18s ease; }
.nav-item .nav-ico .fa{ transition:font-size .18s ease; }   /* cresce/encolhe suave ao minimizar/restaurar a barra */
.nav-item .nav-label{ flex:1 1 auto; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.nav-item .nav-caret{ transition:transform var(--transition); opacity:.7; }
.nav-item:hover{ background:rgb(255 255 255 / 5%); border-radius:999px; }
/* o destaque do item ativo agora é a LUZ que o acompanha (.app-sidebar::before) */
.nav-item.active .nav-ico{ color:var(--corTxtMenu); opacity:1; }
.nav-item.open .nav-caret{ transform:rotate(90deg); }

/* Submenu */
.nav-submenu{ list-style:none; margin:0; padding:2px 0 2px 0; max-height:0; overflow:hidden; transition:max-height var(--transition); }
.nav-item.open + .nav-submenu{ max-height:600px; }
.nav-submenu a{
  display:flex; align-items:center; gap:var(--sp-2);
  padding:7px var(--sp-3) 7px 38px;
  font-size:var(--fontSizeSubmenu);
  color:color-mix(in srgb, var(--corTxtMenu) 80%, transparent);
  border-radius:var(--r-sm);
}
.nav-submenu a::before{ content:""; width:5px; height:5px; border-radius:50%; background:var(--corMarcadoresSubmenu); flex:0 0 5px; }
.nav-submenu a:hover{ background:rgba(255,255,255,.08); color:var(--corTxtMenu); }
.nav-submenu a.active{ color:var(--corSubmenuA); font-weight:var(--fw-medium); }

/* Colapsado (somente desktop — no mobile o controle é o bloco @media abaixo) */
@media (min-width:861px){
  .app.sidebar-collapsed .app-sidebar{ width:var(--sidebar-w-collapsed); flex-basis:var(--sidebar-w-collapsed); }
  .app.sidebar-collapsed .brand-name,
  .app.sidebar-collapsed .nav-label,
  .app.sidebar-collapsed .nav-caret,
  .app.sidebar-collapsed .sidebar-section,
  .app.sidebar-collapsed .nav-submenu,
  .app.sidebar-collapsed .nav-soon{ display:none; }
  .app.sidebar-collapsed .nav-item{ justify-content:center; }
  .app.sidebar-collapsed .sidebar-brand{ padding:0; justify-content:center; }
  /* barra minimizada (só ícones): os ícones do menu CRESCEM (1.1em → 1.4em); ao restaurar, voltam ao 1.1em */
  .app.sidebar-collapsed .nav-item .nav-ico{ width:auto; flex:0 0 auto; }
  .app.sidebar-collapsed .nav-item .nav-ico .fa{ font-size:1.4em; }
}

/* ---- Área principal (topbar + conteúdo) ---- */
.app-main{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; }

.app-topbar{
  height:var(--topbar-h); flex:0 0 var(--topbar-h);
  display:flex; align-items:center; gap:var(--sp-4);
  padding:0 var(--sp-5);
  background:var(--c-surface);
  border-bottom:1px solid var(--c-border);
  box-shadow:var(--sh-xs);
  position:sticky; top:0; z-index:20;
}
.topbar-toggle{
  display:none;   /* desktop: sidebar fixa, sem hambúrguer. Volta no mobile (@media 860). */
  align-items:center; justify-content:center;
  width:44px; height:44px; margin-left:-6px;   /* alvo de toque ≥44px (padrão mobile do DS) */
  border-radius:var(--r-md); border:1px solid transparent;
  background:transparent; color:var(--c-text-muted); cursor:pointer;
  font-size:1.7rem;   /* glifo bem maior — fácil de acertar no dedo */
}
.topbar-toggle i{ line-height:1; }
.topbar-toggle:hover{ background:var(--c-surface-2); }
/* título da página: agora é o título PRINCIPAL (grande) — o cabeçalho interno das telas de módulo morre */
.topbar-title{ font-size:var(--fs-3xl); font-weight:var(--fw-bold); letter-spacing:-.02em; color:var(--c-text); line-height:1.1; margin-left:5px; }
.topbar-spacer{ flex:1 1 auto; }
.topbar-actions{ display:flex; align-items:center; gap:var(--sp-1); }   /* gap enxuto entre sinos/avatar */
.topbar-icon-btn{ position:relative; width:38px; height:38px; border-radius:50%; border:0; background:transparent; color:var(--c-text-muted); cursor:pointer; display:inline-flex; align-items:center; justify-content:center; }
.topbar-icon-btn:hover{ background:var(--c-surface-2); }
.topbar-icon-btn .dot{ position:absolute; top:8px; right:9px; width:7px; height:7px; border-radius:50%; background:var(--corAtiva); border:2px solid var(--c-surface); }

.topbar-user{ display:flex; align-items:center; gap:var(--sp-2); padding:4px 18px 4px 0px; border-radius:var(--r-pill); cursor:pointer; }
.topbar-user:hover{ background:var(--c-surface-2); }
.topbar-user .avatar{ width:32px; height:32px; border-radius:50%; flex:0 0 auto; }
.topbar-user .avatar img{ width:100%; height:100%; border-radius:50%; object-fit:cover; display:block; }
.topbar-user .u-name{ font-size:var(--fs-md); font-weight:var(--fw-medium); }
.topbar-user .u-role{ font-size:var(--fs-xs); color:var(--c-text-muted); }

.app-content{ flex:1 1 auto; padding:var(--sp-6); min-width:0; }
.content-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:var(--sp-4); flex-wrap:wrap; margin-bottom:var(--sp-5); }
.content-head .page-title{ margin:0; }
.content-head .page-subtitle{ color:var(--c-text-muted); font-size:var(--fs-md); margin:4px 0 0; }
/* MINIMALISMO: o título da página vive na topbar (grande). Nas telas de MÓDULO
   (qualquer .start-wrap) o cabeçalho interno some: title/subtitle escondidos; se
   o content-head tiver AÇÕES (botões/links), elas permanecem. O HOME usa
   .app-content (não .start-wrap), então mantém o seu content-head intacto. */
.start-wrap > .content-head .page-title,
.start-wrap > .content-head .page-subtitle{ display:none; }
.start-wrap > .content-head:not(:has(.btn)):not(:has(a)){ display:none; margin:0; }

/* Grid utilitário p/ dashboards */
.grid{ display:grid; gap:var(--sp-4); }
.grid-2{ grid-template-columns:repeat(2,1fr); }
.grid-3{ grid-template-columns:repeat(3,1fr); }
.grid-4{ grid-template-columns:repeat(4,1fr); }

/* ==========================================================================
   12. LOGIN
   - Harmoniza com login/index.php. Usa --fundoMenu/--cor_text_login do tenant.
   ========================================================================== */
.login-screen{
  min-height:100vh; min-height:100dvh; display:flex; align-items:center; justify-content:center;
  padding:var(--sp-5);
  background:
    radial-gradient(1200px 600px at 0% 0%, color-mix(in srgb, var(--fundoMenu) 22%, transparent), transparent 60%),
    radial-gradient(1000px 500px at 100% 100%, color-mix(in srgb, var(--corAtiva) 16%, transparent), transparent 55%),
    var(--c-bg);
}
.login-card{
  width:100%; max-width:380px;
  background:var(--c-surface);
  border:1px solid var(--c-border);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-lg);
  padding:var(--sp-8) var(--sp-7);
}
.login-brand{ display:flex; flex-direction:column; align-items:center; gap:var(--sp-3); margin-bottom:var(--sp-6); }
.login-brand .login-logo{
  width:160px; height:54px;
  background:var(--logo-login) center/contain no-repeat;
}
.login-brand .login-logo.is-empty{ background:none; }
.login-card h2{ text-align:center; margin:0 0 4px; }
.login-card .login-sub{ text-align:center; color:var(--c-text-muted); font-size:var(--fs-md); margin-bottom:var(--sp-6); }
.login-card .btn-block{ margin-top:var(--sp-5); }
/* botão de entrar usa o accent da marca */
.login-card .btn-login{ --_c:#fff; --_bg:var(--corAtiva); --_bd:var(--corAtiva); }
.login-foot{ text-align:center; margin-top:var(--sp-5); font-size:var(--fs-xs); color:var(--c-text-soft); }

/* ==========================================================================
   13. RESPONSIVO (desktop-first)
   ========================================================================== */
@media (max-width:1100px){
  .grid-4{ grid-template-columns:repeat(2,1fr); }
  .grid-3{ grid-template-columns:repeat(2,1fr); }
}
@media (max-width:860px){
  :root{ --topbar-h:54px; }
  .topbar-toggle{ display:inline-flex; }   /* hambúrguer abre o menu (off-canvas) no mobile */
  .topbar-title{ font-size:var(--fs-xl); }  /* título grande, porém cabendo com avatar */
  /* sidebar off-canvas: escondida; o hambúrguer abre o menu completo (248px) */
  .app-sidebar{
    position:fixed; left:0; top:0; bottom:0; z-index:60;
    width:var(--sidebar-w); flex-basis:var(--sidebar-w);
    transform:translateX(-100%); box-shadow:var(--sh-lg);
    transition:transform var(--transition);
  }
  .app.sidebar-open .app-sidebar{ transform:translateX(0); }
  .app-backdrop{ display:none; position:fixed; inset:0; background:rgba(16,24,40,.45); z-index:50; }
  .app.sidebar-open .app-backdrop{ display:block; }
  .app-content{ padding:var(--sp-4); }
  /* cards de atalho: 2 por linha no celular. GRÁFICOS ficam 1/linha via grid local;
     KPIs também ficam 1/linha (valores grandes não cabem em 2 colunas estreitas) — por isso
     .kpi-grid fica FORA deste override e segue o auto-fit local da tela. */
  /* !important: as telas "start" definem .start-grid local (auto-fill) que sobreporia */
  .grid-2,.grid-3,.grid-4,.start-grid{ grid-template-columns:1fr 1fr !important; }
  .form-row > .form-group{ flex-basis:100%; }
  /* tabelas não espremem: rolam lateralmente (baseline antes do modo cards) */
  .table-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  /* alvos de toque confortáveis */
  .btn{ min-height:42px; } .btn-sm{ min-height:38px; }
  /* topbar: só foto + setinha (sem o nome) */
  .topbar-user .u-name, .topbar-user .u-role{ display:none; }
  .topbar-user{ padding:4px; gap:6px; }
  /* cabeçalho de página/form mais compacto no celular */
  .content-head .page-title{ font-size:var(--fs-2xl); }
  .content-head .page-subtitle{ font-size:var(--fs-sm); }
}
/* celular (telefone): título da topbar menor p/ caber melhor ao lado dos sinos + avatar.
   DEPOIS do bloco ≤860 (que põe --fs-xl) p/ vencer por ordem de cascata em viewports ≤680. */
@media (max-width:680px){
  .topbar-title{ font-size:var(--fs-lg); }
}

/* ---- Tabela em CARDS no celular ----------------------------------------
   Cada linha vira um cartão com "RÓTULO | valor" (2 colunas). Requer a classe
   .cards-mobile na <table> e data-label="<Coluna>" em cada <td>. Use nas LISTAGENS. */
@media (max-width:680px){
  /* a TABELA fica transparente: o vão entre os cards mostra o fundo da página
     (não branco), destacando cada cartão. */
  table.cards-mobile{ background:transparent; box-shadow:none; border-radius:0; overflow:visible; }
  table.cards-mobile thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
  /* no celular o gradiente da linha não vale: cada card é uma superfície branca limpa */
  table.cards-mobile tbody tr{ display:block; border:1px solid var(--c-border); padding:var(--sp-3) var(--sp-4); }
  /* rótulo do tamanho do texto (piso 56px p/ alinhar os curtos) colado ao valor —
     sem vão no meio; rótulos longos (NOME FANTASIA) expandem sem quebrar. */
  table.cards-mobile tbody td{ display:grid; grid-template-columns:minmax(56px,auto) minmax(0,1fr); gap:12px; align-items:center; border:0 !important; padding:7px 0; text-align:left; white-space:nowrap; overflow:hidden; }
  table.cards-mobile tbody td::before{ content:attr(data-label); font-weight:var(--fw-semibold); color:var(--c-text-muted); text-transform:uppercase; font-size:var(--fs-xs); letter-spacing:.03em; line-height:1.5; white-space:nowrap; }
  /* valor longo NÃO quebra linha no card: trunca com reticências */
  /* NENHUM filho estica na célula-grid do card: chips (badge/tag e qualquer *-badge custom,
     ex.: .fipe-badge) ficam COMPACTOS à esquerda; valor/texto longo segue truncando
     (justify-self:start = tamanho do conteúdo; max-width:100% + ellipsis = trunca se exceder). */
  table.cards-mobile tbody td > *{ min-width:0; max-width:100%; justify-self:start; overflow:hidden; text-overflow:ellipsis; }
  table.cards-mobile .cell-nome{ min-width:0; }
  table.cards-mobile .cell-nome span{ overflow:hidden; text-overflow:ellipsis; min-width:0; }
  /* coluna ID: no card volta à largura normal (o width:1% é só p/ a tabela no desktop) */
  table.cards-mobile tbody td.col-id{ width:auto; }
  table.cards-mobile tbody td:empty{ display:none; }
  /* ações: label + ícones na MESMA linha (flex evita o 2º ícone cair p/ baixo no grid).
     No celular os alvos ficam MAIORES e com o fundo da própria cor (editar=âmbar,
     excluir=vermelho) + mais espaço entre eles — p/ o dedo não errar e clicar em excluir. */
  /* celular: a barra de ações fica OCULTA; aparece só na linha TOCADA (.is-row-active, via list-rows.js) */
  table.cards-mobile tbody td.row-actions{ display:none; align-items:center; gap:14px; }
  table.cards-mobile tbody tr.is-row-active td.row-actions{ display:flex; }
  /* em seleção/lixeira a barra fica sempre visível (o checkbox .row-sel vive aqui dentro) */
  .sel-mode table.cards-mobile tbody td.row-actions,
  .trash-mode table.cards-mobile tbody td.row-actions{ display:flex; }
  table.cards-mobile tbody td.row-actions::before{ flex:0 0 56px; }
  table.cards-mobile tbody td.row-actions a{ width:44px; height:44px; border-radius:var(--r-pill); font-size:16px; }
  /* ações no card mobile = NEUTRAS (fundo branco + ícone cinza), sem âmbar/vermelho */
  table.cards-mobile tbody td.row-actions a.edit,
  table.cards-mobile tbody td.row-actions a.del{ background:var(--c-bg); color:var(--c-text-muted); }
}
/* ---- Respiro no FIM do conteúdo (mobile) ----------------------------------
   No celular a barra do navegador cobre o rodapé; sem isto o último item fica
   "cortado" ao rolar até o fim. Damos respiro + a safe-area do iOS (home
   indicator) aos containers de PÁGINA que rolam. Telas novas: usar um destes
   wraps para herdar o comportamento. Combina com height:100dvh da casca. */
@media (max-width:860px){
  .list-wrap, .form-wrap, .start-wrap, .rel-wrap, .rep-wrap,
  .cb-wrap, .fu-wrap, .msg-wrap, .perm-wrap, .flt-wrap{
    padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)) !important;
  }
}
@media (max-width:520px){
  .login-card{ padding:var(--sp-6) var(--sp-5); }
  .content-head{ flex-direction:column; align-items:stretch; }
  .content-head .btn{ width:100%; justify-content:center; }
}

/* ==========================================================================
   TRILHO HORIZONTAL no MOBILE (estilo Nubank) — OPT-IN via .rail-m
   - Use SÓ em telas-dashboard onde há conteúdo (gráficos) competindo por espaço
     vertical embaixo; NÃO use em telas que são só cards (launchers/config), onde
     esconder atalho atrás de scroll só atrapalha — ali grade que quebra linha é melhor.
   - Vira flex com overflow lateral; filho com largura fixa < 100% => o próximo
     "espia" na borda (a affordance do swipe). Barra de rolagem escondida.
   - !important: as telas "start" definem .start-grid/.kpi-grid local (carrega depois
     do DS) que sobreporia o display.
   - Sangra -28px (= padding lateral da .start-wrap) p/ ir até a borda da tela.
   ========================================================================== */
@media (max-width:680px){
  .rail-m{
    --rail-bleed:28px;   /* = padding lateral do wrapper; telas com outro padding sobrescrevem (ex.: fu-wrap=26px) */
    display:flex !important; gap:12px;
    overflow-x:auto; overflow-y:hidden;
    margin-left:calc(-1 * var(--rail-bleed)); margin-right:calc(-1 * var(--rail-bleed));
    padding:2px var(--rail-bleed) 14px;
    -webkit-overflow-scrolling:touch;
    scrollbar-width:none; -ms-overflow-style:none;
  }
  .rail-m::-webkit-scrollbar{ display:none; }
  .rail-m > *{ flex:0 0 76% !important; }
}

/* ==========================================================================
   QUICK-ACTIONS (mobile) — card de START vira botão CIRCULAR (estilo Nubank)
   No celular o hub de atalhos vira grade de ícones REDONDOS (maiores) + título
   embaixo (pode quebrar) + BADGE com o número (do .meta, injetado por
   start-actions.js). A descrição (<p>) é descartada. Desktop/tablet (>680px)
   mantêm o card retangular. Fica DEPOIS do @media 860 p/ vencer o grid 2-col.
   ========================================================================== */
.sc-badge{ display:none; }   /* badge numérico aparece só no modo quick-action (mobile) */
@media (max-width:680px){
  /* GRADE (não carrossel): anula o trilho horizontal .rail-m que as telas de start usam.
     3 COLUNAS (não 4): os rótulos do ERP são palavras longas ("Colaboradores"/"Concorrentes")
     e em 4 col (~95px) encostavam um no outro. 3 col dá ~120px e respiro real. */
  .start-grid{ display:grid !important; grid-template-columns:repeat(3,1fr) !important; gap:20px 8px;
    overflow:visible; margin:0; padding:0; }
  .start-card, .shortcut-card{
    background:transparent !important; border:0 !important; border-radius:0; box-shadow:none !important;
    padding:6px 4px; gap:8px; align-items:center; text-align:center;
  }
  .start-card:hover, .shortcut-card:hover{ border-color:transparent; box-shadow:none; transform:none; }
  /* círculo CINZA demarcado: o .ico-badge é branco (p/ saltar do card cinza); aqui o fundo é
     branco, então o branco sumiria. Cinza = igual aos quick-actions da Nubank. Prioridade = lavanda. */
  .start-card .ico-badge, .shortcut-card .ico-badge{ width:60px; height:60px; font-size:24px; position:relative; background:var(--c-surface-2); }
  .start-card .ico-priority, .start-card .ico-accent, .shortcut-card .ico-priority, .shortcut-card .ico-accent{ background:var(--c-accent-soft); }
  /* rótulo: reserva 2 linhas (min-height) p/ os ícones ficarem alinhados entre fileiras
     mesmo quando um nome quebra ("Pessoa Jurídica") e o vizinho não ("Sócios"). */
  .start-card h3, .shortcut-card h3{ font-size:var(--fs-sm); font-weight:var(--fw-medium); margin:0;
    line-height:1.18; min-height:2.36em; display:flex; align-items:flex-start; justify-content:center;
    overflow-wrap:break-word; hyphens:none; }
  .start-card p, .shortcut-card p{ display:none; }          /* descrição descartável no celular */
  .start-card .meta, .shortcut-card .meta{ display:none; }  /* o texto do .meta vira o badge numérico */
  .sc-badge{ display:flex; align-items:center; justify-content:center; position:absolute; top:-3px; right:-6px;
    min-width:20px; height:20px; padding:0 6px; border-radius:var(--r-pill); background:var(--corAtiva); color:#fff;
    font-size:11px; font-weight:var(--fw-bold); line-height:1; border:2px solid var(--c-bg); }
  .start-card.is-soon, .shortcut-card.is-soon, .start-card.soon, .shortcut-card.soon{ opacity:.5; }
}

/* ==========================================================================
   AJUSTES MOBILE (≤680) — barra de topo de start/dashboard
   - Breadcrumb redundante no celular (o título já vive na topbar da casca): SOME.
   (O .refresh-status já é badge no desktop e no mobile — ver bloco do componente.)
   ========================================================================== */
@media (max-width:680px){
  .breadcrumb{ display:none; }
}

/* ENTRADA suave (CSS puro, à prova de falha — sem depender de JS): fade + sobe.
   Stagger com .anim-d1/.anim-d2/.anim-d3. O bloco reduced-motion abaixo zera a duração. */
@keyframes ds-rise{ from{ opacity:0; transform:translateY(12px); } to{ opacity:1; transform:none; } }
.anim-rise{ animation:ds-rise .5s cubic-bezier(.2,.7,.2,1) both; }
.anim-d1{ animation-delay:.07s; } .anim-d2{ animation-delay:.14s; } .anim-d3{ animation-delay:.21s; }

/* Acessibilidade: respeita preferências de movimento reduzido */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{ transition:none !important; animation-duration:.001ms !important; }
}

/* ===== Card de clima (home + coluna do Feed) — preenchido por /assets/js/clima.js ===== */
.clima-list{ display:flex; flex-direction:column; }
.clima-loading{ color:var(--c-text-muted); font-size:var(--fs-sm); padding:4px 0; }
.clima-row{ display:flex; align-items:center; gap:10px; padding:9px 0; border-bottom:1px solid var(--c-border); }
.clima-row:last-child{ border-bottom:0; }
.clima-ic{ width:28px; height:28px; flex:none; color:var(--c-text-muted); }
.clima-ic svg{ width:100%; height:100%; stroke:currentColor; fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.clima-info{ flex:1; min-width:0; display:flex; flex-direction:column; line-height:1.2; }
.clima-cidade{ font-weight:var(--fw-semibold); color:var(--c-text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.clima-cond{ color:var(--c-text-muted); font-size:var(--fs-xs); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.clima-temp{ font-weight:var(--fw-bold); font-size:var(--fs-lg); color:var(--c-text); font-variant-numeric:tabular-nums; flex:none; }
.clima-mm{ color:var(--c-text-muted); font-size:var(--fs-sm); font-variant-numeric:tabular-nums; flex:none; text-align:right; white-space:nowrap; }

/* ===== Emoji picker (chat, comentários do feed) — lib assets/js/emoji.js ===== */
.emoji-btn{ flex:none; border:0; background:transparent; cursor:pointer; color:var(--c-text-muted);
  font-size:17px; line-height:0; padding:7px; border-radius:50%; }
.emoji-btn:hover{ background:var(--c-surface-2); color:var(--c-text); }
.emoji-pop{ position:fixed; z-index:var(--z-modal,1000); width:280px; background:var(--c-bg);
  border:1px solid var(--c-border); border-radius:var(--r-md); box-shadow:var(--sh-lg); overflow:hidden; }
.emoji-pop[hidden]{ display:none; }
.emoji-tabs{ display:flex; border-bottom:1px solid var(--c-border); }
.emoji-tab{ flex:1; border:0; background:transparent; cursor:pointer; padding:8px 0; color:var(--c-text-muted); font-size:16px; }
.emoji-tab:hover{ background:var(--c-surface); }
.emoji-tab.on{ color:var(--corAtiva); box-shadow:inset 0 -2px 0 var(--corAtiva); }
.emoji-grid{ display:grid; grid-template-columns:repeat(8,1fr); gap:2px; padding:8px; max-height:200px; overflow-y:auto; }
.emoji-i{ border:0; background:transparent; cursor:pointer; font-size:20px; line-height:1; padding:4px 0; border-radius:var(--r-sm); }
.emoji-i:hover{ background:var(--c-surface-2); }

/* Chat: fontes maiores + emoji solitário grande/sem-bolha. Aqui (asset versionado por filemtime,
   sempre fresco) além do <style> embutido na casca, p/ vencer cache de opcache do index.php.
   .chat-dock dá especificidade > regra-base embutida; !important vence o fundo roxo do .me. */
.chat-dock .chat-bubble{ font-size:15px; }
.chat-dock .chat-input{ font-size:15px; }
.chat-dock .chat-empty{ font-size:14px; }
.chat-dock .chat-msg.solo .chat-bubble{ background:transparent !important; border:0 !important;
  padding:0 !important; font-size:46px !important; line-height:1.15 !important; }
.chat-dock .chat-msg.solo .chat-meta{ color:var(--c-text-muted); }

/* ==========================================================================
   SELETOR DE PERÍODO (dashboards) — pill segmentado + "Personalizado" (X→Y)
   Componente único: lib assets/js/periodo.js (runPeriodo) + back core/periodo.php.
   Antes este CSS era copiado no <style> de cada start.php; agora é só daqui.
   ========================================================================== */
.per-seg{ position:relative; display:inline-flex; flex-wrap:wrap; background:var(--c-surface-2);
  border-radius:var(--r-pill); padding:3px; gap:2px; }
.per-seg button{ border:0; background:transparent; color:var(--c-text-muted); font:inherit;
  font-size:var(--fs-sm); padding:6px 14px; border-radius:var(--r-pill); cursor:pointer;
  transition:background .18s, color .18s; white-space:nowrap; }
.per-seg button:hover{ color:var(--c-text); }
.per-seg button.is-active{ background:var(--c-bg); color:var(--c-text); font-weight:var(--fw-semibold); }
.per-seg button:focus-visible{ outline:2px solid var(--c-accent); outline-offset:1px; }
/* botão "Personalizado" (abre o popover de datas); quando ativo mostra o intervalo escolhido */
.per-seg .ps-custom{ display:inline-flex; align-items:center; gap:6px; }
.per-seg .ps-custom i{ font-size:.95em; }

/* popover de intervalo (dois campos de data). Anexado ao <body> e posicionado por JS
   (position:fixed) — fica FORA do .per-seg p/ não ser recortado pelo overflow/máscara do pill. */
.per-pop{ position:fixed; z-index:var(--z-modal,1000);
  display:flex; flex-direction:column; gap:10px; width:230px; max-width:calc(100vw - 24px); padding:14px;
  background:var(--c-bg); border:1px solid var(--c-border); border-radius:var(--r-md);
  box-shadow:var(--sh-lg); }
.per-pop label{ display:flex; flex-direction:column; gap:4px; font-size:var(--fs-xs);
  color:var(--c-text-muted); font-weight:var(--fw-medium); }
.per-pop .ds-input{ font-size:var(--fs-sm); }
.per-pop-foot{ display:flex; justify-content:flex-end; gap:8px; margin-top:2px; }

@media (max-width:680px){
  /* uma linha só com SCROLL horizontal (chips no tamanho real, nunca cortados/esticados).
     fade na borda direita sinaliza que há mais; o popover fixo escapa deste overflow. */
  .per-seg{ width:100%; flex-wrap:nowrap; overflow-x:auto; justify-content:flex-start;
    scrollbar-width:none; -webkit-overflow-scrolling:touch;
    -webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent);
            mask-image:linear-gradient(90deg,#000 calc(100% - 22px),transparent); }
  .per-seg::-webkit-scrollbar{ display:none; }
  .per-seg button{ flex:0 0 auto; padding:9px 14px; }
  /* popover vira bottom-sheet fixo: position:fixed escapa do recorte do scroll e fica no alcance do polegar */
  .per-pop{ position:fixed; left:12px; right:12px; top:auto; min-width:0;
    bottom:calc(12px + env(safe-area-inset-bottom, 0px)); }
}
