/* ============================================================================
   PlugIA Constellation V4.0 — CSS universal do Smith
   ----------------------------------------------------------------------------
   Carregado em TODAS as telas (base.html). Cada página tem, além deste, o seu
   próprio arquivo em static/css/pages/<tela>.css.

   Ordem das seções:
     1. Tokens (Constellation V4) + aliases de compatibilidade
     2. Reset e tipografia
     3. Acessibilidade (skip link, foco, reduced motion)
     4. Shell: sidebar, topbar, gradient bar, footer, drawer, paleta ⌘K
     5. Componentes: botões, inputs, cards, metric, callout, badge, dot,
        avatar, tabs, tabela, empty state, skeleton, modal
     6. Camada de compatibilidade (classes legadas ainda usadas em telas
        não migradas — NÃO remover sem migrar as telas)

   Regras (plugia-constellation.md): zero hex hardcoded fora de :root,
   shadow no lugar de border, Pink ≤3%, CTA primário = Ink.
   ========================================================================== */

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
:root {
    /* ── BRAND CORE ── */
    --pink: #FF086B;
    --pink-hover: #E8055F;
    --pink-active: #CC044F;
    --pink-muted: rgba(255, 8, 107, 0.10);
    --pink-subtle: rgba(255, 8, 107, 0.04);

    /* ── CONSTELLATION ── */
    --constellation-blue: #3A5BDC;
    --constellation-blue-hover: #2F4BC4;
    --constellation-blue-muted: rgba(58, 91, 220, 0.10);
    --constellation-blue-subtle: rgba(58, 91, 220, 0.04);
    --constellation-purple: #7E22CE;
    --constellation-purple-hover: #6B1FB3;
    --constellation-purple-muted: rgba(126, 34, 206, 0.10);

    --gradient-constellation: linear-gradient(90deg, #3A5BDC 0%, #7E22CE 50%, #FF086B 100%);
    --gradient-constellation-soft: linear-gradient(90deg, rgba(58,91,220,.08) 0%, rgba(126,34,206,.08) 50%, rgba(255,8,107,.08) 100%);

    /* ── INK ── */
    --ink: #0A0A0B;
    --ink-hover: #1A1A1B;
    --ink-active: #000000;
    --ink-muted: rgba(10, 10, 11, 0.08);

    /* ── TEXT (WCAG AAA) ── */
    --text-primary: #0A0A0B;
    --text-secondary: #3C3C43;
    --text-tertiary: #6E6E73;
    --text-muted: #8E8E93;
    --text-faint: #C7C7CC;
    --text-disabled: #D1D1D6;

    /* ── STONES ── */
    --stone-0: #FFFFFF;
    --stone-50: #FAFAFA;
    --stone-100: #F4F4F5;
    --stone-150: #EEEEF0;
    --stone-200: #E4E4E7;
    --stone-300: #D4D4D8;
    --stone-400: #A1A1AA;
    --stone-500: #71717A;
    --stone-600: #52525B;
    --stone-700: #3F3F46;
    --stone-800: #27272A;
    --stone-900: #18181B;

    --surface-0: var(--stone-0);
    --surface-1: var(--stone-50);
    --surface-2: var(--stone-100);
    --surface-3: var(--stone-150);
    --surface-4: var(--stone-200);

    /* ── STATUS ── */
    --success: #16A34A;
    --success-soft: rgba(22, 163, 74, 0.10);
    --warning: #CA8A04;
    --warning-soft: rgba(202, 138, 4, 0.10);
    --danger: #DC2626;
    --danger-soft: rgba(220, 38, 38, 0.10);
    --info: #2563EB;
    --info-soft: rgba(37, 99, 235, 0.10);

    /* ── SPACING (grid 4px) ── */
    --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
    --space-5: 20px;  --space-6: 24px;  --space-8: 32px;  --space-10: 40px;
    --space-12: 48px; --space-16: 64px; --space-20: 80px; --space-24: 96px;

    /* ── RADIUS ── */
    --radius-xs: 4px;  --radius-sm: 6px;  --radius-md: 8px;
    --radius-lg: 12px; --radius-xl: 16px; --radius-2xl: 24px;
    --radius-full: 9999px;

    /* ── SHADOWS ── */
    --shadow-xs: 0 1px 2px rgba(0,0,0,.04);
    --shadow-sm: 0 1px 3px rgba(0,0,0,.05), 0 1px 2px rgba(0,0,0,.03);
    --shadow-md: 0 4px 8px rgba(0,0,0,.06), 0 0 0 1px rgba(0,0,0,.03);
    --shadow-lg: 0 8px 24px rgba(0,0,0,.08), 0 0 0 1px rgba(0,0,0,.03);
    --shadow-xl: 0 16px 48px rgba(0,0,0,.10), 0 0 0 1px rgba(0,0,0,.03);
    --shadow-2xl: 0 32px 64px rgba(0,0,0,.12);
    --shadow-focus: 0 0 0 3px rgba(58, 91, 220, .30);
    --shadow-focus-ink: 0 0 0 3px rgba(10, 10, 11, .15);
    --shadow-focus-pink: 0 0 0 3px rgba(255, 8, 107, .25);

    --border-color: var(--stone-200);
    --border-hover: var(--stone-300);

    /* Texto colorido: no claro usa a cor cheia; no escuro precisa clarear pra
       manter contraste. Os *-fg trocam de valor no bloco [data-theme="dark"]. */
    --success-fg: var(--success);
    --warning-fg: var(--warning);
    --danger-fg: var(--danger);
    --info-fg: var(--info);
    --brand-fg: var(--constellation-blue);

    /* Seta do <select> — a cor vai embutida no SVG, então há uma versão
       por tema (ver o override em [data-theme="dark"] mais abaixo). */
    --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236E6E73' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

    /* Marcas do checkbox (mask-image: a cor vem do background-color) */
    --check-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
    --check-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.5' stroke-linecap='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'/%3E%3C/svg%3E");

    /* ── MOTION ── */
    --ease-default: cubic-bezier(.16, 1, .3, 1);
    --ease-out: cubic-bezier(0, 0, .2, 1);
    --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
    --duration-instant: 80ms;
    --duration-fast: 150ms;
    --duration-normal: 200ms;
    --duration-slow: 320ms;
    --duration-deliberate: 500ms;

    /* ── TYPOGRAPHY ──
       Geist é a fonte oficial do Constellation; enquanto ela não estiver
       vendorizada em static/vendor/, cai na Inter (já vendorizada) e depois
       na fonte do sistema. Ver docs/design_constellation.md. */
    --font-body: 'Geist', 'Inter', -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', sans-serif;
    --font-display: 'Instrument Serif', Georgia, 'Times New Roman', serif;
    --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

    /* ── LAYOUT ── */
    --sidebar-width: 240px;
    --sidebar-collapsed: 74px;
    --header-height: 56px;
    --content-max: 1280px;

    /* ── Z-INDEX ── */
    --z-dropdown: 100;
    --z-sticky: 200;
    --z-overlay: 300;
    --z-modal: 400;
    --z-toast: 500;
    --z-tooltip: 600;

    /* ── PAGE ALIASES ── */
    --page-bg: var(--stone-50);
    --card-bg: var(--stone-0);
    --header-bg: rgba(255, 255, 255, .92);
    --sidebar-bg: #111114;
    --sidebar-bg-2: #16161B;

    /* ══ Aliases de compatibilidade ══
       Nomes usados pelas telas ainda não migradas. Apontam para os tokens
       Constellation, então migrar uma tela é trocar o nome, não a cor. */
    --sb-w: var(--sidebar-width);
    --sb-w-min: var(--sidebar-collapsed);
    --sb-current: var(--sidebar-width);
    --app-topbar-h: var(--header-height);
    --sb-bg: var(--sidebar-bg);
    --sb-bg-2: var(--sidebar-bg-2);
    --sb-line: rgba(255, 255, 255, .07);
    --sb-text: #9A9AA8;
    --sb-text-strong: #F5F5F7;
    --app-bg: var(--page-bg);
    --app-surface: var(--card-bg);
    --app-surface-2: var(--surface-2);
    --app-border: var(--border-color);
    --app-text: var(--text-primary);
    --app-text-soft: var(--text-tertiary);
    --app-topbar-bg: var(--header-bg);
    --plugia-purple: #6366f1;
    --plugia-pink: var(--pink);
    --plugia-blue: #3b82f6;
}

/* ── DARK THEME ── */
:root[data-theme="dark"] {
    --stone-0: #1C1C1E;
    --stone-50: #0A0A0C;
    --stone-100: #141416;
    --stone-150: #1A1A1C;
    --stone-200: #2C2C2E;
    --stone-300: #3A3A3C;
    --stone-400: #48484A;
    --stone-500: #636366;
    --stone-600: #8E8E93;
    --stone-700: #AEAEB2;
    --stone-800: #D1D1D6;
    --stone-900: #F5F5F7;

    --surface-0: var(--stone-0);
    --surface-1: var(--stone-50);
    --surface-2: var(--stone-100);
    --surface-3: var(--stone-150);
    --surface-4: var(--stone-200);

    --text-primary: #F5F5F7;
    --text-secondary: rgba(255, 255, 255, .72);
    --text-tertiary: rgba(255, 255, 255, .50);
    --text-muted: rgba(255, 255, 255, .32);
    --text-faint: rgba(255, 255, 255, .18);
    --text-disabled: rgba(255, 255, 255, .15);

    --ink: #F5F5F7;
    --ink-hover: #FFFFFF;
    --ink-active: #E5E5EA;
    --ink-muted: rgba(245, 245, 247, .08);

    --border-color: rgba(255, 255, 255, .08);
    --border-hover: rgba(255, 255, 255, .14);

    --page-bg: var(--stone-50);
    --card-bg: var(--stone-0);
    --header-bg: rgba(10, 10, 12, .88);
    --sidebar-bg: #050507;
    --sidebar-bg-2: #0B0B0E;

    --success-fg: #6EE7B7;
    --warning-fg: #FCD34D;
    --danger-fg: #FCA5A5;
    --info-fg: #93C5FD;
    --brand-fg: #A5B4FC;

    --chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23A1A1AA' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");

    --shadow-xs: 0 1px 2px rgba(0,0,0,.30);
    --shadow-sm: 0 1px 3px rgba(0,0,0,.40), 0 0 0 1px rgba(255,255,255,.04);
    --shadow-md: 0 4px 8px rgba(0,0,0,.40), 0 0 0 1px rgba(255,255,255,.04);
    --shadow-lg: 0 8px 24px rgba(0,0,0,.50), 0 0 0 1px rgba(255,255,255,.04);
    --shadow-xl: 0 16px 48px rgba(0,0,0,.60), 0 0 0 1px rgba(255,255,255,.04);
    --shadow-2xl: 0 32px 64px rgba(0,0,0,.70);
}

/* ==========================================================================
   2. RESET E TIPOGRAFIA
   ========================================================================== */
html { background: var(--page-bg); font-size: 16px; }

body {
    background: var(--page-bg) !important;
    color: var(--text-primary);
    font-family: var(--font-body);
    font-size: 14px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    transition: background var(--duration-normal) var(--ease-default),
                color var(--duration-normal) var(--ease-default);
}

::selection { background: var(--pink-muted); color: var(--text-primary); }

.pg-h1 { font-size: 36px; font-weight: 700; line-height: 1.15; letter-spacing: -.025em; color: var(--text-primary); }
.pg-h2 { font-size: 28px; font-weight: 700; line-height: 1.2;  letter-spacing: -.02em;  color: var(--text-primary); }
.pg-h3 { font-size: 22px; font-weight: 600; line-height: 1.3;  letter-spacing: -.01em;  color: var(--text-primary); }
.pg-h4 { font-size: 16px; font-weight: 600; line-height: 1.4;                            color: var(--text-primary); }
.pg-small { font-size: 13px; color: var(--text-secondary); }
.pg-caption,
.section-label {
    font-size: 11px; font-weight: 700; line-height: 1.3;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--text-tertiary);
}
.pg-mono { font-family: var(--font-mono); font-size: 13px; }
.pg-num  { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   3. ACESSIBILIDADE
   ========================================================================== */
.skip-link {
    position: absolute; top: -48px; left: 0;
    z-index: 9999;
    padding: var(--space-2) var(--space-4);
    background: var(--ink);
    color: var(--card-bg);
    font-size: 13px; font-weight: 500;
    text-decoration: none;
    border-radius: 0 0 var(--radius-sm) 0;
    transition: top var(--duration-fast) var(--ease-default);
}
.skip-link:focus { top: 0; }

:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-sm); }

/* ── Reduced motion ────────────────────────────────────────────────────────
   Três tentativas até acertar a ARQUITETURA da regra, e a lição vale registrar:

   1ª) O reset que circula por aí (`animation-duration: .01ms` no `*`) sem
       `animation-iteration-count: 1`. Não desliga animação `infinite` — faz
       ela repetir ~100 mil vezes por segundo. Tudo piscando.
   2ª) Somando o iteration-count, tudo congelou. Pior: spinner parado é lido
       como "travou" — a FORMA de arco promete rotação.
   3ª) Liberar indicador por indicador numa lista de exceções. Insustentável:
       a lista de coisas que giram no app não para de crescer, e a cada
       esquecimento um indicador congela em silêncio.

   A regra final inverte o ônus: em vez de enumerar o que MANTER (infinito e
   sempre crescendo), enumera o que REMOVER — as animações de entrada, que são
   nossas, finitas e conhecidas. Indicador novo em qualquer tela já nasce
   funcionando; no pior caso alguém adiciona uma animação de entrada sem
   pensar e ela não é reduzida — dano menor que um indicador morto.

   O que a preferência realmente pede é evitar deslocamento, escala e
   parallax. Girar 16px num canto não é gatilho vestibular (a WCAG 2.3.3 trata
   de animação disparada por interação); Primer e Atlassian mantêm spinner
   girando em reduced-motion pelo mesmo motivo. */
@media (prefers-reduced-motion: reduce) {
    /* 1. TRANSIÇÕES saem todas. É onde mora a maior parte do desconforto:
          painel que desliza, card que sobe no hover, escala em botão. */
    *, *::before, *::after {
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }

    /* 2. ANIMAÇÕES DE ENTRADA saem — lista explícita, todas nossas. Elas
          deslocam/escalam o elemento ao aparecer, que é o gesto que a
          preferência pede para evitar. */
    .dlg,
    .modal,
    .modal-overlay,
    .cmdk-panel,
    .cmdk-backdrop,
    .busy-overlay,
    .toast,
    .side-panel,
    .agent-steps-container .step-item,
    #planilhasMenu,
    #copilotModelMenu,
    #ac-tables-copilot,
    #ac-columns-copilot { animation: none !important; }

    /* 3. MOVIMENTO CONTÍNUO QUE ATRAVESSA A TELA vira pulso no lugar: a barra
          indeterminada e a varredura de brilho percorrem distância, os dois
          gestos que mais incomodam. */
    .busy-bar > i,
    .upload-progress-indeterminate {
        width: 100% !important;
        transform: none !important;
        animation: reduzidoPulsar 1.6s ease-in-out infinite !important;
    }
    /* O brilho do .skeleton virou uma camada `::after` que ATRAVESSA a barra
       (ver 5.12). Pulsar o elemento e deixar a varredura correndo por baixo
       manteria justamente o deslocamento que esta regra existe para tirar —
       então é o `::after` que perde o percurso e ganha o pulso. */
    .skeleton::after {
        transform: none !important;
        animation: reduzidoPulsar 1.6s ease-in-out infinite !important;
    }
    /* O anel do botão perde a ROTAÇÃO mas mantém o pulso: parar de vez faria
       o botão parecer travado justamente enquanto trabalha. Mesma troca que a
       barra indeterminada e o brilho do skeleton recebem acima. */
    .btn.is-ocupado::after {
        transform: none !important;
        animation: reduzidoPulsar 1.6s ease-in-out infinite !important;
    }
    .thinking-shimmer,
    .step-running .step-label {
        animation: none !important;
        background: none !important;
        -webkit-text-fill-color: currentColor !important;
        color: var(--text-secondary) !important;
    }
}

@keyframes reduzidoPulsar {
    0%, 100% { opacity: 1; }
    50%      { opacity: .45; }
}

/* ==========================================================================
   4. SHELL
   ========================================================================== */

/* ---------- 4.1 Sidebar (sempre dark, nos dois temas) ---------- */
.sidebar {
    position: fixed;
    top: 0; bottom: 0; left: 0;
    width: var(--sidebar-width);
    z-index: var(--z-sticky);
    display: flex;
    flex-direction: column;
    background: linear-gradient(180deg, var(--sidebar-bg) 0%, var(--sidebar-bg-2) 100%);
    border-right: 1px solid var(--sb-line);
    transition: width var(--duration-normal) var(--ease-default),
                transform var(--duration-slow) var(--ease-default);
}
html.sb-collapsed .sidebar { width: var(--sidebar-collapsed); }

.sb-head {
    position: relative;
    display: flex; align-items: center; gap: var(--space-2);
    padding: 14px var(--space-3);
    border-bottom: 1px solid var(--sb-line);
    min-height: var(--header-height);
}
.sb-logo {
    flex: none;
    width: 38px; height: 38px;
    border-radius: var(--radius-lg);
    display: grid; place-items: center;
    overflow: hidden;
}
.sb-logo img { width: 100%; height: 100%; object-fit: contain; }
.sb-name {
    color: var(--sb-text-strong);
    font-weight: 700; font-size: 17px;
    letter-spacing: -.02em; white-space: nowrap;
}

.sb-collapse-btn, .sb-close {
    flex: none;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border: 0; border-radius: var(--radius-md);
    background: transparent;
    color: var(--sb-text);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-default),
                color var(--duration-fast) var(--ease-default);
}
.sb-collapse-btn { margin-left: auto; }
.sb-collapse-btn:hover, .sb-close:hover { background: rgba(255,255,255,.08); color: #fff; }
.sb-collapse-btn svg { width: 17px; height: 17px; transition: transform var(--duration-normal) var(--ease-default); }
html.sb-collapsed .sb-collapse-btn svg { transform: rotate(180deg); }
.sb-close { display: none; margin-left: auto; }

.sb-nav {
    flex: 1;
    overflow-y: auto; overflow-x: hidden;
    padding: var(--space-3) 10px var(--space-4);
}
.sb-nav::-webkit-scrollbar { width: 4px; }
.sb-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border-radius: var(--radius-xs); }

.sb-sec {
    display: flex; align-items: center; gap: var(--space-1);
    width: 100%;
    padding: var(--space-1) 7px;
    margin: var(--space-4) 0 var(--space-1);
    border: 0; background: transparent;
    font: inherit;
    font-size: 10px; font-weight: 700;
    letter-spacing: .08em; text-transform: uppercase;
    color: rgba(255,255,255,.40);
    white-space: nowrap; cursor: pointer;
    transition: color var(--duration-fast) var(--ease-default);
}
.sb-sec:hover { color: rgba(255,255,255,.65); }
.sb-group:first-child .sb-sec { margin-top: 0; }

.sb-sec-count {
    display: none;
    margin-left: auto;
    min-width: 16px; padding: 0 5px;
    border-radius: var(--radius-xs);
    background: rgba(255,255,255,.08);
    color: rgba(255,255,255,.55);
    font-size: 10px; font-weight: 700; letter-spacing: 0; text-align: center;
}
.sb-group.collapsed .sb-sec-count { display: block; }
.sb-sec-chev { width: 13px; height: 13px; margin-left: auto; transition: transform var(--duration-fast) var(--ease-default); }
.sb-group.collapsed .sb-sec-count + .sb-sec-chev { margin-left: var(--space-1); }
.sb-group.collapsed .sb-sec-chev { transform: rotate(-90deg); }
.sb-group.collapsed .sb-items { display: none; }

.sb-link {
    position: relative;
    display: flex; align-items: center; gap: 10px;
    padding: var(--space-2) 9px;
    margin-bottom: 2px;
    border-radius: var(--radius-md);
    color: rgba(255,255,255,.72);
    font-size: 13px; font-weight: 500;
    text-decoration: none; white-space: nowrap;
    transition: background var(--duration-fast) var(--ease-default),
                color var(--duration-fast) var(--ease-default);
}
.sb-link svg { flex: none; width: 16px; height: 16px; opacity: .85; }
.sb-link:hover { background: rgba(255,255,255,.04); color: #fff; }
.sb-link.active { background: rgba(255,255,255,.06); color: #fff; }
.sb-link.active svg { opacity: 1; }
/* dot pink pulsante do item ativo (assinatura Constellation) */
.sb-link.active::after {
    content: "";
    flex: none; margin-left: auto;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--pink);
    box-shadow: 0 0 8px var(--pink);
    animation: pulse 2s ease-in-out infinite;
}

.sb-badge {
    margin-left: auto;
    min-width: 18px; padding: 0 6px;
    border-radius: var(--radius-sm);
    background: rgba(255,255,255,.08);
    color: rgba(255,255,255,.55);
    font-size: 11px; font-weight: 600; text-align: center;
}
.sb-link.active .sb-badge { margin-left: auto; margin-right: var(--space-1); }

.sb-foot { padding: var(--space-3) 10px; border-top: 1px solid var(--sb-line); }
.sb-user {
    display: flex; align-items: center; gap: 10px;
    padding: 7px var(--space-2);
    border-radius: var(--radius-lg);
    transition: background var(--duration-fast) var(--ease-default);
}
.sb-user:hover { background: rgba(255,255,255,.05); }
.sb-user-info { min-width: 0; flex: 1; line-height: 1.25; }
.sb-user-name {
    color: var(--sb-text-strong);
    font-size: 13px; font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sb-user-sub {
    color: rgba(255,255,255,.38);
    font-size: 11px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sb-logout {
    flex: none;
    width: 32px; height: 32px;
    display: grid; place-items: center;
    border-radius: var(--radius-md);
    color: var(--sb-text);
    transition: background var(--duration-fast) var(--ease-default),
                color var(--duration-fast) var(--ease-default);
}
.sb-logout:hover { background: var(--danger-soft); color: #FCA5A5; }
.sb-logout svg { width: 17px; height: 17px; }
.sb-plugthink {
    margin-top: var(--space-2);
    text-align: center;
    font-size: 10px; font-weight: 600; letter-spacing: .05em;
    color: rgba(255,255,255,.28);
    white-space: nowrap;
}

/* Estado colapsado (rail de ícones) */
html.sb-collapsed .sb-name,
html.sb-collapsed .sb-label,
html.sb-collapsed .sb-sec,
html.sb-collapsed .sb-badge,
html.sb-collapsed .sb-user-info,
html.sb-collapsed .sb-plugthink { display: none; }
html.sb-collapsed .sb-head { justify-content: center; padding-left: var(--space-2); padding-right: var(--space-2); }
html.sb-collapsed .sb-head .sb-logo { display: none; }
html.sb-collapsed .sb-collapse-btn { margin-left: 0; }
html.sb-collapsed .sb-link { justify-content: center; padding: 10px 0; }
html.sb-collapsed .sb-link.active::after { display: none; }
html.sb-collapsed .sb-group.collapsed .sb-items { display: block; }
html.sb-collapsed .sb-user { flex-direction: column; gap: var(--space-2); padding: var(--space-1) 0; }

/* ---------- 4.2 Conteúdo ---------- */
html.sb-collapsed { --sb-current: var(--sidebar-collapsed); }

.app-content {
    margin-left: var(--sb-current);
    min-height: 100dvh;
    display: flex; flex-direction: column;
    transition: margin-left var(--duration-normal) var(--ease-default);
}
.app-content > main { flex: 1 1 auto; min-height: 0; }

.page-wrap {
    width: 100%;
    max-width: var(--content-max);
    margin: 0 auto;
    padding: var(--space-8) var(--space-6) var(--space-12);
}
@media (max-width: 640px) { .page-wrap { padding: var(--space-6) var(--space-4) var(--space-10); } }

/* ---------- 4.3 Topbar ---------- */
.app-topbar {
    position: sticky; top: 0;
    z-index: var(--z-sticky);
    display: flex; align-items: center; gap: 10px;
    height: var(--header-height);
    padding: 0 var(--space-4) 0 10px;
    background: var(--header-bg);
    backdrop-filter: blur(20px) saturate(180%);
    -webkit-backdrop-filter: blur(20px) saturate(180%);
    border-bottom: 1px solid var(--border-color);
}
/* Gradient bar 3px — assinatura Constellation, obrigatória em toda página */
.app-topbar::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -3px;
    height: 3px;
    background: var(--gradient-constellation);
}

.tb-crumbs { display: flex; align-items: center; gap: var(--space-1); min-width: 0; font-size: 13px; }
.tb-crumb-root { color: var(--text-tertiary); text-decoration: none; white-space: nowrap; }
.tb-crumb-root:hover { color: var(--text-primary); }
.tb-crumbs svg { flex: none; width: 14px; height: 14px; color: var(--text-tertiary); opacity: .55; }
.tb-crumb-cur {
    color: var(--text-primary); font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.tb-actions { margin-left: auto; display: flex; align-items: center; gap: var(--space-1); }

.tb-search {
    display: flex; align-items: center; gap: var(--space-2);
    height: 32px; min-width: 200px;
    padding: 0 7px 0 10px;
    margin-right: var(--space-1);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--card-bg);
    color: var(--text-tertiary);
    font: inherit; font-size: 13px;
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-default),
                border-color var(--duration-fast) var(--ease-default);
}
.tb-search:hover { background: var(--surface-2); border-color: var(--border-hover); }
.tb-search svg { flex: none; width: 14px; height: 14px; }
.tb-kbd {
    margin-left: auto;
    padding: 1px 5px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    font-size: 11px; line-height: 1.35; white-space: nowrap;
}

.tb-icon {
    position: relative; flex: none;
    width: 32px; height: 32px;
    display: grid; place-items: center;
    border: 0; border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer; text-decoration: none;
    transition: background var(--duration-fast) var(--ease-default),
                color var(--duration-fast) var(--ease-default);
}
.tb-icon:hover { background: var(--surface-2); color: var(--text-primary); }
.tb-icon svg { width: 16px; height: 16px; }
.tb-dot {
    position: absolute; top: 6px; right: 7px;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--pink);
}
.tb-theme .tb-theme-light { display: none; }
:root[data-theme="dark"] .tb-theme .tb-theme-dark { display: none; }
:root[data-theme="dark"] .tb-theme .tb-theme-light { display: block; }

.tb-pop { position: relative; }
.tb-menu {
    position: absolute; top: calc(100% + var(--space-2)); right: 0;
    z-index: var(--z-dropdown);
    min-width: 210px;
    padding: var(--space-1);
    border-radius: var(--radius-lg);
    background: var(--card-bg);
    box-shadow: var(--shadow-lg);
}
.tb-menu-title {
    padding: 7px var(--space-2) var(--space-1);
    font-size: 10px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--text-tertiary);
}
.tb-menu-item {
    display: flex; align-items: center; gap: var(--space-2);
    width: 100%;
    padding: var(--space-2);
    border: 0; border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-primary);
    font: inherit; font-size: 13px;
    text-align: left; text-decoration: none; cursor: pointer;
}
.tb-menu-item:hover { background: var(--surface-2); }
.tb-menu-item.is-current { color: var(--constellation-blue); font-weight: 600; }
.tb-menu-empty { padding: 10px var(--space-2); font-size: 13px; color: var(--text-tertiary); }

/* ---------- 4.4 Footer ---------- */
.app-footer {
    padding: var(--space-6);
    border-top: 1px solid var(--border-color);
    text-align: center;
}
.app-footer-brand { font-size: 12px; color: var(--text-muted); letter-spacing: .02em; }
.app-footer-brand strong { color: var(--text-tertiary); font-weight: 600; }

/* ---------- 4.5 Drawer mobile ---------- */
.sb-backdrop {
    position: fixed; inset: 0;
    z-index: var(--z-overlay);
    background: rgba(10, 10, 11, .55);
    backdrop-filter: blur(2px);
    opacity: 0; pointer-events: none;
    transition: opacity var(--duration-slow) var(--ease-default);
}

/* ---------- 4.6 Paleta de busca (⌘K) ---------- */
.cmdk-backdrop.hidden { display: none; }
.cmdk-backdrop {
    position: fixed; inset: 0;
    z-index: var(--z-modal);
    display: flex; justify-content: center; align-items: flex-start;
    padding: 12vh var(--space-4) var(--space-4);
    background: rgba(10, 10, 11, .45);
    backdrop-filter: blur(4px);
    animation: fadeIn var(--duration-normal) var(--ease-default);
}
.cmdk-panel {
    width: 100%; max-width: 520px;
    overflow: hidden;
    border-radius: var(--radius-xl);
    background: var(--card-bg);
    box-shadow: var(--shadow-xl);
    animation: modalIn var(--duration-slow) var(--ease-default);
}
.cmdk-field {
    display: flex; align-items: center; gap: 10px;
    padding: 14px var(--space-4);
    border-bottom: 1px solid var(--border-color);
}
.cmdk-field svg { flex: none; width: 17px; height: 17px; color: var(--text-tertiary); }
.cmdk-field input {
    flex: 1; border: 0; outline: 0;
    background: transparent; color: var(--text-primary);
    font: inherit; font-size: 15px;
}
.cmdk-list { max-height: 320px; overflow-y: auto; padding: var(--space-1); }
.cmdk-item {
    display: flex; align-items: center; gap: 10px;
    padding: 9px 10px;
    border-radius: var(--radius-md);
    color: var(--text-primary); font-size: 13px;
    text-decoration: none; cursor: pointer;
}
.cmdk-item svg { flex: none; width: 16px; height: 16px; color: var(--text-tertiary); }
.cmdk-item:hover, .cmdk-item.is-active { background: var(--surface-2); }
.cmdk-item .cmdk-hint { margin-left: auto; font-size: 11px; color: var(--text-tertiary); }

/* ---------- 4.7 Responsivo do shell ---------- */
@media (max-width: 1279px) {
    .tb-search { min-width: 0; padding: 0 10px; }
    .tb-search .tb-search-label, .tb-search .tb-kbd { display: none; }
}

@media (max-width: 1023px) {
    .sidebar {
        transform: translateX(-105%);
        width: min(300px, 86vw) !important;
        box-shadow: 24px 0 48px -24px rgba(0,0,0,.5);
    }
    html.sb-open .sidebar { transform: translateX(0); }
    html.sb-open .sb-backdrop { opacity: 1; pointer-events: auto; }
    html.sb-open { overflow: hidden; }

    html { --sb-current: 0px; }
    .sb-close { display: grid; }
    .sb-collapse-btn { display: none; }
    .tb-crumb-root, .tb-crumbs svg { display: none; }

    html.sb-collapsed .sb-name,
    html.sb-collapsed .sb-label,
    html.sb-collapsed .sb-badge,
    html.sb-collapsed .sb-user-info,
    html.sb-collapsed .sb-plugthink { display: block; }
    html.sb-collapsed .sb-head .sb-logo { display: grid; }
    html.sb-collapsed .sb-sec { display: flex; }
    html.sb-collapsed .sb-link { justify-content: flex-start; padding: var(--space-2) 9px; }
    html.sb-collapsed .sb-link.active::after { display: block; }
    html.sb-collapsed .sb-group.collapsed .sb-items { display: none; }
    html.sb-collapsed .sb-user { flex-direction: row; padding: 7px var(--space-2); }

    /* touch targets ≥44px */
    .tb-icon { width: 40px; height: 40px; }
}

/* ==========================================================================
   5. COMPONENTES
   ========================================================================== */

/* ---------- 5.1 Botões ---------- */
.btn {
    font-family: var(--font-body); font-weight: 500;
    border: none; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
    border-radius: var(--radius-md);
    text-decoration: none; white-space: nowrap;
    position: relative;
    font-size: 13px; padding: var(--space-2) var(--space-4);
    transition: background var(--duration-fast) var(--ease-default),
                color var(--duration-fast) var(--ease-default),
                border-color var(--duration-fast) var(--ease-default),
                box-shadow var(--duration-fast) var(--ease-default),
                transform var(--duration-fast) var(--ease-default);
}
.btn svg { width: 16px; height: 16px; flex: none; }
.btn:active { transform: scale(.97); }
.btn:focus-visible { outline: none; box-shadow: var(--shadow-focus-ink); }
.btn[disabled], .btn.is-disabled { opacity: .4; cursor: not-allowed; pointer-events: none; }

/* ---------- Botão "trabalhando" ----------
 *
 * `.is-ocupado` troca o ícone do botão por um ANEL girando — mesmo desenho do
 * `.busy-spin` do overlay e do `loader-2` da tela de login, para o "estou
 * processando" ser sempre a mesma forma no produto inteiro.
 *
 * POR QUE ESCONDER O ÍCONE ORIGINAL
 * Antes cada tela girava o próprio `svg` do botão. No "Salvar conceito" esse
 * ícone é um CHECK — e um check girando diz "concluído" enquanto o sistema
 * ainda trabalha, que é o oposto do estado. Além de feio, um símbolo de
 * sucesso em rotação é informação errada.
 *
 * `::after` e não `::before`: o `::before` já é do `.btn-gradient` (varredura
 * de brilho no hover), e disputar o mesmo pseudo-elemento quebraria os dois.
 */
.btn.is-ocupado { pointer-events: none; opacity: .75; }
.btn.is-ocupado svg { display: none; }
.btn.is-ocupado::after {
    content: "";
    flex: none;
    /* O anel ocupa o LUGAR do ícone, que nestes botões vem antes do rótulo
       (`<i data-lucide="check"></i><span>Salvar</span>`). Sem o `order`, o
       `::after` cairia depois do texto e o controle "pularia" de lado ao
       entrar em carregamento. */
    order: -1;
    width: 14px; height: 14px;
    border: 2px solid currentColor;
    /* Um lado transparente é o que transforma o círculo em ARCO — sem isto o
       anel gira sem parecer que gira. */
    border-top-color: transparent;
    border-radius: 50%;
    opacity: .85;
    animation: btnGirar .7s linear infinite;
}
@keyframes btnGirar { to { transform: rotate(360deg); } }

/* O `.btn-lg` tem texto maior; o anel acompanha para não ficar miúdo. */
.btn-lg.is-ocupado::after, .btn-xl.is-ocupado::after { width: 16px; height: 16px; }

.btn-sm { font-size: 12px; padding: 6px var(--space-3); }
.btn-sm svg { width: 14px; height: 14px; }
.btn-md { font-size: 13px; padding: var(--space-2) var(--space-4); }
.btn-lg { font-size: 14px; padding: 10px var(--space-5); }
.btn-xl { font-size: 15px; padding: var(--space-3) var(--space-6); border-radius: var(--radius-lg); }
.btn-icon { padding: var(--space-2); }

.btn-ink { background: var(--ink); color: var(--card-bg); }
.btn-ink:hover { background: var(--ink-hover); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn-ink:active { background: var(--ink-active); transform: translateY(0) scale(.97); }

.btn-pink { background: var(--pink); color: #fff; }
.btn-pink:hover { background: var(--pink-hover); transform: translateY(-1px); box-shadow: 0 6px 16px rgba(255,8,107,.30); }
.btn-pink:active { background: var(--pink-active); }
.btn-pink:focus-visible { box-shadow: var(--shadow-focus-pink); }

.btn-pink-hollow { background: transparent; color: var(--pink); border: 1px solid var(--pink); }
.btn-pink-hollow:hover { background: var(--pink-subtle); border-color: var(--pink-hover); color: var(--pink-hover); }
.btn-pink-hollow:active { background: var(--pink-muted); }
.btn-pink-hollow:focus-visible { box-shadow: var(--shadow-focus-pink); }

.btn-blue { background: var(--constellation-blue); color: #fff; }
.btn-blue:hover { background: var(--constellation-blue-hover); box-shadow: 0 6px 16px rgba(58,91,220,.30); }
.btn-blue:focus-visible { box-shadow: var(--shadow-focus); }

.btn-gradient { background: var(--gradient-constellation); color: #fff; overflow: hidden; }
.btn-gradient::before {
    content: ""; position: absolute; inset: 0;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,.15), transparent);
    transform: translateX(-100%);
    transition: transform var(--duration-deliberate) var(--ease-out);
}
.btn-gradient:hover::before { transform: translateX(100%); }
.btn-gradient:hover { box-shadow: 0 8px 24px rgba(126,34,206,.30); transform: translateY(-1px); }

.btn-secondary { background: var(--card-bg); color: var(--text-primary); border: 1px solid var(--border-color); }
.btn-secondary:hover { background: var(--surface-2); border-color: var(--border-hover); transform: translateY(-1px); box-shadow: var(--shadow-sm); }
.btn-secondary:active { background: var(--surface-3); }

.btn-ghost { background: transparent; color: var(--text-secondary); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text-primary); }

.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { background: #B91C1C; box-shadow: 0 6px 16px rgba(220,38,38,.30); }

/* ---------- 5.2 Inputs ---------- */
.input, .textarea, .select {
    width: 100%;
    padding: 10px 14px;
    font-family: var(--font-body); font-size: 13px;
    color: var(--text-primary);
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    outline: none;
    transition: border-color var(--duration-fast) var(--ease-default),
                box-shadow var(--duration-fast) var(--ease-default);
}

/* O <select> nativo desenha a setinha do SO e ignora o tema — aqui ele perde
   a aparência padrão e ganha a nossa (chevron em mask-image, que herda a cor
   do texto e portanto acompanha claro/escuro). */
.select {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    padding-right: 34px;
    cursor: pointer;
    background-image: var(--chevron-down);
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 14px 14px;
}
.select[multiple], .select[size] { padding-right: 14px; background-image: none; cursor: default; }
.select:disabled { cursor: not-allowed; opacity: .6; }
/* IE/Edge legado: some com a seta nativa duplicada */
.select::-ms-expand { display: none; }

/* As opções herdam a superfície do sistema operacional; dar cor evita
   texto preto sobre fundo escuro no dark mode (Chrome/Firefox respeitam). */
.select option {
    background: var(--card-bg);
    color: var(--text-primary);
}
.input::placeholder, .textarea::placeholder { color: var(--text-muted); }
.input:hover, .textarea:hover, .select:hover { border-color: var(--border-hover); }
.input:focus, .textarea:focus, .select:focus { border-color: var(--constellation-blue); box-shadow: var(--shadow-focus); }
/* background-color (não o shorthand): o shorthand apagaria a seta do select */
.input[disabled], .textarea[disabled], .select[disabled] { background-color: var(--surface-2); color: var(--text-disabled); cursor: not-allowed; }
.input.has-error { border-color: var(--danger); box-shadow: 0 0 0 3px rgba(220,38,38,.10); }
.textarea { min-height: 80px; resize: vertical; }

.input-with-icon { position: relative; }
.input-with-icon .input { padding-left: 36px; }
.input-with-icon > svg, .input-with-icon .icon {
    position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%);
    width: 16px; height: 16px; color: var(--text-tertiary); pointer-events: none;
}

.field-label { display: block; font-size: 12px; font-weight: 600; color: var(--text-secondary); margin-bottom: var(--space-2); }
.field-helper { font-size: 11px; color: var(--text-tertiary); margin-top: var(--space-1); }
.field-error { font-size: 11px; color: var(--danger); margin-top: var(--space-1); }

/* ---------- 5.3 Checkbox, radio e switch ----------
   O controle nativo do navegador não tem tema, não aceita o focus ring de
   3px do Constellation e muda de cara em cada SO. Aqui o desenho é nosso:
   `appearance:none` + marca em mask-image, que herda a cor do tema (no dark
   a caixa fica clara e a marca escura, sem precisar de segundo ícone). */
.checkbox, .radio {
    appearance: none; -webkit-appearance: none;
    flex: none;
    width: 18px; height: 18px;
    margin: 0;
    display: inline-grid; place-content: center;
    border: 1.5px solid var(--border-hover);
    background: var(--card-bg);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-default),
                border-color var(--duration-fast) var(--ease-default),
                box-shadow var(--duration-fast) var(--ease-default);
}
.checkbox { border-radius: var(--radius-xs); }
.radio { border-radius: 50%; }

.checkbox::before, .radio::before {
    content: "";
    transform: scale(0);
    transition: transform var(--duration-fast) var(--ease-spring, var(--ease-default));
}
.checkbox::before {
    width: 12px; height: 12px;
    background-color: var(--card-bg);
    -webkit-mask: var(--check-mark) center / contain no-repeat;
            mask: var(--check-mark) center / contain no-repeat;
}
.radio::before {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--card-bg);
}

.checkbox:hover:not(:disabled), .radio:hover:not(:disabled) { border-color: var(--ink); }
.checkbox:checked, .checkbox:indeterminate, .radio:checked { background: var(--ink); border-color: var(--ink); }
.checkbox:checked::before, .radio:checked::before { transform: scale(1); }
.checkbox:indeterminate::before {
    transform: scale(1);
    -webkit-mask-image: var(--check-minus);
            mask-image: var(--check-minus);
}
.checkbox:focus-visible, .radio:focus-visible {
    outline: none;
    border-color: var(--constellation-blue);
    box-shadow: var(--shadow-focus);
}
.checkbox:disabled, .radio:disabled {
    background: var(--surface-2);
    border-color: var(--border-color);
    cursor: not-allowed;
    opacity: .6;
}

/* Switch — mesmo elemento nativo (input[type=checkbox]), aparência de toggle.
   Continua acessível por teclado e por leitor de tela. */
.switch {
    appearance: none; -webkit-appearance: none;
    position: relative; flex: none;
    width: 38px; height: 22px;
    margin: 0;
    border: none; border-radius: var(--radius-full);
    background: var(--surface-4);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-default),
                box-shadow var(--duration-fast) var(--ease-default);
}
.switch::after {
    content: "";
    position: absolute; top: 3px; left: 3px;
    width: 16px; height: 16px;
    border-radius: 50%;
    background: #fff;
    box-shadow: var(--shadow-xs);
    transition: transform var(--duration-fast) var(--ease-default);
}
.switch:hover:not(:disabled) { background: var(--stone-300); }
.switch:checked { background: var(--ink); }
.switch:checked:hover { background: var(--ink-hover); }
.switch:checked::after { transform: translateX(16px); }
:root[data-theme="dark"] .switch:checked::after { background: var(--stone-0); }
.switch:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.switch:disabled { opacity: .5; cursor: not-allowed; }

/* Linha clicável: rótulo + descrição ao lado do controle */
.check-row {
    display: flex; align-items: flex-start; gap: 10px;
    padding: var(--space-2);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-default);
}
.check-row:hover { background: var(--surface-1); }
.check-row-body { min-width: 0; flex: 1; }
.check-row-title { font-size: 13px; font-weight: 500; color: var(--text-primary); line-height: 1.4; }
.check-row-desc { font-size: 12px; color: var(--text-tertiary); margin-top: 2px; line-height: 1.4; }
.check-row input { margin-top: 1px; }
/* switch normalmente fica à direita, empurrado pelo texto */
.check-row .switch { margin-left: auto; margin-top: 0; }

/* Chip selecionável (grade de opções) */
.chip-check {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 10px var(--space-3);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--card-bg);
    cursor: pointer;
    transition: border-color var(--duration-fast) var(--ease-default),
                background var(--duration-fast) var(--ease-default);
}
.chip-check:hover { border-color: var(--border-hover); background: var(--surface-1); }
.chip-check:has(:checked) { border-color: var(--ink); background: var(--ink-muted); }
.chip-check.sel { border-color: var(--ink); background: var(--ink-muted); }
.chip-check-body { min-width: 0; }
.chip-check-title { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.chip-check-desc { font-size: 11px; color: var(--text-tertiary); margin-top: 1px; line-height: 1.4; }
.chip-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-2); }

/* ---------- 5.4 Cards ---------- */
.card {
    background: var(--card-bg);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--duration-normal) var(--ease-default),
                transform var(--duration-normal) var(--ease-default);
}
.card-hoverable:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.card-flush { padding: 0; }
/* Compat: nas telas legadas o padding é do .card-body (definido em style.css),
   então o card externo não pode ter o seu — senão dobra. */
.card:has(> .card-body) { padding: 0; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-4); }
.card-flush .card-head { padding: var(--space-5) var(--space-6); margin-bottom: 0; border-bottom: 1px solid var(--border-color); }
.card-title { font-size: 16px; font-weight: 600; color: var(--text-primary); letter-spacing: -.01em; }
.card-subtitle { font-size: 12px; color: var(--text-tertiary); margin-top: var(--space-1); }

/* ---------- 5.5 MetricCard ---------- */
.metric-card {
    background: var(--card-bg);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6);
    box-shadow: var(--shadow-sm);
    border-left: 3px solid var(--metric-accent, var(--ink));
    display: flex; flex-direction: column; gap: var(--space-2);
    transition: box-shadow var(--duration-normal) var(--ease-default);
}
.metric-card:hover { box-shadow: var(--shadow-md); }
.metric-card-label {
    display: flex; align-items: center; gap: var(--space-2);
    font-size: 10px; font-weight: 700; letter-spacing: .08em;
    text-transform: uppercase; color: var(--text-tertiary);
}
.metric-card-label svg { width: 14px; height: 14px; color: var(--metric-accent, var(--ink)); flex: none; }
.metric-card-value {
    font-size: 28px; font-weight: 700;
    color: var(--text-primary);
    letter-spacing: -.025em; line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.metric-card-foot { font-size: 12px; color: var(--text-tertiary); }
.metric-card-delta { font-size: 12px; font-weight: 600; color: var(--success); display: inline-flex; align-items: center; gap: var(--space-1); }
.metric-card-delta.negative { color: var(--danger); }

.metric-card[data-variant="revenue"]     { --metric-accent: var(--pink); }
.metric-card[data-variant="agents"]      { --metric-accent: var(--constellation-purple); }
.metric-card[data-variant="performance"] { --metric-accent: var(--success); }
.metric-card[data-variant="growth"]      { --metric-accent: var(--warning); }
.metric-card[data-variant="info"]        { --metric-accent: var(--constellation-blue); }

.metric-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4); }
@media (max-width: 1023px) { .metric-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .metric-grid { grid-template-columns: 1fr; } }

/* ---------- 5.6 Callout ---------- */
/* .hidden do Tailwind vem antes deste arquivo na cascata; sem esta regra o
   display:flex abaixo venceria e o callout nunca esconderia. */
.callout.hidden, .btn.hidden, .badge.hidden, .toast.hidden { display: none; }
.callout {
    display: flex; gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-md);
    background: var(--callout-bg, var(--surface-2));
    border-left: 3px solid var(--callout-accent, var(--constellation-blue));
    font-size: 13px;
}
.callout-icon { flex-shrink: 0; width: 18px; height: 18px; color: var(--callout-accent); margin-top: 2px; }
.callout-body { flex: 1; min-width: 0; }
.callout-title { font-weight: 600; color: var(--text-primary); margin-bottom: 2px; }
.callout-text { color: var(--text-secondary); line-height: 1.5; }
.callout[data-variant="hint"]    { --callout-bg: var(--constellation-blue-subtle); --callout-accent: var(--constellation-blue); }
.callout[data-variant="info"]    { --callout-bg: var(--info-soft);    --callout-accent: var(--info); }
.callout[data-variant="success"] { --callout-bg: var(--success-soft); --callout-accent: var(--success); }
.callout[data-variant="warning"] { --callout-bg: var(--warning-soft); --callout-accent: var(--warning); }
.callout[data-variant="danger"]  { --callout-bg: var(--danger-soft);  --callout-accent: var(--danger); }

/* ---------- 5.7 Badge / dot ---------- */
.badge {
    display: inline-flex; align-items: center; gap: var(--space-1);
    font-size: 11px; font-weight: 600;
    padding: 2px var(--space-2);
    border-radius: var(--radius-full);
    letter-spacing: .02em; white-space: nowrap;
}
.badge-success { background: var(--success-soft); color: var(--success); }
.badge-warning { background: var(--warning-soft); color: var(--warning); }
.badge-danger  { background: var(--danger-soft);  color: var(--danger); }
.badge-info    { background: var(--info-soft);    color: var(--info); }
.badge-pink    { background: var(--pink-muted);   color: var(--pink); }
.badge-neutral { background: var(--surface-3);    color: var(--text-secondary); }
:root[data-theme="dark"] .badge-success { color: var(--success-fg); }
:root[data-theme="dark"] .badge-warning { color: var(--warning-fg); }
:root[data-theme="dark"] .badge-danger  { color: var(--danger-fg); }
:root[data-theme="dark"] .badge-info    { color: var(--info-fg); }
/* Dot no badge é OPT-IN (.badge-dot): as telas legadas também usam .badge-*
   e não podem ganhar um ponto de surpresa. Estado nunca é só cor (WCAG) —
   o badge sempre carrega o rótulo junto. */
.badge-dot::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: none; }

/* ---------- 5.7b Selo de fonte de dados / tabela mencionada ---------- */
/* O MATIZ vem de fora, na custom property `--selo-h`, escrita pelo
   js/fonte-cores.js a partir de um hash do identificador. Antes as cores eram
   classes utilitárias do Tailwind e 5 das 8 não existiam no build vendorizado
   (o v2 só traz red/yellow/green/blue/indigo/purple/pink), então quase toda
   fonte aparecia sem cor. Com o matiz calculado não há paleta para faltar, e o
   número de bancos cadastrados deixa de ter teto de cores. */
.selo-fonte {
    --selo-h: 210;
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 10px; font-weight: 600; line-height: 1.6;
    padding: 1px 6px; border-radius: var(--radius-full);
    white-space: nowrap; max-width: 13rem; overflow: hidden; text-overflow: ellipsis;
    background: hsl(var(--selo-h) 85% 94%);
    color: hsl(var(--selo-h) 55% 30%);
    border: 1px solid hsl(var(--selo-h) 60% 87%);
}
.selo-tabela {
    --selo-h: 210;
    display: inline-flex; align-items: baseline; gap: 5px;
    font-size: .85em; font-weight: 600; line-height: 1.5;
    padding: 0 7px; border-radius: var(--radius-md);
    background: hsl(var(--selo-h) 85% 94%);
    color: hsl(var(--selo-h) 55% 30%);
    border: 1px solid hsl(var(--selo-h) 60% 87%);
}
/* A fonte fica dentro do selo, apagada: está lá para desambiguar duas tabelas
   homônimas, não para competir com o nome da tabela pela atenção. */
.selo-tabela-fonte { font-size: .85em; font-weight: 500; opacity: .7; }
.selo-tabela-fonte::after { content: "/"; margin-left: 5px; opacity: .55; }
:root[data-theme="dark"] .selo-fonte,
:root[data-theme="dark"] .selo-tabela {
    background: hsl(var(--selo-h) 40% 18%);
    color: hsl(var(--selo-h) 75% 78%);
    border-color: hsl(var(--selo-h) 35% 32%);
}

/* ---------- 5.7c Autocomplete do "@" (tabelas / colunas) ---------- */
/* UM componente para os DOIS "@": o do chat do dashboard e o do gerador de
   planilhas. Eram dois CSS para a mesma interacao — o do chat com tokens do
   Constellation, o do gerador com header em gradiente e cores Tailwind cruas
   nos itens (que nao seguem o tema). Quem usa as duas telas via dois desenhos
   para a mesma coisa.

   O POSICIONAMENTO fica nos modificadores, e nao na base: o chat ancora o
   painel no composer, o gerador abre no cursor com top/left calculados no JS.
   Sao mecanicas de ancoragem diferentes — a aparencia e que tinha de ser uma
   so. E `max-height` mora na LISTA, nao no painel: o gerador escreve
   `style.display = 'block'` inline, o que anula qualquer layout flex do painel
   e faria a lista ser cortada em vez de rolar. */
.ac-panel {
    z-index: var(--z-dropdown, 300);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--card-bg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}
.ac-panel-composer {                 /* ancorado no campo (chat) */
    position: absolute; bottom: calc(100% + 8px); left: 0;
    width: 22rem; max-width: 90vw;
}
.ac-panel-cursor {                   /* aberto no cursor (gerador, ontologias) */
    position: fixed;
    width: 22rem; max-width: 90vw;
}
/* Dentro de um modal o painel precisa passar POR CIMA dele: a escala de
   z-index põe dropdown (100) abaixo de modal (400), e sem este modificador o
   autocomplete abriria atrás da própria caixa que o chamou. */
.ac-panel-sobre-modal { z-index: calc(var(--z-modal, 400) + 10); }

.ac-head {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-color);
    background: var(--surface-2);
    font-size: 11px; font-weight: 600; color: var(--text-secondary);
}
.ac-head svg { width: 13px; height: 13px; flex: none; opacity: .7; }
.ac-head-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-count { margin-left: auto; flex: none; font-weight: 500; color: var(--text-muted); }
.ac-voltar {
    border: 0; background: transparent; padding: 0;
    color: var(--constellation-blue);
    font: inherit; font-size: 11px; font-weight: 600; cursor: pointer;
    display: inline-flex; align-items: center; gap: 4px;
}
.ac-voltar:hover { text-decoration: underline; }

.ac-list { max-height: 13rem; overflow-y: auto; }

.ac-item {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    font-size: 13px; color: var(--text-primary);
    cursor: pointer;
    border-left: 3px solid transparent;
    transition: background var(--duration-fast, .12s) ease;
}
.ac-item:hover, .ac-item.is-selected {
    background: var(--constellation-blue-subtle);
    border-left-color: var(--constellation-blue);
}
.ac-item-col:hover, .ac-item-col.is-selected {
    background: var(--success-soft);
    border-left-color: var(--success);
}
.ac-item svg { flex: none; width: 14px; height: 14px; color: var(--text-tertiary); }
.ac-item-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; }
.ac-item-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ac-item-meta {
    flex: none; display: flex; align-items: center; gap: 6px;
    font-size: 11px; color: var(--text-muted);
}
.ac-empty {
    padding: var(--space-5) var(--space-3);
    text-align: center; font-size: 12px; color: var(--text-muted);
}

/* Enquanto o catálogo do banco não chega. ESQUELETO, e não spinner: o painel
   abre já com a FORMA da lista que está vindo, então nada salta de tamanho
   quando os dados chegam — e a espera lê como "carregando", não como "travou".
   Isso importa porque sobre VPN essa busca passa de 3s, e um painel vazio
   nesse tempo é lido como "não achou nenhuma tabela". */
.ac-loading { padding: var(--space-1) 0; }
.ac-sk {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-2);
    padding: 10px var(--space-3);
}

/* A barra é o `.skeleton` do design system (5.12) — aqui só a MEDIDA da linha
   do autocomplete. Reimplementar o brilho daria duas animações para manter, e
   foi assim que a primeira versão saiu quebrada enquanto a do design system,
   nunca usada, estava quebrada do mesmo jeito. */
.ac-sk .ac-sk-barra { height: 9px; border-radius: var(--radius-full); }
.ac-sk-nome { flex: 1 1 auto; }
.ac-sk-meta { flex: none; width: 3rem; opacity: .55; }
/* Larguras diferentes por linha: barra toda do mesmo tamanho parece uma tabela
   vazia, não uma lista chegando.

   `nth-of-type` e NÃO `nth-child`: no gerador as linhas vêm de um
   `<template x-for>` do Alpine, que deixa o próprio <template> no DOM como
   âncora. Com `nth-child` a contagem começaria nele e as duas telas ficariam
   com larguras trocadas — `nth-of-type` só conta os <div>, então bate nas duas. */
.ac-sk:nth-of-type(1) .ac-sk-nome { max-width: 58%; }
.ac-sk:nth-of-type(2) .ac-sk-nome { max-width: 72%; }
.ac-sk:nth-of-type(3) .ac-sk-nome { max-width: 46%; }
.ac-sk:nth-of-type(4) .ac-sk-nome { max-width: 65%; }
.ac-sk:nth-of-type(5) .ac-sk-nome { max-width: 52%; }
/* Atraso NEGATIVO: a linha entra com a animação já em andamento, em outra fase.
   Com atraso positivo as linhas de baixo ficavam paradas até 0,36s — parte do
   que fazia o conjunto parecer congelado logo que o painel abria. */
.ac-sk:nth-of-type(2) .ac-sk-barra::after { animation-delay: -.24s; }
.ac-sk:nth-of-type(3) .ac-sk-barra::after { animation-delay: -.48s; }
.ac-sk:nth-of-type(4) .ac-sk-barra::after { animation-delay: -.72s; }
.ac-sk:nth-of-type(5) .ac-sk-barra::after { animation-delay: -.96s; }
.ac-loading-txt {
    display: flex; align-items: center; gap: 7px;
    padding: 2px var(--space-3) 10px;
    font-size: 11px; color: var(--text-muted);
}
.ac-loading-txt::before {
    content: ""; flex: none;
    width: 11px; height: 11px;
    border: 2px solid var(--border-color);
    border-top-color: var(--constellation-blue);
    border-radius: 50%;
    animation: ac-girar .7s linear infinite;
}
@keyframes ac-girar { to { transform: rotate(360deg); } }

/* O anel continua girando em reduced-motion, de propósito: girar 16px num
   canto não é gatilho vestibular, e anel PARADO é lido como "travou" — a forma
   de arco promete rotação. É a decisão registrada na seção 2. */

.ac-foot {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    padding: 5px var(--space-3);
    border-top: 1px solid var(--border-color);
    background: var(--surface-2);
    font-size: 10.5px; color: var(--text-muted);
}
.ac-foot kbd {
    padding: 1px 4px;
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: 10px;
}

/* Selo de VIEW e tipo de coluna — mesmos tokens nas duas telas. */
.ac-view {
    flex: none; font-size: 9.5px; font-weight: 700; letter-spacing: .02em;
    padding: 1px 5px; border-radius: var(--radius-sm);
    background: var(--info-soft); color: var(--info);
}
.ac-type {
    flex: none; font-size: 9px; font-weight: 600; text-transform: uppercase;
    padding: 1px 5px; border-radius: var(--radius-sm);
    background: var(--surface-3); color: var(--text-secondary);
}
.ac-type.integer, .ac-type.int, .ac-type.bigint,
.ac-type.datetime, .ac-type.datetime2   { background: var(--info-soft); color: var(--info); }
.ac-type.decimal, .ac-type.float,
.ac-type.numeric, .ac-type.money        { background: var(--warning-soft); color: var(--warning); }
.ac-type.varchar, .ac-type.nvarchar,
.ac-type.char, .ac-type.text, .ac-type.string { background: var(--constellation-blue-subtle); color: var(--constellation-blue); }
.ac-type.date, .ac-type.timestamp       { background: var(--success-soft); color: var(--success); }
.ac-type.bit, .ac-type.boolean          { background: var(--pink-subtle); color: var(--pink); }

.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--text-muted); flex-shrink: 0; }
.dot-success { background: var(--success); box-shadow: 0 0 8px rgba(22,163,74,.5); }
.dot-warning { background: var(--warning); }
.dot-danger  { background: var(--danger); }
.dot-info    { background: var(--info); }
.dot-pink    { background: var(--pink); box-shadow: 0 0 8px rgba(255,8,107,.5); }
.dot-pulse   { animation: pulse 2s ease-in-out infinite; }

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalIn {
    from { opacity: 0; transform: translateY(12px) scale(.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes slideInRight {
    from { transform: translateX(24px); opacity: 0; }
    to   { transform: translateX(0); opacity: 1; }
}
@keyframes skeletonSlide {
    from { transform: translateX(-100%); }
    to   { transform: translateX(100%); }
}

/* ---------- 5.8 Avatar ---------- */
.avatar {
    width: 36px; height: 36px;
    border-radius: var(--radius-full);
    background: var(--gradient-constellation);
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-weight: 600; font-size: 13px;
    flex-shrink: 0; position: relative;
}
.avatar-sm { width: 24px; height: 24px; font-size: 10px; }
.avatar-md { width: 36px; height: 36px; font-size: 13px; }
.avatar-lg { width: 48px; height: 48px; font-size: 16px; }
.avatar-xl { width: 64px; height: 64px; font-size: 20px; }
.avatar-status {
    position: absolute; bottom: -1px; right: -1px;
    width: 10px; height: 10px; border-radius: 50%;
    border: 2px solid var(--card-bg);
    background: var(--success);
}
/* avatar da sidebar (fundo sempre dark) */
.sb-avatar {
    flex: none;
    width: 34px; height: 34px;
    border-radius: var(--radius-full);
    display: grid; place-items: center;
    color: #fff; font-weight: 700; font-size: 13px;
    background: var(--gradient-constellation);
}

/* ---------- 5.9 Tabs ---------- */
.tab-pill { display: inline-flex; padding: 3px; background: var(--surface-2); border-radius: var(--radius-md); gap: 2px; }
.tab-pill button {
    font-family: var(--font-body); font-size: 12px; font-weight: 500;
    color: var(--text-tertiary);
    padding: 6px 14px;
    background: transparent; border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background var(--duration-fast) var(--ease-default), color var(--duration-fast) var(--ease-default);
}
.tab-pill button:hover { color: var(--text-primary); }
.tab-pill button.active { background: var(--card-bg); color: var(--text-primary); box-shadow: var(--shadow-xs); font-weight: 600; }

.tab-horizontal { display: flex; gap: var(--space-6); border-bottom: 1px solid var(--border-color); }
.tab-horizontal button {
    background: transparent; border: none;
    padding: var(--space-3) 0; margin-bottom: -1px;
    font-size: 13px; font-weight: 500;
    color: var(--text-tertiary);
    border-bottom: 2px solid transparent;
    cursor: pointer;
    display: inline-flex; align-items: center; gap: var(--space-2);
    transition: color var(--duration-fast) var(--ease-default), border-color var(--duration-fast) var(--ease-default);
}
.tab-horizontal button:hover { color: var(--text-primary); }
.tab-horizontal button.active { color: var(--constellation-blue); border-bottom-color: var(--constellation-blue); font-weight: 600; }

/* ---------- 5.10 Tabela enterprise ---------- */
.table-wrap { background: var(--card-bg); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm); }
.table-scroll { overflow-x: auto; }
table.enterprise { width: 100%; border-collapse: collapse; font-size: 13px; }
table.enterprise thead th {
    text-align: left;
    padding: var(--space-3) var(--space-4);
    font-size: 10px; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-tertiary);
    background: var(--surface-1);
    border-bottom: 1px solid var(--border-color);
    white-space: nowrap;
}
table.enterprise tbody td { padding: var(--space-4); border-bottom: 1px solid var(--border-color); color: var(--text-primary); }
table.enterprise tbody tr:last-child td { border-bottom: none; }
table.enterprise tbody tr { transition: background var(--duration-fast) var(--ease-default); }
table.enterprise tbody tr:hover { background: var(--surface-1); }
table.enterprise .num { text-align: right; font-variant-numeric: tabular-nums; }
.table-actions { display: inline-flex; gap: 2px; }
.table-actions .btn-icon { width: 28px; height: 28px; padding: 6px; }
.table-actions .btn-icon svg { width: 14px; height: 14px; }

/* ---------- 5.11 Lista de linhas (assistant row) ---------- */
.row-list { list-style: none; margin: 0; padding: 0; }
.row-item {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-3) var(--space-5);
    border-bottom: 1px solid var(--border-color);
    transition: background var(--duration-fast) var(--ease-default);
}
.row-item:last-child { border-bottom: none; }
.row-item:hover { background: var(--surface-1); }
.row-ico {
    flex: none;
    width: 32px; height: 32px;
    display: grid; place-items: center;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    color: var(--text-tertiary);
}
.row-ico svg { width: 16px; height: 16px; }
.row-main { min-width: 0; flex: 1; }
.row-name { font-size: 13px; font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row-sub  { margin-top: 2px; font-size: 11px; color: var(--text-tertiary); font-family: var(--font-mono); }

/* ---------- 5.12 Empty state + skeleton ---------- */
.empty-state { padding: var(--space-12) var(--space-4); text-align: center; color: var(--text-tertiary); }
.empty-state svg { width: 40px; height: 40px; margin: 0 auto var(--space-3); opacity: .45; display: block; }
.empty-state-title { font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: var(--space-1); }
.empty-state-text { font-size: 13px; color: var(--text-tertiary); margin-bottom: var(--space-4); }

/* O BRILHO É UMA CAMADA QUE ATRAVESSA A BARRA, e não um `background-position`
   animado. A versão anterior ficava PARADA na tela, por dois motivos somados —
   e vale registrar os dois, porque ambos parecem funcionar na leitura do CSS:

   1. `background-size: 200%` com `background-position` em PORCENTAGEM desloca a
      imagem em (elemento − imagem) × porcentagem, ou seja ±2 larguras do
      elemento. A faixa clara passava a maior parte do ciclo FORA da barra: o
      que se via era cor chapada com um lampejo rápido.
   2. O gradiente ia de `--surface-2` (#F4F4F5) a `--surface-3` (#EEEEF0) —
      seis pontos por canal. Mesmo quando passava, não dava para enxergar.

   Com `translateX(-100% → 100%)` o percurso é exatamente duas larguras da
   PRÓPRIA barra, então a faixa está sempre parcialmente visível durante a
   passagem; e transform é composto na GPU, sem repintar gradiente por quadro. */
.skeleton {
    /* A base precisa ser mais ESCURA que o brilho com folga. Com
       `--surface-3` (#EEEEF0) e brilho branco sobravam 14 pontos de diferença
       no pico da varredura — no papel é um gradiente, na tela é a mesma cor.
       `--surface-4` (#E4E4E7) dá quase o dobro, e continua discreto. */
    --sk-base: var(--surface-4);
    --sk-brilho: rgba(255, 255, 255, .92);
    position: relative;
    overflow: hidden;
    border-radius: var(--radius-sm);
    background: var(--sk-base);
}
.skeleton::after {
    content: "";
    position: absolute;
    inset: 0;
    transform: translateX(-100%);
    background: linear-gradient(90deg,
        transparent 0%, var(--sk-brilho) 50%, transparent 100%);
    animation: skeletonSlide 1.2s ease-in-out infinite;
}
/* No escuro o brilho CLAREIA a barra em vez de branquear: branco a 92% sobre
   #2C2C2E seria um flash, não um reflexo. */
:root[data-theme="dark"] .skeleton { --sk-brilho: rgba(255, 255, 255, .11); }
.skeleton-line { height: 12px; margin-bottom: var(--space-2); }
/* Reduced motion NÃO é tratado aqui: o bloco global (seção 2) já converte a
   varredura em pulso, para TODO `.skeleton` do app. Repetir a regra por
   componente foi o terceiro erro documentado lá — a lista de indicadores não
   para de crescer e um esquecimento congela um deles em silêncio. */

/* ---------- 5.13 Modal ---------- */
.modal-overlay {
    position: fixed; inset: 0;
    z-index: var(--z-modal);
    background: rgba(10, 10, 11, .40);
    backdrop-filter: blur(4px);
    display: flex; align-items: center; justify-content: center;
    animation: fadeIn var(--duration-normal) var(--ease-default);
}
.modal {
    background: var(--card-bg);
    border-radius: var(--radius-xl);
    padding: var(--space-6);
    box-shadow: var(--shadow-xl);
    max-width: 480px; width: 100%;
    margin: var(--space-4);
    animation: modalIn var(--duration-slow) var(--ease-default);
}
.modal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-4); }
.modal-title { font-size: 18px; font-weight: 600; }
.modal-body { color: var(--text-secondary); margin-bottom: var(--space-6); line-height: 1.5; }
.modal-actions { display: flex; gap: var(--space-2); justify-content: flex-end; }
@media (max-width: 768px) { .modal { max-width: none; height: 100%; margin: 0; border-radius: 0; } }

/* ---------- 5.13b Dialog (modal com head/body/foot roláveis) ---------- */
.dlg-overlay {
    position: fixed; inset: 0;
    z-index: var(--z-modal);
    display: none; align-items: center; justify-content: center;
    padding: var(--space-4);
}
.dlg-overlay.open { display: flex; }
.dlg-backdrop { position: absolute; inset: 0; background: rgba(10, 10, 11, .55); backdrop-filter: blur(3px); }
.dlg {
    position: relative; z-index: 1;
    display: flex; flex-direction: column;
    width: 100%; max-width: 46rem; max-height: 90vh;
    overflow: hidden;
    background: var(--card-bg);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-2xl);
    animation: modalIn var(--duration-slow) var(--ease-default);
}
.dlg-sm { max-width: 27rem; }
.dlg-head {
    flex: 0 0 auto;
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-bottom: 1px solid var(--border-color);
}
.dlg-title { font-size: 17px; font-weight: 600; color: var(--text-primary); letter-spacing: -.01em; }
.dlg-body {
    flex: 1 1 auto; overflow-y: auto;
    padding: var(--space-5);
    display: flex; flex-direction: column; gap: var(--space-5);
}
.dlg-body::-webkit-scrollbar { width: 8px; }
.dlg-body::-webkit-scrollbar-thumb { background: var(--surface-4); border-radius: var(--radius-md); }
.dlg-foot {
    flex: 0 0 auto;
    display: flex; justify-content: flex-end; gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-top: 1px solid var(--border-color);
}
.dlg-alvo {
    display: block; margin-top: 10px;
    padding: 7px 10px;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    font-size: 13px; font-weight: 600; color: var(--text-primary);
    word-break: break-word;
}
.dlg-icone {
    flex: none;
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border-radius: var(--radius-lg);
}
.dlg-icone svg { width: 20px; height: 20px; }
.dlg-icone[data-tom="danger"]  { background: var(--danger-soft);  color: var(--danger); }
.dlg-icone[data-tom="warning"] { background: var(--warning-soft); color: var(--warning); }
.dlg-icone[data-tom="success"] { background: var(--success-soft); color: var(--success); }
.dlg-icone[data-tom="info"]    { background: var(--info-soft);    color: var(--info); }
@media (max-width: 640px) { .dlg { max-height: 100%; height: 100%; border-radius: 0; } }

/* ---------- 5.13b2 Espera (ação que depende do servidor) ---------- */
.busy-overlay {
    position: fixed; inset: 0;
    z-index: var(--z-modal);
    display: flex; align-items: center; justify-content: center;
    padding: var(--space-4);
    background: rgba(10, 10, 11, .55);
    backdrop-filter: blur(3px);
    animation: fadeIn var(--duration-fast) var(--ease-default);
}
.busy-box {
    width: 100%; max-width: 22rem;
    padding: var(--space-6);
    border-radius: var(--radius-xl);
    background: var(--card-bg);
    box-shadow: var(--shadow-2xl);
    text-align: center;
}
.busy-spin {
    width: 32px; height: 32px;
    margin: 0 auto var(--space-4);
    border: 3px solid var(--surface-3);
    border-top-color: var(--constellation-blue);
    border-radius: 50%;
    animation: busySpin .8s linear infinite;
}
@keyframes busySpin { to { transform: rotate(360deg); } }
.busy-title { font-size: 15px; font-weight: 600; color: var(--text-primary); }
.busy-msg { margin-top: var(--space-2); font-size: 13px; line-height: 1.5; color: var(--text-tertiary); }
.busy-bar {
    height: 3px; margin-top: var(--space-4);
    border-radius: var(--radius-full);
    background: var(--surface-3);
    overflow: hidden;
}
.busy-bar > i {
    display: block; width: 40%; height: 100%;
    border-radius: var(--radius-full);
    background: var(--gradient-constellation);
    animation: busySlide 1.4s var(--ease-default) infinite;
}
@keyframes busySlide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}
.busy-elapsed { margin-top: 10px; font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) {
    .busy-spin, .busy-bar > i { animation: none; }
}

/* ---------- 5.13c Toast ---------- */
.toast-wrap {
    position: fixed; bottom: var(--space-6); right: var(--space-6);
    z-index: var(--z-toast);
    display: flex; flex-direction: column; gap: var(--space-2);
    max-width: min(420px, calc(100vw - var(--space-8)));
}
.toast {
    display: flex; align-items: flex-start; gap: 10px;
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-lg);
    background: var(--card-bg);
    box-shadow: var(--shadow-lg);
    border-left: 3px solid var(--toast-accent, var(--ink));
    font-size: 13px; color: var(--text-primary);
    animation: slideInRight var(--duration-slow) var(--ease-default);
}
.toast svg { flex: none; width: 17px; height: 17px; color: var(--toast-accent, var(--ink)); margin-top: 1px; }
.toast[data-tom="success"] { --toast-accent: var(--success); }
.toast[data-tom="danger"]  { --toast-accent: var(--danger); }
.toast[data-tom="warning"] { --toast-accent: var(--warning); }
.toast[data-tom="info"]    { --toast-accent: var(--constellation-blue); }
.toast.saindo { opacity: 0; transform: translateX(24px); transition: opacity var(--duration-normal), transform var(--duration-normal); }
@media (max-width: 640px) {
    .toast-wrap { left: var(--space-4); right: var(--space-4); bottom: var(--space-4); max-width: none; }
}

/* ---------- 5.14 Toolbar de página ---------- */
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-5); flex-wrap: wrap; margin-bottom: var(--space-6); }
.page-head-title { font-size: 27px; font-weight: 700; letter-spacing: -.025em; color: var(--text-primary); margin: 0 0 var(--space-1); }
.page-head-sub { font-size: 14px; color: var(--text-tertiary); margin: 0; }
.page-head-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.toolbar {
    display: flex; align-items: center; gap: var(--space-3);
    flex-wrap: wrap;
    padding: var(--space-4);
    margin-bottom: var(--space-4);
    background: var(--card-bg);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}
.toolbar-grow { flex: 1; min-width: 200px; }

.section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-3); }
.section-link { font-size: 13px; font-weight: 500; color: var(--text-tertiary); text-decoration: none; white-space: nowrap; }
.section-link:hover { color: var(--constellation-blue); }

/* ==========================================================================
   6. COMPATIBILIDADE — classes do layout antigo ainda usadas por telas
      não migradas. Ao migrar uma tela, troque pelas classes acima e apague
      o uso aqui quando ninguém mais referenciar.
   ========================================================================== */
.text-plugia-purple { color: var(--plugia-purple) !important; }
.text-plugia-pink   { color: var(--plugia-pink) !important; }
.text-plugia-blue   { color: var(--plugia-blue) !important; }
.border-plugia-purple { border-color: var(--plugia-purple) !important; }
.border-plugia-pink   { border-color: var(--plugia-pink) !important; }
.border-plugia-blue   { border-color: var(--plugia-blue) !important; }
.bg-plugia-purple { background-color: var(--plugia-purple) !important; }
.bg-plugia-pink   { background-color: var(--plugia-pink) !important; }
.bg-plugia-blue   { background-color: var(--plugia-blue) !important; }
.from-plugia-purple {
    --tw-gradient-from: var(--plugia-purple);
    --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(99, 102, 241, 0));
}
.to-plugia-pink { --tw-gradient-to: var(--plugia-pink); }
.to-plugia-blue { --tw-gradient-to: var(--plugia-blue); }

.gradient-bg { background: var(--gradient-constellation); }
.glass-effect { backdrop-filter: blur(10px); background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.2); }
.card-hover { transition: transform var(--duration-slow) var(--ease-default), box-shadow var(--duration-slow) var(--ease-default); }
.card-hover:hover { transform: translateY(-2px); box-shadow: var(--shadow-lg); }
.btn-primary { background: var(--gradient-constellation); transition: transform var(--duration-slow) var(--ease-default), box-shadow var(--duration-slow) var(--ease-default); }
.btn-primary:hover { transform: translateY(-1px); box-shadow: 0 5px 15px rgba(58,91,220,.4); }
.progress-bar { background: var(--gradient-constellation); }
.dropdown-menu { z-index: var(--z-dropdown); }


/* ============================================================================
 * Item de COLEÇÃO de documentos
 * ----------------------------------------------------------------------------
 * O MESMO objeto aparece em duas telas: o seletor do composer do chat e o do
 * gerador de planilhas. Mora aqui, e não na CSS de uma delas, porque as duas
 * carregam este arquivo pelo base.html — e porque o visual já tinha divergido
 * uma vez (o gerador mostrava só nome + contagem, sem o subtítulo nem os
 * ícones de tipo).
 *
 * AUTO-CONTIDO de propósito: no chat ele convive com `.composer-menu-item`,
 * no gerador anda sozinho dentro de `.q-planilha-menu`. Depender do shell de
 * uma das telas quebraria a outra. As poucas linhas que reconciliam com o
 * shell do chat ficam em pages/chat.css, ao lado do shell que as motiva.
 *
 * A seleção é mostrada pelo CHECKBOX marcado, não por fundo colorido — é como
 * o chat sempre fez, e é o que permite ler a lista de relance sem que várias
 * pastas marcadas virem um bloco de cor.
 * ========================================================================== */
.colecao-option {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2);
    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--text-primary);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
}

.colecao-option:hover { background: var(--surface-2); }

.colecao-option .checkbox { flex: none; margin-top: 0; }

/* Corpo: nome + subtítulo, ocupando a largura que sobra. `min-width: 0` é o
   que autoriza o filho a encolher dentro do flex — sem ele o texto empurra
   os ícones para fora do menu. */
.colecao-option-corpo { flex: 1 1 auto; min-width: 0; }
.colecao-option-corpo b { display: block; font-weight: 500; }
.colecao-option-corpo small {
    display: block;
    font-size: 11.5px; line-height: 1.45;
    color: var(--text-tertiary);
}

/* Uma linha por campo. A descrição de uma coleção é livre e podia ter três
   linhas, deixando as opções com alturas diferentes num menu que se lê de
   relance; o `title` no item continua entregando o texto inteiro. */
.colecao-option-corpo b,
.colecao-option-corpo small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Ícones dos tipos de arquivo, à direita. `flex: 0 0 auto` porque eles têm o
   tamanho deles — quem estica é o corpo. */
.colecao-tipos {
    display: inline-flex;
    gap: 3px;
    flex: 0 0 auto;
    color: var(--text-muted);
}
.colecao-tipos svg { width: 13px; height: 13px; }
