/* ════════════════════════════════════════
   GOOGLE FONTS — Inter
════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');

/* ════════════════════════════════════════
   DESIGN TOKENS — ZEUS × UNI
════════════════════════════════════════ */
:root {
    /* Brand */
    --zeus-amber:   #F5A623;
    --zeus-amber2:  #FFB84D;
    --uni-orange:   #E84C20;
    --uni-red:      #C73A14;

    /* Dark surfaces */
    --bg:           #0d0e14;
    --bg-2:         #12141e;
    /* Opaca de propósito: usada por cabeçalho fixo de tabela, onde fundo
       translúcido deixa a linha de baixo aparecer através. */
    --surface-solid: #191b26;
    /* O par da de cima, para as linhas pares: a primeira coluna é fixa e precisa
       de fundo opaco, mas com um só tom ela ignorava o zebrado e virava uma
       faixa uniforme ao lado de linhas alternadas. Equivale a --surface-solid
       com o mesmo 2% de branco que `tbody tr:nth-child(even)` aplica. */
    --surface-solid-2: #1d1f29;
    --surface:      rgba(255,255,255,0.04);
    --surface-2:    rgba(255,255,255,0.07);
    --surface-hover:rgba(255,255,255,0.10);
    --glass-border: rgba(255,255,255,0.09);
    --glass-border2:rgba(255,255,255,0.15);

    /* Text */
    --text:         #f0f2f7;
    --text-2:       #a8b2c8;
    --text-3:       #5a6480;
    --muted:        #8893ae;

    /* Accents (status) */
    --green:    #22c97a;
    --red:      #ff4d6a;
    --yellow:   #f5c518;
    --orange:   #ff8c42;
    --purple:   #9d6ef5;
    --blue:     #4da6ff;
    --teal:     #2ec4b6;
    --gray:     #6b7a99;

    /* Glow */
    --glow-amber:  0 0 24px rgba(245,166,35,0.25);
    --glow-orange: 0 0 20px rgba(232,76,32,0.20);
    --glow-green:  0 0 16px rgba(34,201,122,0.20);

    /* Topbar */
    --topbar-h: 64px;
    --sidebar-w: 264px;
    --sidebar-collapsed-w: 82px;

    /* Radii */
    --r-sm: 8px;
    --r-md: 12px;
    --r-lg: 16px;

    /* Avisa o navegador que a interface é escura. Sem isto, os controles
       nativos (lista do select, calendário do input date, barra de rolagem)
       são desenhados em branco pelo sistema e o texto claro some no fundo. */
    color-scheme: dark;

    /* ── ESCALA DE ESPAÇO ─────────────────────────────────────────────────
       O arquivo tinha 695 valores em px, usando quase todo número de 2 a 20.
       Componentes irmãos escolhiam espaçamentos diferentes sem motivo, e por
       isso mudança de conteúdo desalinhava a página: não havia referência
       comum. Tudo aqui é múltiplo de 4. */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 24px;
    --sp-6: 32px;
    --sp-7: 48px;

    /* ── ESCALA TIPOGRÁFICA ───────────────────────────────────────────────
       Fluida: o painel roda de 1280 a 2560, e com tamanho fixo o texto ficava
       minúsculo nas telas grandes. Eram 18 tamanhos distintos; agora 6. */
    --fs-caption: clamp(9.5px,  0.10vw + 8.9px,  11px);
    --fs-sm:      clamp(11px,   0.12vw + 10.3px, 12.5px);
    --fs-body:    clamp(12px,   0.16vw + 11.2px, 14px);
    --fs-lg:      clamp(14px,   0.30vw + 12.8px, 17px);
    --fs-xl:      clamp(17px,   0.55vw + 14.8px, 23px);
    --fs-2xl:     clamp(21px,   0.95vw + 17.2px, 31px);

    /* ── CONTROLES ────────────────────────────────────────────────────────
       Uma altura só para input, select e botão — é o que alinha uma barra de
       filtros onde um campo é select e o vizinho é input de data. */
    --ctrl-h:    38px;
    --ctrl-h-sm: 30px;
    --ctrl-h-lg: 46px;

    /* ── MOVIMENTO ────────────────────────────────────────────────────────── */
    --dur-1: .12s;
    --dur-2: .2s;
    --dur-3: .34s;
    --ease:  cubic-bezier(.2, .6, .2, 1);

    /* ── GRADE ────────────────────────────────────────────────────────────
       Medido: em 1440px sobram ~1136px depois da sidebar e do respiro. Como o
       cartão de valor total ocupa duas colunas, são 7 espaços a dividir — o
       mínimo precisa ficar abaixo de 155px para caberem numa linha. Em 150px o
       subtítulo mais longo ("R$ 1.234.567,89 · 45%") ainda não transborda. */
    --card-min:  150px;
    --panel-min: 340px;
}

/* Quem pediu menos movimento no sistema recebe a interface sem animação —
   inclusive as de entrada, que são as mais incômodas para quem tem
   sensibilidade vestibular. As transições viram instantâneas em vez de
   desaparecer, para que estados de foco continuem visíveis. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

/* ════════════════════════════════════════
   APP SIDEBAR
════════════════════════════════════════ */
.app-body {
    padding-left: var(--sidebar-w);
    /* Sem transição PERMANENTE aqui de propósito: o padding reage a qualquer
       mudança da largura, não só ao clique — com ela sempre ligada, a página
       deslizava a cada redimensionamento da janela, e num arraste contínuo o
       valor ficava perseguindo o destino.

       Ela é ligada só enquanto o recolher está acontecendo, pela classe
       `sidebar-animando` que assets/js/app-shell.js põe no clique e tira no
       fim. Sem isso, a barra deslizava e o conteúdo saltava de uma vez — o
       descompasso que fazia o movimento parecer quebrado. */
}

.app-body.sidebar-animando {
    transition: padding-left .34s cubic-bezier(.22,1,.36,1);
}
.app-sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 1000;
    width: var(--sidebar-w);
    display: flex;
    flex-direction: column;
    background:
        radial-gradient(circle at 10% 0, rgba(245,166,35,.11), transparent 35%),
        linear-gradient(180deg, #11131c 0%, #090a10 100%);
    border-right: 1px solid rgba(255,255,255,.08);
    box-shadow: 16px 0 40px rgba(0,0,0,.24);
    /* Mesma duração e mesma curva do `padding-left` do body (.app-body.sidebar-animando):
       os dois precisam andar juntos, senão a barra chega antes e o conteúdo
       parece correr atrás. A curva desacelera longo no fim, que é o que dá o
       assentamento em vez da parada seca do `ease`. */
    transition: width .34s cubic-bezier(.22,1,.36,1), transform .34s cubic-bezier(.22,1,.36,1);
}
.sidebar-brand {
    min-height: 76px;
    /* Não encolhe: o espaço que faltar sai da nav, que rola. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 16px 0 18px;
    border-bottom: 1px solid rgba(255,255,255,.07);
}
.sidebar-brand-logos { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sidebar-brand-logos span { width: 1px; height: 28px; background: rgba(255,255,255,.14); }
.sidebar-zeus { width: 84px; height: 38px; object-fit: contain; filter: drop-shadow(0 0 8px rgba(245,166,35,.35)); }
.sidebar-uni { width: 64px; height: 28px; object-fit: contain; }
.sidebar-collapse {
    width: 30px; height: 30px; padding: 0; flex: 0 0 30px;
    display: grid; place-items: center;
    color: var(--text-2); background: rgba(255,255,255,.05);
    border: 1px solid rgba(255,255,255,.08); border-radius: 8px;
    box-shadow: none;
}
.sidebar-collapse:hover { background: rgba(255,255,255,.09); box-shadow: none; transform: none; }
.sidebar-collapse svg, .sidebar-icon svg, .sidebar-logout svg {
    width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.sidebar-context { padding: 22px 20px 14px; display: flex; flex-direction: column; flex: 0 0 auto; }
.sidebar-eyebrow, .sidebar-section-label {
    color: var(--zeus-amber); font-size: 9px; font-weight: 800;
    letter-spacing: 1.2px; text-transform: uppercase;
}
.sidebar-context strong { margin-top: 6px; font-size: 17px; letter-spacing: -.3px; }
.sidebar-context small { margin-top: 3px; font-size: 11px; color: var(--muted); }
/* A nav é quem rola quando a tela não comporta todos os módulos — a marca, o
   contexto e o rodapé com o usuário ficam parados.
   `min-height: 0` não é detalhe: dentro de um flex column, o item tem
   `min-height: auto` e se recusa a encolher abaixo do próprio conteúdo, então o
   `overflow-y: auto` nunca entrava em ação. A lista simplesmente crescia além da
   tela e os últimos módulos ficavam inalcançáveis, sem barra de rolagem. */
.sidebar-nav {
    padding: 8px 12px 18px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,.18) transparent;
}
/* Os grupos não encolhem: mantêm a altura do próprio conteúdo e empurram a nav
   para rolar.
   Sem isto, o `flex-shrink: 1` que todo filho de flex column herda fazia os
   grupos se comprimirem para caber na altura disponível. Como `.client-group`
   tem `overflow: hidden`, o conteúdo espremido era cortado — o último módulo
   aparecia pela metade e a barra de rolagem nunca surgia, porque para o
   navegador tudo "cabia". É o par que faltava do `min-height: 0` acima: um
   deixa o contêiner rolar, o outro impede que os filhos encolham em vez de
   transbordar. */
.sidebar-nav > * { flex-shrink: 0; }

.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-track { background: transparent; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.16); border-radius: 4px; }
.sidebar-nav::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.28); }
/* Telas baixas (notebook com a barra do sistema, janela reduzida): a marca, o
   bloco de contexto e o rodapé somam ~250px fixos e sobrava uma fresta para os
   módulos — rolava, mas mostrando um item por vez. Aqui o contexto sai e o
   resto comprime, devolvendo a altura para a lista. */
@media (max-height: 760px) {
    .sidebar-context { display: none; }
    .sidebar-brand { min-height: 62px; }
    .sidebar-zeus { width: 70px; height: 32px; }
    .sidebar-uni { width: 54px; height: 24px; }
    .sidebar-nav { padding-top: 14px; }
    .sidebar-footer { padding: 10px 12px 12px; }
}
@media (max-height: 560px) {
    .sidebar-brand { min-height: 52px; }
    .sidebar-section-label { display: none; }
    .client-group-toggle { min-height: 42px; }
}
.sidebar-section-label { padding: 0 9px 8px; color: var(--text-3); }
.client-group { border: 1px solid transparent; border-radius: 13px; overflow: hidden; transition: background .18s, border-color .18s; }
.client-group.open { background: rgba(255,255,255,.025); border-color: rgba(255,255,255,.065); }
.client-group-toggle {
    width: 100%; min-height: 50px; padding: 7px 9px;
    display: flex; align-items: center; gap: 10px;
    color: var(--text-2); text-align: left; border: 0; border-radius: 11px;
    background: transparent; box-shadow: none;
}
.client-group-toggle:hover { color: var(--text); background: rgba(255,255,255,.045); transform: none; box-shadow: none; }
.client-group-toggle.active { color: var(--text); }
.client-monogram {
    width: 32px; height: 32px; flex: 0 0 32px; display: grid; place-items: center;
    border-radius: 9px; color: var(--text-2); font-size: 12px; font-weight: 900;
    background: linear-gradient(145deg, rgba(255,255,255,.1), rgba(255,255,255,.035));
    border: 1px solid rgba(255,255,255,.08);
}
.client-group-toggle.active .client-monogram {
    color: #161008; background: linear-gradient(135deg, var(--zeus-amber), var(--uni-orange));
    border-color: transparent; box-shadow: 0 5px 15px rgba(245,166,35,.2);
}

/* O quadradinho com um ÍCONE em vez de letra ou logo — hoje só o grupo Admin.
 *
 * Precisa da mesma receita de traço dos outros ícones da barra (.sidebar-icon
 * svg, lá em cima): sem `fill: none` o escudo sai como um borrão sólido, e sem
 * `stroke: currentColor` ele some, porque o SVG não herda cor sozinho.
 *
 * O tamanho acompanha o quadradinho em vez de ser fixo em 19px: o monograma
 * mede 32px na sidebar e 26px na tabela do Painel Geral, e um número cravado
 * ficaria apertado num e sobrando no outro. */
.client-monogram.is-icone svg {
    width: 60%; height: 60%; fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}

/* ── O QUADRADINHO COM O LOGO DO CLIENTE ──
 *
 * O gradiente e a borda saem: o logo já traz o próprio fundo (o verde da
 * Norcoast), e deixá-los desenharia uma moldura clara em volta dele — que é
 * justamente o que se queria tirar. `overflow: hidden` com o mesmo raio recorta
 * o canto da imagem no formato do quadrado.
 *
 * `padding: 0` explícito porque .client-monogram é grid com place-items:center,
 * e qualquer respiro herdada reapareceria como faixa da cor de baixo.
 */
.client-monogram.is-logo {
    background: none; border-color: transparent; box-shadow: none;
    overflow: hidden; padding: 0;
}

/* `contain` e não `cover`: os dois tipos de logo convivem aqui.
 *
 * O da Norcoast é um quadrado sólido 204x204 — para ele tanto faz, os dois
 * preenchem igual. O da Mercosul é 31x32 com fundo TRANSPARENTE: um círculo
 * que flutua sobre o fundo da sidebar. Com `cover`, esses 32 avos de diferença
 * viravam corte na altura e comiam a borda do círculo. `contain` nunca corta;
 * no máximo deixa uma folga de 1px, que sobre fundo transparente ninguém vê. */
.client-monogram.is-logo img {
    width: 100%; height: 100%; object-fit: contain; display: block;
}

/* O cliente aberto ganha o gradiente âmbar no monograma — mas quando há logo
 * isso pintaria por baixo dele e vazaria nos cantos arredondados. O destaque de
 * "está aberto" continua existindo: vem do chevron girado e do texto em
 * destaque, que não dependem do quadradinho. */
.client-group-toggle.active .client-monogram.is-logo {
    background: none; box-shadow: 0 5px 15px rgba(0,0,0,.25);
}
.client-group-copy { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.client-group-copy strong { font-size: 12px; white-space: nowrap; }
.client-group-copy small { color: var(--text-3); font-size: 9px; white-space: nowrap; }
.client-chevron {
    width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round; transition: transform .2s;
}
.client-group.open .client-chevron { transform: rotate(90deg); }
.client-group-content { display: none; padding: 2px 5px 6px 13px; }
.client-group.open .client-group-content { display: flex; flex-direction: column; gap: 4px; }
.client-empty {
    margin: 2px 0 5px 36px; padding: 8px 10px; color: var(--text-3);
    font-size: 9px; border-left: 1px dashed rgba(255,255,255,.14);
}
.sidebar-link {
    position: relative; min-height: 50px; padding: 7px 9px;
    display: flex; align-items: center; gap: 12px;
    color: var(--text-2); border: 1px solid transparent; border-radius: 12px;
    transition: color .18s, background .18s, border-color .18s;
}
.sidebar-link:hover { color: var(--text); background: rgba(255,255,255,.055); }
.sidebar-link.active {
    color: #fff;
    background: linear-gradient(135deg, rgba(245,166,35,.18), rgba(232,76,32,.09));
    border-color: rgba(245,166,35,.22);
    box-shadow: inset 3px 0 0 var(--zeus-amber), 0 8px 24px rgba(0,0,0,.12);
}
.sidebar-icon {
    width: 36px; height: 36px; flex: 0 0 36px; display: grid; place-items: center;
    border-radius: 10px; color: var(--muted); background: rgba(255,255,255,.05);
}
.sidebar-link.active .sidebar-icon { color: var(--zeus-amber); background: rgba(245,166,35,.12); }
.sidebar-link-copy { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sidebar-link-copy strong { font-size: 12px; white-space: nowrap; }
.sidebar-link-copy small { color: var(--muted); font-size: 9px; white-space: nowrap; }
.sidebar-footer {
    margin-top: auto; padding: 14px 12px 18px; border-top: 1px solid rgba(255,255,255,.07);
    flex: 0 0 auto;
    display: flex; align-items: center; gap: 8px;
}
.sidebar-user { min-width: 0; flex: 1; display: flex; align-items: center; gap: 10px; padding: 6px; }
.sidebar-avatar {
    width: 35px; height: 35px; flex: 0 0 35px; border-radius: 10px;
    display: grid; place-items: center; color: #111; font-weight: 900;
    background: linear-gradient(135deg, var(--zeus-amber), var(--uni-orange));
}
.sidebar-user-copy { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sidebar-user-copy strong { max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 11px; }
.sidebar-user-copy small { color: var(--muted); font-size: 9px; }
.sidebar-logout {
    width: 35px; height: 35px; flex: 0 0 35px; display: grid; place-items: center;
    color: var(--text-3); border: 1px solid rgba(255,255,255,.08); border-radius: 10px;
}
.sidebar-logout:hover { color: var(--red); border-color: rgba(255,77,106,.25); background: rgba(255,77,106,.08); }
.sidebar-logout span { display: none; }
.sidebar-mobile-toggle, .sidebar-overlay { display: none; }

.sidebar-collapsed.app-body { padding-left: var(--sidebar-collapsed-w); }
.sidebar-collapsed .app-sidebar { width: var(--sidebar-collapsed-w); }

/* ── O texto que some quando a barra recolhe ──
 *
 * Era `display: none`, que não anima: os rótulos desapareciam de um quadro para
 * o outro enquanto a barra ainda deslizava, e esse corte seco é o que fazia o
 * movimento parecer quebrado mesmo com a largura animando bonito.
 *
 * Agora eles desvanecem e deslizam um pouco para a esquerda, acompanhando a
 * borda que se aproxima. O `max-width: 0` no fim é o que garante que não
 * ocupem espaço nem vazem da barra de 82px — opacidade sozinha esconderia o
 * texto mas ele continuaria empurrando o layout.
 *
 * `visibility` entra junto para o rótulo invisível não continuar clicável nem
 * ser lido por leitor de tela. */
/* EXPANDINDO: o texto entra DEPOIS que a barra já abriu espaço — daí o atraso
   de .14s. Sem ele, o rótulo aparece espremido contra a borda e vai sendo
   empurrado, que é a parte que mais denuncia a animação. */
.sidebar-brand-logos .sidebar-uni,
.sidebar-brand-logos span,
.sidebar-context,
.sidebar-section-label,
.client-group-copy,
.client-chevron,
.sidebar-link-copy,
.sidebar-user-copy {
    transition:
        opacity .22s ease .14s,
        max-width .26s ease .14s,
        transform .24s cubic-bezier(.22,1,.36,1) .14s,
        visibility 0s linear 0s;
}

/* RECOLHENDO: sem atraso e mais rápido — o texto sai da frente antes de a barra
   estreitar. O `visibility` só vira hidden no fim (.16s), senão o rótulo some
   de uma vez em vez de desvanecer. */
.sidebar-collapsed .sidebar-brand-logos .sidebar-uni,
.sidebar-collapsed .sidebar-brand-logos span,
.sidebar-collapsed .sidebar-context,
.sidebar-collapsed .sidebar-section-label,
.sidebar-collapsed .client-group-copy,
.sidebar-collapsed .client-chevron,
.sidebar-collapsed .sidebar-link-copy,
.sidebar-collapsed .sidebar-user-copy {
    opacity: 0;
    visibility: hidden;
    max-width: 0;
    margin: 0;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    transform: translateX(-8px);
    transition:
        opacity .16s ease,
        max-width .24s ease,
        transform .18s ease,
        visibility 0s linear .16s;
}
/* ── ÍCONES QUE NÃO SE MEXEM AO RECOLHER (14/09/2026) ──
 *
 * Antes, recolhida, cada linha usava `justify-content: center`. Dois defeitos
 * saíam daí, medidos na barra de 82px:
 *
 * · DESALINHADO: o texto some com `max-width: 0`, mas o `gap` entre o ícone e o
 *   texto continuava valendo. O "centro" incluía esse vão vazio, e os ícones
 *   ficavam à esquerda: logo ZEUS -10px, logos dos clientes -16px, Painel Geral
 *   -12px, módulos -8px, avatar -5px. A barra de rolagem da nav (10px) somava
 *   mais um deslocamento só aos itens dela.
 *
 * · A ANIMAÇÃO "PULAVA": centralizar no clique mandava o ícone para o meio da
 *   barra AINDA LARGA (264px) e depois ele vinha deslizando junto com a borda —
 *   grande, depois pequeno e torto no meio do caminho.
 *
 * Agora nada é centralizado. Cada ícone fica alinhado à esquerda com um recuo
 * calculado para cair exatamente no centro da barra de 82px, e esse recuo é
 * quase o mesmo da barra aberta. Resultado: ao recolher e expandir, os ícones
 * ficam parados; só o texto some e a borda anda.
 *
 * As contas (centro = (82 - largura do ícone) / 2 a partir da borda):
 *   nav 12px + borda 1px + recuo = centro
 *   Painel Geral (ícone 36): 12 + 1 + 10 = 23
 *   cliente (monograma 32):  12 + 1 (grupo) + 12 = 25
 *   módulo (ícone 36):       12 + 1 (grupo) + 0 + 1 + 9 = 23
 *   logo ZEUS (42):          20 = 20
 *   botão recolher (30):     20 + 6 = 26
 */
.sidebar-brand-logos,
.client-group-toggle,
.client-group-content,
.sidebar-user,
.sidebar-footer {
    transition: gap .34s cubic-bezier(.22,1,.36,1), padding .34s cubic-bezier(.22,1,.36,1);
}
.sidebar-link {
    transition: color .18s, background .18s, border-color .18s,
        gap .34s cubic-bezier(.22,1,.36,1), padding .34s cubic-bezier(.22,1,.36,1);
}
.sidebar-zeus { transition: width .34s cubic-bezier(.22,1,.36,1), height .34s cubic-bezier(.22,1,.36,1); }

/* Recolhida, a marca vira coluna: logo em cima, botão de expandir embaixo.
   Antes o botão ficava com `right: -15px`, metade dele para fora da barra de
   82px — e aparecia cortado. Alinhados à esquerda pelo mesmo motivo dos
   ícones: centralizar jogava os dois para o meio da barra ainda larga. */
.sidebar-collapsed .sidebar-brand {
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 9px;
    padding: 12px 0 12px 20px;
}
.sidebar-collapsed .sidebar-brand-logos { gap: 0; }
.sidebar-collapsed .sidebar-zeus { width: 42px; height: 32px; }
.sidebar-collapsed .sidebar-collapse {
    position: static;
    margin-left: 6px;
    transform: rotate(180deg);
}
.sidebar-collapsed .sidebar-nav {
    padding-top: 24px;
    /* A barra de rolagem roubava 10px só da nav e empurrava os ícones dela
       para a esquerda do logo e do rodapé. Continua rolando, sem a barra. */
    scrollbar-width: none;
}
.sidebar-collapsed .sidebar-nav::-webkit-scrollbar { display: none; }
.sidebar-collapsed .client-group { overflow: visible; }
.sidebar-collapsed .client-group-toggle { gap: 0; padding: 7px 7px 7px 12px; }
.sidebar-collapsed .client-group-content { display: none; padding: 2px 0 6px; }
.sidebar-collapsed .sidebar-link { gap: 0; padding: 7px 7px 7px 10px; }
.sidebar-collapsed .client-group-content .sidebar-link { padding-left: 9px; }
/* Mesma lógica dos ícones: coluna alinhada à esquerda com recuo de 23px, que
   centraliza o avatar e o Sair (35px) em 82px sem pular para o meio da barra
   larga no começo da animação. */
.sidebar-collapsed .sidebar-footer { flex-direction: column; align-items: flex-start; padding-left: 23px; padding-right: 0; }
.sidebar-collapsed .sidebar-user { flex: none; gap: 0; padding: 0; }

@media (max-width: 900px) {
    .app-body, .sidebar-collapsed.app-body { padding-left: 0; }
    .app-sidebar, .sidebar-collapsed .app-sidebar { width: min(290px, 86vw); transform: translateX(-105%); }
    .sidebar-mobile-open .app-sidebar { transform: translateX(0); }
    .sidebar-mobile-toggle {
        position: fixed; top: 14px; left: 12px; z-index: 1100;
        width: 38px; height: 38px; padding: 9px; display: flex; flex-direction: column;
        justify-content: center; gap: 4px; background: rgba(17,19,28,.94);
        border: 1px solid rgba(255,255,255,.12); box-shadow: 0 8px 24px rgba(0,0,0,.3);
    }
    .sidebar-mobile-toggle span { display: block; width: 100%; height: 2px; background: var(--zeus-amber); border-radius: 2px; }
    .sidebar-overlay { position: fixed; inset: 0; z-index: 999; background: rgba(0,0,0,.66); backdrop-filter: blur(3px); }
    .sidebar-mobile-open .sidebar-overlay { display: block; }
    .sidebar-collapse { display: none; }
    .sidebar-collapsed .sidebar-brand-logos .sidebar-uni,
    .sidebar-collapsed .sidebar-brand-logos span,
    .sidebar-collapsed .sidebar-context,
    .sidebar-collapsed .sidebar-section-label,
    .sidebar-collapsed .client-group-copy,
    .sidebar-collapsed .client-chevron,
    .sidebar-collapsed .sidebar-link-copy,
    .sidebar-collapsed .sidebar-user-copy { display: flex; }
    .sidebar-collapsed .sidebar-brand { flex-direction: row; align-items: center; justify-content: space-between; padding: 0 16px 0 18px; }
    .sidebar-collapsed .sidebar-brand-logos { gap: 10px; }
    .sidebar-collapsed .sidebar-zeus { width: 84px; }
    .sidebar-collapsed .sidebar-collapse { margin-left: 0; }
    .sidebar-collapsed .sidebar-nav { padding-top: 8px; scrollbar-width: thin; }
    .sidebar-collapsed .client-group { overflow: hidden; }
    .sidebar-collapsed .client-group-toggle { gap: 10px; padding: 7px 9px; }
    .sidebar-collapsed .client-group.open .client-group-content { display: flex; padding: 2px 5px 6px 13px; }
    .sidebar-collapsed .sidebar-link,
    .sidebar-collapsed .client-group-content .sidebar-link { gap: 12px; padding: 9px 11px; }
    .sidebar-collapsed .sidebar-user { flex: 1; gap: 10px; padding: 6px; }
    .sidebar-collapsed .sidebar-footer { flex-direction: row; align-items: center; padding: 14px 12px 18px; }
    .topbar { padding-left: 60px; }
}

/* ════════════════════════════════════════
   RESET / BASE
════════════════════════════════════════ */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html, body {
    width: 100%;
    /* min-height, não height: a página cresce com o conteúdo e rola.
       Com height:100vh + overflow:hidden, tudo que passasse da altura da tela
       era simplesmente cortado — e o conteúdo cresceu (13 status, 939 OS). */
    min-height: 100vh;
    overflow-x: hidden;
    overflow-y: auto;
    font-family: 'Inter', Arial, sans-serif;
    font-size: 13px;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }

/* ════════════════════════════════════════
   PAGE SHELL
════════════════════════════════════════ */
.page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background:
        radial-gradient(ellipse 70% 50% at 15% 0%,  rgba(245,166,35,.07)  0%, transparent 60%),
        radial-gradient(ellipse 50% 40% at 85% 100%, rgba(232,76,32,.06)   0%, transparent 60%),
        var(--bg);
}

/* ════════════════════════════════════════
   TOPBAR
════════════════════════════════════════ */
.topbar {
    flex-shrink: 0;
    height: var(--topbar-h);
    background: rgba(10,11,18,0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border-bottom: 1px solid var(--glass-border);
    color: var(--text);
    display: flex;
    align-items: center;
    padding: 0 18px;
    gap: 14px;
    position: relative;
    z-index: 100;
}

/* Subtle top accent line */
.topbar::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--zeus-amber) 0%, var(--uni-orange) 50%, transparent 100%);
}

/* Os logos vivem apenas na barra lateral (_sidebar.php) — a topbar começa no título. */

/* ── Title ── */
.topbar-title { flex: 0 0 auto; }
.topbar-title h1 {
    font-size: 15px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .8px;
    line-height: 1.1;
    color: var(--text);
}
.topbar-title p {
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    color: var(--muted);
    margin-top: 2px;
    letter-spacing: .4px;
}

/* ── Spacer ── */
.topbar-spacer { flex: 1 1 0; }

/* ── Última atualização (data da coleta do robô) ── */
.topbar-extraction {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    padding: 6px 14px;
}

/* Bolinha de saúde da coleta: verde recente, âmbar 1–2 dias, vermelha parada. */
.topbar-extraction .ext-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex-shrink: 0;
    background: var(--muted);
}
.topbar-extraction.ext-ok .ext-dot {
    background: #22c55e;
    box-shadow: 0 0 8px rgba(34,197,94,.7);
}
.topbar-extraction.ext-atencao {
    border-color: rgba(245,166,35,.45);
}
.topbar-extraction.ext-atencao .ext-dot {
    background: var(--zeus-amber);
    box-shadow: 0 0 8px rgba(245,166,35,.7);
}
.topbar-extraction.ext-alerta {
    border-color: rgba(239,68,68,.5);
    background: rgba(239,68,68,.08);
}
.topbar-extraction.ext-alerta .ext-dot {
    background: #ef4444;
    box-shadow: 0 0 8px rgba(239,68,68,.7);
    animation: ext-pulse 1.8s ease-in-out infinite;
}
@keyframes ext-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

.topbar-extraction .ext-value small {
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    margin-left: 4px;
}
.topbar-extraction.ext-alerta .ext-value small {
    color: #f87171;
}

.topbar-extraction .ext-label {
    display: block;
    font-size: 9px;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 600;
    letter-spacing: .5px;
}

.topbar-extraction .ext-value {
    display: block;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
    margin-top: 1px;
}

/* ── Total OS badge ── */
.topbar-total {
    background: linear-gradient(135deg, rgba(245,166,35,.15) 0%, rgba(245,166,35,.08) 100%);
    border: 1px solid rgba(245,166,35,.3);
    border-radius: var(--r-md);
    padding: 6px 18px;
    text-align: center;
    flex-shrink: 0;
}
.topbar-total .tot-label {
    display: block;
    font-size: 9px;
    text-transform: uppercase;
    color: var(--zeus-amber);
    font-weight: 700;
    letter-spacing: .5px;
    opacity: .85;
}
.topbar-total .tot-value {
    display: block;
    font-size: 26px;
    font-weight: 900;
    line-height: 1.05;
    color: var(--zeus-amber);
    text-shadow: var(--glow-amber);
}

/* ── Variante DINHEIRO do badge da topbar ──
   Nasceu em 03/09/2026, quando a faixa de KPIs saiu da Visão Geral e o "Valor
   total da base" subiu para cá.

   Dois desvios da variante padrão, os dois necessários:

   · A fonte. Os 26px de .tot-value foram dimensionados para "8.525"; um
     R$ 27.615.764,35 nesse tamanho estoura a topbar de 64px e vaza para os
     lados. Mesmo motivo de .donut-pct.money, mais abaixo.
   · A cor. O âmbar fica só no Total de OS — dois badges âmbar lado a lado
     disputam o mesmo olhar, e nenhum dos dois é lido. */
.topbar-total.is-valor {
    background: var(--surface);
    border-color: var(--glass-border);
}
.topbar-total.is-valor .tot-label {
    color: var(--muted);
}
.topbar-total.is-valor .tot-value {
    font-size: clamp(15px, 1.15vw, 19px);
    font-weight: 800;
    color: var(--text);
    text-shadow: none;
    white-space: nowrap;
}

/* ── Action buttons ── */
.logout {
    background: var(--surface);
    border: 1px solid var(--glass-border2);
    color: var(--text-2);
    border-radius: var(--r-sm);
    padding: 6px 14px;
    font-weight: 600;
    font-size: 11px;
    flex-shrink: 0;
    margin-left: 6px;
    transition: all .2s;
    cursor: pointer;
}
.logout:hover {
    background: var(--surface-hover);
    color: var(--text);
    border-color: var(--glass-border2);
    transform: translateY(-1px);
}

/* ════════════════════════════════════════
   MAIN — scrollable area
════════════════════════════════════════ */
/* O recuo lateral tem de ser o mesmo da topbar e da barra de filtro (18px):
   com 10px aqui, tudo abaixo da linha do filtro ficava 8px à esquerda do
   título — desalinhamento visível em todas as telas. */
.main {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    /* Respiro lateral que acompanha a tela: aperta em notebook, abre em monitor
       grande. Antes eram 18px fixos nos dois casos. */
    padding: var(--sp-3) clamp(var(--sp-3), 1.4vw, var(--sp-5)) var(--sp-5);
    /* Sem isto, um filho largo (tabela de 18 colunas) estica o container flex e
       empurra a página inteira para o lado. */
    min-width: 0;
}


/* ════════════════════════════════════════
   KPI STRIP
════════════════════════════════════════ */
/* A grade decide sozinha quantas colunas cabem.
   Antes eram 7 frações cravadas: em 1280px os cartões ficavam espremidos, em
   2560px sobrava espaço morto, e cada variante de contagem exigia uma classe
   nova (`cols-4`) mais um breakpoint para consertar o que a classe estragava. */
.kpi-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--card-min), 1fr));
    gap: var(--sp-2);
    flex-shrink: 0;
}

/* O cartão de valor total pede o dobro: é o único com texto longo
   ("R$ 2.988.693,96" ao lado de um que mostra "49"). Se só couber uma coluna,
   o próprio grid reduz o span — sem media query para desfazer. */
.kpi-strip .kpi-card:first-child { grid-column: span 2; }
.kpi-strip.cols-4 .kpi-card:first-child { grid-column: auto; }

@keyframes fadeSlideUp {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.kpi-card {
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    padding: 11px 12px 10px 12px;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    box-shadow: 0 4px 20px rgba(0,0,0,.25);
    min-width: 0;
    transition: transform .2s, box-shadow .2s, border-color .2s, background .2s;
    animation: fadeSlideUp .4s ease both;
    cursor: default;
}
.kpi-card:nth-child(1) { animation-delay: .05s; }
.kpi-card:nth-child(2) { animation-delay: .10s; }
.kpi-card:nth-child(3) { animation-delay: .15s; }
.kpi-card:nth-child(4) { animation-delay: .20s; }
.kpi-card:nth-child(5) { animation-delay: .25s; }
.kpi-card:nth-child(6) { animation-delay: .30s; }

.kpi-card:hover {
    transform: translateY(-2px);
    background: var(--surface-2);
    border-color: var(--glass-border2);
}
.kpi-card:hover .kpi-icon.blue   { box-shadow: 0 0 18px rgba(77,166,255,.45); }
.kpi-card:hover .kpi-icon.green  { box-shadow: 0 0 18px rgba(34,201,122,.45); }
.kpi-card:hover .kpi-icon.orange { box-shadow: 0 0 18px rgba(245,166,35,.45); }
.kpi-card:hover .kpi-icon.gear   { box-shadow: 0 0 18px rgba(107,122,153,.35); }
.kpi-card:hover .kpi-icon.purple { box-shadow: 0 0 18px rgba(157,110,245,.45); }
.kpi-card:hover .kpi-icon.red    { box-shadow: 0 0 18px rgba(255,77,106,.45); }

.kpi-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    display: grid;
    place-items: center;
    flex-shrink: 0;
    color: #fff;
    transition: box-shadow var(--dur-3) var(--ease);
}
/* Eram emoji (📄 ✔ 💼 ⚙ ⌛ ✕): cada sistema desenhava um traço diferente, em
   cores que ignoravam a paleta, ao lado de uma sidebar com ícones de contorno.
   O `fill: none` não é opcional — sem ele o navegador preenche o contorno de
   preto, que foi exatamente o bug do cadeado. */
.kpi-icon svg {
    width: 19px; height: 19px;
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.kpi-icon.blue   { background: linear-gradient(135deg,#1a6fc4,#4da6ff); }
.kpi-icon.green  { background: linear-gradient(135deg,#15a05c,#22c97a); }
.kpi-icon.orange { background: linear-gradient(135deg,#c77a00,#F5A623); }
.kpi-icon.gear   { background: linear-gradient(135deg,#3a4460,#6b7a99); }
.kpi-icon.purple { background: linear-gradient(135deg,#6a3ecf,#9d6ef5); }
.kpi-icon.red    { background: linear-gradient(135deg,#cc1f3a,#ff4d6a); }

.kpi-body { min-width: 0; }
.kpi-label {
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    color: var(--muted);
    line-height: 1.2;
    margin-bottom: 3px;
    letter-spacing: .4px;
}
.kpi-value {
    font-size: clamp(13px, 1.3vw, 19px);
    font-weight: 800;
    color: var(--text);
    line-height: 1;
    white-space: nowrap;
}
.kpi-sub {
    font-size: 9px;
    color: var(--text-3);
    margin-top: 3px;
    line-height: 1.2;
}
/* Separa valor de percentual: sem ele a linha lia "R$ 2.245.990,91 75,1%", como
   se fosse um número só. */
.kpi-sep { margin: 0 3px; opacity: .5; }

/* ════════════════════════════════════════
   MID ROW — 2 donut panels
════════════════════════════════════════ */
/* Os dois gráficos ficam lado a lado enquanto couberem e empilham sozinhos
   quando não couberem — sem breakpoint. `--panel-min` é a largura abaixo da
   qual um donut com legenda deixa de ser legível. */
.mid-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(var(--panel-min), 1fr));
    gap: var(--sp-2);
    flex-shrink: 0;
}

.donut-panel {
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    padding: var(--sp-3) var(--sp-4);
    display: grid;
    /* Antes: `minmax(0, 250px) minmax(0, 1fr)`. Os 250px eram fixos, então num
       painel de 370px (o que sobra em 1024px de tela) restavam ~106px para uma
       rosca de 110px mais a legenda — e o conteúdo vazava para fora da caixa.
       Agora as duas metades pedem 236px cada; quando não couberem lado a lado,
       o texto sobe e a rosca desce sozinha. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 236px), 1fr));
    gap: var(--sp-3);
    align-items: center;
    box-shadow: 0 4px 20px rgba(0,0,0,.25);
    min-width: 0;
    min-height: 0;
    transition: border-color var(--dur-2) var(--ease), background var(--dur-2) var(--ease);
}
.donut-panel:hover {
    background: var(--surface-2);
    border-color: var(--glass-border2);
}

.donut-info { min-width: 0; }
.donut-info h2 {
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    color: var(--text-2);
    letter-spacing: .5px;
}
.donut-info .sub-label {
    font-size: 9px;
    color: var(--text-3);
    margin-top: 3px;
    line-height: 1.4;
}
.donut-pct {
    font-size: clamp(28px, 3.2vw, 48px);
    font-weight: 900;
    line-height: 1;
    display: block;
    margin-top: 5px;
}
.donut-pct.green {
    color: var(--green);
    text-shadow: var(--glow-green);
}
.donut-pct.navy {
    color: var(--zeus-amber);
    text-shadow: var(--glow-amber);
}
.donut-count {
    font-size: 10px;
    color: var(--text-3);
    display: block;
    margin-top: 4px;
}
/* Rosca + legenda. A legenda é HTML (ver montarLegenda no dashboard.js): assim
   ela quebra, encolhe e muda de lado por CSS, sem depender de evento de resize
   chegar ao JavaScript. */
/* A rosca cresce um pouco com o painel e a legenda deixa de esticar: com
   `flex: 1 1 auto` ela ocupava 450px num painel largo e o valor, empurrado por
   `margin-left:auto`, ficava a 350px do nome — "Resolvidos ......... 262". */
.donut-chart-box {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 14px;
    min-width: 0;
}
.donut-chart-wrap {
    position: relative;
    /* Cresce com a tela, mas sem tomar a largura de que a legenda precisa para
       ficar ao lado: acima de 150px ela era empurrada para baixo da rosca. */
    height: clamp(110px, 8vw, 140px);
    width: clamp(110px, 8vw, 140px);
    flex: 0 0 auto;
}
.donut-legend {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 6px;
    /* Cresce até 220px e não além: o bastante para o nome mais longo, e impede
       que o valor, empurrado para a direita por margin-left:auto, termine a
       350px do rótulo — era o que acontecia com `flex: 1 1 auto` num painel
       largo. Abaixo de 120px a legenda desce para a linha de baixo (flex-wrap
       no pai). */
    flex: 1 1 120px;
    min-width: 0;
    max-width: 220px;
}
.donut-legend li {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 10px;
    color: var(--text-2);
    min-width: 0;
}
.legenda-cor {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: 0 0 9px;
}
.legenda-nome {
    /* Encolhe com reticências em vez de vazar; o nome inteiro fica no title. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.legenda-valor {
    margin-left: auto;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.donut-chart-wrap canvas { width: 100% !important; height: 100% !important; }

/* ════════════════════════════════════════
   BOTTOM ROW — table | bar+reading
════════════════════════════════════════ */
.bot-row {
    display: grid;
    /* O `min()` é o que troca de layout sem media query: quando 100% da largura
       for menor que o mínimo de um painel, a segunda coluna não cabe e empilha. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--panel-min)), 1fr));
    gap: var(--sp-2);
    /* `start`, não `stretch`: esticar o cartão da tabela até a altura da coluna
       vizinha abria um vazio DENTRO dele — 109px na Visão Geral e 339px na
       Análise por Filial, onde a tabela tem só seis linhas. Cada cartão agora
       tem a altura do próprio conteúdo; a diferença sobra como fundo da página,
       que não parece defeito. */
    align-items: start;
}

/* Status table card */
.status-card {
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 4px 20px rgba(0,0,0,.25);
}

.card-head {
    background: linear-gradient(135deg, rgba(245,166,35,.15) 0%, rgba(232,76,32,.10) 100%);
    border-bottom: 1px solid var(--glass-border);
    color: var(--text);
    padding: 8px 14px;
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .5px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 7px;
}
.card-head::before {
    content: '';
    display: inline-block;
    width: 3px;
    height: 14px;
    background: linear-gradient(180deg, var(--zeus-amber), var(--uni-orange));
    border-radius: 2px;
    flex-shrink: 0;
}

.table-wrap {
    /* Teto para a tabela não empurrar a página inteira quando houver muitos
       status; passando disso, rola aqui dentro com o cabeçalho fixo. */
    max-height: 60vh;
    overflow-y: auto;
    overflow-x: auto;
}

/* Scrollbar */
.table-wrap::-webkit-scrollbar { width: 4px; }
.table-wrap::-webkit-scrollbar-track { background: transparent; }
.table-wrap::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border-radius: 4px; }
.table-wrap::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.2); }

table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 11px;
}
th, td {
    padding: 5px 10px;
    border-bottom: 1px solid rgba(255,255,255,.04);
    text-align: left;
    vertical-align: middle;
    white-space: nowrap;
}
th {
    /* Opaco: o cabeçalho é sticky e as linhas rolam por baixo dele. */
    background: var(--surface-solid);
    color: var(--muted);
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .4px;
    position: sticky;
    top: 0;
    z-index: 2;
    box-shadow: 0 1px 0 rgba(255,255,255,.07);
}
tbody tr:nth-child(even) { background: rgba(255,255,255,.02); }
tbody tr:hover {
    background: rgba(245,166,35,.06);
    transition: background .15s;
}
td { color: var(--text-2); }
/* Primeira coluna (nome da filial / status) fica presa à esquerda: quando a
   tabela rola na horizontal, os números continuam identificáveis em vez de
   deslizarem para longe do nome. O texto pode quebrar em duas linhas — só ele,
   os números seguem em linha única. */
.table-wrap th:first-child,
.table-wrap td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface-solid);
    white-space: normal;
    min-width: 118px;
}
/* A coluna fixa precisa de fundo opaco, mas tem de acompanhar o zebrado das
   linhas — com um tom só, ela virava uma faixa lisa ao lado de linhas listradas. */
.table-wrap tbody tr:nth-child(even) td:first-child { background: var(--surface-solid-2); }
.table-wrap tbody tr:hover td:first-child { background: #221f27; }
.table-wrap thead th:first-child { z-index: 3; }
/* O rodapé precisa do mesmo tratamento do cabeçalho. Sem z-index próprio, a
   célula "Total" empata com as demais tfoot th (z-index 2) e o desempate é a
   ordem do DOM: o total da coluna seguinte passava por cima do rótulo, com o
   gradiente laranja invadindo o nome. */
.table-wrap tfoot th:first-child { z-index: 3; }
/* Quando a tabela rola para o lado, as colunas seguintes desaparecem por baixo
   da primeira sem aviso — e um "42,7%" cortado ao meio vira "2,7%", que se lê
   como número errado. A sombra à direita avisa que há conteúdo atrás.
   As linhas de separação do cabeçalho e do rodapé vão junto, porque box-shadow
   não acumula entre regras. */
.table-wrap td:first-child {
    box-shadow: 6px 0 8px -6px rgba(0,0,0,.55);
}
.table-wrap thead th:first-child {
    box-shadow: 0 1px 0 rgba(255,255,255,.07), 6px 0 8px -6px rgba(0,0,0,.55);
}
.table-wrap tfoot th:first-child {
    box-shadow: 0 -1px 0 rgba(255,255,255,.07), 6px 0 8px -6px rgba(0,0,0,.55);
}

tfoot th {
    /* Cor sólida por baixo do gradiente: o total fica fixo no rodapé e as
       linhas passam por trás. */
    background: var(--surface-solid) linear-gradient(135deg, rgba(245,166,35,.2), rgba(232,76,32,.15));
    color: var(--zeus-amber);
    position: sticky;
    top: auto;
    bottom: 0;
    font-size: 10px;
    border-bottom: none;
    box-shadow: 0 -1px 0 rgba(255,255,255,.07);
}

/* Pílula de percentual da coluna "% Resolvido".
   O rodapé escrevia o total como texto solto enquanto as linhas usavam uma
   pílula com padding lateral: os 8px de padding deslocavam o texto das linhas e
   o total ficava desalinhado da coluna inteira. Mesma marcação para os dois, com
   largura mínima para os percentuais se alinharem entre si. */
.pct-pill {
    display: inline-block;
    min-width: 52px;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 800;
    text-align: center;
    background: rgba(245,166,35,.15);
    color: var(--zeus-amber-light, #f5c518);
}
.pct-pill.is-ok {
    background: rgba(34,199,122,.15);
    color: #22c97a;
}

.dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-right: 7px;
    vertical-align: middle;
    /* --c é a cor do status (ver as classes .s-*). Antes era `currentColor`, que
       aqui é a cor do TEXTO da célula: todo mundo brilhava do mesmo cinza,
       inclusive a bolinha vermelha e a verde. */
    box-shadow: 0 0 6px var(--c, transparent);
}

/* Right column */
.right-col {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bar-card {
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    display: flex;
    flex-direction: column;
    /* Altura vem do conteúdo: o gráfico define a sua (uma faixa por status,
       calculada no dashboard.js) e o cartão acompanha. Com `flex: 1 1 0` o
       cartão colapsava e o gráfico ficava para fora dele. */
    flex: 0 0 auto;
    overflow: hidden;
    box-shadow: 0 4px 20px rgba(0,0,0,.25);
}
.bar-card .chart-body {
    flex: 0 0 auto;
    padding: 8px 12px;
    position: relative;
}
.bar-card .chart-body canvas { width: 100% !important; height: 100% !important; }


/* ════════════════════════════════════════
   STATUS COLORS
════════════════════════════════════════ */
/* Cada classe declara a cor em --c e a usa como fundo: assim a bolinha pode
   reaproveitar o mesmo valor no brilho, e a pílula, no fundo. */
.s-green  { --c: var(--green);  background: var(--c); }
.s-red    { --c: var(--red);    background: var(--c); }
.s-orange { --c: var(--orange); background: var(--c); }
.s-yellow { --c: var(--yellow); background: var(--c); }
.s-purple { --c: var(--purple); background: var(--c); }
.s-blue   { --c: var(--blue);   background: var(--c); }
.s-teal   { --c: var(--teal);   background: var(--c); }
.s-gray   { --c: var(--gray);   background: var(--c); }

.pill {
    display: inline-block;
    padding: 3px 8px;
    border-radius: 999px;
    font-size: 10px;
    color: #fff;
    font-weight: 700;
    white-space: nowrap;
}
.pill.s-yellow { color: #1a1a1a; }

/* ════════════════════════════════════════
   LOGIN PAGE
════════════════════════════════════════ */
.login-body {
    min-height: 100vh;
    display: grid;
    place-items: center;
    background:
        radial-gradient(ellipse 70% 60% at 20% 10%, rgba(245,166,35,.12) 0%, transparent 55%),
        radial-gradient(ellipse 60% 50% at 80% 90%, rgba(232,76,32,.10) 0%, transparent 55%),
        #0a0b10;
    overflow: auto;
    font-family: 'Inter', Arial, sans-serif;
    position: relative;
}

/* Animated grid lines */
.login-body::before {
    content: '';
    position: fixed;
    inset: 0;
    background-image:
        linear-gradient(rgba(245,166,35,.04) 1px, transparent 1px),
        linear-gradient(90deg, rgba(245,166,35,.04) 1px, transparent 1px);
    background-size: 50px 50px;
    pointer-events: none;
    z-index: 0;
}

.login-card {
    position: relative;
    z-index: 1;
    width: 400px;
    max-width: calc(100vw - 28px);
    background: rgba(20,22,34,0.85);
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
    border: 1px solid rgba(255,255,255,.1);
    border-radius: 20px;
    padding: 36px;
    box-shadow:
        0 30px 80px rgba(0,0,0,.6),
        0 0 0 1px rgba(245,166,35,.08),
        inset 0 1px 0 rgba(255,255,255,.07);
}

/* Top accent on login card */
.login-card::before {
    content: '';
    position: absolute;
    top: 0; left: 20px; right: 20px;
    height: 2px;
    background: linear-gradient(90deg, var(--zeus-amber), var(--uni-orange), transparent);
    border-radius: 0 0 2px 2px;
}

.login-card h1 {
    text-align: center;
    text-transform: uppercase;
    color: var(--text);
    font-size: 20px;
    font-weight: 900;
    margin-bottom: 5px;
    letter-spacing: 1px;
}
.login-card > p {
    text-align: center;
    color: var(--muted);
    margin-bottom: 28px;
    font-size: 12px;
    font-weight: 500;
}

label {
    display: block;
    font-size: 11px;
    color: var(--muted);
    font-weight: 700;
    margin-bottom: 6px;
    text-transform: uppercase;
    letter-spacing: .5px;
}
input, select, textarea {
    width: 100%;
    max-width: 100%;
    border: 1px solid rgba(255,255,255,.1);
    border-radius: var(--r-sm);
    padding: 10px 13px;
    font-size: 13px;
    background: rgba(255,255,255,.06);
    color: var(--text);
    outline: none;
    font-family: 'Inter', Arial, sans-serif;
    transition: border-color .2s, box-shadow .2s, background .2s;
}
input::placeholder { color: var(--text-3); }
input:focus, select:focus, textarea:focus {
    border-color: rgba(245,166,35,.5);
    background: rgba(255,255,255,.08);
    box-shadow: 0 0 0 3px rgba(245,166,35,.12);
}

/* A lista aberta do select é desenhada pelo sistema operacional, fora do
   controle do CSS do campo. Sem cor explícita aqui, o texto herda o branco
   do input e cai num fundo branco — invisível. */
select option,
select optgroup {
    background-color: #171923;
    color: #e8eaf2;
}
select option:checked,
select option:hover {
    background-color: #26293a;
}

/* O ícone do calendário vem preto por padrão e some no fundo escuro. */
input[type="date"]::-webkit-calendar-picker-indicator {
    filter: invert(1);
    opacity: .65;
    cursor: pointer;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

button {
    border: 0;
    border-radius: var(--r-sm);
    padding: 11px 14px;
    background: linear-gradient(135deg, var(--zeus-amber) 0%, var(--uni-orange) 100%);
    color: #0a0a0a;
    font-weight: 800;
    font-size: 13px;
    cursor: pointer;
    font-family: 'Inter', Arial, sans-serif;
    letter-spacing: .3px;
    transition: opacity .2s, transform .15s, box-shadow .2s;
    box-shadow: 0 4px 18px rgba(245,166,35,.35);
}
button:hover {
    opacity: .92;
    transform: translateY(-1px);
    box-shadow: 0 8px 26px rgba(245,166,35,.45);
}
button:active { transform: translateY(0); }

.login-card input { margin-bottom: 14px; }
.login-card button { width: 100%; margin-top: 8px; }

.alert {
    background: rgba(255,77,106,.12);
    border: 1px solid rgba(255,77,106,.3);
    color: #ff9aaa;
    border-radius: var(--r-sm);
    padding: 10px 12px;
    margin-bottom: 14px;
    font-size: 12px;
    font-weight: 500;
}

/* Dashboard Filter Bar */
.dashboard-filter-bar {
    background: var(--surface);
    border-bottom: 1px solid var(--glass-border);
    padding: 10px 18px;
    display: flex;
    align-items: flex-end;
    gap: 12px;
    flex-shrink: 0;
}
.dashboard-filter-bar .filter-group {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.dashboard-filter-bar .filter-group label {
    font-size: 10px;
    font-weight: 700;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .5px;
}
/* Campos da barra de filtro: mesmo visual para select, texto e data.
   Largura confortável no desktop, mas encolhem em vez de estourar a linha. */
.dashboard-filter-bar .filter-group select,
.dashboard-filter-bar .filter-group input {
    border: 1px solid var(--glass-border2);
    border-radius: 7px;
    padding: 6px 12px;
    font-size: 12px;
    background: var(--surface-2);
    color: var(--text);
    outline: none;
    width: 180px;
    max-width: 100%;
    font-family: 'Inter', Arial, sans-serif;
    transition: border-color .15s, box-shadow .15s;
}
.dashboard-filter-bar .filter-group input[type="date"] {
    width: 150px;
    padding: 5px 12px;
}
.dashboard-filter-bar .filter-group select:focus,
.dashboard-filter-bar .filter-group input:focus {
    border-color: rgba(245,166,35,.5);
    box-shadow: 0 0 0 3px rgba(245,166,35,.12);
}
.dashboard-filter-bar .filter-actions {
    display: flex;
    gap: 8px;
}
.dashboard-filter-bar .btn-filter {
    background: linear-gradient(135deg, var(--zeus-amber), var(--uni-orange));
    color: #0a0a0a;
    border: none;
    border-radius: 7px;
    padding: 7px 16px;
    font-size: 12px;
    font-weight: 800;
    cursor: pointer;
    transition: opacity .18s, transform .15s;
    box-shadow: 0 4px 12px rgba(245,166,35,.2);
}
.dashboard-filter-bar .btn-filter:hover {
    opacity: .9;
    transform: translateY(-1px);
}
.dashboard-filter-bar .btn-clear,
.modal-usuario-actions .btn-clear {
    background: rgba(255,255,255,0.06);
    color: var(--text-2);
    border: 1px solid var(--glass-border2);
    border-radius: 7px;
    padding: 6px 14px;
    font-size: 12px;
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    transition: background .18s;
}
.dashboard-filter-bar .btn-clear:hover,
.modal-usuario-actions .btn-clear:hover {
    background: rgba(255,255,255,0.1);
    color: var(--text);
}

/* ════════════════════════════════════════
   LOGIN V2 — PREMIUM SPLIT LAYOUT
════════════════════════════════════════ */
.login-body {
    min-height: 100vh;
    padding: 28px;
    display: grid;
    place-items: center;
    overflow: hidden;
    background: #08090d;
}
.login-body::before {
    opacity: .55;
    background-size: 64px 64px;
    mask-image: linear-gradient(to right, #000, transparent 85%);
}
.login-orb {
    position: fixed;
    z-index: 0;
    border-radius: 50%;
    pointer-events: none;
    filter: blur(2px);
}
.login-orb-one {
    width: 520px; height: 520px; left: -220px; top: -260px;
    background: radial-gradient(circle, rgba(245,166,35,.18), transparent 68%);
}
.login-orb-two {
    width: 560px; height: 560px; right: -260px; bottom: -300px;
    background: radial-gradient(circle, rgba(232,76,32,.13), transparent 68%);
}
.login-shell {
    position: relative;
    z-index: 1;
    width: min(1120px, 100%);
    min-height: min(690px, calc(100vh - 56px));
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(430px, .92fr);
    overflow: hidden;
    border: 1px solid rgba(255,255,255,.09);
    border-radius: 28px;
    background: rgba(15,17,25,.88);
    box-shadow: 0 40px 120px rgba(0,0,0,.62), inset 0 1px 0 rgba(255,255,255,.05);
}
.login-showcase {
    position: relative;
    padding: 42px 50px 38px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background:
        linear-gradient(145deg, rgba(245,166,35,.08), transparent 40%),
        radial-gradient(circle at 85% 75%, rgba(232,76,32,.15), transparent 38%),
        #0c0e15;
    border-right: 1px solid rgba(255,255,255,.08);
}
.login-showcase::before {
    content: '';
    position: absolute;
    width: 430px; height: 430px;
    right: -160px; top: 130px;
    border: 1px solid rgba(245,166,35,.13);
    border-radius: 50%;
    box-shadow: 0 0 0 70px rgba(245,166,35,.025), 0 0 0 140px rgba(245,166,35,.018);
}
.login-showcase::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 47%, rgba(245,166,35,.035) 47.2%, transparent 47.5%);
    pointer-events: none;
}
.showcase-logos {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 15px;
}
.showcase-logos img:first-child { width: 112px; height: 52px; object-fit: contain; filter: drop-shadow(0 0 12px rgba(245,166,35,.32)); }
.showcase-logos img:last-child { width: 88px; height: 38px; object-fit: contain; }
.showcase-logos > span { width: 1px; height: 34px; background: rgba(255,255,255,.16); }
.showcase-copy {
    position: relative;
    z-index: 1;
    max-width: 500px;
    margin: auto 0 30px;
}
.showcase-kicker {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 20px;
    color: var(--zeus-amber);
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 1.6px;
}
.showcase-kicker i {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--zeus-amber);
    box-shadow: 0 0 12px rgba(245,166,35,.85);
}
.showcase-copy h1 {
    max-width: 480px;
    color: #f7f8fb;
    font-size: clamp(34px, 3.3vw, 50px);
    font-weight: 800;
    line-height: 1.04;
    letter-spacing: -2px;
}
.showcase-copy p {
    max-width: 470px;
    margin-top: 22px;
    color: var(--text-2);
    font-size: 14px;
    line-height: 1.75;
}
.showcase-features {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
}
.showcase-features > div {
    min-width: 0;
    padding: 13px;
    display: flex;
    align-items: center;
    gap: 11px;
    border: 1px solid rgba(255,255,255,.075);
    border-radius: 13px;
    background: rgba(255,255,255,.035);
}
.feature-icon {
    width: 36px; height: 36px; flex: 0 0 36px;
    display: grid; place-items: center;
    color: var(--zeus-amber);
    border-radius: 10px;
    background: rgba(245,166,35,.1);
}
.feature-icon svg, .showcase-features svg, .login-form svg, .alert svg, .login-security svg {
    width: 18px; height: 18px;
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.showcase-features > div > span:last-child { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.showcase-features strong { color: var(--text); font-size: 10px; white-space: nowrap; }
.showcase-features small { color: var(--text-3); font-size: 8px; white-space: nowrap; }
.showcase-bottom {
    position: relative;
    z-index: 1;
    margin-top: 25px;
    color: var(--text-3);
    font-size: 9px;
    letter-spacing: .4px;
}
.showcase-bottom span { margin: 0 7px; color: var(--zeus-amber); }
.login-panel {
    padding: 50px;
    display: grid;
    place-items: center;
    background: rgba(17,19,28,.82);
}
.login-panel .login-card {
    width: 100%;
    max-width: 390px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    backdrop-filter: none;
}
.login-panel .login-card::before { display: none; }
.login-mobile-logos { display: none; }
.login-heading { margin-bottom: 30px; }
.login-badge {
    display: inline-flex;
    margin-bottom: 15px;
    padding: 6px 10px;
    color: var(--zeus-amber);
    font-size: 9px;
    font-weight: 800;
    letter-spacing: .9px;
    text-transform: uppercase;
    border: 1px solid rgba(245,166,35,.18);
    border-radius: 999px;
    background: rgba(245,166,35,.07);
}
.login-heading h2 {
    color: var(--text);
    font-size: 28px;
    font-weight: 800;
    letter-spacing: -.8px;
}
.login-heading p {
    margin-top: 8px;
    color: var(--muted);
    font-size: 12px;
}
.login-panel .alert {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 11px 12px;
}
.login-panel .alert svg { flex: 0 0 18px; }
.login-form { display: flex; flex-direction: column; gap: 18px; }
.login-field label {
    margin-bottom: 8px;
    color: var(--text-2);
    font-size: 10px;
}
.input-shell {
    position: relative;
    display: flex;
    align-items: center;
}
.input-shell > svg {
    position: absolute;
    z-index: 1;
    left: 14px;
    color: var(--text-3);
    pointer-events: none;
}
.login-panel .input-shell input {
    height: 50px;
    margin: 0;
    padding: 0 48px 0 44px;
    color: var(--text);
    font-size: 12px;
    border: 1px solid rgba(255,255,255,.1);
    border-radius: 11px;
    background: rgba(255,255,255,.045);
}
.login-panel .input-shell input:focus {
    border-color: rgba(245,166,35,.48);
    background: rgba(255,255,255,.065);
    box-shadow: 0 0 0 3px rgba(245,166,35,.09);
}
.input-shell:focus-within > svg { color: var(--zeus-amber); }
.password-toggle {
    position: absolute;
    right: 7px;
    width: 38px !important; height: 38px;
    margin: 0 !important; padding: 0;
    display: grid; place-items: center;
    color: var(--text-3);
    background: transparent;
    box-shadow: none;
}
.password-toggle:hover { color: var(--text); background: rgba(255,255,255,.05); box-shadow: none; transform: none; }
.password-toggle .eye-closed { display: none; }
.password-toggle.showing .eye-open { display: none; }
.password-toggle.showing .eye-closed { display: block; }
.login-submit {
    width: 100%;
    height: 51px;
    margin-top: 5px !important;
    padding: 0 17px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 11px;
    border-radius: 11px;
    box-shadow: 0 12px 28px rgba(245,166,35,.22);
}
.login-submit svg { width: 19px; height: 19px; transition: transform .18s; }
.login-submit:hover svg { transform: translateX(3px); }
.login-security {
    margin-top: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    color: var(--text-3);
    font-size: 9px;
}
.login-security svg { width: 14px; height: 14px; }

@media (max-width: 900px) {
    .login-body { padding: 16px; overflow: auto; }
    .login-shell { min-height: calc(100vh - 32px); grid-template-columns: 1fr; }
    .login-showcase { display: none; }
    .login-panel { padding: 40px 28px; }
    .login-mobile-logos {
        margin-bottom: 48px;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 13px;
    }
    .login-mobile-logos img:first-child { width: 100px; height: 45px; object-fit: contain; }
    .login-mobile-logos img:last-child { width: 76px; height: 34px; object-fit: contain; }
    .login-mobile-logos span { width: 1px; height: 30px; background: rgba(255,255,255,.14); }
}

@media (max-width: 480px) {
    .login-body { padding: 0; }
    .login-shell { min-height: 100vh; border: 0; border-radius: 0; }
    .login-panel { padding: 32px 22px; }
    .login-mobile-logos { margin-bottom: 36px; }
    .login-heading h2 { font-size: 25px; }
}

/* ════════════════════════════════════════
   RESPONSIVO — precisa ficar no FIM do arquivo
   Media query não aumenta especificidade: se vier antes da regra que quer
   sobrescrever, perde por ordem. Três degraus: notebook (1300), tablet (900)
   e celular (600). A página pode rolar na vertical, nunca na horizontal.
════════════════════════════════════════ */
@media (max-width: 1300px) {
    /* `.kpi-strip`, `.mid-row`, `.bot-row` e `.priority-items` NÃO aparecem
       mais aqui. Cada um destes três breakpoints redefinia o mesmo
       `grid-template-columns`, e cada um desfazia o de cima: 7 colunas → 3 → 2
       → 1. O layout mudava em degraus, e no degrau errado os cartões saltavam
       de posição. Quem decide agora é o `auto-fit` da regra base, que trata a
       largura como contínua. */
}

@media (max-width: 900px) {
    /* A topbar deixa de ser uma linha só e passa a quebrar. O recuo à esquerda
       abre espaço para o botão de menu, que é fixo naquele canto. */
    .topbar {
        height: auto;
        flex-wrap: wrap;
        padding: 12px 14px 12px 62px;
        gap: 10px;
        row-gap: 12px;
    }
    .topbar-spacer { flex-basis: 100%; height: 0; }
    .topbar-title h1 { font-size: 14px; }


    /* Rosca embaixo do texto; a legenda continua ao lado da rosca, mas com a
       largura toda do painel para trabalhar. */
    .donut-panel { grid-template-columns: 1fr; gap: 10px; }

    .dashboard-filter-bar { flex-wrap: wrap; gap: 10px; padding: 12px 14px; }
    .dashboard-filter-bar .filter-group { flex: 1 1 180px; }
    .dashboard-filter-bar .filter-group select,
    .dashboard-filter-bar .filter-group input,
    .dashboard-filter-bar .filter-group input[type="date"] { width: 100%; }
    .dashboard-filter-bar .filter-actions { flex: 1 1 100%; }

    /* Tabela larga rola dentro da própria caixa, não empurra a página. */
    .table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

@media (max-width: 600px) {
    /* Única regra de contagem de coluna que sobrou, e tem medida por trás: em
       390px a grade cabia dois cartões de 177px, mas o cartão precisa de 176px
       só para o valor ("R$ 3.402.742,42", que não quebra) mais 40px de ícone —
       o conteúdo vazava. Numa coluna sobram 366px e tudo cabe. É decisão de
       formato de tela, não contagem arbitrária. */
    .kpi-strip { grid-template-columns: 1fr; }
    .kpi-strip .kpi-card:first-child { grid-column: auto; }

    .topbar { padding-left: 58px; }
    .topbar-total, .topbar-extraction { flex: 1 1 100%; justify-content: flex-start; }

    .main { padding: 12px; }
    .status-card, .bar-card, .kpi-card { padding: 14px; }

    /* Números grandes encolhem para não vazar do cartão. */
    .kpi-value { font-size: 22px; }
    .tot-value { font-size: 16px; }
}

/* Nenhuma tela deve rolar para o lado. */
html, body { max-width: 100%; overflow-x: hidden; }
img, svg, canvas { max-width: 100%; }

/* ════════════════════════════════════════
   GESTÃO DE COLETAS (coletas.php)

   Primeira tela do painel que escreve no banco — e a primeira que precisa de
   interruptor, aviso de sucesso e formulário fora do login. Tudo aqui é
   acréscimo: nenhuma regra existente foi alterada.
════════════════════════════════════════ */

/* O .alert nasceu só na variante vermelha (é o erro do login). Verde para
   quando a operação deu certo — num painel escuro, cor é o que se lê antes
   do texto. */
.alert { display: flex; align-items: center; gap: 8px; }
.alert > svg {
    width: 16px; height: 16px; flex-shrink: 0;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.alert-ok {
    background: rgba(34,201,122,.12);
    border-color: rgba(34,201,122,.3);
    color: #7fe0ac;
}

/* Explicação de como a tela funciona: precisa ser lida uma vez, não gritar. */
.info-note {
    display: flex; gap: 10px; align-items: flex-start;
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-left: 3px solid var(--zeus-amber);
    border-radius: var(--r-sm);
    padding: 11px 14px;
    margin-bottom: 14px;
}
.info-note > svg {
    width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px;
    color: var(--zeus-amber);
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.info-note p { margin: 0; font-size: 12px; line-height: 1.55; color: var(--text-2); }
.info-note strong { color: var(--text); font-weight: 600; }

.card-head .head-note {
    margin-left: 10px;
    font-size: 11px; font-weight: 500;
    color: var(--yellow);
}

/* ── Tabela ────────────────────────────── */
.tabela-coletas td { vertical-align: top; }
.tabela-coletas .col-filial strong { color: var(--text); font-weight: 700; }
.tabela-coletas .col-filial small,
.tabela-coletas .senha-meta {
    display: block; margin-top: 3px;
    font-size: 10.5px; color: var(--text-3); line-height: 1.4;
}
.tabela-coletas .vazio { color: var(--text-3); }

/* ── Interruptor ───────────────────────── */
.form-toggle { display: flex; align-items: center; gap: 8px; }
.switch { position: relative; display: inline-block; width: 38px; height: 21px; flex-shrink: 0; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch .slider {
    position: absolute; inset: 0;
    background: rgba(255,255,255,.14);
    border-radius: 21px;
    transition: background .18s ease;
    pointer-events: none;
}
.switch .slider::before {
    content: ''; position: absolute;
    width: 15px; height: 15px; left: 3px; top: 3px;
    background: var(--text-2);
    border-radius: 50%;
    transition: transform .18s ease, background .18s ease;
}
.switch input:checked + .slider { background: rgba(245,166,35,.55); }
.switch input:checked + .slider::before { transform: translateX(17px); background: var(--zeus-amber); }
.switch input:focus-visible + .slider { box-shadow: 0 0 0 3px rgba(245,166,35,.22); }
/* Desabilitado é o estado de quem está com a senha recusada: religar dali só
   gastaria tentativa no portal. O title da label explica o porquê. */
.switch input:disabled { cursor: not-allowed; }
.switch input:disabled + .slider { opacity: .4; }
.switch-texto { font-size: 11px; color: var(--text-2); }
.btn-mini { padding: 3px 9px !important; font-size: 10.5px !important; }

/* ── Selos ─────────────────────────────── */
.badge-senha, .badge-perfil, .badge-status {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 20px;
    font-size: 10.5px; font-weight: 600;
    white-space: nowrap;
}
.badge-senha-validada { background: rgba(34,201,122,.14); color: var(--green); }
.badge-senha-pendente { background: rgba(245,197,24,.14); color: var(--yellow); }
.badge-senha-recusada { background: rgba(255,77,106,.14); color: var(--red); }
.badge-senha-ausente  { background: rgba(107,122,153,.16); color: var(--gray); }

/* Selos da Gestão de Usuários (usuarios.php) */
.badge-perfil-admin    { background: rgba(245,166,35,.14); color: var(--zeus-amber); }
.badge-perfil-operador { background: rgba(107,122,153,.16); color: var(--gray); }
.badge-status-ativo    { background: rgba(34,201,122,.14); color: var(--green); }
.badge-status-inativo  { background: rgba(255,77,106,.14); color: var(--red); }

/* O selo de perfil leva um ícone (escudo/pessoa) — vira flex só aqui, sem
   afetar badge-senha e badge-status, que continuam texto puro. */
.badge-perfil { display: inline-flex; align-items: center; gap: 4px; }
.badge-perfil svg {
    width: 10px; height: 10px; flex-shrink: 0;
    fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* ── Avatar da listagem (usuarios.php) ────
   Cor pelo id (usuario_avatar_classe(), app/usuarios_admin.php), não por
   perfil — reaproveita exatamente o degradê dos kpi-icon para a tela inteira
   ler como um conjunto só, em vez de duas paletas concorrendo. */
.usuario-linha { display: flex; align-items: center; gap: 11px; }
.avatar-usuario {
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    width: 34px; height: 34px;
    border-radius: 50%;
    font-size: 13px; font-weight: 800;
    color: #fff;
    box-shadow: 0 3px 10px rgba(0,0,0,.35);
}
.avatar-usuario.cor-1 { background: linear-gradient(135deg,#1a6fc4,#4da6ff); }
.avatar-usuario.cor-2 { background: linear-gradient(135deg,#15a05c,#22c97a); }
.avatar-usuario.cor-3 { background: linear-gradient(135deg,#c77a00,#F5A623); color: #241a04; }
.avatar-usuario.cor-4 { background: linear-gradient(135deg,#6a3ecf,#9d6ef5); }
.avatar-usuario.cor-5 { background: linear-gradient(135deg,#cc1f3a,#ff4d6a); }

/* Linhas com mais ar do que a grade densa do relatório — aqui são poucas
   contas, não milhares de OS, e a tabela ganha com isso. */
.tabela-usuarios th, .tabela-usuarios td { padding: 12px 14px; white-space: normal; }
.tabela-usuarios .col-filial small { margin-top: 1px; }

/* Botão com ícone à esquerda do texto — "+ Novo usuário" e outros que vierem. */
.btn-com-icone { display: inline-flex; align-items: center; gap: 7px; }
.btn-com-icone svg {
    width: 13px; height: 13px;
    fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round;
}

/* O resumo da gaveta ("Editar") ganhou um ícone — mesmo tamanho dos outros
   ícones inline da tela, para não desequilibrar ao lado do texto. */
.senha-drawer > summary { display: inline-flex; align-items: center; gap: 6px; }
.senha-drawer > summary svg {
    width: 11px; height: 11px;
    fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* Entrada suave dos cards — só na Gestão de Usuários (.pagina-usuarios no
   <body>), para não mudar a sensação das outras telas sem terem pedido. */
@keyframes surgir {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.pagina-usuarios .kpi-strip .kpi-card,
.pagina-usuarios .status-card {
    animation: surgir .35s ease both;
}
.pagina-usuarios .kpi-strip .kpi-card:nth-child(2) { animation-delay: .04s; }
.pagina-usuarios .kpi-strip .kpi-card:nth-child(3) { animation-delay: .08s; }
.pagina-usuarios .kpi-strip .kpi-card:nth-child(4) { animation-delay: .12s; }
.pagina-usuarios .status-card { animation-delay: .16s; }

.tentativa { font-size: 11.5px; font-weight: 600; }
.tentativa-ok       { color: var(--green); }
.tentativa-falha    { color: var(--red); }
.tentativa-ignorada { color: var(--text-3); }

/* ── Troca de senha: o botão do popup (Gestão de Coletas) e a gaveta que
      continua em uso na Gestão de Usuários ──────────── */
/* Mesma aparência de propósito: as duas telas têm a mesma coluna estreita, e o
   alvo de clique já estava dimensionado para este tamanho. */
/* ATENÇÃO ao `button` global (bem acima): ele pinta gradiente âmbar, letra 800
   e `box-shadow: 0 4px 18px rgba(245,166,35,.35)`, além de levantar no hover.
   O <summary> que estava aqui antes não era <button> e escapava disso; o botão
   novo nascia com um halo alaranjado em volta. Daí o `box-shadow: none` e o
   hover sem transform — este é um botão discreto de tabela, não uma ação
   principal. */
.btn-senha,
.senha-drawer > summary {
    cursor: pointer;
    display: inline-block;
    padding: 4px 11px;
    border: 1px solid var(--glass-border2);
    border-radius: var(--r-sm);
    font-size: 11px; font-weight: 600;
    font-family: inherit;
    letter-spacing: 0;
    color: var(--text-2);
    background: transparent;
    box-shadow: none;
    list-style: none;
    user-select: none;
    transition: border-color .15s ease, color .15s ease;
}
.senha-drawer > summary::-webkit-details-marker { display: none; }
.btn-senha:hover,
.senha-drawer > summary:hover { color: var(--text); border-color: var(--zeus-amber); }
.btn-senha:hover {
    opacity: 1;
    transform: none;
    box-shadow: none;
    background: transparent;
}
.btn-senha:active { transform: none; }
.senha-drawer[open] > summary {
    color: var(--zeus-amber);
    border-color: rgba(245,166,35,.45);
    margin-bottom: 10px;
}

/* O popup da senha é o mesmo <dialog> da Gestão de Usuários; só o cabeçalho
   muda, porque leva o nome da filial e precisa caber sem cortar. */
.modal-senha .modal-usuario-head h2 {
    text-transform: none;
    letter-spacing: 0;
    font-size: 12.5px;
    line-height: 1.35;
}
.modal-senha-usuario {
    margin: 0 0 14px;
    font-size: 11px;
    color: var(--text-2);
}
.modal-senha-usuario strong { color: var(--text); font-weight: 700; }
.modal-senha .form-aviso { margin: 0; }

/* ── Formulário fora do login ──────────── */
/* As medidas do campo só existiam sob `.login-panel .input-shell input`, então
   qualquer campo de senha fora do login nascia sem estilo nenhum. Mesmos
   valores, num escopo que a tela nova alcança. */
.form-shell { min-width: 232px; max-width: 300px; }
.form-shell label,
.modal-usuario-body label {
    display: block;
    margin: 0 0 5px;
    font-size: 10.5px; font-weight: 600;
    color: var(--text-2);
    text-transform: uppercase; letter-spacing: .4px;
}
.form-shell .input-shell,
.modal-usuario-body .input-shell { margin-bottom: 11px; }
.form-shell .input-shell input,
.form-shell .input-shell select,
.modal-usuario-body .input-shell input,
.modal-usuario-body .input-shell select {
    width: 100%;
    height: 42px;
    margin: 0;
    padding: 0 44px 0 40px;
    color: var(--text);
    font-size: 12px;
    border: 1px solid rgba(255,255,255,.1);
    border-radius: 10px;
    background: rgba(255,255,255,.045);
}
.form-shell .input-shell input:focus,
.modal-usuario-body .input-shell input:focus {
    border-color: rgba(245,166,35,.48);
    background: rgba(255,255,255,.065);
    box-shadow: 0 0 0 3px rgba(245,166,35,.09);
}
/* Os ícones destes formulários são desenhos de contorno, não sólidos. Sem
   `fill: none` o navegador aplica o preenchimento padrão (preto) e o cadeado
   vira uma mancha, o olho vira uma elipse cheia. Na tela de login isso não
   aparecia porque a regra de `.login-form svg` já cobria — fora dela, não. */
.form-shell .input-shell > svg,
.modal-usuario-body .input-shell > svg,
.password-toggle svg {
    width: 15px; height: 15px;
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.password-toggle svg { width: 16px; height: 16px; }

/* ── Popup "Novo usuário" (usuarios.php) ──
   O projeto não tinha modal — só a gaveta <details> das outras telas. Aqui o
   conteúdo (nome, login, perfil, senha) é grande demais para caber numa linha
   de tabela sem empurrar tudo, então vale o <dialog> nativo: sem biblioteca,
   com Esc-para-fechar e foco preso de graça pelo navegador. */
dialog.modal-usuario {
    position: fixed;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
    padding: 0;
    width: min(420px, 92vw);
    max-height: min(88vh, 680px);
    overflow: auto;
    border: 1px solid var(--glass-border);
    border-radius: var(--r-lg);
    background: var(--surface);
    box-shadow: 0 24px 64px rgba(0,0,0,.5);
}
dialog.modal-usuario::backdrop {
    background: rgba(6,7,12,.72);
    backdrop-filter: blur(3px);
}
.modal-usuario-head {
    position: sticky; top: 0;
    display: flex; align-items: center; justify-content: space-between;
    gap: 10px;
    padding: 14px 16px;
    background: linear-gradient(135deg, rgba(245,166,35,.15) 0%, rgba(232,76,32,.10) 100%);
    border-bottom: 1px solid var(--glass-border);
}
.modal-usuario-head h2 {
    font-size: 11px; font-weight: 800;
    text-transform: uppercase; letter-spacing: .5px;
    color: var(--text);
}
/* O X fica sobre o cabeçalho âmbar do modal, e ali um ícone fino em --text-2
   praticamente some — era invisível na prática. Precisa de contraste próprio:
   traço branco, mais grosso, sobre um fundo escurecido que o separa do
   gradiente. */
.modal-close {
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    width: 28px; height: 28px;
    /* PADDING ZERO, e isto não é detalhe: o `button` global manda
       `padding: 11px 14px`. Com a largura fixa em 28px e box-sizing: border-box,
       os 14px de cada lado comiam os 28px inteiros e o ícone ficava com
       width: 0 — o botão aparecia como um quadrado vazio, sem X nenhum. */
    padding: 0;
    border: 1px solid rgba(255,255,255,.16);
    border-radius: 8px;
    background: rgba(0,0,0,.28);
    color: var(--text);
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease, color .15s ease;
}
.modal-close:hover {
    color: #fff;
    background: rgba(0,0,0,.45);
    border-color: rgba(255,255,255,.34);
}
.modal-close:focus-visible {
    outline: 2px solid var(--zeus-amber2);
    outline-offset: 2px;
}
.modal-close svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; }
.modal-usuario-body { padding: 16px; }
.modal-usuario-actions {
    display: flex; justify-content: flex-end; gap: 10px;
    padding: 12px 16px;
    border-top: 1px solid var(--glass-border);
}

.check-linha {
    display: flex; align-items: center; gap: 7px;
    margin: 0 0 12px;
    font-size: 11px; font-weight: 500;
    color: var(--text-2);
    text-transform: none; letter-spacing: 0;
    cursor: pointer;
}
.check-linha input { width: 14px; height: 14px; margin: 0; accent-color: var(--zeus-amber); cursor: pointer; }

/* Lista de filiais no cadastro/edição de usuário (usuarios.php) — some
   quando "Todas as filiais" está marcado (assets/js/usuarios.js). */
.filiais-checklist {
    max-height: 160px;
    overflow-y: auto;
    padding: 8px 10px;
    margin: 0 0 12px;
    border: 1px solid rgba(255,255,255,.08);
    border-radius: 10px;
    background: rgba(255,255,255,.03);
}
.filiais-checklist .check-linha { margin-bottom: 8px; }
.filiais-checklist .check-linha:last-child { margin-bottom: 0; }

.form-aviso {
    margin: 9px 0 0;
    font-size: 10.5px; line-height: 1.5;
    color: var(--text-3);
}

@media (max-width: 900px) {
    .form-shell { min-width: 0; max-width: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Faturamento a conferir — cruzamento eCargo × Rodopar

   Entrou em 03/08/2026, junto com o religamento do cruzamento. O bloco só é
   desenhado quando há caso (ver o if na index.php): um alerta permanente
   zerado vira paisagem, e no dia em que tiver número ninguém repara.
   ══════════════════════════════════════════════════════════════════════════ */

.fat-alerta-card {
    margin: 0 0 18px;
    padding: 14px 16px 16px;
    border: 1px solid rgba(255,77,106,.35);
    border-left: 3px solid var(--red);
    border-radius: 12px;
    background: linear-gradient(135deg, rgba(255,77,106,.10), rgba(255,77,106,.03));
}

.fat-alerta-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.fat-alerta-head svg {
    width: 22px; height: 22px; flex: none;
    fill: none; stroke: var(--red); stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.fat-alerta-head strong { display: block; font-size: 14px; color: var(--text); }
.fat-alerta-head small { display: block; font-size: 11.5px; color: var(--text-3); margin-top: 1px; }

/* auto-fit: com um caso só o item ocupa a linha toda; com dois, dividem. */
.fat-alerta-itens { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 10px; }

.fat-item {
    display: flex; align-items: center; gap: 12px;
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    text-decoration: none;
    transition: border-color .15s ease, transform .15s ease;
}
.fat-item:hover { border-color: var(--red); transform: translateY(-1px); }

.fat-num {
    font-size: 26px; font-weight: 800; line-height: 1;
    color: var(--red);
    font-variant-numeric: tabular-nums;
    min-width: 44px; text-align: center;
}
.fat-txt strong { display: block; font-size: 12.5px; color: var(--text); font-weight: 700; }
.fat-txt small { display: block; font-size: 11px; color: var(--text-3); margin-top: 2px; line-height: 1.4; }

/* Coluna "Faturamento a conferir" da Análise por Filial. */
.fat-alerta-link { text-decoration: none; display: inline-block; }
.fat-alerta-link strong { color: var(--red); font-weight: 600; font-size: 13px; }
.fat-alerta-link small { display: block; color: var(--text-3); font-size: 10.5px; margin-top: 1px; }

/* ── Logs de Usuários (public/logs.php) ─── */

.tabs-logs {
    display: flex; gap: 4px;
    margin: 4px 0 16px;
    border-bottom: 1px solid var(--glass-border);
}
.tabs-logs a {
    padding: 9px 14px;
    font-size: 12px; font-weight: 700;
    color: var(--text-2);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    transition: color .15s ease, border-color .15s ease;
}
.tabs-logs a:hover { color: var(--text); }
.tabs-logs a.active { color: var(--zeus-amber); border-bottom-color: var(--zeus-amber); }

.badge-presenca { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 20px; font-size: 10.5px; font-weight: 600; white-space: nowrap; }
.badge-presenca::before { content: ''; width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.badge-presenca-online  { background: rgba(34,201,122,.14); color: var(--green); }
.badge-presenca-online::before { background: var(--green); box-shadow: 0 0 6px var(--green); }
.badge-presenca-ausente { background: rgba(245,197,24,.14); color: var(--yellow); }
.badge-presenca-ausente::before { background: var(--yellow); }

/* Indicador "atualizado às HH:MM:SS" + pausar, no topbar da aba online. */
.logs-live-indicator {
    display: flex; align-items: center; gap: 8px;
    font-size: 11px; color: var(--text-2);
    margin-right: 6px;
}
.logs-live-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--green);
    box-shadow: 0 0 6px var(--green);
    flex-shrink: 0;
    animation: logs-pulso 2s ease-in-out infinite;
}
.logs-live-dot.logs-live-dot-erro { background: var(--red); box-shadow: 0 0 6px var(--red); animation: none; }
@keyframes logs-pulso {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}

/* ── Aba "Resumo" (public/logs.php) ───────── */

.filter-periodo-presets { flex: 1 1 auto; min-width: 260px; }
.periodo-presets { display: flex; gap: 6px; flex-wrap: wrap; }
.periodo-btn {
    padding: 6px 12px;
    font-size: 11.5px; font-weight: 700;
    color: var(--text-2);
    border: 1px solid var(--glass-border2);
    border-radius: 20px;
    text-decoration: none;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.periodo-btn:hover { color: var(--text); border-color: var(--zeus-amber); }
.periodo-btn.active { color: #241a04; background: var(--zeus-amber); border-color: var(--zeus-amber); }

.tendencia { font-weight: 700; font-size: 11px; }
.tendencia-up { color: var(--green); }
.tendencia-down { color: var(--red); }
.tendencia-flat { color: var(--text-3); }

/* Ranking de usuários mais ativos */
.ranking-lista { display: flex; flex-direction: column; }
.ranking-item {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 16px;
    border-bottom: 1px solid rgba(255,255,255,.04);
}
.ranking-item:last-child { border-bottom: 0; }
.ranking-pos { width: 20px; font-size: 11px; font-weight: 800; color: var(--text-3); flex-shrink: 0; }
.ranking-info { flex: 1; min-width: 0; }
.ranking-info strong { display: block; font-size: 12px; color: var(--text); }
.ranking-info small { display: block; font-size: 10.5px; color: var(--text-3); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ranking-total { text-align: right; font-size: 13px; font-weight: 800; color: var(--zeus-amber); flex-shrink: 0; }
.ranking-total small { display: block; font-size: 9.5px; font-weight: 500; color: var(--text-3); text-transform: uppercase; }

/* Ranking de funcionalidades — barra horizontal com tendência */
.funcionalidades-lista { padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; }
.func-topo { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; font-size: 11.5px; }
.func-topo strong { color: var(--text); font-weight: 700; }
.func-topo span { color: var(--text-2); display: flex; gap: 6px; align-items: baseline; }
.func-barra { height: 6px; border-radius: 4px; background: rgba(255,255,255,.06); overflow: hidden; }
.func-barra span { display: block; height: 100%; background: linear-gradient(90deg, var(--zeus-amber), var(--uni-orange)); border-radius: 4px; }

/* Busca/filtro + grade de cards da atividade individual.
   input/select têm width:100% no reset global (regra para telas pequenas) —
   sem flex-basis explícito aqui, cada um vira uma linha própria dentro do
   flex. */
.individual-filtro {
    display: flex; gap: 8px; align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--glass-border);
    flex-wrap: wrap;
}
.individual-filtro input[type="text"] { flex: 1 1 220px; width: auto; min-width: 160px; }
.individual-filtro select { flex: 0 1 190px; width: auto; }
.individual-filtro button { flex: 0 0 auto; }

/* ── Gráficos da aba Resumo — altura fixa, senão o donut (1:1 por padrão)
   cresce até a largura da coluna inteira e vira o dobro do card vizinho. ── */
.logs-chart-box {
    position: relative;
    height: 240px;
    padding: 16px;
}
.logs-donut-box {
    position: relative;
    height: 240px;
    max-width: 260px;
    margin: 0 auto;
    padding: 16px 0;
}
@media (max-width: 600px) {
    .logs-chart-box, .logs-donut-box { height: 200px; }
}
.individual-grade {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 10px;
    padding: 14px 16px;
}
.individual-card {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 13px;
    border: 1px solid var(--glass-border2);
    border-radius: var(--r-md);
    text-decoration: none;
    transition: border-color .15s ease, transform .15s ease;
}
.individual-card:hover { border-color: var(--zeus-amber); transform: translateY(-1px); }
.individual-info { flex: 1; min-width: 0; }
.individual-info strong { display: block; font-size: 12px; color: var(--text); }
.individual-info small { display: block; font-size: 10px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.individual-total { text-align: right; font-size: 13px; font-weight: 800; color: var(--text); flex-shrink: 0; }
.individual-total small { display: block; font-size: 9px; font-weight: 500; color: var(--text-3); text-transform: uppercase; }

/* ══════════════════════════════════════════════════════════════════════════
   PAINEL GERAL (public/geral.php)

   O consolidado reaproveita quase tudo do que já existe — .kpi-strip,
   .status-card, .table-wrap, .pct-pill, .fat-alerta-card, .donut-panel. O que
   está aqui é só o que a tela dos clientes lado a lado pediu a mais.
   ══════════════════════════════════════════════════════════════════════════ */

/* Link solto na barra lateral: o Painel Geral não pertence a cliente nenhum,
   então não vive dentro de um .client-group dobrável. Só precisa da margem que
   o grupo dava. */
.sidebar-link-solo { margin-bottom: 6px; }

/* O "/22" de "18/22" nos KPIs de contagem — menor e apagado, para o número que
   importa continuar sendo o da frente. */
.kpi-de { font-size: .6em; font-weight: 600; color: var(--text-3); margin-left: 2px; }

/* A tabela de clientes tem duas informações por célula em três colunas (a
   quantidade em cima, o dinheiro embaixo). Sem isto o valor ficaria na mesma
   linha e a coluna dobraria de largura. */
.tabela-clientes .celula-sub {
    display: block; font-size: 10px; font-weight: 500;
    color: var(--text-3); margin-top: 2px; white-space: nowrap;
}
.tabela-clientes .celula-vazia { color: var(--text-3); }

/* O nome do cliente é o caminho para o painel dele — precisa parecer clicável
   sem virar um link azul no meio da tabela. */
.cliente-link {
    display: inline-flex; align-items: center; gap: 9px;
    color: var(--text); font-weight: 700; text-decoration: none;
    transition: color .15s ease;
}
.cliente-link:hover { color: var(--zeus-amber); }
.cliente-link .client-monogram { width: 26px; height: 26px; flex-basis: 26px; font-size: 10px; }
.cliente-link:hover .client-monogram {
    color: #161008; border-color: transparent;
    background: linear-gradient(135deg, var(--zeus-amber), var(--uni-orange));
}

/* Com logo, o gradiente do hover pintaria POR BAIXO da imagem e apareceria nos
 * cantos arredondados, como um halo âmbar em volta da marca. O retorno visual
 * do hover continua existindo — vem do nome do cliente ao lado, que muda de
 * cor pela regra .cliente-link:hover. Mesma decisão da sidebar. */
.cliente-link:hover .client-monogram.is-logo {
    background: none;
}

/* O número das divergências abre o relatório daquele cliente já filtrado. */
.link-diverge { color: var(--red); font-weight: 700; text-decoration: none; }
.link-diverge:hover { text-decoration: underline; }

/* O mesmo semáforo do carimbo da topbar, encolhido para caber na célula: verde
   recente, âmbar 1–2 dias, vermelho parado. As regras de cor da .ext-dot são as
   de lá (extracao_status(), app/helpers.php) — aqui só muda o tamanho. */
.coleta-selo {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 11px; font-weight: 600; color: var(--text-2); white-space: nowrap;
}
.coleta-selo .ext-dot {
    width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; background: var(--muted);
}
.coleta-selo.ext-ok .ext-dot { background: #22c55e; box-shadow: 0 0 7px rgba(34,197,94,.7); }
.coleta-selo.ext-atencao { color: var(--zeus-amber); }
.coleta-selo.ext-atencao .ext-dot { background: var(--zeus-amber); box-shadow: 0 0 7px rgba(245,166,35,.7); }
.coleta-selo.ext-alerta { color: #ef4444; }
.coleta-selo.ext-alerta .ext-dot {
    background: #ef4444; box-shadow: 0 0 7px rgba(239,68,68,.7);
    animation: ext-pulse 1.8s ease-in-out infinite;
}

/* A tabela do consolidado ocupa a faixa inteira: .bot-row é um grid de duas
   colunas, e aqui não há gráfico ao lado dela para preencher a segunda. */
.bot-row-full { grid-template-columns: 1fr; }

/* O mesmo número grande da rosca, quando o que ele mostra é DINHEIRO.
   .donut-pct foi dimensionada para "85,4%" — quatro caracteres. Um
   "R$ 3.099.429,77" na mesma fonte vaza da caixa e o painel geral cortava o
   valor no meio (visto em 1600px, 19/08/2026). */
.donut-pct.money { font-size: clamp(20px, 1.9vw, 30px); word-break: break-word; }

/* ══════════════════════════════════════════════════════════════════════════
   COMPOSIÇÃO DO VALOR (public/index.php)

   Os três grupos de faturamento numa faixa só. Nasceu do pedido da UNI em
   19/08/2026 para a apresentação à diretoria: o total cheio era lido como se
   fosse tudo pendência.
   ══════════════════════════════════════════════════════════════════════════ */
.composicao-card {
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    box-shadow: 0 4px 20px rgba(0,0,0,.25);
    flex-shrink: 0;
}
/* Cabeçalho NEUTRO, ao contrário dos outros cards do painel.
   O `.card-head` padrão traz um gradiente âmbar e uma barrinha da mesma cor —
   e aqui, logo acima de uma barra verde/laranja/azul, aquele âmbar não pertence
   a grupo nenhum e briga com os três. Neste bloco a cor é dado; no cabeçalho,
   ruído. */
.composicao-card .card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    background: transparent;
    border-bottom: 0;
    padding: 14px 16px 10px;
    color: var(--text-2);
}

.composicao-card .card-head::before { display: none; }
/* O total no cabeçalho: é o número que a diretoria já conhece, e serve de
   âncora para as três partes que vêm abaixo somarem na cabeça de quem lê. */
.comp-total { font-size: 15px; font-weight: 800; color: var(--text); letter-spacing: -.2px; }

/* A barra vem antes dos números: numa apresentação, a proporção é lida antes
   do valor. Sem gap entre as faixas — elas formam uma barra só.

   Alta o bastante (22px) para o percentual caber DENTRO dela: quem projeta esta
   tela numa reunião lê a proporção sem procurar o número embaixo. */
/* Fina de propósito: 8px. A versão de 22px foi feita para caber o percentual
   dentro, e ficou pesada — dominava um bloco em que o texto é que informa. O
   percentual voltou para os cartões, onde já estava. */
.comp-barra {
    display: flex;
    gap: 3px;
    height: 8px;
    margin: 0 16px 16px;
    background: transparent;
}

/* A largura final mora em `--alvo` e o `--atraso` escalona as três: elas entram
   em sequência, da esquerda para a direita, como uma linha sendo desenhada. Os
   dois vêm de public/index.php.

   `cubic-bezier(.16,1,.3,1)` é uma saída bem longa — a faixa desacelera até
   parar em vez de travar no fim, que é o que faz o movimento parecer suave em
   vez de mecânico. */
.comp-faixa {
    display: block;
    height: 100%;
    width: var(--alvo, 0);
    border-radius: 99px;
    position: relative;
    transform-origin: left center;
    animation: comp-crescer 1.9s cubic-bezier(.16,1,.3,1) var(--atraso, 0s) both;
    transition: filter .32s ease, transform .32s cubic-bezier(.22,1,.36,1), box-shadow .32s ease;
}

@keyframes comp-crescer {
    from { width: 0; opacity: 0; }
    to   { width: var(--alvo, 0); opacity: 1; }
}

.comp-faixa.is-ok       { background: linear-gradient(90deg, #22c97a, #2ec4b6); }
.comp-faixa.is-conferir { background: linear-gradient(90deg, #ff8c42, #ff4d6a); }
.comp-faixa.is-faturar  { background: linear-gradient(90deg, #4da6ff, #9d6ef5); }

/* ── O elo entre a barra e os cartões ──
   Passar o mouse numa faixa acende o cartão dela, e vice-versa. As duas metades
   do bloco falam das mesmas três coisas, e sem isto é preciso comparar cor com
   cor para saber qual é qual. Quem apaga as outras é a classe no cartão-pai.

   Todas as transições em .32s: o padrão do projeto (.16s) é rápido demais
   quando o que muda é opacidade de vários elementos ao mesmo tempo — parecia um
   piscar, não um realce. */
.composicao-card.tem-foco .comp-faixa:not(.is-foco) {
    filter: saturate(.25) brightness(.65);
    transform: scaleY(.7);
}

.composicao-card.tem-foco .comp-item:not(.is-foco) { opacity: .38; }

/* A faixa em foco engorda e ganha um brilho da própria cor. `currentColor` não
   serve aqui (o fundo é gradiente), então a sombra sai neutra e o realce vem do
   tamanho. */
.comp-faixa.is-foco {
    transform: scaleY(2);
    box-shadow: 0 0 14px rgba(255,255,255,.22);
    z-index: 1;
}

.comp-item {
    cursor: default;
    transition: opacity .32s ease, border-color .32s ease, transform .32s cubic-bezier(.22,1,.36,1), background .32s ease;
}

.comp-item.is-foco {
    transform: translateY(-3px);
    background: var(--surface-2);
}

.comp-itens {
    display: grid;
    /* 190px, e não 210: com 210 os três blocos precisavam de 654px e a
       coluna do painel tem 650 — o terceiro caía sozinho numa segunda linha. */
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 12px;
    padding: 0 16px 16px;
}
.comp-item {
    display: flex; flex-direction: column; gap: 3px;
    padding: 12px 14px;
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    border-left-width: 3px;
    background: var(--surface-solid);
}
.comp-item.is-ok       { border-left-color: #22c97a; }
.comp-item.is-conferir { border-left-color: #ff8c42; }
.comp-item.is-faturar  { border-left-color: #4da6ff; }

.comp-rotulo {
    font-size: 10px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .5px; color: var(--text-2);
}
.comp-valor { font-size: 19px; font-weight: 800; color: var(--text); letter-spacing: -.3px; }
.comp-sub { font-size: 10px; color: var(--text-3); line-height: 1.45; }
.comp-item .comp-sub strong { color: var(--text-2); }

/* O percentual do rodapé. No hover ele apenas CLAREIA — nada de cor e nada de
   escala.
   Escalar era o caminho errado: `transform` não ocupa espaço no layout, então o
   número crescia por cima do "·" e do texto ao lado em vez de empurrá-los. E
   `font-weight` também não serve, porque a fonte fica mais larga e desloca a
   linha inteira a cada hover.
   Só a cor muda: é o único destaque que não mexe em um pixel de posição. */
.comp-sub b {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    transition: color .32s ease;
}

.comp-item.is-foco .comp-sub b { color: var(--text); }

/* ═══════════════════════════════════════════════════════════════════════════
   RÉGUA DE COBRANÇA — Painel Geral (public/geral.php)

   Uma linha do tempo: sete marcos ligados por um trilho contínuo, cada um com
   a contagem dentro da bolinha e o valor logo abaixo. Lê-se da esquerda (OS
   emitida hoje) para a direita (parada há meses), e a cor acompanha o caminho
   — neutro no ciclo normal, quente onde o dinheiro está velho.

   As sete somam o total do canto direito: cada OS mora em uma bolinha só.
   ═══════════════════════════════════════════════════════════════════════════ */

.regua-row { flex-shrink: 0; }

.regua-panel {
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    padding: var(--sp-4) var(--sp-4) var(--sp-3);
}

.regua-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
}

.regua-head h2 { margin: 0; font-size: 15px; letter-spacing: .2px; }

.regua-total { text-align: right; line-height: 1.25; }

.regua-total-valor {
    display: block;
    font-size: 22px;
    font-weight: 700;
    color: var(--zeus-amber);
}

.regua-total-count { display: block; font-size: 11px; color: var(--muted); }

/* O trilho.
   `space-between` em vez de larguras iguais: o valor em reais de uma faixa
   vazia esticaria a coluna tanto quanto o de R$ 6 mi, e a régua ficaria com
   buracos. Assim cada marco ocupa o que precisa e a distância entre eles é que
   se distribui. */
.regua-trilho {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-2);
    padding: var(--sp-4) 4px var(--sp-2);
    position: relative;
    overflow-x: auto;
    scrollbar-width: none;
}

/* A barra de rolagem some, mas a rolagem continua: em tela estreita ela
   aparecia por cima do valor da última faixa e cortava o número. */
.regua-trilho::-webkit-scrollbar { height: 0; }

/* A linha que costura os marcos, com o gradiente que vai do azul (ciclo normal)
   ao vermelho (parado há meses). Ela conta a mesma história das bolhas antes de
   qualquer número ser lido.

   O `top` é o centro vertical da pista das bolhas, e ele é PREVISÍVEL porque a
   pista tem altura fixa: 16 do padding + 15 do rótulo + 8 + 12 da haste + 8 +
   38 (metade dos 76 da pista) = 97. Se alguma dessas medidas mudar, esta
   também muda — é o preço de uma linha que passa pelo centro de bolhas de
   tamanhos diferentes. */
.regua-trilho::after {
    content: '';
    position: absolute;
    left: 10px;
    right: 10px;
    top: 96px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg,
        rgba(77,166,255,.5) 0%,
        rgba(245,166,35,.5) 55%,
        rgba(255,77,106,.6) 100%);
    z-index: 0;
}

/* `flex: 1` para os sete dividirem a largura em partes iguais: com largura
   automática, a faixa de R$ 6 mi ficava larga e a de R$ 8 mil estreita, e os
   marcos deixavam de estar a distâncias regulares — que é o que faz uma régua
   parecer uma régua.

   O `box-shadow`, o `border-radius` e o `outline` são ZERADOS de propósito: o
   projeto tem um estilo global de `button` que desenha um halo âmbar
   arredondado, e aqui ele virava uma caixa em volta de cada marco, cortando a
   linha do tempo em sete cartões soltos. */
.regua-marco {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    background: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    outline: none;
    padding: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
    position: relative;
    z-index: 1;
}

.regua-marco:hover, .regua-marco:active { box-shadow: none; }

.regua-marco.is-vazio { cursor: default; opacity: .4; }

.regua-rotulo {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .4px;
    color: var(--muted);
}

.regua-haste {
    width: 1px;
    height: 12px;
    background: var(--glass-border2);
}

/* A pista da bolha tem altura FIXA, igual à da maior bolinha possível. É o que
   mantém todas centradas na mesma linha horizontal mesmo com diâmetros
   diferentes — sem isto, a bolinha de 38px subiria e a linha do trilho passaria
   por baixo dela. */
.regua-bolha-area {
    height: 76px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

/* O anel por cliente, desenhado em SVG por assets/js/geral.js. Fica ABSOLUTO e
   centrado sobre a bolha, e não no fluxo, para não empurrar nada quando o
   diâmetro muda de uma faixa para a outra.

   `pointer-events: none` para o clique atravessar e chegar no botão: o anel é
   informação, não alvo. */
.regua-anel {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    opacity: .85;
    transition: opacity .14s ease;
}

.regua-marco:hover .regua-anel { opacity: 1; }

/* Diâmetro e fonte vêm de `--regua-lado` / `--regua-fonte`, calculados por
   linha em public/geral.php a partir da quantidade de OS: quanto mais OS
   paradas, maior a bolha. Os valores de reserva servem só para o caso de o
   estilo inline não chegar.

   Fundo com gradiente RADIAL e OPACO — a luz vem de cima, como num objeto
   físico, e o opaco impede que a linha do trilho apareça atravessando o
   número. */
.regua-bolinha {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--regua-lado, 58px);
    height: var(--regua-lado, 58px);
    min-width: var(--regua-lado, 58px);
    border-radius: 50%;
    background: radial-gradient(circle at 50% 28%, #242737, #14161f);
    border: 1px solid var(--glass-border2);
    font-size: var(--regua-fonte, 16px);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.3px;
    color: var(--text);
    position: relative;
    transition: transform .16s ease, border-color .16s ease;
}

/* O HALO. Um cone de luz girado atrás da bolha, borrado, na cor da faixa: é o
   que dá o ar de painel de controle sem encher a tela de cor chapada.

   `inset: -4px` e `z-index: -1` deixam o brilho vazar por fora da borda sem
   empurrar layout nenhum — a bolha continua ocupando o mesmo espaço. */
.regua-bolinha::before {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    background: conic-gradient(from 180deg, transparent, var(--regua-cor, var(--zeus-amber)), transparent 70%);
    opacity: .55;
    filter: blur(5px);
    z-index: -1;
    transition: opacity .16s ease;
}

/* A cor do halo por faixa: azul enquanto é ciclo normal (a média até o
   documento é de 5,7 dias), esquentando a partir dos 15 dias. Pintar tudo de
   vermelho ensinaria a ignorar a cor justamente onde ela importa. */
.regua-marco[data-faixa="0"]  .regua-bolinha { --regua-cor: #2ec4b6; }
.regua-marco[data-faixa="1"]  .regua-bolinha { --regua-cor: #4da6ff; }
.regua-marco[data-faixa="7"]  .regua-bolinha { --regua-cor: #4da6ff; }
.regua-marco[data-faixa="15"] .regua-bolinha { --regua-cor: #f5c518; }
.regua-marco[data-faixa="30"] .regua-bolinha { --regua-cor: #F5A623; }
.regua-marco[data-faixa="60"] .regua-bolinha { --regua-cor: #ff8c42; }
.regua-marco[data-faixa="61"] .regua-bolinha { --regua-cor: #ff4d6a; }

/* O destaque do hover mora na BOLINHA, não no botão: é ela que a pessoa está
   mirando, e assim o realce não vira uma moldura em volta do marco inteiro.
   O halo acende junto, em vez de trocar a cor da borda — é o mesmo elemento
   que já dá a identidade da faixa. */
.regua-marco:not(.is-vazio):hover .regua-bolinha {
    transform: translateY(-3px);
    border-color: var(--glass-border2);
}

.regua-marco:not(.is-vazio):hover .regua-bolinha::before { opacity: .95; }

.regua-marco:focus-visible { outline: none; }
.regua-marco:focus-visible .regua-bolinha {
    border-color: var(--zeus-amber);
    box-shadow: 0 0 0 3px rgba(245,166,35,.28);
}

.regua-valor {
    font-size: 11px;
    font-weight: 600;
    color: var(--zeus-amber);
    white-space: nowrap;
    letter-spacing: -.1px;
}

/* O número dentro da bolha fica BRANCO em todas as faixas. Quem colore é o
   halo atrás dela; tingir o número junto deixava o texto sem contraste sobre o
   fundo escuro, e era a versão que não agradou. */

.regua-nota {
    margin: var(--sp-3) 0 0;
    padding-top: var(--sp-2);
    border-top: 1px solid var(--glass-border);
    font-size: 11px;
    color: var(--muted);
}

/* A ressalva de quem a régua não alcança. Âmbar e não vermelho: não é falha do
   sistema nem pendência nova, é um limite do portal de origem — o tom precisa
   avisar sem parecer alarme. */
/* Virou <button> em 28/08/2026 (abre a faixa `fora` na janela da régua), daí o
   reset de aparência: sem ele o navegador aplica fundo, borda e a fonte dele,
   e a ressalva deixaria de parecer parte do painel. `text-align: left` porque
   botão centraliza texto por padrão e este tem duas linhas. */
.regua-ressalva {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    width: 100%;
    margin: var(--sp-2) 0 0;
    padding: 8px 10px;
    border-radius: 8px;
    background: rgba(245,166,35,.07);
    border: 1px solid rgba(245,166,35,.22);
    font-family: inherit;
    font-size: 11px;
    /* Explícito: há um `button { font-weight: 800 }` global mais acima, e sem
       isto a ressalva inteira saía em negrito — os <strong> deixavam de
       destacar coisa nenhuma, porque tudo já estava destacado. */
    font-weight: 400;
    line-height: 1.45;
    text-align: left;
    color: var(--muted);
    cursor: pointer;
    transition: background .14s, border-color .14s;
}

.regua-ressalva:hover,
.regua-ressalva:focus-visible {
    background: rgba(245,166,35,.13);
    border-color: rgba(245,166,35,.42);
}

.regua-ressalva strong { color: var(--zeus-amber2); font-weight: 600; }

/* Empurrado para a direita: é a única parte da ressalva que promete uma AÇÃO, e
   colada ao texto ela lia como continuação da frase. */
.regua-ressalva-acao {
    flex-shrink: 0;
    margin-left: auto;
    align-self: center;
    padding: 3px 9px;
    border-radius: 999px;
    background: rgba(245,166,35,.16);
    color: var(--zeus-amber);
    font-size: 10px;
    font-weight: 700;
    white-space: nowrap;
}

.regua-ressalva:hover .regua-ressalva-acao { background: rgba(245,166,35,.28); }

.regua-ressalva-icone {
    flex-shrink: 0;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: rgba(245,166,35,.18);
    color: var(--zeus-amber);
    font-size: 10px;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: 1px;
}

/* ── A janela que abre no clique ──────────────────────────────────────────── */

/* Acima da `.app-sidebar`, que é `fixed` e vive em z-index 1000: com um valor
   menor, a barra lateral ficava POR CIMA da janela e comia as duas primeiras
   colunas da lista — a OS e o cliente, justamente as que se vai ler. */
.regua-modal {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-4);
}

.regua-modal[hidden] { display: none; }

.regua-modal-fundo { position: absolute; inset: 0; background: rgba(4,5,10,.74); backdrop-filter: blur(3px); }

.regua-modal-caixa {
    position: relative;
    width: min(1180px, 100%);
    max-height: min(80vh, 780px);
    display: flex;
    flex-direction: column;
    background: var(--bg-2);
    border: 1px solid var(--glass-border2);
    border-radius: var(--r-md);
    box-shadow: 0 26px 70px rgba(0,0,0,.6);
    overflow: hidden;
}

.regua-modal-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--glass-border);
}

.regua-modal-ident { min-width: 0; }

.regua-modal-acoes { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.regua-botao-export {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 13px;
    border-radius: 8px;
    background: rgba(34,201,122,.10);
    border: 1px solid rgba(34,201,122,.35);
    color: #52d99a;
    font-size: 12px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
    transition: background .14s ease, border-color .14s ease;
}

.regua-botao-export:hover { background: rgba(34,201,122,.18); border-color: rgba(34,201,122,.6); }

.regua-export-icone { font-size: 13px; line-height: 1; }

.regua-modal-head h3 {
    margin: 0 0 3px;
    font-size: 16px;
    font-weight: 700;
    letter-spacing: -.2px;
}

.regua-modal-sub { font-size: 12px; color: var(--zeus-amber); font-weight: 600; }

/* O `box-shadow: none` é obrigatório: o estilo global de `button` do projeto
   pinta um halo âmbar arredondado, e nele o X ganhava aquele borrão em volta —
   o mesmo defeito que já tinha aparecido nos marcos da régua. */
.regua-modal-fechar {
    background: var(--surface);
    border: 1px solid var(--glass-border);
    border-radius: 8px;
    box-shadow: none;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
    transition: color .14s ease, border-color .14s ease, background .14s ease;
}

.regua-modal-fechar:hover {
    color: var(--text);
    border-color: var(--glass-border2);
    background: var(--surface-2);
    box-shadow: none;
}

/* ── A barra de chips e filtros ── */

.regua-modal-barra {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--glass-border);
    background: rgba(255,255,255,.015);
}

.regua-chips { display: flex; gap: 8px; flex-wrap: wrap; }

/* Um chip por cliente com a contagem e o valor daquela faixa. É a informação
   que o anel colorido dava na régua e que não cabia lá — aqui há espaço para o
   número escrito, que se lê melhor que uma fatia de cor. */
.regua-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    padding: 6px 11px;
    border-radius: 99px;
    background: var(--surface);
    border: 1px solid var(--glass-border);
    box-shadow: none;
    color: var(--muted);
    font: inherit;
    font-size: 11px;
    cursor: pointer;
    transition: border-color .14s ease, background .14s ease, color .14s ease;
}

.regua-chip:hover { border-color: var(--glass-border2); background: var(--surface-2); box-shadow: none; }

.regua-chip.is-ativo {
    border-color: rgba(245,166,35,.5);
    background: rgba(245,166,35,.10);
    color: var(--text);
}

.regua-chip-nome { font-weight: 600; color: var(--text); }
.regua-chip-qtd { font-weight: 700; color: var(--zeus-amber2); }
.regua-chip-valor { font-size: 10px; opacity: .75; }

.regua-filtros { display: flex; gap: 10px; }

/* `position: relative` porque a lista abre absoluta a partir daqui. */
.regua-filtro { display: flex; flex-direction: column; gap: 3px; position: relative; }

/* O `hidden` do HTML vale `display: none`, mas vem da folha do navegador e
   PERDE para a regra de classe acima — o menu continuava na tela com o atributo
   marcado. O JS esconde o filtro que tem uma opção só (geral.js,
   preencherSelect); sem esta linha aquilo não teria efeito nenhum. */
.regua-filtro[hidden] { display: none; }

.regua-filtro-rot {
    font-size: 9px;
    letter-spacing: .6px;
    text-transform: uppercase;
    color: var(--muted);
    padding-left: 2px;
}

.regua-menu-botao {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    background: var(--surface-solid);
    border: 1px solid var(--glass-border);
    border-radius: 8px;
    box-shadow: none;
    color: var(--text);
    font: inherit;
    font-size: 12px;
    padding: 7px 10px;
    width: 190px;
    cursor: pointer;
    text-align: left;
    transition: border-color .14s ease;
}

.regua-menu-botao:hover { border-color: var(--glass-border2); box-shadow: none; }

/* Borda âmbar quando há filtro ativo: é o aviso de que a lista abaixo não está
   mostrando a faixa inteira. */
.regua-menu-botao.is-filtrado { border-color: rgba(245,166,35,.55); }

.regua-menu-texto { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.regua-menu-seta {
    flex-shrink: 0;
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid var(--muted);
}

/* A lista. Rola quando passa de dez itens — a faixa de 90+ tem nove filiais,
   mas outras têm mais, e uma lista de 20 opções empurraria a janela inteira. */
.regua-menu-lista {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 5;
    margin: 4px 0 0;
    padding: 4px;
    list-style: none;
    min-width: 100%;
    max-height: 280px;
    overflow-y: auto;
    background: var(--surface-solid);
    border: 1px solid var(--glass-border2);
    border-radius: 8px;
    box-shadow: 0 14px 34px rgba(0,0,0,.6);
}

/* DUAS COLUNAS: nome à esquerda, contagem à direita, sempre na mesma linha
   vertical. É o que o <select> nativo não fazia — lá o "(95)" colava no fim do
   nome e cada linha terminava num lugar diferente. */
.regua-menu-item {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 14px;
    padding: 7px 9px;
    border-radius: 6px;
    font-size: 12px;
    color: var(--text);
    cursor: pointer;
    white-space: nowrap;
}

.regua-menu-item:hover { background: var(--surface-2); }

.regua-menu-item.is-ativo {
    background: rgba(245,166,35,.12);
    color: var(--zeus-amber2);
}

.regua-menu-nome { overflow: hidden; text-overflow: ellipsis; }

.regua-menu-qtd {
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.regua-menu-item.is-ativo .regua-menu-qtd { color: var(--zeus-amber); }

/* É ESTE elemento que rola, e não a página: o JS escuta o scroll dele para
   pedir a página seguinte da lista. */
.regua-modal-corpo { overflow: auto; padding: 0 var(--sp-4) var(--sp-3); }

.regua-tabela { width: 100%; border-collapse: collapse; font-size: 12px; }

.regua-tabela thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--surface-solid);
    text-align: left;
    padding: 10px;
    font-size: 10px;
    letter-spacing: .5px;
    text-transform: uppercase;
    color: var(--muted);
    white-space: nowrap;
}

.regua-tabela td { padding: 9px 10px; border-bottom: 1px solid var(--glass-border); }
.regua-tabela tbody tr:hover { background: var(--surface); }
.regua-tabela .num { text-align: right; white-space: nowrap; }

/* Só a coluna do selo pode quebrar: "OS COM VALOR DIVERGENTE" é longo e, sem
   isto, empurra a tabela inteira para uma rolagem horizontal. */
.regua-tabela .selo { white-space: normal; min-width: 150px; color: var(--muted); }

.regua-modal-estado { padding: var(--sp-3) 0; text-align: center; font-size: 12px; color: var(--muted); }

/* Trava a rolagem do fundo enquanto a janela está aberta — sem isto, rolar
   dentro da lista continua rolando o painel atrás dela. */
body.regua-aberta { overflow: hidden; }

@media (max-width: 640px) {
    /* Pista e linha encolhem juntas, senão a linha descola do centro das
       bolhas — é a mesma conta do bloco acima, com a pista em 62. */
    .regua-bolha-area { height: 62px; }
    .regua-trilho::after { top: 90px; }
    .regua-marco { min-width: 76px; }
    .regua-modal { padding: var(--sp-2); }
    .regua-modal-caixa { max-height: 88vh; }
}

/* ── O relógio da página ──
   Discreto de propósito: é diagnóstico, não informação de trabalho. Fica no
   canto, na cor de texto secundário, e só chama atenção quando o número passa
   de 1 s (o ⚠ vem do próprio texto, em tempo_pagina_texto()). */
.tempo-pagina {
    margin: 0;
    padding: 6px 14px 10px;
    text-align: right;
    font-size: 11px;
    letter-spacing: .02em;
    color: var(--muted, #7a8699);
    opacity: .75;
}

/* ════════════════════════════════════════
   RANKING DE STATUS (Visão Geral)
   ════════════════════════════════════════
   Substituiu a tabela em 03/09/2026. A tabela funcionava quando dividia a faixa
   com o gráfico de barras; sozinha na largura toda, as cinco colunas se
   afastavam metros umas das outras e a barra ficava boiando no vazio.

   Aqui o nome fica em cima e a barra logo abaixo dele, na mesma coluna — as
   duas coisas que respondem "quem é maior" ficam juntas, e os números se
   alinham à direita, onde se leem. */
.rank-wrap {
    /* Mesmo teto da tabela que substituiu: passando disso rola aqui dentro,
       com o cabeçalho preso no topo. */
    max-height: 60vh;
    overflow-y: auto;
}
.rank-wrap::-webkit-scrollbar { width: 4px; }
.rank-wrap::-webkit-scrollbar-track { background: transparent; }
.rank-wrap::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border-radius: 4px; }

/* A grade das colunas mora aqui e vale para o cabeçalho, as linhas e o total —
   um lugar só, para os três nunca saírem do prumo. */
.rk {
    display: grid;
    grid-template-columns: minmax(200px, 1fr) 90px 90px 160px 90px;
    align-items: center;
    gap: 12px;
    padding: 4px 16px;
    border-bottom: 1px solid rgba(255,255,255,.04);
}
.rk > div:nth-child(n+2) { text-align: right; }

.rk-head {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--surface-solid);
    color: var(--muted);
    font-size: 9.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .4px;
    padding: 6px 16px;
}

.rk:not(.rk-head):not(.rk-total):hover { background: rgba(245,166,35,.05); }

.rk-nome .dot { width: 7px; height: 7px; margin-right: 0; }
.rk-nome {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 11.5px;
    color: var(--text);
    /* O nome é o único texto livre da linha: corta com reticências em vez de
       empurrar a grade. O title traz o nome inteiro. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A barra alinha com o texto, não com a bolinha: recuo igual à bolinha (9px)
   mais o gap (8px). */
.rk-barra {
    height: 3px;
    margin: 3px 0 0 17px;
    border-radius: 3px;
}
/* max(3px, …): um status com 1 OS entre 3.000 daria barra de largura zero e a
   linha pareceria não ter dado. O brilho é o que a torna visível nesse
   tamanho — e some junto com a animação para quem pede menos movimento. */
.rk-barra > span {
    display: block;
    height: 100%;
    width: max(3px, var(--w, 0%));
    border-radius: 3px;
    box-shadow: 0 0 8px var(--c, transparent);
    /* Entrada em cascata: cada barra cresce da esquerda, 40ms depois da
       anterior (--atraso vem do PHP). Mesma curva da barra de Composição do
       valor, mais curta — são até 15 linhas, e 1,9s aqui viraria espera. */
    animation: rk-crescer 1.1s cubic-bezier(.16,1,.3,1) var(--atraso, 0s) both;
}
@keyframes rk-crescer {
    from { width: 0; opacity: 0; }
    to   { width: max(3px, var(--w, 0%)); opacity: 1; }
}

.rk-qtd {
    font-size: 12.5px;
    font-weight: 800;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.rk-val {
    font-size: 11.5px;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
/* Percentuais em cinza: são apoio. O que se lê é a quantidade e o dinheiro. */
.rk-pct {
    font-size: 10.5px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.rk-total {
    background: linear-gradient(135deg, rgba(245,166,35,.12) 0%, rgba(232,76,32,.08) 100%);
    border-bottom: none;
    font-weight: 800;
    color: var(--zeus-amber);
}
.rk-total .rk-qtd,
.rk-total .rk-val,
.rk-total .rk-pct { color: var(--zeus-amber); font-weight: 800; }

/* Numa tela estreita a grade vira duas faixas: nome e barra em cima, números
   embaixo — em vez de espremer cinco colunas em 400px. */
@media (max-width: 760px) {
    .rk {
        grid-template-columns: 1fr auto auto;
        gap: 10px 14px;
    }
    .rk-col-nome { grid-column: 1 / -1; }
    .rk-head { display: none; }
}

/* ── O total como abertura do card de Composição (04/09/2026) ──
   Ele foi cartão de KPI e, por um dia, badge na topbar. Nos dois lugares era um
   número grande sem contexto, repetindo o que este card já mostrava. Aqui ele
   abre a leitura: total, quantas OS o formam, e logo abaixo a barra dizendo em
   que estado esse dinheiro está. */
.comp-hero {
    padding: 20px 22px 4px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.comp-hero-label {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .6px;
    color: var(--muted);
}
/* clamp em vez de tamanho fixo: são 15 caracteres em telas de 1600px e de
   1280px, e um valor cortado ao meio é pior do que um valor menor. */
.comp-hero-valor {
    font-size: clamp(30px, 3.4vw, 52px);
    font-weight: 900;
    line-height: 1.02;
    letter-spacing: -1px;
    color: var(--text);
}
.comp-hero-sub {
    font-size: 11.5px;
    color: var(--muted);
}

/* ── Rótulo e percentual na mesma linha ──
   O percentual vivia no meio da linha de apoio, junto da contagem de OS. É a
   resposta de "quanto do bolo é isto", e por isso sobe para a altura do nome —
   na cor do grupo, a mesma da faixa correspondente na barra. */
.comp-topo {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}
.comp-pct {
    font-size: 12.5px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}
.comp-item.is-ok .comp-pct       { color: var(--green); }
.comp-item.is-conferir .comp-pct { color: var(--orange); }
.comp-item.is-faturar .comp-pct  { color: var(--blue); }

/* Etiqueta no canto do cabeçalho: quantos status a lista tem. Some da leitura
   quando não interessa e responde de imediato "a lista acabou?" quando o card
   está rolando. */
.card-head-tag {
    margin-left: auto;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: .5px;
    color: var(--muted);
    text-transform: uppercase;
}

/* ── A barra vira o FUNDO da linha ──
   Antes era um traço fino sob o nome. Como faixa atrás do texto, ela ocupa
   altura zero: o ranking aparece sem custar um pixel a mais por linha — e a
   lista voltou a caber inteira na tela, que foi o pedido de 03/09.

   Fica em ::before para não disputar com o hover da linha, e com opacidade
   baixa porque é fundo: o que se lê é o nome, não a cor. */
/* A classe .s-* entra aqui só para trazer a variável --c com a cor do status.
   O `background: none` desfaz o preenchimento que ela também declara: sem isso
   o bloco inteiro sai chapado de cor, engolindo o texto. Quem pinta a faixa é
   o ::before, com opacidade baixa. */
.rk-col-nome {
    position: relative;
    background: none;
}
.rk-col-nome::before {
    content: '';
    position: absolute;
    inset: -4px auto -4px -16px;   /* volta o padding da linha, para a faixa encostar na borda */
    width: calc(var(--w, 0%) + 16px);
    background: var(--c, transparent);
    opacity: .14;
    border-radius: 0 3px 3px 0;
    animation: rk-crescer-fundo 1.1s cubic-bezier(.16,1,.3,1) var(--atraso, 0s) both;
}
@keyframes rk-crescer-fundo {
    from { width: 0; opacity: 0; }
    to   { width: calc(var(--w, 0%) + 16px); opacity: .14; }
}
/* O texto por cima da faixa. */
.rk-nome { position: relative; z-index: 1; }

/* ══════════════════════════════════════════════════════════════════════════
   PAINEL GERAL — A CARTEIRA E O VALOR EM TRATATIVA (public/geral.php)

   Em 04/09/2026 o Painel Geral trocou a faixa de cinco KPIs e os dois gráficos
   de rosca pelo mesmo desenho da Composição do valor: total como abertura,
   barra da proporção, cartões com o nome de cada parte. Lá as partes são os
   três grupos de faturamento — e por isso o CSS de cima traz `.is-ok`,
   `.is-conferir` e `.is-faturar` com cores fixas. Aqui as partes são os
   clientes, que mudam com a permissão da conta, então a cor chega pelo
   markup em `--c` e estas regras só a repassam.
   ══════════════════════════════════════════════════════════════════════════ */

/* O total à esquerda e as contas coletando à direita, na mesma linha. Não é
   grid de duas colunas iguais: o valor pode ter 15 caracteres em corpo 52 e
   precisa de toda a largura que sobrar. */
.comp-hero-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}

.comp-hero-aside {
    padding: 20px 22px 4px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    text-align: right;
}

/* Bem menor que o valor da carteira, de propósito: são duas medidas de
   naturezas diferentes na mesma linha, e a hierarquia é que impede a leitura
   de tratar "17/22" como se fosse resposta da mesma pergunta. */
.comp-aside-valor {
    font-size: 22px;
    font-weight: 900;
    line-height: 1;
    letter-spacing: -.5px;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}
.comp-aside-valor small {
    font-size: 13px;
    font-weight: 700;
    color: var(--text-3);
    margin-left: 1px;
}

/* A cor vem do PHP. Sem gradiente: com três faixas fixas o degradê dava
   textura ao bloco, mas com N clientes vizinhos ele embaralha onde uma faixa
   acaba e a outra começa. */
.comp-faixa.is-cliente { background: var(--c, var(--muted)); }

.comp-item.is-cliente { border-left-color: var(--c, var(--muted)); }
.comp-item.is-cliente .comp-pct { color: var(--c, var(--text-2)); }

/* O cartão do cliente é um link para o painel dele. Herdar a cor do texto é o
   que mantém o número em branco: sem isto o `a` do tema pinta o valor inteiro
   de âmbar. */
a.comp-item {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}
a.comp-item:hover {
    border-color: var(--c, var(--glass-border));
    background: var(--surface-2);
    transform: translateY(-2px);
}

/* Nome de cliente é nome próprio: sai o CAIXA ALTA que o rótulo dos grupos de
   faturamento usa, e o corpo cresce — na Composição o rótulo é uma etiqueta
   ("JÁ FATURADO"), aqui é o título do cartão. */
.comp-item.is-cliente .comp-rotulo {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    text-transform: none;
    letter-spacing: 0;
    font-size: 13px;
    font-weight: 700;
    color: var(--text);
}

.comp-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--c, var(--muted));
    flex: 0 0 auto;
}

/* ── Valor em tratativa ── */

/* 1.1fr / 1fr: a coluna da esquerda carrega o valor grande e duas linhas de
   texto; a da direita, quatro nomes curtos com números alinhados à direita. */
/* O respiro é do CONTAINER, não de cada coluna. A lista é mais alta que o
   texto da esquerda, então é ela que define a altura do bloco — com o padding
   herdado do `.comp-hero` (que só vale para a coluna da esquerda), o primeiro
   nome encostava na borda de cima do cartão e o valor do maior cliente, na
   borda da direita. */
.trat-row {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
    gap: 28px;
    align-items: center;
    padding: 20px 26px 22px 0;
}

/* Zera o padding próprio do `.comp-hero` e mantém só o recuo da esquerda: o de
   cima e o de baixo agora vêm do `.trat-row`, e somados dariam quase 40px. */
.trat-hero { padding: 0 0 0 22px; }
.trat-desc { margin-bottom: 6px; }

/* Laranja, e menor que o da carteira: é um recorte daquele total, não outro
   total. A cor é a mesma da coluna "Em tratativa" da tabela acima. */
.trat-valor {
    font-size: clamp(26px, 2.6vw, 40px);
    color: var(--orange);
}

.trat-lista {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 13px;
}

.trat-topo {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 5px;
}
.trat-nome {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-2);
}
.trat-num {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.trat-trilho {
    display: block;
    height: 5px;
    border-radius: 99px;
    background: rgba(255,255,255,.06);
    overflow: hidden;
}
/* max(3px, …) pelo mesmo motivo da barrinha da Visão Geral: um cliente com
   pouco valor em tratativa daria uma barra de largura zero, e a linha
   pareceria não ter dado nenhum. */
.trat-barra {
    display: block;
    height: 100%;
    width: max(3px, var(--w, 0%));
    border-radius: 99px;
    background: var(--c, var(--muted));
    animation: trat-crescer 1.2s cubic-bezier(.16,1,.3,1) var(--atraso, 0s) both;
}

/* Keyframe próprio, e não o `comp-crescer` da barra de cima: aquele termina em
   `width: var(--alvo)`, variável que não existe aqui — a barra cresceria de
   zero até zero e a lista apareceria vazia. */
@keyframes trat-crescer {
    from { width: 0; opacity: 0; }
    to   { width: max(3px, var(--w, 0%)); opacity: 1; }
}

/* Numa tela estreita o valor e a lista empilham, e o aside das contas
   coletando volta a alinhar à esquerda — encostado na direita, sozinho numa
   linha, ele ficava solto. */
@media (max-width: 900px) {
    .trat-row { grid-template-columns: 1fr; gap: 18px; padding: 20px 22px 22px; }
    .trat-hero { padding: 0; }
}
@media (max-width: 620px) {
    .comp-hero-aside {
        align-items: flex-start;
        text-align: left;
        padding-top: 0;
    }
}

/* ════════════════════════════════════════
   FATURAMENTO E BLOQUEIO POR FALTA DE PAGAMENTO
   app/faturamento.php · public/faturamento.php · assets/js/pagamento.js · public/bloqueado.php
════════════════════════════════════════ */

/* O aviso do topo. Fica no fluxo do body, antes do .page (public/_sidebar.php),
   e gruda no alto ao rolar: é um aviso de prazo, não pode sumir com a página.

   Dois níveis (faturamento_nivel_aviso(), app/faturamento.php), pela régua
   da tela de Faturamento: amarelo a partir do 2º dia de atraso, vermelho a
   partir do 5º — o último aviso antes do bloqueio. As cores moram em
   variáveis, e o nível só as troca. */
.aviso-pagamento {
    --av-fundo: linear-gradient(90deg, rgba(245,166,35,.24) 0%, rgba(255,184,77,.10) 100%);
    --av-borda: rgba(245,166,35,.5);
    --av-texto: var(--zeus-amber2);
    --av-icone-fundo: rgba(245,166,35,.16);
    --av-selo-fundo: rgba(245,166,35,.16);
    --av-selo-borda: rgba(245,166,35,.5);
    --av-selo-texto: var(--zeus-amber);
    --av-sombra: none;

    position: sticky; top: 0; z-index: 900;
    overflow: hidden;
    display: flex; align-items: center; gap: 12px;
    padding: 9px 18px;
    background: var(--av-fundo);
    border-bottom: 1px solid var(--av-borda);
    box-shadow: var(--av-sombra);
    color: var(--av-texto);
    font-size: 12px; font-weight: 600; line-height: 1.45;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}
/* O `display: flex` acima ganha do atributo `hidden` — sem esta linha a faixa
   ficava na tela o tempo todo, vazia, com o aviso desligado. */
.aviso-pagamento[hidden] { display: none; }
.aviso-pagamento > * { position: relative; z-index: 1; }

.aviso-pagamento-icone {
    flex: 0 0 28px;
    width: 28px; height: 28px; border-radius: 50%;
    display: grid; place-items: center;
    background: var(--av-icone-fundo);
}
.aviso-pagamento-icone svg {
    width: 16px; height: 16px;
    fill: none; stroke: currentColor; stroke-width: 2.2;
    stroke-linecap: round; stroke-linejoin: round;
}
.aviso-pagamento-selo {
    flex: none;
    padding: 3px 9px;
    border-radius: 99px;
    background: var(--av-selo-fundo);
    border: 1px solid var(--av-selo-borda);
    color: var(--av-selo-texto);
    font-size: 9.5px; font-weight: 900;
    text-transform: uppercase; letter-spacing: 1px;
}
.aviso-pagamento-texto { min-width: 0; }

/* ── Vermelho ──
   Sólido e com volume: um gradiente do escuro para o vivo, listras diagonais
   bem leves de "faixa de atenção", um filete de luz em cima e uma sombra
   vermelha que descola a faixa do fundo. A versão translúcida anterior virava
   vinho sobre o fundo escuro do painel. */
.aviso-pagamento[data-nivel="alerta"] {
    --av-fundo:
        repeating-linear-gradient(135deg, rgba(255,255,255,.055) 0 12px, transparent 12px 24px),
        linear-gradient(90deg, #8c0b14 0%, #c4111d 30%, #e3202c 62%, #ff3b3f 100%);
    --av-borda: #ff6b6e;
    --av-texto: #fff;
    --av-icone-fundo: rgba(255,255,255,.18);
    --av-selo-fundo: #fff;
    --av-selo-borda: #fff;
    --av-selo-texto: #c4111d;
    --av-sombra:
        inset 0 1px 0 rgba(255,255,255,.22),
        inset 0 -1px 0 rgba(0,0,0,.25),
        0 10px 28px -10px rgba(227,32,44,.65);
    text-shadow: 0 1px 1px rgba(0,0,0,.28);
}
.aviso-pagamento[data-nivel="alerta"] .aviso-pagamento-selo {
    text-shadow: none;
    box-shadow: 0 2px 8px rgba(0,0,0,.25);
}

/* O ícone pulsa: um anel que se abre e some, a cada 1,8 s. */
.aviso-pagamento[data-nivel="alerta"] .aviso-pagamento-icone::after {
    content: '';
    position: absolute; inset: 0;
    border-radius: 50%;
    border: 2px solid rgba(255,255,255,.6);
    animation: aviso-pulso 1.8s cubic-bezier(.22,1,.36,1) infinite;
}
@keyframes aviso-pulso {
    0%   { transform: scale(1);   opacity: .9; }
    100% { transform: scale(1.7); opacity: 0; }
}

/* Um brilho que atravessa a faixa de tempos em tempos — chama o olho sem
   piscar. Parado a maior parte do ciclo (de 45% a 100%). */
.aviso-pagamento[data-nivel="alerta"]::after {
    content: '';
    position: absolute; inset: 0;
    background: linear-gradient(100deg, transparent 35%, rgba(255,255,255,.22) 50%, transparent 65%);
    transform: translateX(-100%);
    animation: aviso-brilho 5s ease-in-out infinite;
    pointer-events: none;
}
@keyframes aviso-brilho {
    0%        { transform: translateX(-100%); }
    45%, 100% { transform: translateX(100%); }
}

@media (max-width: 900px) {
    /* Abre espaço para o botão fixo do menu mobile, como a .topbar faz. */
    .aviso-pagamento { padding-left: 60px; min-height: 52px; gap: 10px; }
}
@media (max-width: 560px) {
    /* No celular o selo come espaço demais: o ícone já avisa. */
    .aviso-pagamento-selo { display: none; }
}

/* A tela de acesso bloqueado — página cheia, no fundo do login. */
.bloqueio-shell {
    position: relative; z-index: 1;
    width: min(460px, calc(100vw - 32px));
    padding: 24px 0;
}
.bloqueio-card {
    display: flex; flex-direction: column; align-items: flex-start; gap: 12px;
    padding: 32px 30px 28px;
    border-radius: var(--r-lg);
    background: rgba(17,19,28,.86);
    border: 1px solid var(--glass-border2);
    box-shadow: 0 24px 60px rgba(0,0,0,.45);
    backdrop-filter: blur(18px);
    -webkit-backdrop-filter: blur(18px);
    color: var(--text-2);
    font-size: 13px; line-height: 1.6;
}
.bloqueio-icone {
    width: 48px; height: 48px; border-radius: 14px;
    display: grid; place-items: center;
    color: var(--red);
    background: rgba(255,77,106,.10);
    border: 1px solid rgba(255,77,106,.30);
}
.bloqueio-icone svg {
    width: 24px; height: 24px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.bloqueio-eyebrow {
    margin-top: 6px;
    color: var(--zeus-amber);
    font-size: 10px; font-weight: 800;
    text-transform: uppercase; letter-spacing: 1px;
}
.bloqueio-card h1 {
    margin-top: -6px;
    color: var(--text);
    font-size: 26px; font-weight: 800; letter-spacing: -.3px;
    text-wrap: balance;
}
.bloqueio-card p { margin: 0; }
.bloqueio-saudacao { color: var(--text); font-weight: 600; }
.bloqueio-status {
    display: flex; align-items: center; gap: 8px;
    margin-top: 4px !important;
    color: var(--muted); font-size: 11px;
}
.bloqueio-pulso {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--zeus-amber);
    animation: bloqueio-pulsar 1.6s ease-in-out infinite;
}
@keyframes bloqueio-pulsar { 50% { opacity: .25; } }
.bloqueio-sair {
    margin-top: 10px !important;
    background: linear-gradient(135deg, var(--zeus-amber) 0%, var(--uni-orange) 100%);
    color: #0a0a0a;
    font-weight: 800; font-size: 13px;
}
.bloqueio-sair:hover { opacity: .92; }
.bloqueio-sair:focus-visible { outline: 2px solid var(--zeus-amber2); outline-offset: 3px; }
@media (max-width: 480px) {
    .bloqueio-card { padding: 26px 20px 22px; }
}

/* ── Tela de Faturamento (public/faturamento.php) ── */
.fat-status-red .kpi-value    { color: var(--red); }
.fat-status-orange .kpi-value { color: var(--zeus-amber); }
.fat-status-green .kpi-value  { color: var(--green); }
.fat-status-gear .kpi-value   { color: var(--text-2); }

.fat-vazio { padding: 16px 14px; color: var(--muted); font-size: 12px; }
td.fat-vazio { text-align: center; }

.fat-tabela-wrap { overflow-x: auto; }
.fat-tabela { width: 100%; border-collapse: collapse; font-size: 12px; }
.fat-tabela th {
    text-align: left; padding: 9px 14px;
    font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
    color: var(--muted); border-bottom: 1px solid var(--glass-border);
}
.fat-tabela td { padding: 11px 14px; border-bottom: 1px solid rgba(255,255,255,.05); color: var(--text-2); vertical-align: middle; }
.fat-tabela td strong { color: var(--text); text-transform: capitalize; }
.fat-tabela tbody tr:last-child td { border-bottom: 0; }
.fat-col-acoes { text-align: right; white-space: nowrap; }
.fat-col-acoes .fat-acao { display: inline; }
.fat-quem { display: block; margin-top: 3px; color: var(--muted); font-size: 10px; }

.fat-pill {
    display: inline-block; padding: 3px 10px; border-radius: 99px;
    font-size: 10.5px; font-weight: 700; white-space: nowrap;
}
.fat-pill-amarelo  { background: rgba(245,166,35,.14); color: var(--zeus-amber2); border: 1px solid rgba(245,166,35,.35); }
.fat-pill-vermelho { background: rgba(229,32,46,.16);  color: #ff8a92;           border: 1px solid rgba(229,32,46,.45); }
.fat-pill-azul     { background: rgba(77,166,255,.12); color: var(--blue);       border: 1px solid rgba(77,166,255,.3); }
.fat-pill-verde    { background: rgba(34,201,122,.12); color: var(--green);      border: 1px solid rgba(34,201,122,.3); }

/* Botões próprios: o estilo global de `button` é o gradiente laranja, e um link
   precisa ter a mesma cara de um botão ao lado dele. */
.fat-btn {
    display: inline-flex; align-items: center; gap: 6px;
    margin-left: 6px; padding: 7px 12px;
    border-radius: 8px; border: 1px solid transparent;
    font: 700 11.5px 'Inter', Arial, sans-serif; letter-spacing: .2px;
    text-decoration: none; cursor: pointer; box-shadow: none;
    transition: background .15s, border-color .15s, opacity .15s;
}
.fat-btn:hover { transform: none; box-shadow: none; }
.fat-btn svg {
    width: 14px; height: 14px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
.fat-btn-primario { background: linear-gradient(135deg, var(--zeus-amber), var(--uni-orange)); color: #0a0a0a; }
.fat-btn-primario:hover { opacity: .9; }
.fat-btn-secundario { background: rgba(245,166,35,.08); color: var(--zeus-amber); border-color: rgba(245,166,35,.35); }
.fat-btn-secundario:hover { background: rgba(245,166,35,.16); }
.fat-btn-discreto { background: transparent; color: var(--text-2); border-color: var(--glass-border2); }
.fat-btn-discreto:hover { background: rgba(255,255,255,.06); opacity: 1; }
.fat-btn:focus-visible { outline: 2px solid var(--zeus-amber); outline-offset: 2px; }

/* Formulário de configuração: três grupos lado a lado, que empilham. */
.fat-form {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px; padding: 16px 14px;
}
.fat-grupo {
    border: 1px solid var(--glass-border); border-radius: var(--r-md);
    padding: 12px 14px 14px; margin: 0;
    /* Quantas colunas couberem com pelo menos 150px: o mês ("setembro de 2026")
       e o CNPJ cortavam em duas colunas fixas num grupo estreito. */
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; align-content: start;
}
.fat-grupo legend {
    padding: 0 6px; margin-left: -6px;
    font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; color: var(--text);
}
.fat-grupo legend small { color: var(--muted); font-weight: 600; text-transform: none; letter-spacing: 0; }
.fat-campo { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.fat-campo-largo, .fat-chave { grid-column: 1 / -1; }
.fat-campo label {
    display: flex; align-items: center; gap: 6px;
    font-size: 10px; font-weight: 700; color: var(--muted);
    text-transform: uppercase; letter-spacing: .5px;
}
.fat-campo input {
    width: 100%; padding: 8px 11px;
    border: 1px solid var(--glass-border2); border-radius: 8px;
    background: var(--surface-2); color: var(--text);
    font: 600 12px 'Inter', Arial, sans-serif;
    outline: none; transition: border-color .15s, box-shadow .15s;
}
.fat-campo input:focus { border-color: rgba(245,166,35,.5); box-shadow: 0 0 0 3px rgba(245,166,35,.12); }

.fat-ponto { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.fat-ponto-amarelo  { background: var(--zeus-amber); }
.fat-ponto-vermelho { background: #e5202e; }
.fat-ponto-bloqueio { background: var(--text-2); }

/* A chave "Cobrança ligada": um checkbox de verdade, desenhado como interruptor. */
.fat-chave {
    display: flex; align-items: center; gap: 12px;
    padding: 10px 12px; border-radius: 10px;
    background: rgba(255,255,255,.03); border: 1px solid var(--glass-border);
    cursor: pointer;
    /* O `label` global do painel é caixa-alta; aqui é uma frase. */
    text-transform: none; letter-spacing: normal;
}
.fat-chave input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.fat-chave-trilho {
    position: relative; flex: 0 0 38px; width: 38px; height: 22px; border-radius: 99px;
    background: rgba(255,255,255,.1); border: 1px solid var(--glass-border2);
    transition: background .2s, border-color .2s;
}
.fat-chave-trilho::after {
    content: ''; position: absolute; top: 2px; left: 2px;
    width: 16px; height: 16px; border-radius: 50%;
    background: var(--text-2);
    transition: transform .2s cubic-bezier(.22,1,.36,1), background .2s;
}
.fat-chave input:checked + .fat-chave-trilho { background: rgba(34,201,122,.3); border-color: var(--green); }
.fat-chave input:checked + .fat-chave-trilho::after { transform: translateX(16px); background: var(--green); }
.fat-chave input:focus-visible + .fat-chave-trilho { outline: 2px solid var(--zeus-amber); outline-offset: 2px; }
.fat-chave strong { display: block; font-size: 12px; color: var(--text); }
.fat-chave small { display: block; font-size: 10px; color: var(--muted); }

.fat-form-rodape {
    grid-column: 1 / -1;
    display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.fat-form-rodape small { color: var(--muted); font-size: 10.5px; }
.fat-form-rodape .fat-btn { margin-left: auto; padding: 9px 18px; font-size: 12px; }

@media (max-width: 560px) {
    .fat-grupo { grid-template-columns: 1fr; }
    .fat-col-acoes { white-space: normal; }
    .fat-col-acoes .fat-btn { margin: 4px 0 0; }
}
