/* ============================================================
   Integrator Financeiro 2026 - Design System
   Tema CLARO, menu superior com dropdowns, fonte Inter.
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');

:root {
    --bg: #f5f7fb;
    --surface: #ffffff;
    --elevated: #f8fafc;
    --line: #e5e9f2;
    --line-soft: #eef1f7;

    --ink: #17233b;
    --muted: #5c6b84;
    --faint: #94a3b8;

    /* ---- Marca ---- */
    /* #2A0669: tom informado. As variacoes mantem o MESMO matiz e mudam so a
       luminosidade, para nao existirem dois roxos diferentes na tela. */
    --brand: #2A0669;         /* menu, botoes principais */
    --brand-dark: #1B0344;    /* barra da marca, acima do menu */
    --brand-soft: #43159C;    /* hover e a ponta clara dos gradientes */

    --accent: #43159C;        /* texto interativo: link, dominio, foco */
    --accent-2: #0891b2;      /* cyan escuro (contraste no claro) */
    --accent-ink: #2A0669;    /* texto interativo em destaque */

    --ok: #059669;
    --warn: #b45309;
    --err: #dc2626;

    /* Alturas das duas faixas do topo. O cabecalho fixo da tabela e o painel
       do menu no celular se posicionam a partir DESTAS variaveis - mudar a
       altura da faixa aqui ja acerta todo o resto. */
    --brand-h: 96px;          /* faixa da marca */
    --nav-h: 62px;            /* barra do menu */
    --topo-h: 158px;          /* soma das duas (usada no calc) */

    --radius: 14px;
    --radius-sm: 9px;
    --shadow: 0 1px 2px rgba(16, 24, 40, .05), 0 8px 24px rgba(16, 24, 40, .06);
    --shadow-pop: 0 12px 32px rgba(16, 24, 40, .14);

    /* ------------------------------------------------------------
       SUPERFICIES QUE O TEMA TROCA.
       Estas nasceram escritas a mao pelo CSS afora. Viraram variaveis para
       que o tema escuro seja UMA lista de valores, e nao uma cacada por
       "#fff" em 5.700 linhas. Os valores sao exatamente os de antes - esta
       conversao nao muda um pixel do tema claro.
       ------------------------------------------------------------ */

    /* Linha par da tabela. O contraste com a impar e o que guia o olho numa
       linha larga; sem ele a leitura pula de coluna. */
    --zebra: #f4f6fb;

    /* Fundo de chip/etiqueta neutra (stat-chip). */
    --chip: #f1f5f9;

    /* Fundo do aviso ambar claro (hint-erro). */
    --bg-aviso: #fffbeb;

    /* Painel do submenu flutuante - lilas que amarra o menu a barra roxa. */
    --menu-painel: #f4f1fb;

    /* ------------------------------------------------------------
       BRANCO QUE CONTINUA BRANCO.

       Esta e a distincao que faz o tema escuro funcionar: ha branco que e
       SUPERFICIE (cartao, campo, painel - vira escuro no tema escuro) e ha
       branco que vive SOBRE O ROXO da marca - o avatar, o item ativo do
       menu. Esse segundo nao pode virar escuro: sumiria dentro da barra,
       que continua roxa nos dois temas.

       Sem separar os dois, "trocar #fff por var(--surface)" apagaria o
       avatar e o realce do menu no escuro.
       ------------------------------------------------------------ */
    --sobre-marca: #ffffff;

    /* ------------------------------------------------------------
       A SUPERFICIE DA BARRA, separada de `--brand`.

       `--brand` faz DOIS trabalhos no CSS: e o fundo da barra lateral e e a
       cor de texto/borda em vinte lugares (numeros do calendario, botao
       suave, barra do ranking). No tema escuro os dois pedem coisas opostas -
       o fundo tem de escurecer, o texto tem de CLAREAR para continuar legivel
       sobre cartao escuro.

       Com uma variavel so, escurecer a barra apagaria esses vinte textos.
       Por isso a barra ganhou a sua. No claro os valores sao os mesmos de
       sempre; quem muda de verdade e o tema escuro.
       ------------------------------------------------------------ */
    --barra: #2A0669;         /* fundo da barra lateral / menu */
    --barra-topo: #1B0344;    /* faixa da marca, acima do menu */
}

/* ============================================================
   TEMA ESCURO

   Uma lista de valores, e nao um segundo CSS. Isso so foi possivel porque a
   etapa anterior transformou as cores escritas a mao em variaveis - sem
   aquilo, cada tela teria manchas brancas e o conserto seria uma cacada.

   `[data-tema="escuro"]` no <html>, posto por js/tema.js ANTES da pintura.

   O QUE NAO INVERTE, e por que:

   - A BARRA LATERAL continua roxa. Ela ja e escura no tema claro; inverte-la
     deixaria os dois temas parecidos e tiraria a referencia visual de onde a
     pessoa esta. O menu e o mesmo nos dois.
   - `--sobre-marca` continua branco: e o avatar e o item ativo DENTRO da
     barra roxa. Escuro ali, sumiriam.
   - O QR do 2FA continua com fundo branco (esta no template, com o motivo).
   - Os e-mails e a Central de Pagamento nao tem tema: um vai para o cliente,
     o outro E do cliente.

   AS CORES SEMANTICAS CLAREIAM. Verde, vermelho, ambar e ciano do tema claro
   foram escolhidos para contrastar com BRANCO - sobre fundo escuro eles
   ficam abafados e o "pago" verde vira quase preto. Aqui entram as versoes
   claras dos mesmos tons: mesma leitura, contraste invertido.
   ============================================================ */
[data-tema="escuro"] {
    /* Diz ao navegador que a pagina e escura: barra de rolagem, seletor de
       data e o <input type="month"> da NF-e passam a vir escuros tambem. Sem
       isto, o calendario nativo abre um retangulo branco no meio da tela. */
    color-scheme: dark;

    /* ------------------------------------------------------------
       A BARRA E MAIS ESCURA QUE O CONTEUDO, e nao roxa.

       A primeira versao mantinha o roxo da marca na lateral. Ficou "muito
       diferente" - e estava certo: roxo saturado ao lado de um conteudo
       cinza-azulado vira um bloco colado, nao uma barra do mesmo produto.

       No escuro a hierarquia se inverte em relacao ao claro: la a barra e
       ESCURA sobre conteudo claro; aqui ela e a superficie MAIS escura de
       todas, e o conteudo flutua acima dela. A marca continua presente pelo
       indigo do item ativo e dos botoes, nao pelo fundo.
       ------------------------------------------------------------ */
    --barra: #0f131c;
    --barra-topo: #0b0e15;

    --bg: #141926;            /* fundo da pagina, acima da barra */
    --surface: #1a2130;       /* cartao, campo, painel flutuante */
    --elevated: #222a3b;      /* hover e superficie acima do cartao */
    --line: #2a3346;
    --line-soft: #232b3c;     /* cabecalho de tabela */

    --ink: #e8ecf4;           /* texto principal */
    --muted: #94a3bd;
    --faint: #6b7891;

    --zebra: #1d2432;         /* linha par - separacao sutil, nao listra */
    --chip: #232b3c;
    --bg-aviso: #2b2517;      /* ambar rebaixado: aviso sem virar lanterna */
    --menu-painel: #1e2434;   /* submenu flutuante */

    /* INTERATIVO: indigo vivo, nao o roxo escuro da marca. O #43159C sobre
       fundo escuro fica ilegivel; este e o mesmo lugar do circulo cromatico
       com a luminosidade que o escuro pede. */
    --accent: #818cf8;
    --accent-ink: #a5b4fc;
    --accent-2: #22d3ee;

    /* `--brand` aqui e COR DE TEXTO (numeros do calendario, botao suave,
       ranking) - quem faz o fundo da barra e `--barra`, acima. */
    --brand: #818cf8;
    --brand-soft: #a5b4fc;

    /* ESTADO. Tons claros dos mesmos significados. */
    --ok: #34d399;
    --warn: #fbbf24;
    --err: #f87171;

    /* SOMBRA quase preta: a do tema claro e um cinza-azulado que sobre fundo
       escuro aparece como um halo claro em volta do cartao. */
    --shadow: 0 1px 2px rgba(0, 0, 0, .40), 0 8px 24px rgba(0, 0, 0, .34);
    --shadow-pop: 0 12px 32px rgba(0, 0, 0, .55);
}

/* ------------------------------------------------------------
   A BARRA NO ESCURO - ajustes que a troca de fundo pede
   ------------------------------------------------------------ */

/* Uma linha separando a barra do conteudo. No claro a diferenca de cor ja
   basta; no escuro as duas superficies sao escuras e, sem a linha, viram uma
   so a um metro de distancia. */
[data-tema="escuro"] .nav-lateral {
    border-right: 1px solid var(--line);
    box-shadow: none;   /* a sombra roxa do claro nao existe sobre preto */
}

/* ITEM ATIVO: veu indigo com texto claro, e nao o bloco branco do claro.
   Branco puro sobre uma barra quase preta e um berro - e o item ativo precisa
   ser lido de relance, nao gritar o dia inteiro. */
[data-tema="escuro"] .menu-link.active,
[data-tema="escuro"] .menu-item.active .menu-title {
    background: rgba(129, 140, 248, .18);
    color: #c7d2fe;
    box-shadow: inset 2px 0 0 var(--accent);
}

/* O AVATAR CONTINUA CLARO, mas nao branco puro: sobre a barra quase preta ele
   viraria uma lampada. Um cinza muito claro mantem a leitura da inicial sem o
   estouro. */
[data-tema="escuro"] .avatar {
    background: #cbd5e1;
    color: #0f131c;
}

/* A seta do calendario tem icone BRANCO por dentro: com o fundo virando
   indigo claro, o icone sumiria. Fundo escuro, icone claro. */
[data-tema="escuro"] .cal-seta {
    background: var(--elevated);
    color: var(--accent-ink);
}
[data-tema="escuro"] .cal-seta:hover {
    background: var(--accent);
    color: #0f131c;
}

/* ------------------------------------------------------------
   O AMARELO DO AUTOPREENCHIMENTO

   Nao vem deste CSS: e o Chrome marcando o campo que ele preencheu, com um
   amarelo que ele mesmo escolhe. No tema claro passa por um creme discreto e
   ninguem nota; sobre fundo escuro vira aquele oliva que engole o texto.

   `background-color` NAO resolve - o navegador aplica a cor dele por cima.
   O jeito que funciona e uma sombra interna gigante, que pinta a area toda
   por dentro, mais o `-webkit-text-fill-color` para o texto (o `color`
   comum tambem e ignorado no estado autofill).

   A transicao de uma hora existe para o Chrome nao repintar o amarelo depois
   de ganhar o foco - e um truque conhecido, e feio, mas e o que ha.
   ------------------------------------------------------------ */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active,
textarea:-webkit-autofill,
select:-webkit-autofill {
    -webkit-box-shadow: 0 0 0 1000px var(--surface) inset !important;
            box-shadow: 0 0 0 1000px var(--surface) inset !important;
    -webkit-text-fill-color: var(--ink) !important;
    caret-color: var(--ink);
    -webkit-transition: background-color 9999s ease-in-out 0s;
            transition: background-color 9999s ease-in-out 0s;
}

/* A tela de LOGIN tem cartao proprio, mais escuro que o `--surface` das
   demais - o autofill precisa acompanhar o cartao onde o campo esta, e nao
   uma superficie que ali nao existe. */
.login-card input:-webkit-autofill,
.login-card input:-webkit-autofill:hover,
.login-card input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px var(--elevated) inset !important;
            box-shadow: 0 0 0 1000px var(--elevated) inset !important;
}

/* ------------------------------------------------------------
   PILULAS: TEXTO ESCURO SOBRE FUNDO TINGIDO

   Todas seguem o mesmo desenho - fundo da cor a 10% e texto na MESMA cor,
   so que escura. Sobre branco funciona; sobre fundo escuro o veu a 10% vira
   um borrao e o texto escuro desaparece dentro dele. Foi o que aconteceu com
   as datas de vencimento e o contador de dias.

   O conserto e o mesmo em todas: o veu sobe um pouco (o fundo escuro engole
   mais do que o branco) e o texto vai para a versao CLARA do mesmo tom. A
   leitura nao muda - vermelho continua vermelho -, so a luminosidade
   inverte.
   ------------------------------------------------------------ */

/* Datas de vencimento por faixa de atraso */
[data-tema="escuro"] .data-atraso  { background: rgba(239, 68, 68, .22);  color: #fca5a5; }
[data-tema="escuro"] .data-proxima { background: rgba(245, 158, 11, .22); color: #fcd34d; }
[data-tema="escuro"] .data-media   { background: rgba(234, 88, 12, .22);  color: #fdba74; }
[data-tema="escuro"] .data-leve    { background: rgba(250, 204, 21, .20); color: #fde047; }

/* Contador de dias em atraso. O `.atraso-grave` e fundo CHEIO vermelho com
   texto branco - esse ja lia bem no escuro e fica como esta. */
[data-tema="escuro"] .dias-badge.atraso-medio { background: rgba(234, 88, 12, .22);  color: #fdba74; }
[data-tema="escuro"] .dias-badge.atraso-leve  { background: rgba(250, 204, 21, .20); color: #fde047; }
[data-tema="escuro"] .dias-badge.atraso       { background: rgba(239, 68, 68, .20);  color: #fca5a5; }
[data-tema="escuro"] .dias-badge.proximo      { background: rgba(245, 158, 11, .20); color: #fcd34d; }

/* Valor pago maior/menor que o esperado */
[data-tema="escuro"] .valor-menor { color: #fca5a5; }
[data-tema="escuro"] .valor-maior { color: #6ee7b7; }

/* ============================================================
   TELA DE TICKETS NO ESCURO: os veus de 8-9% nao sobrevivem.

   As pilulas desta tela foram desenhadas com fundo tingido a
   8-9% de opacidade sobre BRANCO. Sobre o #1a2130 do cartao
   escuro, 9% de qualquer cor da uma diferenca de dois ou tres
   pontos de luminancia: a pilula perde a moldura e vira texto
   solto no meio da linha.

   A correcao segue o padrao que o resto do arquivo ja adotou
   (ver `.data-atraso` e as irmas, mais acima): veu a ~.20,
   borda a ~.34 e o texto num tom claro da mesma familia. Nao e
   so trocar a cor da letra - sem subir o fundo, a pilula
   continua sem forma.
   ============================================================ */

/* PILULA DE COPIA (numero do ticket, dominio). A cor mora numa unica
   custom property `--fc`, entao trocar o triplete conserta fundo, borda,
   texto e o botao de copiar de uma vez - por isso ela foi escrita assim. */
[data-tema="escuro"] .pill-copia  { --fc: 148, 163, 189; }   /* cinza claro   */
[data-tema="escuro"] .pill-ticket { --fc: 167, 139, 250; }   /* violeta claro */
[data-tema="escuro"] .pill-dominio{ --fc: 103, 232, 249; }   /* ciano claro   */
/* As tres de baixo NAO sao da tela de tickets, e entram aqui por
   necessidade: a regra generica de `.pill-copia` acima tem duas classes de
   especificidade e venceria o `--fc` delas, que tem uma so. Sem estas
   linhas, telefone, documento e e-mail colapsariam todos no mesmo cinza no
   tema escuro - o CNPJ da tela de NF-e, que e o dado principal dali,
   perderia o roxo da marca. */
[data-tema="escuro"] .pill-telefone { --fc: 148, 163, 189; }  /* ardosia clara */
[data-tema="escuro"] .pill-email    { --fc: 148, 163, 189; }  /* ardosia clara */
[data-tema="escuro"] .pill-doc      { --fc: 165, 180, 252; }  /* roxo da marca, clareado */

/* O veu da pilula precisa de mais corpo no escuro do que o .06 do claro. */
[data-tema="escuro"] .pill-copia {
    background: rgba(var(--fc), .12);
    border-color: rgba(var(--fc), .30);
}

/* SELOS DA COLUNA DOMINIO: data center, servidor e contas ativas. */
[data-tema="escuro"] .badge-us {
    background: rgba(165, 180, 252, .18);
    color: #c7d2fe;
    border-color: rgba(165, 180, 252, .34);
}
[data-tema="escuro"] .badge-ca {
    background: rgba(248, 113, 113, .18);
    color: #fca5a5;
    border-color: rgba(248, 113, 113, .34);
}
[data-tema="escuro"] .badge-uk {
    background: rgba(96, 165, 250, .18);
    color: #93c5fd;
    border-color: rgba(96, 165, 250, .34);
}
[data-tema="escuro"] .badge-shared,
[data-tema="escuro"] .badge-neutro {
    background: rgba(148, 163, 189, .16);
    color: #b6c2d6;
    border-color: rgba(148, 163, 189, .30);
}
[data-tema="escuro"] .badge-contas {
    background: rgba(129, 140, 248, .20);
    color: #c7d2fe;
    border-color: rgba(129, 140, 248, .36);
}
[data-tema="escuro"] .badge-email {
    background: rgba(148, 163, 189, .16);
    border-color: rgba(148, 163, 189, .30);
}

/* SITUACAO E PRIORIDADE (colunas Ultima fala e Prioridade). */
[data-tema="escuro"] .badge-ok {
    background: rgba(52, 211, 153, .18);
    border-color: rgba(52, 211, 153, .34);
}
[data-tema="escuro"] .badge-err,
[data-tema="escuro"] .badge-prio-urgente {
    background: rgba(248, 113, 113, .18);
    border-color: rgba(248, 113, 113, .34);
}
/* No escuro os dois clareiam, mantendo as familias: azul para a media,
   ardosia para a baixa. */
[data-tema="escuro"] .badge-prio-media {
    background: rgba(96, 165, 250, .16);
    border-color: rgba(96, 165, 250, .32);
    color: #93c5fd;
}
[data-tema="escuro"] .badge-prio-baixa {
    background: rgba(52, 211, 153, .16);
    border-color: rgba(52, 211, 153, .32);
    color: #6ee7b7;
}
/* As pilulas da barra de prioridade no escuro. Sem isto, o --cat de cada uma
   continuaria sendo a cor do tema claro dentro de um fundo escuro. */
[data-tema="escuro"] .seg-prio a.prio-urgente { --cat: #fca5a5; --cat-bg: rgba(248, 113, 113, .16); }
[data-tema="escuro"] .seg-prio a.prio-alta    { --cat: #fcd34d; --cat-bg: rgba(251, 191, 36, .16); }
[data-tema="escuro"] .seg-prio a.prio-media   { --cat: #93c5fd; --cat-bg: rgba(96, 165, 250, .16); }
[data-tema="escuro"] .seg-prio a.prio-baixa   { --cat: #6ee7b7; --cat-bg: rgba(52, 211, 153, .16); }

[data-tema="escuro"] .badge-q {
    background: rgba(251, 191, 36, .18);
    border-color: rgba(251, 191, 36, .34);
}
[data-tema="escuro"] .badge-icp {
    background: rgba(165, 180, 252, .18);
    border-color: rgba(165, 180, 252, .34);
}

/* DEPARTAMENTO. O teal do ABERTURA E-MAIL fica quase preto no escuro. */
[data-tema="escuro"] .badge-cat-abertura-email {
    background: rgba(45, 212, 191, .18);
    color: #5eead4;
    border-color: rgba(45, 212, 191, .34);
}

/* ---- OS BOTOES DA COLUNA ACOES ----

   No claro, cada um tinge o fundo com 9% da sua cor ao passar o mouse. No
   escuro esse veu desaparece e o botao parece morto - a pessoa passa o
   mouse, nada muda, e ela clica duas vezes para conferir. */
[data-tema="escuro"] .btn-icon.acao-ver:hover {
    background: rgba(165, 180, 252, .16);
    border-color: rgba(165, 180, 252, .42);
    color: #c7d2fe;
}
[data-tema="escuro"] .btn-icon.acao-categoria:hover {
    background: rgba(216, 180, 254, .16);
    border-color: rgba(216, 180, 254, .42);
    color: #e9d5ff;
}
[data-tema="escuro"] .btn-icon.acao-plano:hover {
    background: rgba(52, 211, 153, .16);
    border-color: rgba(52, 211, 153, .42);
    color: #6ee7b7;
}

/* O do link do cliente e o unico colorido EM REPOUSO - some sem isto. */
[data-tema="escuro"] .btn-icon.acao-token {
    color: #34d399;
    border-color: rgba(52, 211, 153, .42);
}
[data-tema="escuro"] .btn-icon.acao-token:hover {
    color: #6ee7b7;
    background: rgba(52, 211, 153, .18);
    border-color: rgba(52, 211, 153, .62);
}
/* ---- BUSCA DE RESPOSTA PRONTA ----
   O roxo da marca a 10% e a 16% foi escolhido contra fundo BRANCO; sobre o
   fundo escuro ele praticamente desaparece, e sao justamente as duas marcas
   que dizem "e esta linha que o Enter usa" e "foi aqui que casou". Aqui vao
   os tons claros da marca, que e como o tema escuro resolve o resto. */
[data-tema="escuro"] .rp-item-ativo { background: rgba(167, 139, 250, .18); }

[data-tema="escuro"] .rp-lista mark {
    background: rgba(167, 139, 250, .26);
    color: #ede9fe;
}

/* ---- ENVIO SIGILOSO na tela do chamado ---- */
[data-tema="escuro"] .msg-sigilo {
    border-color: rgba(45, 212, 191, .45);
    background: rgba(45, 212, 191, .10);
}
[data-tema="escuro"] .msg-sigilo-topo { color: #5eead4; }
[data-tema="escuro"] .msg-sigilo-btn {
    color: #5eead4;
    border-color: rgba(45, 212, 191, .45);
}
[data-tema="escuro"] .msg-sigilo-btn:hover {
    background: rgba(45, 212, 191, .16);
    border-color: rgba(45, 212, 191, .65);
    color: #99f6e4;
}

/* Etiquetas de pais, painel e categoria */
[data-tema="escuro"] .badge-linux     { color: #67e8f9; }
[data-tema="escuro"] .badge-cpanel    { color: #d8b4fe; }
[data-tema="escuro"] .badge-nfe       { color: #fcd34d; }

[data-tema="escuro"] .congela-flag    { color: #67e8f9; }
[data-tema="escuro"] .venda-badge     { color: #fca5a5; }

/* O CONTADOR DE REINCIDENCIA ("2x") e a excecao da lista: o fundo dele nao e
   um veu tingido, e o vermelho CHEIO da variavel --err, com texto branco. No
   escuro o --err clareia (#f87171) e o branco por cima cai para ~2,8:1 - o
   problema aqui e o FUNDO, e nao o texto. Entao escurece-se o fundo e mantem-se
   o branco. Trocar a cor do texto, como nas outras, deixaria letra ciana sobre
   vermelho solido. */
[data-tema="escuro"] .alerta-vezes { background: #b91c1c; color: #fff; }

/* Avisos e blocos informativos com texto escuro fixo */
[data-tema="escuro"] .alert-info,
[data-tema="escuro"] .acesso-regra   { color: #93c5fd; }

/* `.criterio-aba` e `.previa-linha dd` NAO entram aqui, e vale registrar por
   que: o levantamento que gerou esta lista procurou `color: #xxxxxx` escuro, e
   essas duas usam var(--muted) e var(--ink) - ja mudam sozinhas com o tema.
   Sobrescrever seria trocar uma cor certa por outra. */

/* A PILULA DO GRUPO NO SUBMENU - o escuro segue o proprio caminho.

   No tema CLARO ela virou solida, roxo cheio com letra branca (ver o bloco
   `@media (min-width: 1081px)`). Aqui isso nao serve: `--brand` no escuro e
   um indigo CLARO (#818cf8), e letra branca por cima dele daria 2,6:1 -
   trocaria um problema de destaque por um de leitura.

   O escuro ja resolve por inversao: a pilula e mais ESCURA que o painel
   (`--surface` #1a2130 dentro de `--menu-painel` #1e2434) e a letra e o
   lavanda claro. Da 8,5:1, e a hierarquia contra os itens ja esta certa.

   O `background` precisa estar escrito aqui, e nao so a cor: sem ele o roxo
   solido do bloco de 1081px venceria - media query nao muda especificidade,
   e este seletor tem uma classe a mais. */
[data-tema="escuro"] .menu-item .dropdown .sub-group {
    background: var(--surface);
    border-color: rgba(129, 140, 248, .30);
    color: #c7d2fe;
}

/* OS ROTULOS DE ID sao TRES cores, e nao uma: roxo para o codigo nosso, ciano
   e cinza para os do banco. A cor mora em `.id-cobr` / `.id-tx` / `.id-e2e`,
   e nao em `.id-rotulo` - pintar o rotulo aqui apagaria a distincao entre os
   tres, porque o seletor com [data-tema] tem especificidade maior que a
   classe sozinha. `.id-e2e` ja usa var(--muted) e nao precisa de nada. */
[data-tema="escuro"] .id-cobr { color: #c7d2fe; }
[data-tema="escuro"] .id-tx   { color: #67e8f9; }

/* O hamburguer do celular acompanha a barra. */
[data-tema="escuro"] .nav-lateral .hamburger { background: var(--barra); }


/* A COR DO CONTADOR DE CONGELADAS. No claro e um ciano escuro; no escuro ele
   desapareceria. Mesma familia, luminosidade trocada. */
[data-tema="escuro"] .resumo-congelado { color: #67e8f9; }

/* O AVISO EM TOM DA MARCA. O roxo a 5% sobre fundo escuro nao aparece - o veu
   passa a ser claro, que e como se destaca um bloco no escuro. */
[data-tema="escuro"] .alert-marca {
    background: rgba(179, 157, 219, .10);
    border-color: rgba(179, 157, 219, .28);
}

/* CARTAO DE RESUMO: o roxo claro do tema claro vira um roxo profundo. */
[data-tema="escuro"] .resumo-card {
    background: rgba(179, 157, 219, .09);
    border-color: rgba(179, 157, 219, .24);
}

/* A ZEBRA DA TABELA precisa de mais contraste no escuro do que no claro:
   duas superficies escuras proximas viram uma so a um metro de distancia. */
[data-tema="escuro"] tbody tr:hover { background: var(--elevated); }


/* ============================================================
   O atributo hidden tem que ganhar de qualquer display do CSS.
   Sem isto, um elemento com `hidden` que tenha classe com
   `display: inline-block` (ex.: .badge) aparece na tela vazio -
   foi o que acontecia com o badge de falha em Cobrancas do mes.
   ============================================================ */
[hidden] { display: none !important; }

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

/* ============================================================
   TAMANHO DA INTERFACE (o - e o + da barra lateral)

   `zoom`, e nao `font-size`. A escolha nao foi de gosto: este arquivo tem
   1.521 medidas em PIXEL e 192 das 193 declaracoes de `font-size` sao em px.
   Mexer na fonte do <html> nao moveria praticamente nada - as fontes ficariam
   presas no tamanho de sempre, e o pouco que herdasse cresceria dentro de
   caixas que nao cresceram, estourando o texto para fora delas.

   `zoom` escala a caixa inteira: fonte, espacamento, icone e borda juntos. E
   a unica alavanca que funciona sobre uma folha de estilo em px sem reescrever
   as 1.521 medidas.

   O QUE ELE NAO FAZ: media query nao acompanha. Em 130% numa tela de 1.400px,
   o layout continua achando que tem 1.400px enquanto o conteudo ocupa o
   equivalente a 1.077. Tabela larga pode passar a rolar na horizontal - e por
   isso o teto e 130%, e nao 150%.

   NO <body>, e nao no <html>: em `html` o `zoom` briga com a barra de rolagem
   da pagina em alguns navegadores. A barra lateral e `position: fixed` DENTRO
   do body, entao escala junto com o `padding-left` que a compensa - os dois
   continuam batendo em qualquer escala.
   ============================================================ */
body {
    zoom: var(--escala-ui, 1);
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
    /* COR SOLIDA no fundo do sistema.
       Havia duas manchas radiais (roxo no topo direito, ciano embaixo a
       esquerda) por cima da cor de fundo. Elas nao acompanhavam a rolagem nem
       o conteudo, entao em tela longa apareciam como uma faixa mais clara no
       meio do nada - e sobre tabela cheia so atrapalhavam a leitura. */
    background: var(--bg);
    color: var(--ink);
    font-size: 14.5px;
    line-height: 1.45;
    -webkit-font-smoothing: antialiased;
}

/* ============================================================
   NAVBAR SUPERIOR
   ============================================================ */
.nav-wrap {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--barra);
    box-shadow: 0 6px 22px rgba(42, 6, 105, .26);
}

/* ============================================================
   BARRA DA MARCA - faixa fina acima do menu.
   Tom mais escuro que o menu para separar as duas sem precisar
   de borda, e para o menu continuar sendo o elemento com peso.
   ============================================================ */
.brand-bar {
    background: var(--barra-topo);
    color: #fff;
}
.brand-inner {
    display: flex;
    align-items: center;
    justify-content: center;      /* a marca fica no meio da faixa */
    gap: 12px;
    padding: 14px 112px;          /* folga em cima e embaixo do logo */
    min-height: var(--brand-h);
}
/* O logo tem 632x147 (proporcao 4,3:1) e fundo transparente.
   A altura e fixada e a largura vem sozinha, para nao distorcer.
   width/height no <img> reservam o espaco antes de carregar - sem isso
   a faixa "pula" quando a imagem chega. */
.brand-logo {
    display: inline-flex;
    align-items: center;
    line-height: 0;
    text-decoration: none;
    color: rgba(255, 255, 255, .95);
    font-size: 20px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
}
.brand-logo img {
    height: 64px;                 /* 40% maior que os 46px anteriores */
    width: auto;
    display: block;
}

.nav-inner {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 112px;
    min-height: 62px;
    width: 100%;
}

.nav-brand { display: flex; align-items: center; gap: 10px; white-space: nowrap; }

.logo-mark {
    width: 36px; height: 36px;
    display: grid; place-items: center;
    border-radius: 10px;
    font-weight: 800; font-size: 14px; color: #fff;
    background: linear-gradient(135deg, #43159C, #22d3ee);
    box-shadow: 0 4px 14px rgba(67, 21, 156, .35);
}

.logo-text { display: flex; flex-direction: column; line-height: 1.15; }
.logo-text strong { font-size: 14.5px; font-weight: 700; }
.logo-text span { font-size: 10.5px; color: var(--muted); }

.menu { display: flex; align-items: center; flex: 1; flex-wrap: wrap; gap: 3px; }

.menu-link, .menu-item .menu-title {
    display: block;
    padding: 9px 16px;
    border-radius: 999px;
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: .01em;
    color: rgba(255, 255, 255, .85);
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;
    user-select: none;
    transition: background .15s, color .15s, box-shadow .15s;
}

.menu-item { position: relative; }

.menu-item .menu-title::after {
    content: '';
    display: inline-block;
    margin-left: 7px;
    width: 6px; height: 6px;
    border-right: 1.7px solid currentColor;
    border-bottom: 1.7px solid currentColor;
    transform: rotate(45deg) translateY(-2px);
    opacity: .7;
}

.menu-link:hover, .menu-item:hover .menu-title {
    color: #fff;
    background: rgba(255, 255, 255, .14);
}

.menu-link.active, .menu-item.active .menu-title {
    color: #2A0669;
    background: var(--sobre-marca);
    box-shadow: 0 4px 14px rgba(15, 10, 60, .25);
}

.menu-item .dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 120;
    min-width: 235px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 13px;
    padding: 7px;
    box-shadow: var(--shadow-pop);
}

/* ponte invisivel para o mouse nao "cair" entre o titulo e o dropdown */
/* A PONTE INVISIVEL entre o item e o painel.
   O painel nao encosta no item - ha um respiro de 8px. Sem cobrir esse vao,
   o ponteiro "sai" do item no meio do caminho, o `:hover` cai e o submenu
   fecha na cara de quem estava indo ate ele. Esta faixa de 8px pertence ao
   painel, entao atravessa-la nunca deixa de ser hover. */
.menu-item .dropdown::before {
    content: '';
    position: absolute;
    top: -8px; left: 0; right: 0;
    height: 8px;
}

/* ============================================================
   A PONTE DO MENU LATERAL FICA NA ESQUERDA, e nao em cima.

   A regra acima nasceu no menu SUPERIOR, onde o painel desce e o vao fica
   ACIMA dele. Na barra lateral o painel sai pelo LADO: o `left` que o
   menu-lateral.js calcula e `borda direita da barra + 8`, entao o vao esta
   a ESQUERDA. A ponte de cima nao cobria nada ali, e o submenu fechava no
   meio do trajeto do mouse - de forma intermitente, porque depende da
   velocidade e do angulo com que o ponteiro cruza os 8px.

   `bottom: 0` em vez de altura fixa: o painel tem alturas diferentes por
   item, e a ponte precisa acompanhar a borda esquerda inteira - entrar pela
   parte de baixo de um painel alto e tao comum quanto entrar pelo topo.

   OS 8px SAO OS MESMOS DO JS (`var MARGEM = 8` no menu-lateral.js). Mudar um
   sem o outro reabre exatamente este defeito.
   ============================================================ */
.nav-lateral .menu-item .dropdown::before {
    top: 0;
    bottom: 0;
    left: -8px;
    right: auto;
    width: 8px;
    height: auto;
}

.menu-item:hover .dropdown { display: block; }

/* SUBMENU PRESO PELO CLIQUE (`.fixado`), na barra lateral de tela grande.
   Existe para a barra RECOLHIDA, onde o item e so um icone de 64px: ali
   passar o mouse e a unica forma de ver o submenu, e quem clica no icone
   esperando abrir nao consegue nada. Com o clique o painel fica preso ate
   clicarem fora, no Escape, ou de novo no mesmo icone.
   Vale tambem com a barra aberta - clicar nao atrapalha quem usa hover. */
.nav-lateral .menu-item.fixado .dropdown { display: block; }

.menu-item .dropdown a,
.menu-item .dropdown .soon {
    display: block;
    padding: 8px 12px;
    border-radius: 8px;
    font-size: 13px;
    color: var(--muted);
    text-decoration: none;
    white-space: nowrap;
}

/* Itens do submenu em MAIUSCULAS. O espacamento entre letras evita o efeito
   de "bloco" que texto todo em caixa alta costuma ter, e o tamanho cai um
   pouco porque maiuscula ocupa mais largura que minuscula. */
.menu-item .dropdown a,
.menu-item .dropdown .soon {
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: 12.5px;
}
.menu-item .dropdown a { color: var(--ink); font-weight: 600; }
.menu-item .dropdown a:hover { background: var(--elevated); color: var(--accent-ink); }

.menu-item .dropdown a.active {
    background: rgba(42, 6, 105, .08);
    color: var(--accent-ink);
    font-weight: 600;
}

.menu-item .dropdown .soon { color: var(--faint); cursor: not-allowed; }

/* ============================================================
   SUBMENU FLUTUANTE EM TELA GRANDE - painel com tom proprio

   Em branco puro o painel se confundia com o conteudo da pagina atras dele:
   um retangulo branco sobre fundo quase branco, separado so pela sombra. Um
   tom levemente arroxeado o amarra a barra roxa de onde ele sai, e a
   fronteira passa a ser visivel sem depender da sombra.

   `min-width: 1081px` e a tela grande de verdade: abaixo disso o menu vira
   gaveta (no topo) ou sanfona (na lateral), e nos dois casos o painel deixa
   de flutuar e ja tem cor propria. Mexer neles daqui pintaria de lilas um
   bloco que mora dentro de um painel branco ou sobre a barra roxa.
   ============================================================ */
@media (min-width: 1081px) {
    .menu-item .dropdown {
        background: var(--menu-painel);
        border-color: rgba(67, 21, 156, .16);
    }

    /* O ITEM SOB O MOUSE FICA BRANCO - a relacao se inverte.
       Com o painel claro-acinzentado (`--elevated`, #f8fafc) o realce sumia:
       eram dois tons quase iguais, e o item destacado parecia igual aos
       outros. Branco sobre lilas separa sem precisar de borda nova. */
    .menu-item .dropdown a:hover {
        background: var(--surface);
        color: var(--accent-ink);
    }

    /* O item ATIVO precisa continuar mais forte que o item sob o mouse -
       senao passar o mouse ao lado faria a tela atual parecer outra. */
    .menu-item .dropdown a.active {
        background: rgba(67, 21, 156, .13);
        color: var(--accent-ink);
    }

    /* A PILULA DO GRUPO NAO E PINTADA AQUI, e nunca foi.

       Havia neste ponto um `.menu-item .dropdown .sub-group` com fundo
       branco, e ele era CODIGO MORTO: a regra base tem a mesma
       especificidade e esta escrita depois, entao ganhava o empate. Media
       query nao aumenta especificidade - isso e fácil de esquecer, e foi o
       que fez a regra parecer viva por tanto tempo.

       A pilula agora e solida, definida na regra base. Ver o comentario
       longo em `.menu-item .dropdown .sub-group`, adiante neste arquivo. */

    /* A linha que separa os grupos tambem sobe de tom: `--line-soft` foi
       escolhido para funcionar sobre branco e sumia no lilas. */
    .menu-item .dropdown .grupo + .grupo {
        border-top-color: rgba(67, 21, 156, .14);
    }
}
.menu-item .dropdown .soon em {
    font-style: normal; font-size: 9.5px; font-weight: 600;
    color: var(--warn);
    border: 1px solid rgba(180, 83, 9, .3);
    border-radius: 999px;
    padding: 1px 6px;
    margin-left: 5px;
}

/* Submenu em grupos (ex.: Cobrancas): a pilula com o nome do grupo.

   SOLIDA, no roxo cheio da marca. Ja foi lilas a 10% com letra roxa media, e
   a intencao era nao gritar mais alto que os itens - so que passou do ponto e
   virou o contrario de um titulo:

       fundo da pilula sobre o painel ..... 1,20:1   (nao se via)
       texto #6D4AB8 sobre a pilula ....... 4,71:1   (o minimo, raspando)
       os ITENS que ela agrupa ........... 16,00:1

   O rotulo do grupo era menor E mais claro que o conteudo do grupo. Solido
   inverte isso: a pilula aparece (14,17:1 contra o painel) e o texto branco
   dentro dela fica em 15,81:1 - mais forte que os itens, que e o que um
   cabecalho de secao deve ser.

   ESTA E A REGRA QUE MANDA, e por isso a mudanca esta aqui.
   Havia uma copia dentro de `@media (min-width: 1081px)` tentando pintar esta
   pilula - e ela nunca teve efeito nenhum: mesma especificidade e escrita
   ANTES desta, entao esta ganhava o empate. Codigo morto que parecia vivo.
   Foi apagada.

   Os tres contextos que precisam de outra cor tem seletor com uma classe a
   mais e continuam ganhando desta: o tema escuro (`[data-tema="escuro"] ...`),
   a sanfona da barra (`.nav-lateral ...`) e a gaveta do celular
   (`body.nav-open .nav-lateral ...`). */
.menu-item .dropdown .sub-group {
    display: inline-block;
    margin: 3px 12px 5px;
    padding: 3px 11px;
    border-radius: 999px;
    background: var(--brand);
    border: 1px solid var(--brand);
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: #fff;
}

/* Os itens recuam para a direita: o recuo e o que diz "isto esta DENTRO do
   grupo". No padding, e nao na margem, para o fundo do hover continuar
   cobrindo a largura inteira do submenu. */
.menu-item .dropdown .grupo a { padding-left: 26px; }

.menu-item .dropdown .grupo + .grupo {
    margin-top: 4px;
    padding-top: 3px;
    border-top: 1px solid var(--line-soft);
}

/* No MENU SUPERIOR o rodape e uma fileira; na lateral vira coluna (ver o
   bloco "rodape: usuario e sair", mais abaixo). O visual das pecas - convite,
   chip do usuario, relogio e Sair - fica junto, na secao do rodape do menu.
   Duas metades da mesma caixa em pontos distantes do arquivo divergem na
   primeira alteracao que alguem fizer em uma so. */
.nav-right { display: flex; align-items: center; gap: 10px; }

/* O .btn-ghost aqui e do modal de confirmacao (fragments/componentes), que
   tambem aparece sobre fundo escuro. O botao Sair deixou de usa-lo: agora e
   .btn-sair, com icone e o vermelho reservado para o hover. */
.nav-wrap .btn-ghost {
    border-color: rgba(255, 255, 255, .4);
    color: #fff;
}
.nav-wrap .btn-ghost:hover { background: rgba(255, 255, 255, .13); border-color: #fff; color: #fff; }

.hamburger {
    display: none;
    background: none; border: none; color: #fff; cursor: pointer; padding: 4px;
}
.hamburger svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }

/* ============================================================
   CONTEUDO
   ============================================================ */
/* Conteudo ocupa toda a largura do monitor, com respiro generoso nas laterais */
main { padding: 24px 112px 44px; width: 100%; max-width: none; margin: 0; }
main.wide { max-width: none; }

/* Em monitor muito largo o texto fica esticado demais para ler.
   As telas de formulario e leitura ganham um teto; as de tabela
   (main.wide) continuam usando a largura toda, que e onde ela ajuda. */
@media (min-width: 1700px) {
    main:not(.wide) { max-width: 1500px; margin: 0 auto; }
}

@media (max-width: 1500px) {
    main { padding: 24px 48px 40px; }
    .nav-inner { padding: 0 48px; }
    .brand-inner { padding: 0 48px; }
}

.page-head { display: flex; align-items: baseline; gap: 14px; margin: 2px 0 16px; }
.page-head h2 { margin: 0; font-size: 20px; font-weight: 700; }

/* ------------------------------------------------------------------
   Verificacao automatica (tickets): contagem regressiva no cabecalho.
   ------------------------------------------------------------------ */
.auto-refresh {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    font-size: 12px;
    color: var(--muted);
}

.auto-ponto {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--ok);
    box-shadow: 0 0 0 3px rgba(5, 150, 105, .14);
    flex: none;
}

.auto-refresh.verificando .auto-ponto { animation: auto-pulsar 1s ease-in-out infinite; }
.auto-refresh.novidade { color: var(--ok); font-weight: 700; }
.auto-refresh.falhou   { color: var(--err); }
.auto-refresh.falhou .auto-ponto { background: var(--err); box-shadow: 0 0 0 3px rgba(220, 38, 38, .12); }

/* Pilula, e nao link sublinhado: ao lado da contagem regressiva o sublinhado
   parecia parte do texto, e ninguem clicava. */
.auto-agora {
    border: 1px solid var(--line);
    background: var(--surface);
    border-radius: 999px;
    padding: 3.5px 12px;
    font-family: inherit;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--accent-ink);
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}

.auto-agora:hover {
    background: var(--bg);
    border-color: var(--accent-ink);
}

.auto-agora:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

@keyframes auto-pulsar { 50% { opacity: .25; } }

/* Linha que chegou na ultima verificacao: um clarao curto e some. */
.linha-nova > td { animation: auto-destacar 4s ease-out; }

@keyframes auto-destacar {
    0%, 22% { background: rgba(5, 150, 105, .15); }
    100%    { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .auto-refresh.verificando .auto-ponto { animation: none; }
    .linha-nova > td { animation: none; box-shadow: inset 3px 0 0 var(--ok); }
}

/* Lista de campos alterados (auditoria de cadastro). Uma linha por campo:
   o texto e gravado como "a: 'x' -> 'y'; b: ..." e ler isso grudado nao e
   leitura. Monoespacada porque a coluna e cheia de valor colado em aspas. */
.mudancas {
    margin: 0;
    padding-left: 16px;
    list-style: none;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    font-size: 12px;
    line-height: 1.6;
}

.mudancas li { position: relative; }

.mudancas li::before {
    content: '';
    position: absolute;
    left: -12px; top: 8px;
    width: 5px; height: 5px;
    border-radius: 50%;
    background: var(--faint);
}

/* Nome do cliente em caixa alta. E no CSS, e nao no texto gravado: o banco
   guarda o nome como a pessoa digitou ("Otavio Augusto", "AGF ENERGIA") e
   assim continua - so a exibicao muda. */
/* ============================================================
   DICA: o balao que explica os botoes de icone (js/dica.js).

   Filho do <body> e `position: fixed` de proposito: a tabela mora
   dentro de `.tabela-rolavel`, que recorta tudo que passa da
   borda por causa do `overflow-x: auto`. A coluna Acoes fica
   justo na borda direita - um `::after` dentro da celula seria
   cortado ao meio.

   Cores fixas, e nao variaveis de tema: e uma etiqueta flutuante
   sobre qualquer fundo, e precisa do mesmo contraste alto nos
   dois temas. O balao do menu recolhido (`.menu-link::before`) ja
   usa esse mesmo tom escuro.
   ============================================================ */
.dica-balao {
    /* `inset: auto` ANTES do top/left, e nao depois: `inset` e atalho para os
       quatro lados, e declarado embaixo apagaria o que veio antes.

       Estes quatro anulam o estilo que o navegador aplica a [popover] - o
       balao vira popover quando a API existe, para subir a top layer e nao
       ficar atras dos baloes da propria tela. Sem eles, o `inset: 0` +
       `margin: auto` do UA centralizariam a dica no meio da janela, e a borda
       e o `overflow` cortariam o texto. */
    inset: auto;
    margin: 0;
    border: 0;
    overflow: visible;

    position: fixed;
    top: 0;
    left: 0;
    /* Vale para o caso SEM popover, em que o balao fica na camada normal. */
    z-index: 9000;
    max-width: 280px;
    padding: 7px 11px;
    border-radius: 8px;
    background: #1B0344;
    color: #fff;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.45;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .38);
    /* Nao intercepta o mouse: o balao aparece perto do botao, e um
       balao clicavel roubaria o clique de quem mirou direito. */
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transform: translateY(3px);
    transition: opacity .12s ease, transform .12s ease, visibility .12s;
}

.dica-balao.dica-visivel {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.dica-balao.dica-abaixo { transform: translateY(-3px); }
.dica-balao.dica-abaixo.dica-visivel { transform: translateY(0); }

/* No escuro o roxo quase preto some no fundo: clareia a moldura para o
   balao continuar se descolando do cartao atras dele. */
[data-tema="escuro"] .dica-balao {
    background: #2b2150;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .6);
}

/* Sem JavaScript nao ha balao nenhum - e ai o `title` original continua
   no elemento, porque quem o remove e o proprio script. */

.nome-cliente { text-transform: uppercase; }

/* Cliente sem dominio no cadastro: o nome ocupa o lugar da pilula, em tom
   apagado. Nao e um dado igual aos outros - e o que sobrou quando o dado
   principal falta -, e o cinza diz isso sem precisar de legenda. */
.dominio-vazio {
    display: inline-block;
    font-size: 12.5px;
    color: var(--muted);
    text-transform: uppercase;
}

/* ============================================================
   RODAPE DO MENU: convite de 2FA, conta e relogio de sessao

   UM BLOCO SO. Antes eram tres pecas soltas - um cartao amarelo inteiro, uma
   pilula de usuario e um relogio - cada uma com sua forma, sua cor e seu
   alinhamento. Empilhadas no pe da barra roxa viravam o canto mais bagunçado
   da tela. Agora compartilham caixa, borda e ritmo.
   ============================================================ */

/* CONVITE PARA ATIVAR A VERIFICACAO EM DUAS ETAPAS.

   O AVISO INTEIRO E UM LINK, e nao um texto com botao dentro. Alvo grande,
   uma acao so, nada para escolher: quem le "ative" ja quer ir.

   O DESTAQUE VEM DO ICONE, e nao do bloco. Ja tentamos os dois extremos e os
   dois erraram: tinta lavada sobre roxo escuro vira borrao acinzentado
   (invisivel), e fundo ambar inteiro vira um berro amarelo que cansa em dois
   dias - foi o que aconteceu aqui. O meio termo funciona melhor: um quadrado
   ambar SOLIDO de 26px puxa o olho de longe, o texto claro le sem esforco, e
   o conjunto continua parecendo parte do sistema em vez de um adesivo colado
   por cima.

   SEM CONTAGEM REGRESSIVA: o 2FA e recomendado, nunca obrigatorio. Nao ha
   prazo para exibir - e um numero que encolhe sem nada acontecer no zero
   ensina a ignorar o aviso inteiro. */
.aviso-2fa {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 10px;
    border-radius: 11px;
    background: rgba(255, 255, 255, .07);
    border: 1px solid rgba(251, 191, 36, .42);
    color: #fff;
    text-decoration: none;
    line-height: 1.3;
    transition: background .15s, border-color .15s, transform .05s;
}

.aviso-2fa:hover {
    background: rgba(251, 191, 36, .16);
    border-color: rgba(251, 191, 36, .75);
}
.aviso-2fa:active { transform: translateY(1px); }

/* O UNICO ponto de cor cheia do rodape. E o que faz o aviso ser notado sem
   que o bloco precise gritar. */
.aviso-2fa-icone {
    flex: none;
    width: 26px; height: 26px;
    display: grid; place-items: center;
    border-radius: 8px;
    background: #fbbf24;
    color: #3b2405;
}

.aviso-2fa-icone svg { width: 15px; height: 15px; }

.aviso-2fa-texto { display: block; min-width: 0; }

.aviso-2fa-texto b {
    display: block;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .1px;
}

/* A segunda linha em ambar: repete a cor do icone e amarra as duas pontas do
   aviso, sem precisar de mais uma borda ou mais um fundo. */
.aviso-2fa-texto span {
    display: block;
    margin-top: 1px;
    font-size: 11px;
    font-weight: 600;
    color: #fbbf24;
}

/* NO MENU SUPERIOR o rodape vira fileira: o aviso encolhe para caber ao lado
   do usuario, e a segunda linha sai - ali nao ha altura para duas. */
.nav-wrap:not(.nav-lateral) .aviso-2fa { padding: 6px 10px; }
.nav-wrap:not(.nav-lateral) .aviso-2fa-texto span { display: none; }

/* NA LATERAL RECOLHIDA sobram 64px: o texto nao cabe e viraria uma coluna de
   letras. Fica so o escudo, centralizado, e o balao do title explica. */
body.menu-recolhido .nav-lateral .aviso-2fa {
    justify-content: center;
    padding: 8px 0;
    border-color: rgba(251, 191, 36, .5);
}
body.menu-recolhido .nav-lateral .aviso-2fa-texto { display: none; }

/* ------------------------------------------------------------
   O BLOCO DA CONTA: avatar, nome, relogio e sair
   ------------------------------------------------------------ */
.conta-bloco {
    display: grid;
    gap: 7px;
    padding: 7px;
    border-radius: 12px;
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .12);
}

/* LARGURA INTEIRA, e nao pilula. A pilula existia para o menu superior, onde
   o chip flutua numa fileira; empilhada na barra estreita ela ficava com
   metade do espaço vazio a direita - foi o que apareceu na tela sem nome. */
.user-chip {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 4px 6px 4px 4px;
    border-radius: 9px;
    text-decoration: none;
    transition: background .15s;
}

.user-chip:hover { background: rgba(255, 255, 255, .09); }

.avatar {
    width: 30px; height: 30px;
    flex: none;
    display: grid; place-items: center;
    border-radius: 50%;
    font-size: 12.5px; font-weight: 700; color: #2A0669;
    text-transform: uppercase;
    background: var(--sobre-marca);
    box-shadow: 0 2px 8px rgba(15, 10, 60, .25);
}

.user-dados { min-width: 0; }

.user-name {
    display: block;
    font-size: 12.5px;
    font-weight: 700;
    color: #fff;
    /* Nome longo corta com reticencias em vez de empurrar o bloco: a barra
       tem largura fixa e nao pode alargar por causa de um login comprido. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* O QUE O CLIQUE FAZ, escrito. O chip sempre levou para a troca de senha,
   mas isso so estava no balao do title - que ninguem espera em um nome. */
.user-acao {
    display: block;
    font-size: 10.5px;
    font-weight: 600;
    color: rgba(255, 255, 255, .5);
}

.user-chip:hover .user-acao { color: rgba(255, 255, 255, .78); }

/* Relogio e Sair na mesma linha, dividindo a largura. Empilhados ocupavam
   duas faixas para dizer muito pouco. */
.conta-acoes {
    display: flex;
    align-items: stretch;
    gap: 6px;
}

.conta-acoes .inline { flex: none; }

/* NO MENU SUPERIOR o rodape nao e rodape: e um canto da fileira, com a altura
   de uma barra so. Empilhado - avatar em cima, relogio e Sair embaixo - ele
   dobraria a altura do cabecalho de todas as telas. Aqui as mesmas pecas se
   deitam numa linha, e o "Trocar minha senha" sai (o balao do title continua
   dizendo, e ali nao ha altura para a segunda linha). */
.nav-wrap:not(.nav-lateral) .conta-bloco {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 6px;
}

.nav-wrap:not(.nav-lateral) .user-acao { display: none; }
.nav-wrap:not(.nav-lateral) .user-name { max-width: 160px; }
.nav-wrap:not(.nav-lateral) .sessao-relogio { flex: none; }

/* ------------------------------------------------------------
   BOTAO DE TEMA CLARO / ESCURO
   ------------------------------------------------------------ */

/* Vive na barra ROXA, nos dois temas - por isso as cores aqui sao veu branco
   sobre roxo, e nao variaveis de superficie. Se usasse `--surface`, no escuro
   ele sumiria dentro da propria barra.

   Discreto de proposito: e ajuste de ambiente, escolhido uma vez e esquecido.
   Com destaque, competiria todo dia com o menu, que e o que se vem usar. */
/* SO PARA LEITOR DE TELA. Fica no fluxo (1px, recortado) em vez de
   `display:none`, porque o que esta escondido de verdade nao e lido - e o
   ponto aqui e justamente ser lido e nao ser visto. */
.sr-apenas {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ============================================================
   OS BOTOES DE TAMANHO (- 100% +), logo acima do tema.

   Tres colunas numa linha so, no lugar de tres botoes empilhados: eles
   pertencem ao mesmo controle, e separados ocupariam metade do rodape da
   barra. O do meio e mais largo porque carrega o numero.

   Herdam a aparencia do `.tema-botao` (mesma borda, mesmo fundo, mesma
   familia) para nao parecerem de outro sistema - a diferenca e so a forma.
   ============================================================ */
.fonte-botoes {
    display: grid;
    grid-template-columns: 1fr 1.6fr 1fr;
    gap: 4px;
    margin-bottom: 8px;
}

.fonte-botao {
    display: flex;
    align-items: center;
    justify-content: center;
    /* 34px de altura: o mesmo alvo confortavel do tema, e acima do minimo de
       toque quando a barra vira gaveta no celular. */
    min-height: 34px;
    padding: 6px 4px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, .14);
    background: rgba(255, 255, 255, .05);
    color: rgba(255, 255, 255, .72);
    font-family: inherit;
    font-size: 13px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}

.fonte-botao:hover:not(:disabled) {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}

/* NO LIMITE o botao APAGA, e nao some. Sumir mudaria a largura das tres
   colunas e faria o "+" pular de lugar justamente quando a pessoa esta
   clicando nele repetidamente. */
.fonte-botao:disabled {
    opacity: .35;
    cursor: not-allowed;
}

.fonte-botao.fonte-valor {
    font-size: 11.5px;
    letter-spacing: .2px;
}

/* BARRA RECOLHIDA: so cabe o numero. O - e o + de 64px de largura ficariam
   com 18px cada, abaixo de qualquer alvo clicavel decente. O numero sozinho
   continua sendo o botao de voltar a 100%, que e o que mais importa quando
   alguem se perdeu na escala. */
body.menu-recolhido .nav-lateral .fonte-botoes { grid-template-columns: 1fr; }
body.menu-recolhido .nav-lateral #fonteMenos,
body.menu-recolhido .nav-lateral #fonteMais { display: none; }

/* NO MENU SUPERIOR o rodape e uma fileira, nao uma coluna: as tres colunas
   param de esticar e passam a ocupar so o que precisam, como acontece com o
   tema logo ao lado. */
.nav-wrap:not(.nav-lateral) .fonte-botoes {
    width: auto;
    margin-bottom: 0;
    grid-template-columns: auto auto auto;
}
.nav-wrap:not(.nav-lateral) .fonte-botao {
    min-height: 30px;
    padding: 6px 9px;
}

.tema-botao {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 8px 11px;
    margin-bottom: 8px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, .14);
    background: rgba(255, 255, 255, .05);
    color: rgba(255, 255, 255, .72);
    font-family: inherit;
    font-size: 12px;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
    transition: background .15s, color .15s, border-color .15s;
}

.tema-botao:hover {
    background: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}

.tema-botao svg { width: 16px; height: 16px; flex: none; }

/* NO MENU SUPERIOR vira so o icone: ali o rodape e uma fileira, e mais uma
   palavra empurraria o Sair para fora da barra. */
.nav-wrap:not(.nav-lateral) .tema-botao {
    width: auto;
    margin-bottom: 0;
    padding: 7px 9px;
}
.nav-wrap:not(.nav-lateral) .tema-rotulo { display: none; }

/* RECOLHIDA (64px): so o icone, centralizado - o mesmo tratamento do Sair. */
body.menu-recolhido .nav-lateral .tema-botao { justify-content: center; padding: 8px 0; }
body.menu-recolhido .nav-lateral .tema-rotulo { display: none; }

/* ------------------------------------------------------------
   RELOGIO DA SESSAO
   ------------------------------------------------------------ */
.sessao-relogio {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 6px 10px;
    border-radius: 8px;
    background: rgba(255, 255, 255, .07);
    color: rgba(255, 255, 255, .72);
    font-size: 12px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    /* Discreto de proposito: e uma informacao de fundo, que so precisa ser
       notada quando muda de cor. Um relogio chamativo no canto da tela
       distrai o dia inteiro para avisar uma vez a cada duas horas. */
}

.sessao-relogio svg { width: 14px; height: 14px; flex: none; }

/* ULTIMOS CINCO MINUTOS: sai do fundo e vira aviso. E o unico momento em que
   este elemento deve puxar o olho - da tempo de salvar o que esta aberto. */
.sessao-relogio.alerta {
    background: #dc2626;
    color: #fff;
    animation: pulso-sessao 2s ease-in-out infinite;
}

@keyframes pulso-sessao {
    0%, 100% { opacity: 1; }
    50%      { opacity: .62; }
}

/* Quem prefere menos movimento na tela nao perde o aviso - perde so a
   piscada. A cor continua fazendo o trabalho. */
@media (prefers-reduced-motion: reduce) {
    .sessao-relogio.alerta { animation: none; }
}

/* ------------------------------------------------------------
   SAIR
   ------------------------------------------------------------ */

/* ICONE + PALAVRA, e nao so a palavra. Recolhida a barra, o texto some e a
   porta continua dizendo o que o botao faz - sem precisar de um segundo
   botao so para esse caso.

   PRECISA DO `.nav-wrap` NA FRENTE. O botao e `class="btn btn-sair"`, e a
   regra generica `.btn` mora 700 linhas ABAIXO desta: com a mesma
   especificidade, quem vem depois ganha, e `.btn` levaria embora a borda
   (`border: none`), o padding e a transicao daqui - o botao voltaria a ser um
   retangulo sem contorno. Duas classes no seletor resolvem sem depender de
   onde cada bloco esta no arquivo. */
.nav-wrap .btn-sair {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 6px 12px;
    height: 100%;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, .22);
    background: rgba(255, 255, 255, .07);
    color: rgba(255, 255, 255, .9);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}

.nav-wrap .btn-sair svg { width: 15px; height: 15px; flex: none; }

/* Vermelho so no hover: sair e destrutivo o bastante para avisar, e comum o
   bastante para nao ficar vermelho o dia inteiro no canto do olho. */
.nav-wrap .btn-sair:hover {
    background: #dc2626;
    border-color: #dc2626;
    color: #fff;
    /* `.btn:hover` clareia tudo com `filter`. Sobre vermelho isso lava a cor
       justamente onde ela precisa ser firme. */
    filter: none;
}

/* ============================================================
   ATIVACAO DO 2FA - QR e segredo lado a lado
   ============================================================ */
.dois-fatores-passo {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 24px;
}

/* Monoespacado e em blocos: sao 32 caracteres onde 0 e O se confundem, e o
   erro de digitacao so apareceria la na frente como "codigo invalido". */
.segredo-2fa {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: .06em;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 9px;
    padding: 10px 14px;
    margin: 0 0 10px;
    /* Quebra em vez de esticar o cartao numa tela estreita. */
    overflow-wrap: anywhere;
}

/* CAMPO DO CODIGO DE 6 DIGITOS (segunda etapa do login).

   Monoespacado, grande e espacado: sao seis numeros lidos de um celular e
   digitados de cabeca, e o erro classico e trocar 0 por O ou 1 por 7. Em
   fonte de texto comum, num tamanho comum, esse erro passa despercebido ate
   o "codigo invalido".

   Centralizado porque o campo e mais largo que o conteudo - alinhado a
   esquerda, os digitos ficariam encolhidos num canto de uma caixa vazia. */
.codigo-2fa {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 26px;
    font-weight: 700;
    letter-spacing: .35em;
    text-align: center;
    /* Compensa o letter-spacing, que empurra o texto meio caractere para a
       esquerda ao acrescentar espaco DEPOIS do ultimo digito. */
    text-indent: .35em;
}

/* ============================================================
   CARTAO DO 2FA em Minha senha

   Mora ao lado da troca de senha porque as duas coisas respondem a mesma
   pergunta - "como eu entro no sistema". Numa tela propria, em outro menu,
   so acharia quem ja soubesse que existe.
   ============================================================ */
.card-2fa { margin-top: 18px; }

.cabeca-2fa {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    margin-bottom: 14px;
}

/* O titulo e a explicacao ocupam o meio; o escudo e a pilula seguram as
   pontas. */
.cabeca-2fa > div { flex: 1; min-width: 0; }
.cabeca-2fa h3 { margin: 0; }
.cabeca-2fa .badge { flex: none; margin-top: 3px; }

/* O ESCUDO diz o estado antes da leitura. Verde com o visto = protegida;
   ambar com a exclamacao = so a senha. Cor e desenho mudam JUNTOS - so a cor
   nao serve para quem nao distingue verde de vermelho. */
.escudo-2fa {
    flex: none;
    width: 40px; height: 40px;
    display: grid; place-items: center;
    border-radius: 11px;
}

.escudo-2fa svg { width: 22px; height: 22px; }

.escudo-2fa.ligado {
    background: rgba(5, 150, 105, .1);
    color: var(--ok);
    border: 1px solid rgba(5, 150, 105, .26);
}

.escudo-2fa.desligado {
    background: rgba(180, 83, 9, .1);
    color: var(--warn);
    border: 1px solid rgba(180, 83, 9, .26);
}

/* CINZA, e nao vermelho, para "DESLIGADA". Nao ha nada errado com a conta -
   ha uma protecao opcional que nao foi ligada. Vermelho aqui gritaria erro
   onde existe apenas uma escolha. */
.badge-neutro {
    background: rgba(100, 116, 139, .1);
    color: var(--muted);
    border: 1px solid rgba(100, 116, 139, .24);
}

/* ============================================================
   CARTAO DE RESPOSTA do ticket - o unico lugar da tela onde se AGE

   Acima dele fica a conversa: uma pilha de baloes brancos que so se le.
   Sem distinguir, o cartao de responder era mais um retangulo branco na
   sequencia, e quem abria o ticket rolava procurando "onde eu escrevo?".

   O DESTAQUE E DE MOLDURA, nao de fundo. Fundo colorido atras de um editor
   de texto briga com o proprio texto que se esta escrevendo - e o texto
   aqui vai para o cliente, entao ele precisa aparecer exatamente como vai
   sair. A barra da esquerda e a tinta de fundo bem lavada marcam a area sem
   entrar no caminho.

   Roxo da marca, o mesmo do botao "Enviar resposta": a moldura e o botao
   passam a ler como um bloco so - aqui se escreve, e daqui se envia.
   ============================================================ */
.card-responder {
    border-color: rgba(67, 21, 156, .28);
    border-left: 3px solid var(--brand-soft);
    background:
        linear-gradient(180deg, rgba(67, 21, 156, .045), transparent 120px),
        var(--surface);
}

/* O titulo "Responder" ganha a cor da marca: e o rotulo da area, e em preto
   ele pesava igual aos nomes dos participantes da conversa acima. */
.card-responder > h3 { color: var(--accent-ink); }

/* ============================================================
   RESPOSTA PRONTA - a faixa acima do editor do ticket

   COLADA NO EDITOR, formando uma peca so: faixa com fundo proprio, cantos
   arredondados em cima e SEM borda embaixo, encaixando na barra do Quill.
   Solta, com margem entre as duas, ela parecia um filtro da pagina - e
   filtro de pagina nao se relaciona com o que se escreve logo abaixo.

   Por isso tambem `margin-bottom: -1px`: a borda de baixo desta faixa e a
   de cima da barra do Quill ficariam empilhadas, virando uma linha de 2px
   mais escura no meio do componente.
   ============================================================ */
/* FUNDO TINGIDO DE ROXO, e nao o cinza `--elevated`.
   Com o cinza, a faixa tinha exatamente a mesma cor da barra do Quill logo
   abaixo: as duas viravam um bloco cinza unico e o seletor sumia dentro
   dele. O tom da marca separa as duas na primeira olhada e liga a faixa ao
   resto do destaque do cartao.

   A linha de baixo e SOLIDA e na cor da marca: e a fronteira entre "o que
   escrever" e "como formatar", que era justamente o que faltava. */
.resposta-pronta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px 13px;
    background: rgba(67, 21, 156, .07);
    border: 1px solid rgba(67, 21, 156, .22);
    border-bottom: 2px solid var(--brand-soft);
    border-radius: 9px 9px 0 0;
    margin-bottom: -1px;
}

/* O balao de fala diz "texto pronto" antes de qualquer palavra ser lida.
   Na cor da marca, e nao em cinza: em cinza ele lia como ornamento. */
.resposta-pronta .rp-ico {
    width: 18px;
    height: 18px;
    color: var(--brand-soft);
    flex: none;
}

.resposta-pronta label {
    font-size: 11.5px;
    font-weight: 800;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--accent-ink);
    cursor: pointer;
}

/* CRESCE ate 420px e encolhe quando falta espaco. Titulo de resposta pronta
   e uma frase curta ("Cancelamento confirmado"), nao uma palavra: com
   largura fixa pequena, o campo cortava justamente a parte que distingue um
   texto do outro.

   position: relative porque a lista de resultados e absoluta DENTRO dele -
   ancorada no campo, e nao na pagina, para acompanhar quando a faixa quebra
   em duas linhas no celular. */
.rp-busca {
    position: relative;
    flex: 1 1 240px;
    max-width: 420px;
}

.resposta-pronta .rp-campo {
    width: 100%;
    padding: 8px 30px 8px 12px;   /* 30 a direita: o espaco do X */
    /* BRANCO sobre o fundo tingido: o campo tem de parecer um campo, e nao
       um pedaco da faixa. Era o que faltava para o olho reconhecer que ali
       se escolhe alguma coisa. */
    background: var(--surface);
    border: 1px solid rgba(67, 21, 156, .35);
    border-radius: 8px;
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}

.resposta-pronta .rp-campo::placeholder {
    color: var(--muted);
    font-weight: 500;
}

.resposta-pronta .rp-campo:hover { border-color: var(--brand-soft); }

.resposta-pronta .rp-campo:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(42, 6, 105, .13);
}

.rp-limpar {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);
    width: 22px;
    height: 22px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--muted);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

/* var(--elevated), e nao um rgba de cinza-escuro: no tema escuro o fundo do
   campo JA e escuro, e uma lavagem preta por cima nao aparece. */
.rp-limpar:hover { color: var(--ink); background: var(--elevated); }
.rp-limpar[hidden] { display: none; }

/* ---- A LISTA DE RESULTADOS -------------------------------------------

   z-index alto porque ela cobre a barra do Quill, que vem logo abaixo e tem
   fundo proprio: sem isto os resultados apareciam ATRAS dos botoes de
   negrito e italico.

   max-height com rolagem, e nao lista inteira: o teto de 8 resultados do JS
   ja limita, mas titulo longo quebra em duas linhas e a conta muda. */
.rp-lista {
    position: absolute;
    z-index: 30;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 4px;
    list-style: none;
    max-height: 320px;
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: 0 14px 34px rgba(15, 23, 42, .18);
}

.rp-lista[hidden] { display: none; }

.rp-item {
    display: block;
    padding: 7px 10px;
    border-radius: 7px;
    cursor: pointer;
}

/* UM SO ESTADO para o mouse e para as setas: o JS marca com .rp-item-ativo
   tambem no mouseenter. Com :hover separado, mover o mouse sem querer
   deixava DUAS linhas acesas - e a que o Enter usaria nao era obvia. */
.rp-item-ativo { background: rgba(67, 21, 156, .10); }

.rp-item-titulo {
    display: block;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--ink);
}

/* O trecho do corpo: uma linha so, cortada com reticencias. Duas linhas por
   resultado e a lista inteira ja nao cabe na tela. */
.rp-item-trecho {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* O <mark> do navegador e amarelo-marca-texto e destoa de tudo. Aqui ele
   so precisa dizer "foi por aqui que casou". */
.rp-lista mark {
    background: rgba(67, 21, 156, .16);
    color: inherit;
    border-radius: 3px;
    padding: 0 1px;
    font-weight: 700;
}

/* "Nada encontrado" e "+ N": texto, nao opcao. Sem cursor de clique e sem
   realce, para nao parecer que da para escolher. */
.rp-vazio {
    padding: 8px 10px;
    font-size: 12.5px;
    color: var(--muted);
}

/* A dica some no celular: ali a faixa ja quebra em duas linhas, e uma
   terceira so para explicar o obvio empurraria o editor para baixo. */
.resposta-pronta .rp-dica {
    font-size: 12px;
    color: var(--muted);
}

@media (max-width: 700px) {
    .resposta-pronta .rp-dica { display: none; }

    /* ALVO DE TOQUE. No desktop a linha de 30px e confortavel com o mouse;
       no dedo, nao - o minimo que iOS e Android recomendam e 44px, e a lista
       e usada em pe, no meio do atendimento. O X pelo mesmo motivo.

       Vale a pena tambem porque a busca substituiu um <select>, que no
       celular abria a roda nativa do sistema, com alvos grandes de graca. */
    .rp-item { padding: 12px 10px; }

    .rp-limpar {
        width: 36px;
        height: 36px;
        font-size: 22px;
    }

    .resposta-pronta .rp-campo { padding-right: 40px; }

    /* Menor porque o teclado virtual come metade da tela: com 320px a lista
       nascia atras dele e so o primeiro resultado aparecia. */
    .rp-lista { max-height: 220px; }
}

/* Sem a faixa, o topo do editor volta a ser o canto arredondado da barra do
   Quill; com ela, quem arredonda e a faixa. Sem isto sobraria um canto
   redondo no meio da peca. */
.resposta-pronta + .ql-toolbar.ql-snow { border-radius: 0; }

/* ============================================================
   AJUDA DAS VARIAVEIS (Sistema > Respostas prontas)

   O cartao que ensina a escrever {nome}, {dominio}, {vencimento}. Aparece em
   duas telas: na LISTA como consulta, no FORMULARIO com as chaves clicaveis.
   O mesmo CSS serve as duas - o que muda e so o elemento da chave (<code> ou
   <button>), e por isso `.var-chave` traz a aparencia e `.var-inserir` so
   acrescenta o que e de botao.
   ============================================================ */
.var-ajuda { margin-top: 20px; }

.var-ajuda h3 { margin: 0 0 4px; }

/* O ANTES E DEPOIS lado a lado. E a parte que dispensa a explicacao: quem
   nunca usou entende a ideia sem ler o paragrafo acima. */
.var-exemplo {
    display: flex;
    align-items: center;
    gap: 16px;
    margin: 14px 0 18px;
    padding: 12px 14px;
    background: var(--chip);
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm);
    font-size: 13px;
    line-height: 1.55;
}

.var-exemplo > div { flex: 1 1 0; min-width: 0; }
.var-exemplo p { margin: 4px 0 0; }

.var-exemplo-rotulo {
    display: block;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--muted);
}

.var-exemplo-seta {
    flex: none;
    font-size: 20px;
    color: var(--brand-soft);
}

/* Empilha no celular, e a seta deita: uma seta para a direita entre dois
   blocos empilhados aponta para o vazio. */
@media (max-width: 700px) {
    .var-exemplo { flex-direction: column; align-items: stretch; gap: 10px; }
    .var-exemplo-seta { text-align: center; transform: rotate(90deg); }
}

/* A tabela e de CONSULTA, nao de dados: fonte menor e sem a moldura pesada
   das tabelas de listagem, que aqui competiria com o cartao. */
.var-tabela { font-size: 13px; }
.var-tabela td { padding: 7px 10px; }
.var-tabela th { padding: 8px 10px; }

/* A linha de grupo nao e um dado - e uma divisoria com nome. Fundo tingido e
   maiuscula pequena a separam das quinze linhas de verdade. */
.var-tabela .var-grupo td {
    padding: 10px 10px 4px;
    background: none;
    border-bottom: none;
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--accent-ink);
}

/* A CHAVE tem cara de codigo porque e codigo: monoespacada, tingida, com a
   moldura da marca. E o que faz o olho encontra-la dentro de uma frase
   corrida no exemplo acima. */
.var-chave {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 7px;
    background: rgba(67, 21, 156, .08);
    border: 1px solid rgba(67, 21, 156, .22);
    color: var(--accent-ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px;
    font-weight: 700;
    white-space: nowrap;
}

/* So a versao clicavel ganha cursor e resposta ao toque - o <code> da tela de
   consulta continua sendo texto, e mostrar mao sobre ele prometeria uma acao
   que nao existe. */
.var-inserir {
    cursor: pointer;
    transition: background-color .12s, border-color .12s, transform .06s;
}

.var-inserir:hover {
    background: rgba(67, 21, 156, .16);
    border-color: var(--brand-soft);
}

.var-inserir:active { transform: translateY(1px); }

.var-inserir:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* As armadilhas. Recuo pequeno e linha fina a esquerda: sao avisos, e nao
   uma segunda lista de recursos. */
.var-avisos {
    margin: 16px 0 0;
    padding: 0 0 0 16px;
    border-left: 3px solid var(--line);
    list-style: none;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--muted);
}

.var-avisos li + li { margin-top: 8px; }
.var-avisos b { color: var(--ink); }

.var-avisos code {
    padding: 1px 5px;
    border-radius: 5px;
    background: var(--chip);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12px;
    color: var(--accent-ink);
}

/* NO ESCURO o veu roxo a 8% sobre fundo escuro some, e a chave perde a
   moldura que a distingue do texto. Sobe o veu e clareia a borda - mesma
   correcao das outras pilulas tingidas do sistema. */
[data-tema="escuro"] .var-chave {
    background: rgba(129, 140, 248, .16);
    border-color: rgba(129, 140, 248, .34);
}

[data-tema="escuro"] .var-inserir:hover {
    background: rgba(129, 140, 248, .26);
    border-color: var(--accent);
}

/* ============================================================
   LISTA DE TESTE dos meios de pagamento (Sistema)

   Um <details> RECOLHIDO por padrao. Na operacao normal ninguem usa isto -
   a tela e sobre ligar e desligar -, e tres caixas de texto abertas em tres
   cartoes fariam a decisao principal desaparecer no meio delas. Abre sozinho
   quando ja existe lista, que e quando ha o que ver.
   ============================================================ */
.teste-bloco {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px dashed var(--line);
}

/* Tracejado, e nao solido: separa sem parecer outro cartao. */

.teste-bloco > summary {
    cursor: pointer;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--muted);
    list-style: none;
    display: flex;
    align-items: center;
    gap: 8px;
    user-select: none;
}

.teste-bloco > summary::-webkit-details-marker { display: none; }

/* Triangulo proprio que gira ao abrir. O nativo varia de forma entre
   navegadores e nao aceita cor - com o rotulo em cinza claro, ficava um
   marcador preto puxando mais atencao que o proprio texto. */
.teste-bloco > summary::before {
    content: "";
    width: 0;
    height: 0;
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transition: transform .15s;
}

.teste-bloco[open] > summary::before { transform: rotate(90deg); }

.teste-bloco > summary:hover { color: var(--ink); }

.teste-ajuda {
    margin: 10px 0 8px;
    line-height: 1.6;
}

/* Caixa e botao lado a lado, com o botao alinhado ao FIM: assim ele fica na
   base do textarea em vez de flutuar no meio da altura. */
.teste-form {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 10px;
}

.teste-form textarea {
    flex: 1;
    min-width: 260px;
    max-width: 460px;
    padding: 9px 12px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 9px;
    color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px;
    line-height: 1.5;
    outline: none;
    /* Vertical apenas: na horizontal a caixa sairia do cartao. */
    resize: vertical;
    transition: border-color .15s, box-shadow .15s;
}

.teste-form textarea:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(42, 6, 105, .13);
    background: var(--surface);
}

.teste-aviso { margin: 10px 0 0; }

/* ============================================================
   ADIANTAR FATURA - estado vazio e cartao de previa
   ============================================================ */

/* ESTADO VAZIO. Uma tela que abre sem conteudo precisa dizer o que fazer -
   caso contrario o vazio parece falha de carregamento.

   Largura travada em 460px e centralizada: o texto e curto e, esticado na
   largura de um monitor, viraria uma linha unica de ponta a ponta que o olho
   nao consegue varrer. O `padding-top` empurra o bloco para longe da barra de
   busca de proposito - ele e resposta, nao continuacao dela. */
.vazio {
    max-width: 460px;
    margin: 0 auto;
    padding: 52px 20px 40px;
    text-align: center;
    color: var(--muted);
}

/* Lupa grande e bem apagada: e ilustracao, nao botao. Em cor cheia pareceria
   clicavel e disputaria com o campo de busca logo acima, que e o que a pessoa
   deve usar. */
.vazio-ico {
    width: 46px;
    height: 46px;
    color: var(--faint, rgba(92, 107, 132, .45));
    margin-bottom: 14px;
}

.vazio-titulo {
    margin: 0 0 6px;
    font-size: 16px;
    font-weight: 700;
    color: var(--ink);
}

.vazio-texto {
    margin: 0;
    font-size: 13.5px;
    line-height: 1.65;
}

/* A nota sobre a data fica separada por uma linha porque responde outra
   pergunta: as duas de cima dizem COMO usar, esta diz o que vai acontecer.
   Junto no mesmo paragrafo, o aviso mais importante da tela virava rodape. */
.vazio-nota {
    margin: 18px auto 0;
    padding-top: 16px;
    border-top: 1px solid var(--line-soft, rgba(92, 107, 132, .14));
    font-size: 12.5px;
    line-height: 1.6;
}

/* Cabecalho do cartao: nome + pilula do dominio, separados do corpo por uma
   linha. Sem a linha, o nome do cliente parecia mais um campo entre os
   outros; com ela, ele vira o titulo daquilo tudo. */
.previa-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 12px;
    padding-bottom: 14px;
    margin-bottom: 18px;
    border-bottom: 1px solid var(--line-soft, rgba(92, 107, 132, .14));
}

.previa-head h3 {
    margin: 0;
    font-size: 17px;
}

/* Grade de "rotulo em cima, valor embaixo".
   `auto-fit` com minimo de 200px porque os campos tem larguras muito
   diferentes (um valor em reais e uma data ocupam metade de um e-mail) - com
   colunas fixas, ou o e-mail quebrava ou sobrava um vazio enorme do lado da
   data. Assim o navegador encaixa quantos couberem e reflui sozinho no
   celular, sem media query. */
.previa-dados {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 14px 22px;
    margin: 0 0 18px;
}

.previa-dados dt {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    margin-bottom: 4px;
}

.previa-dados dd {
    margin: 0;
    font-size: 14px;
}

/* O valor e o unico numero que a pessoa confere contra o que combinou com o
   cliente. Tamanho maior e tabular-nums para os algarismos alinharem. */
.previa-dados .valor-forte {
    font-size: 19px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.01em;
}

/* E-mail longo quebra em vez de esticar a coluna e desalinhar a grade. */
.previa-dados .quebra {
    overflow-wrap: anywhere;
}

/* ---- As duas datas, ligadas por uma seta ----------------------------------
   Uma faixa propria, com fundo, separando do resto: as duas datas sao
   CONSEQUENCIA uma da outra, e essa relacao e o que a tela precisa deixar
   claro antes de alguem clicar. Em campos soltos na mesma grade, ninguem
   relacionava - o "vencimento do cliente mudou" so aparecia depois. */
.previa-datas {
    display: flex;
    align-items: stretch;
    flex-wrap: wrap;
    gap: 12px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 14px 16px;
    margin-bottom: 18px;
}

.data-bloco {
    flex: 1;
    min-width: 190px;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.data-rotulo {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
}

.data-valor {
    font-size: 18px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
}

.data-nota {
    font-size: 12px;
    color: var(--muted);
}

/* A data da FATURA e a que o cliente vai ver - as outras sao contexto. Barra
   colorida na lateral em vez de fundo: dentro de uma faixa que ja tem fundo
   proprio, um segundo fundo viraria caixa dentro de caixa. */
.data-fatura {
    border-left: 3px solid var(--accent, #2a0669);
    padding-left: 12px;
}

.data-fatura .data-valor { color: var(--accent, #2a0669); }

/* A seta some no celular: empilhados, os dois blocos ficam um sobre o outro e
   uma seta apontando para a direita passaria a apontar para lugar nenhum. */
.previa-seta {
    display: flex;
    align-items: center;
    color: var(--faint, rgba(92, 107, 132, .45));
}

.previa-seta svg { width: 22px; height: 22px; }

@media (max-width: 700px) {
    .previa-seta { display: none; }
}

/* O botao que executa fica a DIREITA e o de voltar a esquerda: a leitura
   termina no lado direito, e e onde a mao procura a acao. Voltar e saida, nao
   acao - por isso fantasma e do outro lado. */
.previa-acoes {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 10px;
    border-top: 1px solid var(--linha, rgba(92, 107, 132, .16));
    padding-top: 16px;
}

/* Tabelas */

/* ============================================================
   A CAIXA QUE ROLA DE LADO. Criada pelo tabela-responsiva.js em
   volta de toda <table> - por isso nao aparece em template nenhum.

   POR QUE EXISTE. As tabelas eram filhas diretas do <main>, sem
   nada entre elas e a pagina. Abaixo de 860px viram cartoes e
   tudo cabe; acima disso continuam tabela, e a de Cobrancas tem
   VINTE colunas. Num notebook o conteudo passava da largura util
   e o excesso era CORTADO - a coluna Acoes ficava fora do
   alcance, sem barra de rolagem e sem nada dizendo que havia
   mais coisa a direita.

   O RAIO E A SOMBRA MUDAM DE DONO. Eram da <table>; passam para
   a caixa. Numa area que rola, a borda arredondada da tabela
   rolaria junto e sumiria - o canto direito ficaria reto assim
   que a pessoa arrastasse. Na caixa, a moldura fica parada e o
   conteudo desliza por dentro dela.
   ============================================================ */
.tabela-rolavel {
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    /* Sem margem propria: a tabela ja tinha a dela, e duplicar
       afastaria a tabela do bloco de filtros acima. */
    margin: 0;
}

.tabela-rolavel > table {
    box-shadow: none;
    /* A tabela pode passar de 100% aqui dentro - e para isso que a
       caixa existe. O 100% vira PISO: numa tela larga, com poucas
       colunas, ela continua ocupando a linha inteira em vez de
       encolher para o tamanho do texto. */
    min-width: 100%;
}

table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow);
}

th, td { padding: 11px 14px; text-align: left; font-size: 13.5px; border-bottom: 1px solid var(--line-soft); }

th {
    background: var(--elevated);
    /* --ink, e nao --muted. A --muted (#5c6b84) sobre o --elevated (#f8fafc) e
       cinza claro sobre quase branco: em 11px, maiusculas e espacado, o rotulo
       da coluna quase desaparecia no fundo. O cabecalho e a legenda da tabela
       inteira - se ele custa esforco para ler, toda a leitura abaixo custa. */
    color: var(--ink);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* ============================================================
   CABECALHO FIXO ao rolar (desktop).
   Em lista de 100 linhas voce perde a referencia das colunas na
   linha 30 e precisa subir para conferir. Grudado no topo, logo
   abaixo da navbar, o cabecalho continua na tela.
   O tom solido e obrigatorio: com fundo transparente as linhas
   apareceriam ATRAS do cabecalho ao rolar.
   ============================================================ */
@media (min-width: 861px) {
    thead th {
        position: sticky;
        top: var(--topo-h);              /* faixa da marca + menu */
        z-index: 5;
        background: var(--line-soft);             /* solido, nao var(--elevated) translucido */
        box-shadow: inset 0 -1px 0 var(--line);
    }
    /* a tabela precisa deixar o sticky "escapar" */
    table { overflow: visible; }
    /* como o overflow saiu, o arredondado volta pelas pontas */
    thead tr:first-child th:first-child { border-top-left-radius: var(--radius); }
    thead tr:first-child th:last-child { border-top-right-radius: var(--radius); }
    tbody tr:last-child td:first-child { border-bottom-left-radius: var(--radius); }
    tbody tr:last-child td:last-child { border-bottom-right-radius: var(--radius); }

    /* ------------------------------------------------------------
       TABELA DENTRO DE CARD: o offset da pagina NAO vale aqui.

       O `top` de um elemento sticky e medido a partir do ancestral
       que rola. Numa tabela solta na pagina, quem rola e a janela e
       --topo-h (a faixa da marca + menu) e o offset certo. Dentro de
       um card com rolagem propria, quem rola e o card - e o mesmo
       --topo-h grudava o cabecalho 158px ABAIXO do topo do card, ou
       seja, no meio das linhas. Era o cabecalho aparecendo no meio
       da tabela em Relatorios > Fechamento.
       ------------------------------------------------------------ */
    .card thead th { position: static; }

    /* Card que rola sozinho: gruda no topo do PROPRIO card.
       Depois da regra acima de proposito - mesma especificidade,
       vence a ultima. */
    .card-scroll thead th { position: sticky; top: 0; }
}

tbody tr { transition: background .12s; }
/* Zebrado: cor sim, cor nao */
tbody tr:nth-child(even) { background: var(--zebra); }

/* Hover bem visivel na linha (vale tambem sobre o zebrado) */
tbody tr:hover,
tbody tr:nth-child(even):hover { background: rgba(42, 6, 105, .16); }
tr:last-child td { border-bottom: none; }

/* Linha de referencia numa tabela ordenada (ex.: o mes vigente no fechamento).
   Marca a esquerda em vez de fundo colorido: o zebrado ja usa fundo, e duas
   regras de fundo brigando deixariam a linha destacada mais clara que a vizinha
   dependendo da posicao dela na lista. */
tbody tr.linha-destaque,
tbody tr.linha-destaque:nth-child(even) { background: rgba(42, 6, 105, .07); }
tbody tr.linha-destaque td:first-child { box-shadow: inset 3px 0 0 var(--roxo, #2a0669); }

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }

/* Estrela de cliente novo (assinante ha menos de 30 dias) */
.star { color: #f59e0b; font-size: 16px; line-height: 1; cursor: default; }

/* Link de dominio (abre em nova aba) */
.domain-link { color: var(--accent); text-decoration: none; font-weight: 500; }
.domain-link:hover { text-decoration: underline; }
.msg { color: var(--muted); max-width: 320px; }
.muted { color: var(--muted); }
.small { font-size: 12px; }

/* Badges */
.badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .03em;
    /* A pilula NAO pode quebrar: "VPS ICP", "VPS LINUX" e "VPS CPANEL" tem
       espaco e, numa coluna estreita, partiam em duas linhas - o border-radius
       de 999px em duas linhas vira uma capsula torta. */
    white-space: nowrap;
    vertical-align: middle;
}

/* Duas pilulas na mesma celula (ex.: servidor + data center) precisam de ar
   entre elas - encostadas, parecem uma so cortada ao meio. */
.badge + .badge { margin-left: 5px; }

.badge-us { background: rgba(42, 6, 105, .09); color: var(--accent-ink); border: 1px solid rgba(42, 6, 105, .25); }
.badge-ca { background: rgba(220, 38, 38, .08); color: var(--err); border: 1px solid rgba(220, 38, 38, .22); }
/* Reino Unido: azul, para nao se confundir com o roxo dos EUA nem com o
   vermelho do Canada numa lista onde os tres aparecem misturados. */
.badge-uk { background: rgba(37, 99, 235, .09); color: #1d4ed8; border: 1px solid rgba(37, 99, 235, .28); }
.badge-ok { background: rgba(5, 150, 105, .09); color: var(--ok); border: 1px solid rgba(5, 150, 105, .24); }
.badge-err { background: rgba(220, 38, 38, .08); color: var(--err); border: 1px solid rgba(220, 38, 38, .22); }
.badge-q { background: rgba(180, 83, 9, .09); color: var(--warn); border: 1px solid rgba(180, 83, 9, .24); }

/* Alerta de reassinatura (/assinaturas): fica colado ao nome do cliente, entao
   precisa de respiro a esquerda e nao pode quebrar a linha da tabela. */
.alerta-reassinatura {
    margin-left: 6px;
    white-space: nowrap;
    cursor: help;
}

/* Contador de reincidencia dentro da pilula ("2x", "3x").
   Fundo solido em vez de so negrito: dentro de uma pilula que ja e vermelha
   clara, negrito quase nao se separa do resto do texto. */
.alerta-vezes {
    display: inline-block;
    margin-left: 4px;
    padding: 0 5px;
    border-radius: 999px;
    background: var(--err);
    color: #fff;
    font-weight: 700;
    font-size: .92em;
    line-height: 1.5;
}

/* Badges de modelo do cliente (tipo_host + painel) */
/* A coluna do modelo se ajusta ao conteudo, em vez de espremer a pilula */
td:has(> .badge-icp), td:has(> .badge-linux), td:has(> .badge-cpanel),
td:has(> .badge-shared), td:has(> .badge-mail), td:has(> .badge-other) { width: 1%; white-space: nowrap; }

/* ============================================================
   PROVEDOR na aba "Todos" de Congelar/Descongelar.

   UMA COR POR PROVEDOR, e nao uma so para "e VPS". A aba mistura os quatro
   em 50 linhas: a cor e o que deixa varrer a lista com o olho, e ler quatro
   rotulos parecidos linha a linha e justamente o que a coluna existe para
   evitar. Os quatro matizes ficam bem separados na roda de cores (roxo 272,
   azul 224, ciano 193, verde 163), entao nao se confundem nem de relance.

   "Sem provedor" sai em VERMELHO, e nao em cinza: nao e falta de informacao,
   e cadastro quebrado - o botao ao lado esta desabilitado por causa dele.
   O tom e #b91c1c e nao o #dc2626 dos outros vermelhos porque sobre o veu
   de 9% aquele da 4,19:1, abaixo do minimo; este da 5,58:1.

   No escuro vale a mesma inversao do resto do arquivo (tinta clara + veu
   mais forte), pelo mesmo motivo: tinta escura some dentro do veu.
   ============================================================ */
.badge-prov-cpanel   { background: rgba(126, 34, 206, .10); color: #7e22ce; border: 1px solid rgba(126, 34, 206, .28); }
.badge-prov-contabo  { background: rgba(14, 116, 144, .10); color: #0e7490; border: 1px solid rgba(14, 116, 144, .28); }
.badge-prov-leaseweb { background: rgba(4, 120, 87, .10);   color: #047857; border: 1px solid rgba(4, 120, 87, .28); }
.badge-prov-ovh      { background: rgba(29, 78, 216, .10);  color: #1d4ed8; border: 1px solid rgba(29, 78, 216, .28); }
.badge-prov-sem      { background: rgba(185, 28, 28, .09);  color: #b91c1c; border: 1px solid rgba(185, 28, 28, .30); }

[data-tema="escuro"] .badge-prov-cpanel   { background: rgba(216, 180, 254, .20); color: #d8b4fe; border-color: rgba(216, 180, 254, .34); }
[data-tema="escuro"] .badge-prov-contabo  { background: rgba(103, 232, 249, .20); color: #67e8f9; border-color: rgba(103, 232, 249, .34); }
[data-tema="escuro"] .badge-prov-leaseweb { background: rgba(110, 231, 183, .20); color: #6ee7b7; border-color: rgba(110, 231, 183, .34); }
[data-tema="escuro"] .badge-prov-ovh      { background: rgba(147, 197, 253, .20); color: #93c5fd; border-color: rgba(147, 197, 253, .34); }
[data-tema="escuro"] .badge-prov-sem      { background: rgba(252, 165, 165, .20); color: #fca5a5; border-color: rgba(252, 165, 165, .34); }

.badge-icp    { background: rgba(42, 6, 105, .09); color: var(--accent-ink); border: 1px solid rgba(42, 6, 105, .25); }
.badge-linux  { background: rgba(8, 145, 178, .09); color: #0e7490; border: 1px solid rgba(8, 145, 178, .25); }
.badge-cpanel { background: rgba(147, 51, 234, .08); color: #7e22ce; border: 1px solid rgba(147, 51, 234, .22); }
.badge-shared { background: rgba(92, 107, 132, .09); color: var(--muted); border: 1px solid rgba(92, 107, 132, .22); }

/* NF-e (Cobrancas > Pagas): AMBAR, a cor de "tem coisa a fazer" no resto do
   sistema. No legado esta celula era um fundo #FFD700 chapado com um icone de
   recibo - berrante demais para uma lista de 100 linhas, mas o amarelo era
   deliberado e vale manter a familia da cor.
   Nao usa verde nem vermelho de proposito: nao e sucesso nem erro, e uma
   pendencia - alguem ainda precisa emitir a nota. */
.badge-nfe { background: rgba(180, 83, 9, .10); color: #92400e; border: 1px solid rgba(180, 83, 9, .28); }
.badge-mail   { background: rgba(180, 83, 9, .09); color: var(--warn); border: 1px solid rgba(180, 83, 9, .24); }
.badge-other  { background: rgba(148, 163, 184, .12); color: var(--faint); border: 1px solid rgba(148, 163, 184, .3); }

/* ------------------------------------------------------------------
   Prioridade do ticket: um <select> que ja parece a pilula da cor certa,
   trocavel sem sair da linha.
   ------------------------------------------------------------------ */
.form-prioridade { display: inline-flex; align-items: center; gap: 6px; }

.prioridade {
    appearance: none;
    padding: 3px 22px 3px 10px;
    border-radius: 999px;
    font-family: inherit;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .03em;
    text-transform: uppercase;
    cursor: pointer;
    /* seta desenhada em CSS: <select> sem appearance perde a nativa */
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 12px) 52%, calc(100% - 8px) 52%;
    background-size: 4px 4px, 4px 4px;
    background-repeat: no-repeat;
}

.prioridade:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* TEXTO PROPRIO, e nao `var(--err)`.

   O --err (#dc2626) foi escolhido para texto sobre BRANCO, onde da 4,8:1.
   Aqui ele fica sobre o proprio vermelho a 10%, e cai para 4,13:1 - reprova.
   Um tom abaixo resolve sem mudar a leitura da cor. O mesmo vale para a alta
   logo abaixo. */
.badge-prio-urgente { background: rgba(220, 38, 38, .10);  color: #c81e1e;     border: 1px solid rgba(220, 38, 38, .34); }
.badge-prio-alta    { background: rgba(180, 83, 9, .10);   color: #a54a06;     border: 1px solid rgba(180, 83, 9, .30); }
/* Neutra e o padrao: cinza de proposito, para so o que foi classificado
   chamar atencao na lista. */
/* A ESCALA GIROU, e o motivo foi ela nao funcionar.

   A primeira versao punha MEDIA num ambar (#a16207) logo abaixo do laranja da
   ALTA (#b45309), "na mesma familia para as duas se lerem como vizinhas". Na
   tela isso nao aconteceu: numa pilula pequena, com fundo a 10% de opacidade,
   a diferenca de matiz some e sobra o texto - e aqueles dois hex estao a um
   passo um do outro. As duas prioridades viravam a mesma cor.

   AMARELO NAO TEM SAIDA. Para passar em contraste sobre fundo claro ele
   escurece ate virar marrom, que e onde o laranja ja esta. Insistir na
   "escala quente" so produziria a mesma colisao com outro hex.

   Entao a escala passou a ser de ATENCAO, e nao de temperatura:

     URGENTE  vermelho   - para agora
     ALTA     laranja    - hoje
     MEDIA    azul       - a fila normal
     BAIXA    ardosia    - quando der

   Quatro familias diferentes, distinguiveis de relance mesmo em pilula de
   11px. E o degrade continua fazendo sentido: o olho pousa no vermelho, depois
   no laranja, e o cinza da baixa RECUA - que e o certo, porque baixa e a
   maioria dos chamados (hospedagem e VPS Linux) e nao deve competir por
   atencao numa lista de cinquenta linhas. */
.badge-prio-media   { background: rgba(37, 99, 235, .09);  color: #1d4ed8;     border: 1px solid rgba(37, 99, 235, .26); }

/* Mantida so para nao quebrar uma linha antiga gravada como 'NEUTRA' que
   escape da conversao. Nao usar em codigo novo. */
.badge-prio-neutra  { background: var(--bg);               color: var(--muted); border: 1px solid var(--line); }

/* SO PARA LEITOR DE TELA: sai do fluxo sem `display:none`, que o leitor pula.

   Existe por causa do ponto da prioridade definida a mao: ele e um simbolo
   dentro de um `title`, e `title` em <span> nao e anunciado de forma confiavel
   por leitor de tela nenhum. O texto equivalente tem de estar no documento.

   Um retangulo de 1px com `clip-path` e a tecnica que funciona em todos os
   leitores; `text-indent` negativo quebra em RTL e `opacity:0` deixa o
   elemento ocupando espaco. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* O LAPIS que marca a prioridade decidida a mao.

   Discreto de proposito: e uma nota de rodape ao lado do dado, nao um segundo
   dado. A coluna e estreita e quem varre a fila esta lendo o NIVEL - a origem
   dele so importa quando a pessoa para naquela linha.

   Sem `margin-left`: o elemento vive dentro do `.form-prioridade`, que ja e
   `inline-flex` com `gap: 6px`. Era exatamente o que faltava na versao
   anterior, em que o ponto ficava fora do form e a largura do select o
   empurrava para longe da pilula. */
.prio-mao {
    display: inline-flex;
    align-items: center;
    color: var(--faint);
    cursor: help;
}
.prio-mao .ico {
    width: 13px;
    height: 13px;
    display: block;
}
/* Acende ao passar o mouse na linha inteira: em repouso ele nao deve competir
   com o nivel; quando a pessoa para naquela linha, deve estar la. */
tbody tr:hover .prio-mao { color: var(--accent); }
/* BAIXA em VERDE - e o degrade fica completo.

   Ela passou por tres cores nesta conversa, e cada troca teve motivo:
   era azul, cedeu o azul para a media, virou ardosia (um azul dessaturado,
   perto demais do azul que acabara de ceder), depois cinza neutro, e agora
   verde.

   O verde e melhor que o cinza por dizer alguma coisa em vez de so recuar:
   numa escala de atencao, ele e o "nada pegando fogo aqui". A leitura fica a
   de semaforo, que ninguem precisa aprender - vermelho, laranja, azul da fila
   normal, verde de tranquilo.

   #0a7a31, e nao o #16a34a: o tom base da a 2,96:1 sobre o proprio fundo a
   10% e reprova. Este e o mesmo verde que o sistema ja usa em "Pagamento
   confirmado", entao nao entra cor nova no projeto. */
.badge-prio-baixa   { background: rgba(22, 163, 74, .10);  color: #0a7a31;    border: 1px solid rgba(22, 163, 74, .28); }

/* Departamentos do ticket. Sete cores distintas: numa lista de cancelamentos
   misturada com suporte, a cor separa antes de ler. */
td:has(> .badge-cat-suporte), td:has(> .badge-cat-financeiro),
td:has(> .badge-cat-comercial), td:has(> .badge-cat-cancelamento),
td:has(> .badge-cat-ouvidoria), td:has(> .badge-cat-seguranca),
td:has(> .badge-cat-plano),
td:has(> .badge-cat-abertura-email) { width: 1%; white-space: nowrap; }

/* Maiuscula igual a pilula de STATUS, que fica na coluna ao lado */
[class*="badge-cat-"] { text-transform: uppercase; }

.badge-cat-suporte      { background: rgba(8, 145, 178, .09);  color: #0e7490; border: 1px solid rgba(8, 145, 178, .25); }
.badge-cat-financeiro   { background: rgba(5, 150, 105, .09);  color: var(--ok); border: 1px solid rgba(5, 150, 105, .24); }
.badge-cat-comercial    { background: rgba(37, 99, 235, .09);  color: #1d4ed8; border: 1px solid rgba(37, 99, 235, .28); }
.badge-cat-cancelamento { background: rgba(220, 38, 38, .08);  color: var(--err); border: 1px solid rgba(220, 38, 38, .22); }
.badge-cat-ouvidoria    { background: rgba(147, 51, 234, .08); color: #7e22ce; border: 1px solid rgba(147, 51, 234, .22); }
.badge-cat-seguranca    { background: rgba(180, 83, 9, .09);   color: var(--warn); border: 1px solid rgba(180, 83, 9, .24); }
.badge-cat-plano        { background: rgba(42, 6, 105, .09);   color: var(--accent-ink); border: 1px solid rgba(42, 6, 105, .25); }

/* ABERTURA E-MAIL - a unica categoria que nao veio do legado.
   Faltava a regra, e por isso o rotulo aparecia como texto solto no meio de
   uma coluna de pilulas: o `classeCss()` gerava `badge-cat-abertura-email` e
   nada casava com ela.

   TEAL PASTEL: e a faixa que sobrou. Ciano ja e o suporte, verde o financeiro,
   azul o comercial, vermelho o cancelamento, roxo a ouvidoria e o plano,
   ambar a seguranca. Duas categorias com a mesma cor numa coluna que se le de
   relance seria pior do que nao ter cor. */
.badge-cat-abertura-email {
    background: rgba(13, 148, 136, .09);
    color: #0f766e;
    border: 1px solid rgba(13, 148, 136, .26);
}

/* Botoes */
.btn {
    border: none;
    border-radius: 9px;
    padding: 8px 16px;
    cursor: pointer;
    font-family: inherit;
    font-weight: 600;
    font-size: 13px;
    color: #fff;
    transition: filter .15s, transform .05s;
}

.btn:hover { filter: brightness(1.08); }

/* Botao desativado: apagado e sem reagir ao mouse. O `filter` do hover acima
   e global, entao sem esta regra um botao desabilitado ainda "acenderia" ao
   passar o mouse e pareceria clicavel. */
.btn:disabled,
.btn[disabled] {
    opacity: .45;
    cursor: not-allowed;
    filter: none;
}
.btn:disabled:hover,
.btn[disabled]:hover { filter: none; }
.btn:disabled:active,
.btn[disabled]:active { transform: none; }
.btn:active { transform: translateY(1px); }

.btn-start { background: linear-gradient(135deg, #43159C, #2A0669); box-shadow: 0 4px 14px rgba(42, 6, 105, .28); }
.btn-stop { background: linear-gradient(135deg, #ef4444, #dc2626); box-shadow: 0 4px 14px rgba(220, 38, 38, .22); }
/* Confirmacao de pagamento recebido: verde, para nao se confundir com as demais acoes */
.btn-pago { background: linear-gradient(135deg, #10b981, #059669); box-shadow: 0 4px 14px rgba(5, 150, 105, .24); }

.btn-ghost {
    background: transparent;
    border: 1px solid var(--line);
    color: var(--muted);
    box-shadow: none;
}
.btn-ghost:hover { color: var(--ink); border-color: var(--faint); }
.btn-sm { padding: 6px 13px; font-size: 12.5px; }

/* ============================================================
   VARIANTES DE ACAO EM LISTA
   ============================================================ */

/* SOFT - a acao IRMA da principal.
   Mesmo roxo do .btn-start, mas preenchido com um tom claro. Serve quando
   duas acoes sao do mesmo tipo e uma e a mais comum: as duas se leem como
   parentes, e a hierarquia aparece sem uma delas virar cinza.
   O .btn-ghost nao servia aqui - cinza e a cor de "secundario generico", e
   fazia "Liberar Cloud" parecer menos importante do que e. */
.btn-soft {
    background: rgba(42, 6, 105, .09);
    color: var(--brand);
    border: 1px solid rgba(42, 6, 105, .22);
    box-shadow: none;
}
.btn-soft:hover {
    background: rgba(42, 6, 105, .15);
    border-color: rgba(42, 6, 105, .38);
    filter: none;
}

/* PERIGO DISCRETO - contorno vermelho que so preenche no hover.
   Acao destrutiva pouco usada nao precisa de bloco vermelho solido
   competindo com a acao principal em toda linha da tabela; precisa e ficar
   inconfundivel no momento em que a pessoa vai nela. */
.btn-danger-ghost {
    background: transparent;
    color: var(--err);
    border: 1px solid rgba(220, 38, 38, .38);
    box-shadow: none;
}
.btn-danger-ghost:hover {
    background: var(--err);
    color: #fff;
    border-color: var(--err);
    filter: none;
}

/* ESPACO ENTRE AS ACOES DA LINHA.
   A celula nao tinha regra nenhuma e os botoes ficavam encostados - o que
   parece um controle so, e aumenta a chance de clicar no vizinho.
   `margin` e nao `flex`: a classe .acoes e usada em sete telas com conteudos
   diferentes, e trocar o display de todas elas por causa desta mudaria
   alinhamento em lugares que ninguem pediu. */
td.acoes > * + * { margin-left: 6px; }

/* ACOES QUE NAO PODEM QUEBRAR EM DUAS LINHAS.
   Usada nas tres telas do menu Site, onde sao tres icones fixos.

   O sintoma sem isto: a coluna "Acoes" recebe a largura que sobra da tabela,
   e quando sobra pouco os tres icones viram 2 + 1 - o terceiro cai sozinho
   embaixo, desalinhado. Numa lista de 35 linhas isso e um serrilhado que muda
   de forma a cada linha.

   `white-space: nowrap` na celula e o suficiente: os botoes sao inline-flex e
   os formularios que os envolvem sao `display: inline`, entao o que os
   separava era espaco em branco - e sem quebra o navegador passa a exigir a
   largura dos tres para a coluna, em vez de espremer.

   NAO vai em `td.acoes` direto de proposito: a classe e usada em sete telas, e
   ha uma (Cobrancas) com cinco acoes na linha, onde quebrar e o comportamento
   desejado. Forcar tudo numa linha la roubaria largura das colunas de valor.

   So acima de 860px. Abaixo disso a tabela vira cartao e `.cel-acoes` ja
   trata a celula como flex com quebra - que e o certo no celular, onde os
   botoes ocupam a largura toda. */
@media (min-width: 861px) {
    td.acoes.uma-linha { white-space: nowrap; }
}

.inline { display: inline; }

/* ============================================================
   CARD DA TRAVA DE EDICAO (Clientes > editar).
   Verde discreto: e uma confirmacao de que esta tudo certo, nao um
   alerta. O ponto pulsa devagar para dizer "isto esta ativo agora".
   ============================================================ */
.lock-card {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    background: rgba(5, 150, 105, .06);
    border: 1px solid rgba(5, 150, 105, .28);
    border-radius: 12px;
    padding: 13px 16px;
    margin: 0 0 16px;
}
.lock-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #059669;
    flex: 0 0 auto;
    margin-top: 5px;
    animation: lock-pulse 2.4s ease-in-out infinite;
}
.lock-texto { display: flex; flex-direction: column; gap: 3px; }
.lock-texto b { color: #047857; font-size: 14px; }
.lock-texto .small { line-height: 1.5; }

@keyframes lock-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(5, 150, 105, .45); }
    50%      { box-shadow: 0 0 0 5px rgba(5, 150, 105, 0); }
}

/* Quem prefere menos movimento na tela nao ve a animacao */
@media (prefers-reduced-motion: reduce) {
    .lock-dot { animation: none; }
}

/* ============================================================
   BLOCO DE CANCELAMENTO (Clientes > editar).
   Vermelho discreto: e uma acao com consequencia, nao um erro.
   ============================================================ */
.cancel-box {
    background: rgba(220, 38, 38, .05);
    border: 1px solid rgba(220, 38, 38, .26);
    border-radius: 12px;
    padding: 14px 16px;
    margin-top: 14px;
}
.cancel-box.registrado {
    background: rgba(92, 107, 132, .06);
    border-color: rgba(92, 107, 132, .28);
}
.cancel-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}
.cancel-head b { color: var(--err); font-size: 14px; }
.cancel-box.registrado .cancel-head b { color: var(--ink); }

/* Consequencia colateral do cancelamento: as cobrancas que serao derrubadas.
   Dentro da caixa vermelha, mas com fundo proprio - e a parte que a pessoa
   precisa CONFERIR antes de salvar, nao mais um paragrafo de explicacao. */
.cancel-aviso {
    margin-top: 12px;
    padding: 11px 13px;
    border-radius: var(--radius-sm);
    background: var(--surface);
    border: 1px solid rgba(220, 38, 38, .3);
}
.cancel-aviso > b { display: block; color: var(--err); font-size: 13.5px; }
.cancel-aviso ul { margin: 8px 0; padding-left: 18px; }
.cancel-aviso li { font-size: 13px; margin: 3px 0; }

/* Linha que falhou no lote: fica na lista, destacada, para ser reprocessada */
.linha-falha { background: rgba(220, 38, 38, .06); }
.linha-falha:hover { background: rgba(220, 38, 38, .1); }

/* Numeracao da lista "enviar cobrancas do mes": a cor diz se o cliente esta
   ativo, como no legado (verde/vermelho na primeira coluna). */
.ordem { text-align: center; font-weight: 500; color: #fff; width: 44px; }
.ordem.ativo { background: #15803d; }
.ordem.inativo { background: #b91c1c; }

/* ============================================================
   ACOES EM ICONE (coluna Acoes das listagens).
   Quatro botoes com texto ocupavam mais da metade da largura util
   da tabela; em icone cabem no lugar de um. O que cada um faz
   continua acessivel pelo title (mouse) e pelo aria-label (leitor
   de tela) - icone sozinho, sem rotulo, nao pode ser a unica pista.
   ============================================================ */
.btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface);
    color: var(--muted);
    cursor: pointer;
    vertical-align: middle;
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.btn-icon + .btn-icon,
.btn-icon + form.inline,
form.inline + .btn-icon,
form.inline + form.inline { margin-left: 4px; }

.btn-icon .ico { width: 17px; height: 17px; display: block; }
.btn-icon:hover { background: var(--elevated); color: var(--ink); border-color: var(--faint); }
.btn-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.btn-icon:disabled { opacity: .4; cursor: not-allowed; }
.btn-icon:disabled:hover { background: var(--surface); color: var(--muted); border-color: var(--line); }

/* Cor so no hover: a linha fica calma, a acao se identifica ao passar o mouse */
.btn-icon.acao-gerar:hover  { color: #2A0669; background: rgba(42, 6, 105, .09);  border-color: rgba(42, 6, 105, .38); }
.btn-icon.acao-email:hover  { color: #0e7490; background: rgba(14, 116, 144, .09); border-color: rgba(14, 116, 144, .38); }
.btn-icon.acao-editar:hover { color: var(--ink); }
.btn-icon.acao-ver:hover    { color: #2A0669; background: rgba(42, 6, 105, .09); border-color: rgba(42, 6, 105, .38); }
.btn-icon.acao-categoria:hover { color: #7e22ce; background: rgba(147, 51, 234, .09); border-color: rgba(147, 51, 234, .34); }
.btn-icon.acao-plano:hover     { color: #059669; background: rgba(5, 150, 105, .09);  border-color: rgba(5, 150, 105, .38); }
/* Link da Central de Pagamento: mesmo azul do reenvio por e-mail, porque e a
   mesma acao vista de outro angulo - mandar o link de pagamento ao cliente. */
.btn-icon.acao-link:hover      { color: #0e7490; background: rgba(14, 116, 144, .09); border-color: rgba(14, 116, 144, .38); }

/* Links ATIVOS (ver e cassar). Ambar, e nao vermelho: o botao so ABRE uma
   lista - quem destroi e o botao vermelho de dentro do modal. Vermelho aqui
   prometeria estrago no clique e faria hesitar justamente quem deveria estar
   conferindo isso de rotina. Ambar diz "atencao", que e o certo. */
.btn-icon.acao-link-off:hover  { color: #b45309; background: rgba(180, 83, 9, .09); border-color: rgba(180, 83, 9, .40); }

/* Excluir e destrutivo: neutro em repouso, vermelho ao passar o mouse.
   Vermelho o tempo todo, numa coluna com 5 acoes, vira alarme de fundo. */
.btn-icon.acao-excluir:hover { color: #dc2626; background: rgba(220, 38, 38, .09); border-color: rgba(220, 38, 38, .42); }

/* ---- MENU SITE: publicar / tirar do ar ----
   O par que liga e desliga um plano, banner ou destaque na pagina publica.

   Cor so no hover, como a lixeira e ao contrario do acao-pago: sao os botoes
   MAIS clicados destas telas, e verde ou ambar permanentes numa lista de 35
   linhas viram parede colorida - o olho para de distinguir qualquer coisa.

   Verde para publicar, ambar para tirar do ar. Ambar e nao vermelho de
   proposito: vermelho, ao lado de uma lixeira que tambem fica vermelha, faria
   os dois botoes parecerem a mesma familia de risco. Tirar do ar se desfaz num
   clique; excluir, nao. */
.btn-icon.acao-publicar:hover { color: #059669; background: rgba(5, 150, 105, .10); border-color: rgba(5, 150, 105, .40); }
.btn-icon.acao-ocultar:hover  { color: #b45309; background: rgba(180, 83, 9, .10);  border-color: rgba(180, 83, 9, .40); }

/* ---- Link do cliente (coluna Acoes dos tickets) ----
   Verde parado, e nao so no hover: e a unica acao da coluna que gera algo para
   ENVIAR ao cliente, e e procurada de relance numa lista de 50 linhas.

   O botao ABRE O BALAO do link; nao copia mais em silencio. A confirmacao
   verde que existia aqui (.acao-token.btn-copiar-ok) saiu junto - quem copia
   agora e o botao de dentro do balao, e a confirmacao acontece la. */
.btn-icon.acao-token {
    width: 32px;
    height: 32px;
    border: 1px solid rgba(5, 150, 105, .38);
    border-radius: 9px;
    background: var(--surface);
    color: #059669;
    opacity: 1;
}
.btn-icon.acao-token .ico { width: 17px; height: 17px; }
.btn-icon.acao-token:hover {
    color: #047857;
    background: rgba(5, 150, 105, .12);
    border-color: rgba(5, 150, 105, .6);
}

/* Confirmar pagamento mexe em dinheiro: fica verde o tempo todo */
.btn-icon.acao-pago { color: #059669; border-color: rgba(5, 150, 105, .38); }
.btn-icon.acao-pago:hover { color: #047857; background: rgba(5, 150, 105, .12); border-color: rgba(5, 150, 105, .6); }

/* CANCELAR O CLIENTE pela linha da cobranca: vermelho o tempo todo, e nao so
   no hover como a lixeira.

   A diferenca de tratamento e proposital e vale a pena explicar. Excluir uma
   cobranca apaga UMA linha e o cliente continua ali; este botao encerra o
   CLIENTE - derruba todas as cobrancas em aberto, grava churn e muda a
   situacao do cadastro. Cor permanente e o unico jeito de o olho separar os
   dois antes do clique, ja que eles ficam a poucos pixels de distancia na
   mesma coluna.

   Desabilitado (cliente ainda nao congelado) ele perde a cor junto com o
   `.btn-icon:disabled` la de cima: continua vermelho, so que apagado - o que
   diz "aqui teria uma acao" sem convidar a tentar. */
.btn-icon.acao-cancelar {
    color: #dc2626;
    border-color: rgba(220, 38, 38, .45);
    background: rgba(220, 38, 38, .06);
}
.btn-icon.acao-cancelar:hover:not(:disabled) {
    color: #fff;
    background: #dc2626;
    border-color: #dc2626;
}
[data-tema="escuro"] .btn-icon.acao-cancelar {
    color: #fca5a5;
    border-color: rgba(248, 113, 113, .45);
    background: rgba(248, 113, 113, .12);
}
[data-tema="escuro"] .btn-icon.acao-cancelar:hover:not(:disabled) {
    color: #1a2130;
    background: #fca5a5;
    border-color: #fca5a5;
}

/* ============================================================
   SWITCH em card (avisos por WhatsApp).

   O card inteiro e <label>: clicar em qualquer ponto marca a opcao.
   Um checkbox de 13px como alvo unico e cruel no celular.
   ============================================================ */
.switch-card {
    display: flex;
    align-items: flex-start;
    gap: 13px;
    padding: 13px 15px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--elevated);
    cursor: pointer;
    transition: border-color .15s, background .15s;
}

/* ============================================================
   PENDENCIA: o card fica vermelho enquanto a liberacao nao saiu.

   Cliente "aguardando liberacao" e cobrado do mesmo jeito - a
   cobranca do mes nasce sozinha. Um cadastro que fica assim por
   esquecimento vira o pior caso possivel: o cliente paga e nao
   recebe. A borda existe para essa ficha nao passar despercebida
   entre as dezenas que se abre num dia.

   SO A BORDA E O TRILHO, sem fundo colorido: o card continua com o
   fundo dos demais, e o rotulo com o contraste de sempre. Fundo
   tingido faria o bloco parecer um erro que aconteceu; a borda diz
   "falta fazer isto" sem gritar, que e o que se quer de uma
   pendencia. Texto vermelho, pelo mesmo motivo, tambem nao.

   Some sozinho: o `switch-card-alerta` sai no mesmo instante em
   que a chave e marcada, pelo JS do formulario.
   ============================================================ */
.switch-card-alerta {
    border-color: var(--err);
}

/* O TRILHO TAMBEM. Desligado, o padrao dele e o cinza de `--line` - a
   mesma cor de qualquer borda da tela, que num card ja vermelho passa
   por "campo neutro" em vez de "falta fazer isto".

   `input` sem `:checked` de proposito: quando alguem marca a chave a
   mao, o trilho volta ao verde no mesmo instante, junto com a borda -
   os dois sinais contam a mesma historia, e nao meia cada um. */
.switch-card-alerta input:not(:checked) + .switch-trilho {
    background: var(--err);
}
/* O checkbox some da vista mas continua no DOM: e ele que envia o valor,
   recebe o foco do teclado e responde ao espaco. Nada de display:none,
   que o tiraria da ordem de tabulacao. */
.switch-card input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}
.switch-trilho {
    flex: none;
    width: 42px;
    height: 24px;
    border-radius: 999px;
    background: var(--line);
    position: relative;
    transition: background .15s;
    margin-top: 1px;
}
.switch-trilho i {
    position: absolute;
    top: 3px;
    left: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: 0 1px 2px rgba(15, 23, 42, .3);
    transition: transform .15s;
}
.switch-card input:checked + .switch-trilho { background: var(--ok); }
.switch-card input:checked + .switch-trilho i { transform: translateX(18px); }
.switch-card input:focus-visible + .switch-trilho {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
.switch-texto { display: flex; flex-direction: column; gap: 3px; }
.switch-texto b { font-size: 14px; }
.switch-card:has(input:checked) { border-color: rgba(5, 150, 105, .45); }

/* ============================================================
   CALENDARIO DE NOVOS PAGANTES (dashboard).

   Grid de 7 colunas fixas, uma por dia da semana. Colunas fixas e
   nao auto-fit: um calendario com 6 colunas numa semana e 7 na
   outra deixa de ser calendario.
   ============================================================ */
.cal-topo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin: 0 0 14px;
}

/* ------------------------------------------------------------
   NAVEGACAO DE MESES: um controle so, em pilula.

   As setas e o nome do mes juntos dentro da mesma borda: assim o
   conjunto se le como UM controle, e nao como tres elementos
   soltos que por acaso ficaram perto.
   ------------------------------------------------------------ */
.cal-nav {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: var(--elevated);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 4px;
}

/* Setas SOLIDAS na cor da marca.

   Antes eram cinzas com fundo transparente e passavam por decoracao.
   Os quadradinhos do calendario ja usam roxo CLARO; a seta preenchida
   com o roxo cheio se separa deles e se le como botao. */
.cal-seta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: none;
    border-radius: 999px;
    background: var(--brand);
    color: #fff;
    cursor: pointer;
    text-decoration: none;
    transition: background .15s, transform .05s;
}
.cal-seta svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.cal-seta:hover { background: var(--brand-soft); color: #fff; }
.cal-seta:active { transform: scale(.94); }
.cal-seta:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* No mes atual a seta de avancar fica apagada, mas OCUPA O LUGAR:
   sumindo, o nome do mes deslizaria e o proximo clique erraria. */
.cal-seta-off {
    background: var(--line-soft);
    color: var(--muted);
    cursor: default;
}
.cal-seta-off:hover { background: var(--line-soft); color: var(--muted); }
.cal-seta-off:active { transform: none; }

.cal-mes-atual {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    /* Largura fixa para "maio" e "setembro" nao moverem as setas */
    min-width: 168px;
    padding: 3px 10px;
    line-height: 1.2;
}
.cal-mes-atual > b { font-size: 15px; text-transform: capitalize; }

/* ============================================================
   OS TRES NUMEROS DO MES.

   Ficavam dentro da pilula de navegacao, em 11,5px, dividindo duas
   linhas com o nome do mes. Cabiam dois e mal - e o terceiro (o
   recorrente) e justamente o que ninguem calcula de cabeca.

   Aqui cada numero tem faixa propria: valor grande, rotulo, e uma
   linha explicando o que ele e. GRID de tres colunas iguais para os
   valores ficarem alinhados entre si mesmo com larguras diferentes -
   com flex, "R$ 1.200,00" ao lado de "12" desalinharia os rotulos.
   ============================================================ */
.cal-resumo {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin: 12px 0 14px;
    padding: 12px 6px;
    border: 1px solid var(--line-soft);
    border-top: 2px solid var(--brand);
    border-radius: 10px;
    background: var(--surface);
}
.cal-resumo-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1px;
    padding: 0 6px;
}
/* Divisorias entre as colunas: separam sem desenhar tres caixas. */
.cal-resumo-item + .cal-resumo-item { border-left: 1px solid var(--line-soft); }

.cal-resumo-num {
    font-size: 21px;
    font-weight: 700;
    line-height: 1.15;
    color: var(--brand);
    white-space: nowrap;
}
.cal-resumo-rot {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
}
/* A nota e o que impede a pergunta "por que o recorrente e menor?".
   Discreta de proposito: le-se uma vez e depois nao atrapalha. */
.cal-resumo-nota { font-size: 10.5px; color: var(--muted); line-height: 1.25; }

/* Dinheiro em verde, como no resto do sistema. O recorrente ganha o
   mesmo peso do bruto: num negocio de assinatura ele e o numero que
   diz o tamanho do mes seguinte. */
.cal-resumo-num.cal-bruto,
.cal-resumo-num.cal-recorrente { color: var(--ok); font-size: 19px; }

.cal-hoje-link {
    font-size: 12.5px;
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px dashed currentColor;
}
.cal-hoje-link:hover { color: var(--brand); }

/* Durante o fetch: some o "pisca" de conteudo trocando, sem travar a tela */
.cal-carregando { opacity: .45; transition: opacity .12s; pointer-events: none; }

.cal-cab,
.cal-semana {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 5px;
}
.cal-cab {
    margin-bottom: 5px;
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}
.cal-cab span { text-align: center; }
.cal-semana + .cal-semana { margin-top: 5px; }

.cal-dia {
    position: relative;
    min-height: 54px;
    border: 1px solid var(--line-soft);
    border-radius: 8px;
    padding: 5px 7px;
    background: var(--surface);
}
.cal-num { font-size: 11px; color: var(--muted); }

/* O numero do dia fica pequeno e a QUANTIDADE grande: o que se procura
   aqui e o valor, nao a data. */
.cal-valor {
    display: block;
    margin-top: 2px;
    font-size: 17px;
    font-weight: 600;
    line-height: 1.1;
    color: var(--brand);
}

/* Celula fora do mes: existe so para o grid nao desalinhar */
.cal-dia.cal-fora { border-color: transparent; background: transparent; }
.cal-dia.cal-fds { background: var(--bg); }
.cal-dia.cal-hoje { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }

/* Intensidade proporcional ao maior dia do mes (nivel 0 a 4) */
.cal-dia.n1 { background: rgba(42, 6, 105, .07); border-color: rgba(42, 6, 105, .16); }
.cal-dia.n2 { background: rgba(42, 6, 105, .14); border-color: rgba(42, 6, 105, .26); }
.cal-dia.n3 { background: rgba(42, 6, 105, .24); border-color: rgba(42, 6, 105, .38); }
.cal-dia.n4 { background: rgba(42, 6, 105, .36); border-color: rgba(42, 6, 105, .5); }
.cal-dia.n3 .cal-num,
.cal-dia.n4 .cal-num { color: rgba(255, 255, 255, .85); }
.cal-dia.n3 .cal-valor,
.cal-dia.n4 .cal-valor { color: #fff; }

/* VALOR PAGO NO DIA - subordinado a quantidade, nunca competindo com ela.
   A quantidade e o que se procura no calendario (17px, cor da marca); o valor
   e o detalhe que diz quanto aquele dia rendeu (11px, discreto). Invertida, a
   grade viraria uma planilha financeira e perderia a leitura de "em que dia
   entrou gente". */
.cal-reais {
    display: block;
    margin-top: 1px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.1;
    color: var(--ok);
    white-space: nowrap;
}
.cal-reais::before { content: 'R$ '; font-weight: 400; opacity: .7; }

/* Nos dias mais escuros o verde perde contraste no roxo forte; o branco
   mantem a leitura sem precisar clarear o fundo da celula. */
.cal-dia.n3 .cal-reais,
.cal-dia.n4 .cal-reais { color: rgba(255, 255, 255, .92); }

@media (max-width: 720px) {
    .cal-dia { min-height: 44px; padding: 4px 5px; }
    .cal-valor { font-size: 14px; }
    .cal-cab { font-size: 10px; }

    /* No celular as tres colunas espremem "R$ 12.345,67" ate quebrar.
       Uma abaixo da outra, com a divisoria virando linha horizontal. */
    .cal-resumo { grid-template-columns: 1fr; gap: 0; padding: 4px 10px; }
    .cal-resumo-item { padding: 9px 0; }
    .cal-resumo-item + .cal-resumo-item {
        border-left: 0;
        border-top: 1px solid var(--line-soft);
    }
    .cal-resumo-num { font-size: 19px; }
    .cal-resumo-num.cal-bruto,
    .cal-resumo-num.cal-recorrente { font-size: 17px; }
}

/* Situacao + motivo lado a lado, sempre na mesma linha.
   inline-flex em vez de dois elementos soltos: assim eles ficam centrados
   entre si e a celula nunca quebra o icone para a linha de baixo, por mais
   estreita que a coluna fique. */
.status-linha {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

/* Motivo do cancelamento.
   Colorido JA EM REPOUSO, ao contrario das acoes da ultima coluna: ele nao
   e um botao a mais na linha, e um sinal de que aquele cancelamento tem
   registro. Precisa saltar ao lado do badge vermelho para a ausencia dele
   (cliente vindo do legado) ser percebida de relance. */
.btn-icon.acao-motivo {
    width: 26px;
    height: 26px;
    color: var(--brand);
    background: rgba(42, 6, 105, .07);
    border-color: rgba(42, 6, 105, .22);
}
.btn-icon.acao-motivo .ico { width: 15px; height: 15px; }
.btn-icon.acao-motivo:hover {
    color: var(--brand);
    background: rgba(42, 6, 105, .14);
    border-color: rgba(42, 6, 105, .45);
}

@media (max-width: 720px) {
    .btn-icon { width: 34px; height: 34px; }   /* alvo de toque maior no celular */
    .btn-icon.acao-motivo { width: 30px; height: 30px; }
}
.link { background: none; border: none; color: var(--accent); cursor: pointer; text-decoration: underline; font-family: inherit; }

/* ============================================================
   BALAO do cancelamento (atributo popover do HTML).
   Fica na TOP LAYER do navegador, e nao dentro da tabela - a
   `table` tem overflow:hidden (por causa do canto arredondado) e
   recortaria qualquer painel posicionado dentro de uma celula.
   Abre e fecha sem JavaScript, pelo popovertarget do botao.
   ============================================================ */
.pop-cancel,
.pop-modal {
    /* ------------------------------------------------------------
       CENTRALIZACAO EXPLICITA, e nao herdada do navegador.

       O padrao de [popover] na folha do proprio navegador e
       `position: fixed; inset: 0; margin: auto`, que centraliza - e era
       o UNICO pedaco do posicionamento que nao estava escrito aqui. Na
       tela de Congelar o balao aparecia no canto inferior esquerdo.

       Por que 50% + translate, e nao inset: 0 + margin: auto:

       O `margin: auto` so centraliza quando SOBRA espaco - ele precisa
       das quatro bordas fixadas E de uma altura menor que a janela para
       ter o que distribuir. Basta uma dessas condicoes faltar (altura
       automatica, um inset sobrescrito, o `margin: 0` de algum reset) e
       ele resolve para zero, empurrando o balao para um canto - sem
       erro nenhum, so fora do lugar.

       Ja `top/left: 50%` mais `translate(-50%, -50%)` nao depende de
       espaco sobrando nem de altura conhecida: o balao e deslocado pela
       metade do PROPRIO tamanho, qualquer que seja ele. E o unico jeito
       de centralizar que da o mesmo resultado em toda situacao.

       right/bottom: auto sao necessarios - sem eles um `inset: 0` de
       outra regra (ou do navegador) continuaria esticando a caixa.
       ------------------------------------------------------------ */
    position: fixed;
    top: 50%;
    left: 50%;
    right: auto;
    bottom: auto;
    transform: translate(-50%, -50%);
    margin: 0;

    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    box-shadow: 0 18px 44px rgba(15, 23, 42, .22);
    padding: 0;
    width: min(400px, calc(100vw * var(--escala-inv, 1) - 32px));
    height: fit-content;
    max-height: calc(80vh * var(--escala-inv, 1));
    overflow-y: auto;
}
.pop-cancel::backdrop,
.pop-modal::backdrop { background: rgba(15, 23, 42, .34); }

/* Select e texto longo dentro do balao */
.pop-select {
    width: 100%;
    padding: 8px 11px;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--bg);
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
}

/* O plano vem do banco com quebras de linha; sem isto vira um paragrafao. */
.plano-texto {
    white-space: pre-wrap;
    line-height: 1.5;
    max-height: calc(40vh * var(--escala-inv, 1));
    overflow-y: auto;
}

/* No card proprio do plano, o texto e o unico conteudo: sem risco em cima
   (nao ha campo nenhum acima dele para separar) e com teto de altura, para
   um plano de vinte linhas nao esticar o balao alem do que cabe na tela. */
.ficha-bloco > .plano-texto {
    margin: 4px 0 10px;
    font-size: 13.5px;
    color: var(--ink);
    max-height: calc(26vh * var(--escala-inv, 1));
}

/* ============================================================
   MODAL DE MOTIVO DO CONGELAMENTO
   Cada motivo e um botao grande com titulo + consequencia escrita
   embaixo. Nao e select nem radio de proposito: aqui a escolha muda
   QUAL E-MAIL o cliente recebe, e os dois dizem coisas opostas -
   um manda pagar, o outro diz que pagar nao resolve. Escolher errado
   nao da erro em lugar nenhum, so chega a mensagem errada. Ler a
   consequencia antes de clicar tem de ser o caminho natural.
   ============================================================ */
.pop-motivo .pop-alvo {
    padding: 12px 16px 0;
    color: var(--muted);
}

.motivo-opcao { padding: 10px 16px 0; }
.motivo-opcao:last-of-type { padding-bottom: 4px; }

.motivo-btn {
    display: block;
    width: 100%;
    text-align: left;
    background: var(--elevated);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 12px 14px;
    cursor: pointer;
    font-family: inherit;
    transition: border-color .15s, background .15s;
}

.motivo-btn:hover {
    border-color: var(--brand-soft);
    background: var(--surface);
}

.motivo-titulo {
    display: block;
    font-size: 13.5px;
    font-weight: 700;
    color: var(--ink);
}

.motivo-efeito {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--muted);
}

.pop-motivo .pop-rodape {
    margin: 4px 0 0;
    padding: 12px 16px 16px;
    border-top: 1px solid var(--line-soft);
    line-height: 1.5;
}

.pop-acoes { padding: 0 16px 16px; }
.pop-acoes .btn { width: 100%; }
/* A lista de campos ja tem folga embaixo quando o botao vem depois */
.pop-modal form .pop-dados { padding-bottom: 12px; }

/* ============================================================
   BALAO COM A FICHA (icone de plano, na lista de Tickets).

   O balao normal tem 400px - largura de "um dado e o titulo dele".
   Este mostra a ficha do cliente em blocos coloridos, os MESMOS da
   tela de Clientes, e por isso usa a mesma largura daquele modal:
   780px. Nos 400px originais a grade de blocos nunca formaria duas
   colunas, e cada rotulo brigaria com o valor na mesma linha.

   As cores nao sao redefinidas aqui: os blocos usam .ficha-bloco e
   .ficha-infra / .ficha-acesso / .ficha-plano, declarados uma vez so
   mais abaixo. Cada assunto tem a mesma cor nas duas telas.
   ============================================================ */
.pop-ficha {
    width: min(780px, calc(100vw * var(--escala-inv, 1) - 32px));
    max-height: calc(86vh * var(--escala-inv, 1));
}

/* DUAS COLUNAS FIXAS, e nao o auto-fit da .ficha-grade.
   Com minmax(250px, 1fr) os 780px do balao davam TRES colunas, e a grade
   preenchia os buracos na ordem em que os blocos aparecem: Assinatura ficava
   metade vazia ao lado de Infraestrutura, e Dados de acesso caia sozinho na
   linha seguinte com um vao do lado. Fixando duas, cada linha e uma decisao:
   Assinatura sozinha em cima, Infraestrutura e Acesso lado a lado, Plano
   embaixo atravessando as duas.

   align-items: stretch (a .ficha-grade usa `start`) e o que faz os dois
   blocos do meio terminarem na MESMA altura. Com `start`, o de menos linhas
   sobe e deixa um degrau - foi exatamente o que ficou feio. */
.pop-ficha-corpo {
    padding: 16px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: stretch;
}

/* ---- Pilula PASTEL com valor + botao de copiar --------------------------
   Usada nas colunas Ticket e Cliente. Mesmo esquema dos blocos da ficha:
   uma cor por --fc, aplicada em 6% no fundo, 26% na borda e cheia no texto.

   PASTEL, e nao pilula cheia como as de prioridade e departamento: aquelas
   comunicam ESTADO, e disputam a atencao de proposito. Estas duas so
   embrulham um identificador - se tivessem o mesmo peso, a linha inteira
   viraria um varal de etiquetas coloridas e nenhuma seria notada.

   Cores diferentes entre si porque sao coisas diferentes: numero do ticket
   e o nosso identificador, dominio e o do cliente. Iguais, o olho pararia
   nas duas toda vez para descobrir qual e qual. */
.pill-copia {
    --fc: 92, 107, 132;                  /* cinza do --muted: o padrao */
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 3px 5px 3px 10px;
    border: 1px solid rgba(var(--fc), .26);
    border-radius: 999px;
    background: rgba(var(--fc), .06);
    white-space: nowrap;
    max-width: 100%;
}

.pill-ticket   { --fc: 124, 58, 237; }   /* violeta */
.pill-dominio  { --fc: 8, 145, 178; }    /* ciano   */
/* ARDOSIA, e nao verde. O verde ficou reservado para a pilula do WhatsApp,
   que e a UNICA coisa clicavel da celula: com as duas verdes, elas viravam
   um bloco so e a acao deixava de se destacar do dado.
   A regra que sobrou vale para a linha inteira - cor forte e para o que se
   clica; o que so se le fica em tom neutro. */
.pill-telefone { --fc: 71, 85, 105; }    /* ardosia */

/* CNPJ/CPF na tela de NF-e. Roxo da marca porque, ali, o documento e o dado
   PRINCIPAL da linha - e o que se copia para dentro do emissor de nota. Nas
   outras telas ele nem aparece; aqui e o motivo de a tela existir. */
.pill-doc { --fc: 67, 21, 156; }         /* roxo da marca */

/* E-mail: ardosia, o mesmo tom neutro do telefone. Copia-se para mandar a
   nota, mas e coadjuvante - com cor forte competiria com o documento ao lado
   e a linha ficaria com dois centros. */
.pill-email { --fc: 71, 85, 105; }       /* ardosia */

/* O valor pode ser um <b> (texto) ou um <a> (dominio clicavel, na tela de
   Cobrancas). Os dois se leem igual - o link so ganha o sublinhado no
   hover, para nao virar um segundo destaque dentro da pilula. */
.pill-copia b,
.pill-copia > a {
    font-size: 12.5px;
    font-weight: 700;
    color: rgb(var(--fc));
    text-decoration: none;
    font-variant-numeric: tabular-nums;
    /* Dominio longo encolhe com reticencias em vez de esticar a coluna: o
       valor inteiro continua no title do botao e na copia. */
    overflow: hidden;
    text-overflow: ellipsis;
}

.pill-copia > a:hover { text-decoration: underline; }

/* O botao herda a cor da pilula em que esta. Sem isto ele ficaria cinza
   dentro de uma moldura colorida, parecendo desligado. */
.pill-copia .btn-copiar { color: rgb(var(--fc)); }
.pill-copia .btn-copiar:hover { background: rgba(var(--fc), .16); }

/* A pilula do dominio e menor: ela fica na segunda linha da celula, embaixo
   do nome do cliente, e nao pode competir com ele. */
.pill-dominio { margin-top: 3px; }
.pill-dominio b { font-size: 11.5px; }

/* ---- DOMINIO + DATA CENTER na mesma linha (lista de tickets) -------------
   A pergunta e uma so - "que servico e este, e onde ele mora?" -, entao os
   dois dados andam juntos.

   `align-items: center` porque a pilula do dominio e mais alta que a sigla:
   sem isto ela encostava na base e ficava desalinhada por dois pixels - o
   bastante para a linha parecer torta numa tabela de 40 registros.

   `flex-wrap` para o dominio longo em tela estreita empurrar a sigla para a
   linha de baixo, em vez de esticar a coluna. */
.linha-dominio {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    /* SEM margem no topo: ela existia porque o nome do cliente ocupava a
       primeira linha da celula. Agora o dominio E a primeira linha, e os 3px
       o desalinhavam das outras colunas. */
}

/* Quem espaça aqui e o container - a margem propria da pilula duplicaria. */
.linha-dominio .pill-dominio { margin-top: 0; }

/* A SEGUNDA LINHA da celula do cliente: localizacao/servidor e contas ativas.
   Ficavam coladas no fim do dominio, e como o dominio varia de tamanho cada
   linha terminava num ponto diferente - o olho tinha de caçar o fim do nome
   para achar a sigla. Numa faixa propria, elas alinham entre si. */
.linha-selos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-top: 5px;
}

/* CONTAS ATIVAS - indigo pastel.
   Era ardósia, e sumia: ficava do mesmo tom da sigla de data center ao lado, e
   a informação que MOTIVA a pílula (este cliente tem mais de um serviço)
   passava batida.

   Indigo porque é a única faixa fria livre nesta célula: ciano é compartilhada,
   e cada data center tem a sua. Continua pastel, e não uma cor de alerta - é
   uma contagem, não um problema a resolver. O peso do texto faz o resto do
   destaque, sem precisar gritar. */
.badge-contas {
    background: rgba(99, 102, 241, .12);
    color: #4f46e5;
    border: 1px solid rgba(99, 102, 241, .30);
    font-weight: 700;
}

/* MENOR que os outros badges: e complemento do dominio, nao estado do
   chamado. Do mesmo tamanho, competiria com a prioridade e a categoria, que
   sao o que se varre na fila. */
.badge-local {
    font-size: 10px;
    padding: 2px 7px;
    letter-spacing: .04em;
}

/* CHAMADO QUE NASCEU DE UM E-MAIL (fila de tickets).

   MESMO TAMANHO REDUZIDO do .badge-local, pelo mesmo motivo: e procedencia,
   nao estado. Do tamanho da prioridade ou da categoria, competiria com o que
   se varre de fato quando se olha a fila.

   ARDOSIA, e nao uma cor de aviso. O chamado por e-mail e legitimo - passou
   pela confirmacao do link. A marca existe para quem atende saber que ha um
   endereco do outro lado (e ver qual, no title), e nao para sinalizar
   problema. Vermelho ou ambar aqui fariam a equipe tratar como suspeito todo
   chamado de um canal normal. */
.badge-email {
    margin-left: 8px;
    font-size: 10px;
    padding: 2px 7px;
    letter-spacing: .04em;
    background: rgba(92, 107, 132, .09);
    color: var(--muted);
    border: 1px solid rgba(92, 107, 132, .22);
    vertical-align: middle;
}

/* IDENTIFICACAO DO PAGAMENTO (tela de Pagamentos).
   AMBAR. A escolha e por exclusao: na mesma linha ja convivem o ciano do
   dominio, o roxo do badge BOLETO, o ciano do PIX, o verde do CONFIRMADO e o
   vermelho/verde do valor divergente. Ardosia, que era o tom anterior, se
   confundia com o cinza do texto comum e a pilula sumia; ambar e a unica
   faixa quente que ninguem ocupa aqui.

   O CODIGO APARECE INTEIRO. Sao 36 caracteres e a coluna fica larga, mas
   cortar com reticencias tira dele a unica funcao que tem: e por este numero
   que se confere um pagamento contra o e-mail do cliente ou a tela do banco,
   e conferencia com metade do codigo nao e conferencia - o comeco de dois
   UUID diferentes pode ser igual.

   Por isso tambem NAO ha `overflow: hidden` aqui: a regra generica de
   `.pill-copia b` corta, e ela precisa ser desfeita nesta pilula. O
   `min-width: 0` some junto - ele so existia para permitir o corte. */
.pill-ident { --fc: 180, 83, 9; }        /* ambar */
.pill-ident b {
    overflow: visible;
    text-overflow: clip;
    font-size: 11.5px;
    font-weight: 600;
}

/* Cor do contador de CONGELADAS no resumo de Cobrancas. Estava escrita no
   `style=` da tag - inline nao obedece tema nenhum, e no escuro este ciano
   escuro ficaria ilegivel sobre fundo escuro. Como classe, o tema alcanca. */
.resumo-congelado { color: #0e7490; }

/* Aviso em tom da MARCA (Clientes > Dados de acesso). Mesmo caso: veio de um
   `style=` inline com o roxo a 5%. Vira classe para o tema poder ajustar o
   veu sem que alguem precise achar a tag. */
.alert-marca {
    background: rgba(42, 6, 105, .05);
    border: 1px solid rgba(42, 6, 105, .18);
}

/* VALOR EM COLUNA: alinhado a direita e com algarismos de largura fixa.

   Os dois juntos e que fazem a coluna somar de olho - a virgula cai sempre no
   mesmo lugar, e "1.234,50" fica exatamente sob "89,90". Alinhado a esquerda,
   ou com fonte proporcional, ler a ordem de grandeza exige contar digitos. */
.col-valor {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* O cabecalho acompanha a coluna: alinhado a esquerda sobre numeros a
   direita, ele aponta para o lugar errado. */
th.col-valor { text-align: right; }

/* ---- Botao de copiar, colado no valor -----------------------------------
   Discreto em repouso e colorido no hover: ele fica DENTRO de um campo de
   leitura, e um botao chamativo ali competiria com o proprio dado. */
.dd-copiavel {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* :not(.btn) - o TAMANHO E A COR daqui valem so para o botaozinho de icone.

   .btn-copiar e duas coisas ao mesmo tempo: o gancho que o copiar.js procura
   (qualquer elemento com esta classe e data-copiar) e a aparencia do
   botaozinho de 22px que mora dentro das pilulas. Enquanto os dois papeis
   andaram juntos ninguem reparou; no balao do link, em Tickets, o gancho
   precisou pousar num botao de TEXTO - e este bloco, que vem depois de .btn
   e de .btn-start no arquivo, ganhava o desempate e devolvia um botao de
   22px, transparente e cinza, com o halo roxo do .btn-start boiando embaixo.

   Escrever as cores de novo num override nao resolveria: seriam duas fontes
   para o mesmo roxo, divergindo no primeiro ajuste. Aqui a regra apenas
   DECLARA PARA QUEM ELA E - o botao de icone -, e o botao de texto volta a
   ser pintado pelo .btn/.btn-start, como qualquer outro. Todos os onze usos
   existentes sao .btn-copiar puro e continuam iguais. */
.btn-copiar:not(.btn) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--muted);
    cursor: pointer;
    opacity: .5;
    transition: opacity .12s ease, color .12s ease, background .12s ease;
}

.btn-copiar .ico { width: 14px; height: 14px; }

/* ---- Pilula do WhatsApp: ACAO, e nao dado ------------------------------

   Fica AO LADO da pilula do telefone, nao dentro dela. Copiar e um jeito
   de pegar o numero e pertence ao dado; abrir a conversa leva para fora do
   sistema. Na mesma moldura os dois se pareciam, e o clique errado custa
   uma aba aberta sem querer no meio de uma cobranca.

   Preenchida, e nao contornada como as outras pilulas: as demais embrulham
   um identificador para ler, esta e para clicar. O peso extra e o que
   diferencia "informacao" de "botao" numa linha de tabela cheia. */
.pill-zap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    margin-left: 5px;
    vertical-align: middle;
    border: 1px solid rgba(5, 150, 105, .3);
    border-radius: 999px;
    background: rgba(5, 150, 105, .12);
    color: #059669;
    text-decoration: none;
    transition: background .12s ease, border-color .12s ease, color .12s ease;
}

.pill-zap:hover {
    background: #059669;
    border-color: #059669;
    color: #fff;
    text-decoration: none;
}

.pill-zap .ico { width: 15px; height: 15px; }

.btn-copiar:not(.btn):hover {
    opacity: 1;
    color: var(--accent);
    background: rgba(var(--fc, 92, 107, 132), .14);
}

/* Copiado: o icone fica verde por um instante. O `title` nao serve de aviso -
   ele so aparece se a pessoa parar o mouse em cima, e quem acabou de clicar
   ja tirou a mao dali. */
.btn-copiar-ok,
.btn-copiar-ok:hover {
    opacity: 1;
    color: #059669;
    background: rgba(5, 150, 105, .16);
}

/* ---- COPIAR NUM BOTAO DE TEXTO (o do balao do link, em Tickets) --------

   O tamanho e a cor ja se resolvem sozinhos: o bloco do botaozinho de icone
   esta escrito com :not(.btn) e nao alcanca este, entao .btn e .btn-start
   pintam o botao como qualquer outro da tela. So a CONFIRMACAO precisa de
   regra propria.

   O piscar padrao nao serve num botao de texto: ele pinta o fundo de verde a
   16% e a letra de #059669, o que da 3,4:1 - abaixo dos 4,5:1 que texto
   pequeno exige. Preenchido resolve (5,5:1) e muda mais que o suficiente
   para ser notado de relance. */
.btn.btn-copiar.btn-copiar-ok,
.btn.btn-copiar.btn-copiar-ok:hover {
    background: #047857;
    box-shadow: none;
    color: #fff;
    filter: none;
}

/* A PALAVRA tambem muda, e nao so a cor. O copiar.js so acende e apaga a
   classe - trocar o texto por JS obrigaria a mexer nele e a guardar o rotulo
   original em algum lugar. Com dois <span> e uma regra de CSS, o mesmo
   resultado nasce do proprio estado. */
.copiar-depois { display: none; }
.btn-copiar-ok .copiar-antes { display: none; }
.btn-copiar-ok .copiar-depois { display: inline; }

/* ---- BALAO DO LINK DO CLIENTE (Tickets) ----
   Mais largo que os 400px do balao comum: dentro dele mora um endereco de
   ~70 caracteres, e no tamanho padrao ele quebrava em quatro linhas de
   monoespacada - o que dificulta conferir o token de relance. */
.pop-link { width: min(520px, calc(100vw * var(--escala-inv, 1) - 32px)); }

/* O textarea ja e o ultimo elemento do <dd>; a margem de cima dele (12px,
   herdada de .link-copiavel) sobraria depois do rotulo.

   O white-space e pelo mesmo motivo do .pop-nota abaixo - o td.nowrap da
   coluna. O navegador ja poe pre-wrap em todo <textarea>, mas por folha do
   proprio navegador: basta uma regra de autor mexer nisso um dia para o
   endereco virar uma linha so. Escrito, nao depende de sorte. */
.pop-link .link-copiavel {
    margin-top: 2px;
    white-space: pre-wrap;
}

.pop-nota {
    margin: 0;
    padding: 0 16px 14px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--muted);

    /* white-space: normal e OBRIGATORIO, e nao zelo. O balao mora dentro do
       <td class="nowrap"> da coluna Acoes, e a top layer do popover nao
       interrompe HERANCA - ela muda so onde o navegador PINTA. Sem isto as
       duas frases sairiam numa linha unica e, como .pop-modal tem
       overflow-y: auto (o que faz o overflow-x virar auto tambem), o balao
       ganharia barra de rolagem horizontal.

       Os baloes vizinhos escapam por sorte: so tem valores curtos. O unico
       texto corrido que ja existia neles, .plano-texto, tambem precisou
       declarar o seu (pre-wrap). */
    white-space: normal;
}

/* Dois botoes lado a lado. Sem isto o `.pop-acoes .btn { width: 100% }`
   empilharia os dois, cada um ocupando a largura inteira. */
.pop-acoes-duplo {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

/* <a> nao e <button>: precisa do alinhamento que o .btn da por conta em
   elementos de formulario. */
.pop-acoes-duplo .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
}

/* ---- Lista de campos EM LINHA, para o card que atravessa a grade --------
   Rotulo em cima do valor, tres colunas. Um card largo com a lista normal
   (rotulo a esquerda, valor a direita) abre meio palmo de vazio no meio de
   cada linha, e gasta tres linhas quase vazias onde cabia uma. */
.ficha-lista-3col {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0 20px;
}

.ficha-lista-3col .ficha-linha {
    display: block;
    padding: 2px 0 6px;
    /* Sem o risco: aqui as linhas ficam LADO a lado, e um tracinho embaixo de
       cada uma pareceria sublinhado solto em vez de separacao. */
    border-bottom: none;
}

.ficha-lista-3col .ficha-linha dt { margin-bottom: 2px; }
.ficha-lista-3col .ficha-linha dd { text-align: left; }

/* Balao estreito (celular): tudo em coluna unica. Dois blocos de 190px lado
   a lado espremeriam rotulo e valor na mesma linha. */
@media (max-width: 700px) {
    .pop-ficha-corpo { grid-template-columns: 1fr; }
    .ficha-lista-3col { grid-template-columns: 1fr; }
    .ficha-lista-3col .ficha-linha {
        display: flex;
        justify-content: space-between;
        gap: 14px;
        padding: 7px 0;
        border-bottom: 1px dashed rgba(var(--fc), .22);
    }
    .ficha-lista-3col .ficha-linha:last-child { border-bottom: none; }
    .ficha-lista-3col .ficha-linha dd { text-align: right; }
}

.pop-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 13px 16px;
    border-bottom: 1px solid var(--line-soft);
    background: var(--elevated);
    border-radius: var(--radius) var(--radius) 0 0;
}
.pop-head b { font-size: 13.5px; }
.pop-fechar {
    background: none;
    border: none;
    color: var(--muted);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
}
.pop-fechar:hover { color: var(--ink); }

/* Rotulo em cima, valor embaixo: o texto da observacao pode ser longo
   e numa grade de duas colunas ele espremeria tudo. */
.pop-dados { margin: 0; padding: 14px 16px 16px; }
.pop-dados dt {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted);
    margin: 0 0 3px;
}
.pop-dados dt ~ dt { margin-top: 12px; }
.pop-dados dd { margin: 0 0 12px; font-size: 13.5px; }
.pop-dados dd:last-child { margin-bottom: 0; }

/* Navegador sem suporte a popover mostraria o painel solto no meio da
   tabela. Melhor escondido - o title do botao ainda diz o motivo. */
@supports not selector(:popover-open) {
    .pop-cancel, .pop-modal { display: none; }
}

/* Alerts */
/* Explicacao do criterio de uma aba. Discreta de proposito: e para ser lida
   uma vez, nao um alerta que exige acao. */
/* display: block, e nao flex. Com flex, cada <b> e cada trecho de texto vira
   um item e o paragrafo sai todo numa linha so, espremido. */
.criterio-aba {
    display: block;
    margin: -4px 0 16px;
    padding: 10px 14px;
    background: rgba(67, 21, 156, .05);
    border: 1px solid rgba(67, 21, 156, .14);
    border-left: 3px solid rgba(67, 21, 156, .38);
    border-radius: var(--radius-sm);
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--muted);
}

.criterio-aba b { color: var(--ink); font-weight: 700; }

.alert { padding: 11px 16px; border-radius: var(--radius-sm); margin: 0 0 16px; font-size: 13.5px; }
.alert-ok { background: rgba(5, 150, 105, .07); color: var(--ok); border: 1px solid rgba(5, 150, 105, .25); }
.alert-erro { background: rgba(220, 38, 38, .06); color: var(--err); border: 1px solid rgba(220, 38, 38, .22); }
/* AVISO, e nao erro: nada quebrou, falta um passo. Usado quando a conferencia
   do extrato nao tem recebimento sincronizado contra o que comparar - vermelho
   ali faria parecer defeito do sistema. */
.alert-aviso { background: rgba(180, 83, 9, .07); color: #92400e; border: 1px solid rgba(180, 83, 9, .25); }
.alert-aviso a { color: inherit; font-weight: 500; }

/* EXPLICACAO, e nao alarme. O aviso de "esta tela e de um dia por vez" nao
   noticia problema nenhum - conta como a tela funciona e para onde ir quando o
   que se quer e outra coisa. Ambar seria um alerta falso que a pessoa aprende a
   ignorar; azul lê-se como informacao. */
.alert-info {
    background: rgba(37, 99, 235, .06);
    color: #1e40af;
    border: 1px solid rgba(37, 99, 235, .2);
}
.alert-info a { color: inherit; font-weight: 600; text-decoration: underline; }

/* ==========================================================================
   PILULAS DE FILTRO (Extrato simplificado > Tipo).

   Sao as MESMAS .badge que aparecem na coluna Tipo da tabela, so que
   clicaveis. De proposito: a pilula do filtro e a pilula da linha tem de ser
   reconheciveis como a mesma coisa, senao o "PIX" de cima parece um botao
   qualquer em vez do recorte daquele tipo. Aqui a classe de cor vem do proprio
   lancamento, entao a correspondencia e automatica.

   A que esta ligada ganha um anel escuro em volta - e nao uma cor diferente,
   que destruiria a associacao com a coluna.
   ========================================================================== */
.chips {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 0 0 16px;
}

.chips-rotulo {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
}

/* inline-flex, e nao line-height: 0, para tirar o espaco que o navegador poe
   embaixo de um inline - com line-height zerado a pilula ficaria desalinhada
   das vizinhas de altura diferente. */
.chips a { text-decoration: none; display: inline-flex; align-items: center; }
.chips .badge { cursor: pointer; transition: filter .12s, box-shadow .12s; }
.chips a:hover .badge { filter: brightness(.94); }

.chips a.ativo .badge {
    box-shadow: 0 0 0 2px var(--ink);
    font-weight: 800;
}

/* A contagem: mesma cor da pilula, um pouco apagada, separada por um respiro.
   Numero e rotulo colados viram uma palavra so ("PIX2603"). */
.chip-num {
    margin-left: 7px;
    padding-left: 7px;
    border-left: 1px solid currentColor;
    opacity: .65;
    font-variant-numeric: tabular-nums;
}


/* ==========================================================================
   PREVIA DO ENVIO (Clientes > Dados de acesso, dentro do modal).

   Rotulo a esquerda, valor a direita em monoespacada. Monoespacada porque o
   que se confere aqui e caractere a caractere - senha, IP, dominio - e em
   fonte proporcional "rn" e "m" ficam parecidos justamente na hora em que a
   diferenca importa.
   ========================================================================== */
/* Modal mais largo SO quando a previa esta dentro. Os 440px padrao sao a
   largura de uma frase de confirmacao; um dominio e uma URL de painel nao
   cabem, e quebravam no meio da palavra ("...canada.paine / l.integrator.host")
   - conferir um endereco partido ao meio e pedir para o erro passar. */
.modal.modal-previa { max-width: 580px; }

/* A rolagem fica NA PREVIA, e nao no modal: assim Cancelar e Confirmar
   continuam sempre visiveis no rodape, mesmo num notebook de tela baixa. */
#previaAcesso { max-height: calc(44vh * var(--escala-inv, 1)); overflow-y: auto; margin: 14px 0 4px; }

.previa-topo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0 0 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
}
.previa-cliente {
    font-size: 14px;
    font-weight: 700;
    color: var(--ink);
    line-height: 1.3;
}

.previa-bloco + .previa-bloco { margin-top: 16px; }

/* Titulo do grupo no mesmo tom dos cabecalhos de tabela do sistema, para a
   previa parecer parte da mesma casa e nao um componente importado. */
.previa-bloco h4 {
    margin: 0 0 6px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--faint);
}
.previa-bloco dl {
    margin: 0;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.previa-linha {
    display: flex;
    align-items: baseline;
    gap: 14px;
    padding: 9px 13px;
    font-size: 13px;
    border-bottom: 1px solid var(--line-soft);
}
.previa-linha:last-child { border-bottom: none; }

/* Rotulo em largura FIXA, e nao em porcentagem: com porcentagem os valores
   comecavam em colunas diferentes em cada bloco, e a coluna irregular e o que
   fazia a lista parecer desalinhada. */
.previa-linha dt {
    flex: 0 0 132px;
    color: var(--muted);
    font-weight: 600;
}
.previa-linha dd {
    margin: 0;
    flex: 1 1 auto;
    min-width: 0;
    color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 12.5px;
    /* anywhere, e nao break-all: quebra so quando a linha realmente nao cabe,
       e de preferencia num ponto ou barra - em vez de partir toda palavra no
       caractere em que a largura acabou. */
    overflow-wrap: anywhere;
    /* Um clique seleciona o valor inteiro: quem confere costuma querer colar
       em outro lugar, e arrastar o mouse por uma senha e onde se perde metade
       dela sem perceber. */
    user-select: all;
}

/* SENHA. Ambar, e nao vermelho: nao ha erro nenhum aqui - ha uma linha que
   merece um segundo olhar antes de sair da empresa. */
.previa-segredo { background: rgba(180, 83, 9, .06); }
.previa-segredo dt { color: #92400e; }
.previa-segredo dd { color: #7c2d12; font-weight: 700; }

.previa-vazio {
    color: var(--err) !important;
    font-family: inherit !important;
    font-style: italic;
    user-select: auto;
}

.previa-carregando {
    margin: 0;
    padding: 18px 0;
    text-align: center;
    font-size: 12.5px;
    color: var(--muted);
}

/* ==========================================================================
   ICONE DE COBRANCA EXTRA (Cobrancas > coluna Pag. Extra).

   Ambar, a mesma familia do selo de NF-e: nao e sucesso nem erro - e "esta
   linha e de outra natureza, repare nela". Verde diria que esta tudo certo e
   vermelho diria que ha problema; nenhum dos dois e verdade sobre uma cobranca
   avulsa.

   `vertical-align` porque o SVG e inline e, sem isso, ele desce abaixo da
   linha de base e desalinha a altura da celula inteira.
   ========================================================================== */
.ico-extra {
    width: 19px;
    height: 19px;
    color: #92400e;
    vertical-align: -4px;
}

/* Barra de filtros */
.filter-bar {
    display: flex;
    align-items: center;
    gap: 14px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 13px 15px;
    margin-bottom: 16px;
    flex-wrap: wrap;
    box-shadow: var(--shadow);
}

/* ------------------------------------------------------------------
   Chave liga/desliga (ex.: aviso por e-mail em Congelar). E um <button>
   de verdade dentro de um <form> POST: sem JavaScript, e com o estado
   vindo do servidor - um switch so no navegador mentiria depois de um
   F5 ou numa segunda aba aberta.
   ------------------------------------------------------------------ */
.chave-aviso {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 12px 15px;
    margin-bottom: 14px;
    box-shadow: var(--shadow);
}

.chave-texto { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 240px; }

.chave {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 6px 14px 6px 8px;
    border-radius: 999px;
    border: 1px solid var(--line);
    background: var(--bg);
    color: var(--muted);
    font-family: inherit;
    font-size: 11.5px;
    font-weight: 800;
    letter-spacing: .06em;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}

.chave-bolinha {
    width: 13px; height: 13px;
    border-radius: 50%;
    background: currentColor;
    box-shadow: 0 0 0 3px rgba(92, 107, 132, .16);
}

.chave.on {
    background: rgba(5, 150, 105, .10);
    border-color: rgba(5, 150, 105, .38);
    color: var(--ok);
}
.chave.on .chave-bolinha { box-shadow: 0 0 0 3px rgba(5, 150, 105, .16); }

.chave.off {
    background: rgba(220, 38, 38, .07);
    border-color: rgba(220, 38, 38, .32);
    color: var(--err);
}
.chave.off .chave-bolinha { box-shadow: 0 0 0 3px rgba(220, 38, 38, .14); }

.chave:hover { filter: brightness(.96); }
.chave:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* SEARCH JUNTO COM TEXT.
   A busca de /tickets virou input[type="search"] (para ganhar o "x" de
   limpar e para o autocomplete="off" pegar), e com o seletor so em
   [type="text"] ela perdeu o estilo INTEIRO: encolheu para a largura padrao
   do navegador e ficou sem borda, sem fundo e sem foco.

   Regra que casa por TIPO quebra assim, em silencio, no dia em que alguem
   troca o tipo do campo. Os dois tipos andam juntos daqui para a frente -
   inclusive nas duas media queries la embaixo. */
.filter-bar input[type="text"],
.filter-bar input[type="search"] {
    flex: 1;
    min-width: 260px;
    padding: 9.5px 13px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 9px;
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}

.filter-bar input[type="text"]:focus,
.filter-bar input[type="search"]:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(42, 6, 105, .13);
    background: var(--surface);
}

/* O "x" NATIVO do campo de busca. Sem isto ele vem cinza-claro sobre fundo
   claro e some - existe, mas ninguem enxerga. A mascara pinta o desenho com a
   cor do tema, entao ele acompanha claro e escuro sozinho. */
.filter-bar input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
    width: 13px;
    height: 13px;
    cursor: pointer;
    background: var(--muted);
    -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 4l8 8M12 4l-8 8' stroke='black' stroke-width='2.2' stroke-linecap='round' fill='none'/></svg>") center / contain no-repeat;
    mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M4 4l8 8M12 4l-8 8' stroke='black' stroke-width='2.2' stroke-linecap='round' fill='none'/></svg>") center / contain no-repeat;
}

.filter-bar .radio { color: var(--muted); font-size: 13.5px; display: flex; align-items: center; gap: 6px; cursor: pointer; }
.filter-bar .radio input { accent-color: var(--accent); }

/* Abas segmentadas (Todos / ICP / Linux) */
.seg {
    display: inline-flex;
    gap: 4px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 11px;
    padding: 4px;
    margin-bottom: 14px;
    box-shadow: var(--shadow);
    /* Clientes ja tem 7 abas. Sem isto a barra estoura a largura da tela
       em monitor menor - com wrap ela vira duas fileiras de pilulas. */
    max-width: 100%;
    flex-wrap: wrap;
}

.seg a {
    padding: 7px 18px;
    border-radius: 8px;
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted);
    text-decoration: none;
    transition: background .15s, color .15s;
}

.seg a:hover { color: var(--ink); }

.seg a.active {
    background: linear-gradient(135deg, #43159C, #2A0669);
    color: #fff;
    box-shadow: 0 4px 12px rgba(42, 6, 105, .28);
}

/* ------------------------------------------------------------------
   BARRA SECUNDARIA (.seg.seg-sub) - um recorte DENTRO da aba escolhida.
   Hoje: Cobrancas > Pagas, com Todas / Inter / Cartao.

   Precisa parecer subordinada, e nao uma segunda fileira de abas do mesmo
   nivel. Duas barras identicas empilhadas dizem "escolha uma das duas
   coisas", quando na verdade a de baixo so existe por causa da de cima.

   Como isso e feito: menor, sem sombra, com a caixa quase invisivel e o
   ativo em roxo CHAPADO em vez do gradiente com sombra da principal. O
   recuo a esquerda e o sinal mais barato de hierarquia que existe - o olho
   entende antes de ler.
   ------------------------------------------------------------------ */
.seg.seg-sub {
    margin-left: 18px;
    margin-top: -6px;
    padding: 3px;
    border-radius: 9px;
    background: var(--chip);
    border-color: transparent;
    box-shadow: none;
}

.seg.seg-sub a {
    padding: 5px 13px;
    font-size: 11.5px;
    letter-spacing: .03em;
}

.seg.seg-sub a.active {
    background: var(--brand);
    box-shadow: none;
}

/* A contagem informa, nao anuncia: peso normal e um tom abaixo do rotulo.
   Na pilula ativa herda o branco, senao sumiria contra o roxo. */
.seg.seg-sub a span { font-weight: 500; opacity: .75; }

@media (max-width: 860px) {
    /* Recuo nao cabe em tela estreita: a barra ja ocupa a largura toda e o
       deslocamento so roubaria espaco das pilulas. */
    .seg.seg-sub { margin-left: 0; }
}

/* ------------------------------------------------------------------
   Painel de filtros: recortes diferentes do MESMO filtro, dentro de uma
   caixa so. Soltas na pagina, as barras pareciam controles sem dono.
   ------------------------------------------------------------------ */
.filtros {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 10px 14px;
    margin-bottom: 16px;
}

/* Centralizado e sem rotulo: "Abertos/Fechados" e o nome dos departamentos ja
   dizem o que cada linha filtra - a palavra ao lado so ocupava espaco e
   empurrava tudo para a direita. */
.filtros-linha {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 7px 0;
}

.filtros-linha + .filtros-linha { border-top: 1px solid var(--line-soft); }

/* Dentro do painel as barras nao carregam mais caixa propria - seria uma
   moldura dentro da outra. */
.filtros .seg { margin: 0; box-shadow: none; }
.filtros .seg-sub { margin-top: 0; justify-content: center; }

/* Situacao como chave liga/desliga: uma capsula com os dois lados, e o lado
   aceso preenchido. O pontinho na frente e o que faz ler como "ligado neste",
   em vez de duas abas soltas. */
.filtros .seg-status {
    background: var(--bg);
    border-radius: 999px;
    padding: 3px;
    gap: 3px;
}

.filtros .seg-status a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 18px 7px 14px;
    border-radius: 999px;
}

.filtros .seg-status a::before {
    content: '';
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    opacity: .3;
    transition: opacity .15s, box-shadow .15s;
}

.filtros .seg-status a.active::before {
    opacity: 1;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, .22);
}

/* Segunda fileira de filtro (ex.: departamentos do ticket).
   `display: flex` e nao `inline-flex`: com inline-flex esta barra subia para o
   lado da de cima e as duas viravam uma fileira so, ilegivel.
   Sao pilulas soltas, sem a caixa do .seg, justamente para nao parecerem o
   mesmo controle das abas de status. */
.seg-sub {
    display: flex;
    width: fit-content;
    max-width: 100%;
    gap: 6px;
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
    margin-top: 2px;
}

/* Cada departamento tem a SUA cor, a mesma da pilula na coluna Categoria.
   Duas variaveis por aba (--cat = tinta, --cat-bg = fundo) evitam escrever
   duas regras completas para cada um dos sete. */
/* PRIORIDADE: as mesmas duas variaveis, com as cores dos badges da coluna.

   A barra reaproveita `.seg-sub` inteira - so a paleta muda. Uma barra propria
   ganharia altura, espacamento e comportamento de rolagem ligeiramente
   diferentes da de departamento, e duas barras quase iguais uma acima da outra
   e onde a diferenca incomoda mais.

   `prio-todas` usa o roxo da marca, igual a `cat-todas`: as duas pilulas
   significam a mesma coisa - "sem recorte" - e a cor repetida ensina isso. */
.seg-prio a.prio-todas      { --cat: #2A0669; --cat-bg: rgba(42, 6, 105, .09); }
.seg-prio a.prio-urgente    { --cat: #dc2626; --cat-bg: rgba(220, 38, 38, .10); }
.seg-prio a.prio-alta       { --cat: #b45309; --cat-bg: rgba(180, 83, 9, .10); }
.seg-prio a.prio-media      { --cat: #1d4ed8; --cat-bg: rgba(37, 99, 235, .10); }
.seg-prio a.prio-baixa      { --cat: #0a7a31; --cat-bg: rgba(22, 163, 74, .10); }

.seg-sub a.cat-todas        { --cat: #2A0669; --cat-bg: rgba(42, 6, 105, .09); }
.seg-sub a.cat-suporte      { --cat: #0e7490; --cat-bg: rgba(8, 145, 178, .10); }
.seg-sub a.cat-financeiro   { --cat: #059669; --cat-bg: rgba(5, 150, 105, .10); }
.seg-sub a.cat-comercial    { --cat: #1d4ed8; --cat-bg: rgba(37, 99, 235, .10); }
.seg-sub a.cat-cancelamento { --cat: #dc2626; --cat-bg: rgba(220, 38, 38, .09); }
.seg-sub a.cat-ouvidoria    { --cat: #7e22ce; --cat-bg: rgba(147, 51, 234, .09); }
.seg-sub a.cat-seguranca    { --cat: #b45309; --cat-bg: rgba(180, 83, 9, .10); }
.seg-sub a.cat-plano        { --cat: #4c1d95; --cat-bg: rgba(76, 29, 149, .09); }
.seg-sub a.cat-outras       { --cat: #64748b; --cat-bg: rgba(100, 116, 139, .10); }

/* ------------------------------------------------------------------
   Carga em andamento (relatorio Leaseweb). A barra existe para a espera
   ter fim visivel: "carregando" sem numero nenhum e indistinguivel de
   travado.
   ------------------------------------------------------------------ */
.cache-box {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 18px 20px;
    margin-bottom: 18px;
}

.cache-topo {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.cache-barra {
    height: 8px;
    border-radius: 999px;
    background: var(--bg);
    border: 1px solid var(--line);
    overflow: hidden;
}

.cache-progresso {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: linear-gradient(135deg, #43159C, #2A0669);
    transition: width .4s ease;
}

/* Sem numero de total ainda: a barra "respira" para nao parecer parada */
.cache-progresso[style*="width: 0%"] {
    width: 30% !important;
    animation: cache-pulsando 1.2s ease-in-out infinite;
}

@keyframes cache-pulsando {
    0%, 100% { opacity: .35; }
    50%      { opacity: .9; }
}

/* ------------------------------------------------------------------
   Escolha da conta (relatorio Leaseweb). Cartoes grandes porque e a
   unica acao da tela naquele momento - um select escondido no meio da
   pagina faria a pessoa procurar o que fazer.
   ------------------------------------------------------------------ */
.escolha-contas {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 18px;
}

.escolha-conta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 150px;
    padding: 16px 20px;
    border-radius: var(--radius);
    border: 1px solid var(--cat, var(--line));
    background: var(--cat-bg, var(--surface));
    color: var(--cat, var(--ink));
    text-decoration: none;
    box-shadow: var(--shadow);
    transition: transform .12s, box-shadow .12s;
}

.escolha-conta b { font-size: 19px; letter-spacing: .04em; }
.escolha-conta span { font-size: 12.5px; color: var(--muted); }
.escolha-conta:hover { transform: translateY(-2px); box-shadow: var(--shadow-pop); }


/* Tons genericos: valem para as pilulas do .seg-sub E para os cartoes de
   escolha de conta - as duas coisas leem as mesmas variaveis. */
.tom-roxo     { --cat: #2A0669; --cat-bg: rgba(42, 6, 105, .09); }
.tom-verde    { --cat: #059669; --cat-bg: rgba(5, 150, 105, .10); }
.tom-vermelho { --cat: #dc2626; --cat-bg: rgba(220, 38, 38, .09); }
/* Ambar = pendencia, nao erro. Usado na aba "Sem baixa" do extrato: o dinheiro
   entrou (nao ha nada de errado com o banco), o que falta e alguem dar baixa. */
.tom-ambar    { --cat: #b45309; --cat-bg: rgba(180, 83, 9, .10); }
.tom-laranja  { --cat: #b45309; --cat-bg: rgba(180, 83, 9, .10); }
/* Rosa = erro NOSSO, de cadastro. Usado na aba "Instancia duplicada" do
   inventario Leaseweb, que fica ao lado de duas pilulas ja quentes ("Sem
   cadastro" em vermelho, "Custo divergente" em laranja). Repetir o vermelho
   ali faria duas abas diferentes parecerem a mesma coisa de relance - o rosa
   e da mesma familia (o assunto e problema), mas nao se confunde. */
.tom-rosa     { --cat: #be185d; --cat-bg: rgba(190, 24, 93, .09); }

/* ------------------------------------------------------------
   OS TONS NO TEMA ESCURO

   Achado ao acrescentar a pilula "Instancia duplicada": as pilulas de tom
   NUNCA foram acertadas para o escuro. Elas seguem o desenho de sempre -
   tinta escura sobre veu de 10% da mesma cor -, e sobre fundo escuro a tinta
   some dentro do veu. O caso extremo era o roxo do "Todos": #2A0669 sobre o
   veu resultava em 1,11:1, ou seja, praticamente invisivel.

   Aqui vale a mesma inversao das outras pilulas: tinta CLARA do mesmo tom e
   veu um pouco mais forte. Sobe para ~7:1 nos cinco tons.

   TRES CUIDADOS que explicam a forma destas regras:

   1. NAO se mexe em `--cat`. Essa variavel tambem pinta a pilula ATIVA
      (fundo cheio, texto branco) e os cartoes de escolha de conta, e os dois
      ja liam bem no escuro. Trocar a variavel consertaria a inativa e
      quebraria as outras duas - por isso a cor vai direto na regra.

   2. `:not(.active)` pelo mesmo motivo: a ativa fica exatamente como estava.

   3. O NUMERINHO tem fundo branco a 60%, pensado para tinta escura. Com a
      tinta clara ele cai para 1,2:1. No escuro o fundo dele inverte tambem.
   ------------------------------------------------------------ */
[data-tema="escuro"] .seg-sub a.tom-roxo:not(.active):not(.vazia)     { color: #c4b5fd; background: rgba(167, 139, 250, .18); border-color: rgba(167, 139, 250, .38); }
[data-tema="escuro"] .seg-sub a.tom-verde:not(.active):not(.vazia)    { color: #6ee7b7; background: rgba(52, 211, 153, .18);  border-color: rgba(52, 211, 153, .38); }
[data-tema="escuro"] .seg-sub a.tom-vermelho:not(.active):not(.vazia) { color: #fca5a5; background: rgba(248, 113, 113, .18); border-color: rgba(248, 113, 113, .38); }
[data-tema="escuro"] .seg-sub a.tom-ambar:not(.active):not(.vazia),
[data-tema="escuro"] .seg-sub a.tom-laranja:not(.active):not(.vazia)  { color: #fdba74; background: rgba(251, 146, 60, .18);  border-color: rgba(251, 146, 60, .38); }
[data-tema="escuro"] .seg-sub a.tom-rosa:not(.active):not(.vazia)     { color: #f9a8d4; background: rgba(244, 114, 182, .18); border-color: rgba(244, 114, 182, .38); }

[data-tema="escuro"] .seg-sub a:not(.active) .seg-num {
    background: rgba(0, 0, 0, .28);
    border-color: rgba(255, 255, 255, .14);
}

/* Recarregar da API: e a UNICA forma de trazer dados novos (a carga nao vence
   sozinha), entao precisa estar visivel - mas nao e uma acao destrutiva, e o
   azul solido de botao primario pesava demais ao lado das pilulas de filtro. */
.recarregar {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    margin-left: auto;
}

/* Dados com mais de meia hora: o horario fica em ambar para chamar o olho
   sem bloquear nada. */
.recarregar .envelhecido { color: var(--warn); font-weight: 700; }

/* BLOCO TECNICO RECOLHIVEL (Sistema > E-mails)
   Assunto e caminho de arquivo sao dados de MANUTENCAO, nao de operacao. Na
   tabela principal eles empurravam para fora da tela justamente as colunas que
   respondem a pergunta do dia a dia (quem recebe copia oculta, quantos sairam).
   Ficam aqui, fechados por padrao, a um clique de distancia. */
.detalhe-tecnico {
    margin-top: 18px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 12px 16px;
}

.detalhe-tecnico > summary {
    cursor: pointer;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--accent-ink);
    list-style: none;
}

.detalhe-tecnico > summary::-webkit-details-marker { display: none; }

/* Triangulo proprio: o nativo varia entre navegadores e nao herda a cor. */
.detalhe-tecnico > summary::before {
    content: "▸";
    display: inline-block;
    margin-right: 7px;
    transition: transform .15s;
}

.detalhe-tecnico[open] > summary::before { transform: rotate(90deg); }

.detalhe-tecnico > summary:hover { text-decoration: underline; }

.detalhe-tecnico table { margin-top: 12px; }

.detalhe-tecnico code {
    background: var(--elevated);
    border: 1px solid var(--line-soft);
    border-radius: 5px;
    padding: 1px 5px;
    font-size: 11.5px;
    word-break: break-all;
}


/* PILULA DE ACAO
   Mesma linguagem visual das pilulas de filtro (.seg-sub), porem para algo que
   EXECUTA em vez de filtrar. Le as mesmas variaveis --cat / --cat-bg dos
   .tom-*, entao mudar a cor e so trocar a classe do tom - nenhum CSS novo por
   cor, e nada sai do tom pastel do resto da tela.

   O peso extra (fonte 700 e o hover com sombra) e o que diferencia de um
   filtro: pilula de acao dispara uma consulta a API, pilula de filtro nao. */
.pill-acao {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 15px;
    font-size: 11.5px;
    font-weight: 700;
    border-radius: 999px;
    background: var(--cat-bg, var(--elevated));
    border: 1px solid var(--cat, var(--line));
    color: var(--cat, var(--ink));
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: filter .15s, box-shadow .15s;
}

.pill-acao:hover { filter: brightness(.94); box-shadow: var(--shadow); }

/* O simbolo de recarregar gira ao passar o mouse - so na pilula, e so no
   hover: animacao permanente em tela de relatorio cansa. */
.pill-acao .pill-ico { font-size: 13px; line-height: 1; transition: transform .35s; }
.pill-acao:hover .pill-ico { transform: rotate(180deg); }

.seg-sub a {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6.5px 13px;
    font-size: 11.5px;
    border-radius: 999px;
    background: var(--cat-bg, var(--surface));
    border: 1px solid var(--cat, var(--line));
    color: var(--cat, var(--ink));
    transition: border-color .15s, background .15s, color .15s;
}

.seg-sub a:hover { filter: brightness(.92); }

/* Departamento sem nenhum ticket no filtro atual: perde a cor e vira cinza.
   Assim a cor passa a significar "tem chamado aqui" - continua clicavel e
   legivel, so sai da frente. */
.seg-sub a.vazia {
    background: transparent;
    border-color: var(--line);
    color: var(--muted);
    font-weight: 600;
}

.seg-num {
    min-width: 20px;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .6);
    border: 1px solid var(--line);
    font-size: 11px;
    font-weight: 700;
    text-align: center;
    color: inherit;
}

/* Aba escolhida: a mesma cor, agora preenchida. Sem isto o roxo do .seg
   sobrescreveria a cor do departamento e a selecao ficaria sempre roxa. */
.seg-sub a.active {
    background: var(--cat, #2A0669);
    border-color: var(--cat, #2A0669);
    color: #fff;
    box-shadow: none;
}

.seg-sub a.active .seg-num {
    background: rgba(255, 255, 255, .2);
    border-color: rgba(255, 255, 255, .3);
    color: #fff;
}

/* Paginacao */
.pagination {
    display: flex; gap: 6px;
    align-items: center; justify-content: center;
    margin: 20px 0 10px;
    flex-wrap: wrap;
}

.pagination a, .pagination .current {
    padding: 6.5px 12px;
    border-radius: 8px;
    font-size: 13px;
    text-decoration: none;
    border: 1px solid var(--line);
    color: var(--muted);
    background: var(--surface);
    transition: border-color .15s, color .15s;
}

.pagination a:hover { border-color: var(--accent); color: var(--accent-ink); }
.pagination .current {
    background: linear-gradient(135deg, #43159C, #2A0669);
    color: #fff; font-weight: 700; border-color: transparent;
}

/* KPIs */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(165px, 1fr));
    gap: 13px;
    margin: 2px 0 18px;
}

.kpi {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 15px 17px;
    display: flex; flex-direction: column; gap: 5px;
    box-shadow: var(--shadow);
    position: relative;
    overflow: hidden;
}

.kpi::before {
    content: '';
    position: absolute; inset: 0 auto auto 0;
    width: 100%; height: 3px;
    background: linear-gradient(90deg, #43159C, #22d3ee);
    opacity: .8;
}

.kpi-label { color: var(--muted); font-size: 12px; font-weight: 500; }
.kpi-value { font-size: 27px; font-weight: 800; letter-spacing: -.02em; }
.kpi-delta { font-size: 12px; font-weight: 700; }
.delta-up { color: var(--ok); }
.delta-down { color: var(--err); }
.kpi-ok { color: var(--ok); }
.kpi-warn { color: #d97706; }
.kpi-err { color: var(--err); }

/* Cards / grid */
.grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 13px;
    margin-bottom: 18px;
    align-items: start;
}

/* Impede que canvas/conteudo largo estoure as colunas do grid */
.grid-2 > * { min-width: 0; }

.full-row { margin-bottom: 18px; }

.col-stack { display: flex; flex-direction: column; gap: 13px; }
.col-stack > * { min-width: 0; }

.card canvas { max-width: 100% !important; }

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

.card h3 { margin: 0 0 15px; font-size: 14.5px; font-weight: 700; }

/* Caixa de grafico com altura fixa (nao estica no mobile) */
.chart-box { position: relative; height: 260px; }
.chart-box-sm { height: 180px; }
/* Resumo em numeros acima do grafico de recebiveis */
.aging-topo {
    display: flex;
    gap: 28px;
    flex-wrap: wrap;
    margin: 0 0 12px;
}
.aging-topo b { display: block; font-size: 17px; font-weight: 600; color: var(--brand); }
.aging-topo .aging-vencido { color: var(--err); }

/* Grafico de largura total: mais alto, porque tem 24 meses no eixo x */
.chart-box-alto { height: 320px; }

/* ============================================================
   RELATORIOS > PROJECAO 24 MESES
   ============================================================ */

/* OS SEIS CAMPOS EM GRADE, e nao em linha.

   Enfileirados, "Ticket de quem entra" e "Ticket de quem sai" ficariam a meia
   tela um do outro - e sao justamente os dois que so fazem sentido lidos como
   par. `auto-fit` com minimo de 190px poe tres por linha no monitor e um no
   celular, sem breakpoint escrito a mao. */
.projecao-campos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 14px 18px;
}

.projecao-campos .field { margin: 0; }

/* A VARIACAO ao lado do numero do cartao de resumo.

   Menor e mais leve que o valor de propósito: o numero grande e o destino
   ("em 24 meses: 521 clientes"), e este e o comentario sobre ele ("+121"). Com
   o mesmo peso, os dois competiam e a leitura travava no meio.

   Verde por padrao porque a projecao costuma subir; a classe `negativo` troca
   para vermelho quando nao sobe - e esse e o caso que ninguem pode deixar
   passar batido. */
.resumo-nota {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--ok);
}

.resumo-nota.negativo { color: var(--err); }

@media (max-width: 900px) {
    .chart-box { height: 230px; }
    .chart-box-sm { height: 160px; }
    .chart-box-alto { height: 260px; }
}

.card table { box-shadow: none; }
.card table.compact th, .card table.compact td { padding: 7.5px 9px; font-size: 12.8px; }

/* Ranking servidores */
/* ============================================================
   RANKINGS (top afiliados, servidores por clientes).

   Duas linhas por item: nome e numero em cima, barra embaixo,
   ocupando a largura toda. Antes eram tres colunas na mesma
   linha, e a do nome tinha 140px fixos - e-mail de afiliado nao
   cabe em 140px, entao a coluna que MAIS importa era justamente
   a que aparecia cortada, para sobrar espaco para a barra.
   ============================================================ */
.rank {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.rank-scroll { max-height: 340px; overflow-y: auto; padding-right: 6px; scrollbar-width: thin; }

.rank-row {
    display: grid;
    grid-template-columns: 26px minmax(0, 1fr) auto;
    grid-template-areas:
        "pos nome  total"
        "pos barra barra";
    align-items: center;
    gap: 3px 10px;
    padding: 7px 9px;
    border-radius: 9px;
}

/* Posicao: e um RANKING, e ranking se le pela ordem. Sem o numero,
   a unica pista da colocacao era o comprimento da barra. */
.rank-pos {
    grid-area: pos;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-align: center;
    font-variant-numeric: tabular-nums;
}
.rank-topo .rank-pos { color: var(--brand); }

.rank-name {
    grid-area: nome;
    font-size: 13px;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rank-total {
    grid-area: total;
    display: flex;
    align-items: baseline;
    gap: 6px;
    font-size: 13px;
    white-space: nowrap;
}
.rank-total b { font-size: 15px; font-weight: 600; color: var(--brand); }
.rank-pct { color: var(--muted); font-size: 11.5px; }

.rank-bar-wrap {
    grid-area: barra;
    background: var(--line-soft);
    border-radius: 999px;
    height: 6px;
    overflow: hidden;
}
/* Cor solida da marca, sem degrade para ciano: a barra mede uma
   coisa so, e o degrade sugeria uma escala que nao existe. */
.rank-bar {
    background: rgba(42, 6, 105, .32);
    height: 100%;
    border-radius: 999px;
    transition: width .3s;
}
.rank-topo .rank-bar { background: var(--brand); }

/* ============================================================
   FORMULARIO DE EDICAO
   ============================================================ */
.edit-form { display: flex; flex-direction: column; gap: 14px; }

.edit-form fieldset.card { border: 1px solid var(--line); margin: 0; }

/* Duas colunas de cards (Endereco|Financeiro, Infra|Status) */
.form-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 14px;
    align-items: start;
}

/* Grades do card largo de dados cadastrais */
/* Uma coluna: cada campo na sua linha, sempre.
   O .form-grid puro e `auto-fit`, entao ele ENCAIXA dois campos lado a lado
   se couberem - util na maioria dos casos, atrapalha quando a ordem vertical
   e o que importa (dominio numa linha, plano na seguinte). */
.form-grid.cols-1 { grid-template-columns: 1fr; }
.form-grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
.form-grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.form-grid.cols-6 { grid-template-columns: repeat(6, 1fr); }
.field.span-3 { grid-column: span 3; }
.field.s2 { grid-column: span 2; }   /* 1/3 numa grade de 6 */
.field.s3 { grid-column: span 3; }   /* 1/2 numa grade de 6 */

/* Barra hero do editar cliente */
.edit-hero {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    background: #334155;
    border-radius: var(--radius);
    padding: 18px 24px;
    margin: 4px 0 26px;
    color: #fff;
    box-shadow: 0 8px 22px rgba(51, 65, 85, .28);
}

.hero-left { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

.hero-kicker {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .12em;
    text-transform: uppercase;
    opacity: .75;
}

.hero-title {
    font-size: 21px;
    font-weight: 800;
    letter-spacing: -.01em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hero-domain {
    color: #fff;
    opacity: .88;
    font-size: 13.5px;
    text-decoration: none;
    width: fit-content;
    border-bottom: 1px dashed rgba(255, 255, 255, .5);
}

.hero-domain:hover { opacity: 1; border-bottom-style: solid; }

.hero-badge {
    background: var(--surface);
    color: #334155;
    border-radius: 999px;
    padding: 7px 16px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .04em;
    box-shadow: 0 4px 14px rgba(15, 23, 42, .3);
    white-space: nowrap;
}

.edit-form legend {
    padding: 2px 10px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--accent-ink);
    background: rgba(42, 6, 105, .07);
    border: 1px solid rgba(42, 6, 105, .18);
    border-radius: 999px;
}

.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 13px 16px;
}

.field { display: flex; flex-direction: column; gap: 5px; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.field.span-2 { grid-column: span 2; }
.field.field-sm { max-width: 140px; }

.field input, .field select, .field textarea {
    padding: 9px 12px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 9px;
    color: var(--ink);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 400;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}

.field textarea { resize: vertical; }

/* Textarea alto o bastante para ler a descricao do plano sem rolar.
   Altura em px, e nao `rows`: rows conta LINHAS de texto e o resultado
   final muda com a fonte, entao a mesma marcacao dava caixas de alturas
   diferentes em telas diferentes. */
.field textarea.alto { height: 150px; }

.field input:focus, .field select:focus, .field textarea:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(42, 6, 105, .13);
    background: var(--surface);
}

.field input.invalid, .field select.invalid {
    border-color: var(--err);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .1);
}

.field-error { color: var(--err); font-size: 12px; font-weight: 600; }

/* ==========================================================================
   DADOS DE ACESSO x PAINEL (Clientes > editar).

   Verde e vermelho na borda, e nao um aviso no topo do formulario: o campo
   que falta tem de ser encontravel de relance num formulario com dezenas
   deles. O fundo levissimo faz o estado sobreviver a quem nao distingue bem
   as duas cores - a diferenca de claro/escuro entre os dois fundos ja separa,
   e a dica escrita embaixo diz o que fazer sem depender de cor nenhuma.
   ========================================================================== */
.field input.campo-ok, .field select.campo-ok {
    border-color: var(--ok);
    background: rgba(5, 150, 105, .05);
}
.field input.campo-erro, .field select.campo-erro {
    border-color: var(--err);
    background: rgba(220, 38, 38, .05);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .08);
}

.campo-dica { font-size: 11.5px; font-weight: 600; color: var(--muted); min-height: 1px; }
.campo-dica.erro { color: var(--err); }

/* A regra do painel, acima dos campos. Azul de informacao: nao e alarme -
   conta o que aquele painel exige, e e o que explica o vermelho abaixo. */
.acesso-regra {
    margin: 0 0 14px;
    padding: 9px 13px;
    border-radius: var(--radius-sm);
    background: rgba(37, 99, 235, .06);
    border: 1px solid rgba(37, 99, 235, .18);
    color: #1e40af;
    font-size: 12.5px;
    font-weight: 500;
}
.acesso-regra[hidden] { display: none; }

/* Confirmacao cruzada valor <-> periodo */
.field input.confirm-needed, .field select.confirm-needed {
    border-color: var(--warn);
    background: rgba(245, 158, 11, .06);
    animation: pulse-warn 1s ease-in-out infinite alternate;
}

@keyframes pulse-warn {
    from { box-shadow: 0 0 0 3px rgba(245, 158, 11, .15); }
    to   { box-shadow: 0 0 0 6px rgba(245, 158, 11, .3); }
}

.confirm-hint { color: #b45309; font-size: 12px; font-weight: 700; }

.form-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    padding-bottom: 10px;
}

.form-actions .btn { text-decoration: none; display: inline-block; }

@media (max-width: 1000px) {
    .form-cols { grid-template-columns: 1fr; }
    .form-grid.cols-4 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 700px) {
    .field.span-2 { grid-column: span 1; }
    .field.span-3 { grid-column: span 1; }
    .field.s2, .field.s3 { grid-column: span 1; }
    .form-grid.cols-4 { grid-template-columns: 1fr; }
    .form-grid.cols-3 { grid-template-columns: 1fr; }
    .form-grid.cols-6 { grid-template-columns: 1fr; }
}

/* ============================================================
   CARD RESUMO (destaque de totais)
   ============================================================ */
.resumo-card {
    display: flex;
    gap: 40px;
    flex-wrap: wrap;
    /* Tom SOLIDO. Era um degrade de roxo para ciano; em cartao largo os dois
       tons ficavam visiveis lado a lado e pareciam dois blocos colados. Um
       roxo bem claro so, com a borda dando o contorno. */
    background: rgba(42, 6, 105, .07);
    border: 1px solid rgba(42, 6, 105, .25);
    border-radius: var(--radius);
    padding: 15px 24px;
    margin: 2px 0 16px;
}

.resumo-item { display: flex; flex-direction: column; gap: 3px; }

.resumo-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--muted);
}

.resumo-valor { font-size: 20px; font-weight: 800; letter-spacing: -.01em; }
.resumo-valor.destaque { color: var(--ok); }

/* INTERRUPTOR DA RECARGA AUTOMATICA (Assinaturas).
   Fica dentro de um .resumo-item, mas nao e um numero - por isso o peso e o
   tamanho voltam ao normal: com font-weight 800 herdado do .resumo-valor, o
   contador "em 12s" competia com a quantidade de pendentes ao lado, que e a
   informacao que a pessoa abriu a tela para ver. */
/* AVISO dentro de um .field, abaixo do campo.
   Ambar e nao vermelho: nao e erro - o cadastro e valido e vai ser gravado.
   E uma consequencia que a pessoa precisa saber ANTES de confirmar. */
.hint-erro {
    display: block;
    margin-top: 6px;
    font-size: 12.5px;
    line-height: 1.45;
    color: #92400e;
    background: var(--bg-aviso);
    border: 1px solid #fde68a;
    border-radius: 8px;
    padding: 7px 10px;
}
.hint-erro[hidden] { display: none; }

.auto-recarga {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 14px;
    font-weight: 500;
    color: var(--muted);
    cursor: pointer;
    /* Alvo de toque confortavel no celular sem esticar o cartao. */
    padding: 2px 0;
    user-select: none;
}
.auto-recarga input { width: 16px; height: 16px; cursor: pointer; accent-color: var(--brand); }
/* O contador muda de valor a cada segundo; largura minima evita o texto
   "pulando" entre "em 9s" e "em 30s" e mexendo no cartao inteiro. */
.auto-recarga span { min-width: 74px; }

/* ============================================================
   ELEMENTOS DA LISTAGEM DE COBRANCAS (estilo referencia)
   ============================================================ */
.num-badge {
    display: inline-grid;
    place-items: center;
    min-width: 26px;
    height: 26px;
    padding: 0 6px;
    border-radius: 7px;
    background: #dc2626;
    color: #fff;
    font-weight: 800;
    font-size: 12px;
}

/* A DATA DE VENCIMENTO usa a MESMA escala de faixas da coluna Pag. Dias.
   As duas colunas contam a mesma historia - uma com a data, outra com o
   numero de dias -, e se cada uma pintasse de um jeito a linha ficaria
   com dois sinais brigando. Uma classe por faixa, mesma cor nas duas. */
.data-atraso,
.data-proxima,
.data-grave,
.data-media,
.data-leve {
    font-weight: 700;
    padding: 4px 10px;
    border-radius: 7px;
    white-space: nowrap;
}

/* `.data-atraso` (vermelho claro unico) continua para as OUTRAS telas -
   avisos e fechamento -, onde a pergunta e so "venceu ou nao". */
.data-atraso {
    background: rgba(239, 68, 68, .14);
    color: #b91c1c;
}

.data-proxima {
    background: rgba(245, 158, 11, .16);
    color: #b45309;
}

/* Ver o bloco das faixas em .dias-badge logo abaixo: o vermelho e CHEIO,
   os outros dois sao fundo lavado. */
.data-grave {
    background: #dc2626;
    color: #fff;
}

.data-media {
    background: rgba(234, 88, 12, .18);
    color: #c2410c;
}

.data-leve {
    background: rgba(250, 204, 21, .28);
    color: #854d0e;
}

/* VALOR PAGO CONFRONTADO COM O ESPERADO (tela de Pagamentos).
   Todo valor comparavel ganha pilula - o que muda e a COR. A moldura passa
   a significar "este valor foi conferido", e nao "deu problema": a linha
   sem pilula nenhuma e a que nao tem vinculo, e portanto nao foi conferida
   contra nada. Antes essa mesma ausencia significava "bateu certo", que sao
   coisas opostas.

   `white-space: nowrap` porque "R$ 1.234,56" nao pode quebrar dentro da
   moldura; `display: inline-block` para o padding vertical valer - em
   inline puro ele nao empurra a linha e a moldura fica cortada. */
.valor-menor,
.valor-maior,
.valor-igual {
    display: inline-block;
    padding: 3px 9px;
    border-radius: 7px;
    white-space: nowrap;
}

.valor-menor {
    background: rgba(239, 68, 68, .16);
    color: #b91c1c;
}

.valor-maior {
    background: rgba(16, 185, 129, .18);
    color: #047857;
}

/* Cinza bem lavado e SEM peso de cor: pagamento certo e a maioria das
   linhas, entao esta pilula aparece dezenas de vezes por tela. Ela precisa
   dar a moldura sem disputar atencao com as duas de cima, que sao as que
   pedem acao. */
.valor-igual {
    background: rgba(92, 107, 132, .12);
    color: var(--muted);
}

.dias-badge {
    display: inline-grid;
    place-items: center;
    min-width: 30px;
    height: 24px;
    padding: 0 8px;
    border-radius: 7px;
    font-weight: 800;
    font-size: 12.5px;
}
/* ATRASO EM TRES FAIXAS, do amarelo ao vermelho conforme o tempo passa.
   Um vermelho unico dizia apenas "esta vencida"; a lista de atrasados
   inteira ficava da mesma cor e nao ajudava a escolher por onde comecar.

   As tres sao mais SATURADAS que as pilulas de dado da linha (telefone,
   dominio): aqui a cor e o recado, nao a moldura.

   O amarelo puro nao da contraste com texto claro - por isso o fundo vem
   mais forte (.28) e a letra em marrom escuro, e nao no tom da propria cor
   como nas outras duas.

   O VERMELHO E CHEIO, os outros dois sao fundo lavado. Como tres tintas da
   mesma familia e na mesma opacidade, vermelho e laranja quase nao se
   distinguiam - separa-los so mexendo no matiz exigiria empurrar o laranja
   para o amarelo, e ai ele colidiria com a faixa de baixo. Trocar a
   INTENSIDADE resolve num eixo que nenhuma outra faixa usa: a mais grave e
   a unica pilula preenchida da linha, entao ela salta antes da leitura. */
.dias-badge.atraso-grave { background: #dc2626;                 color: #fff; }
.dias-badge.atraso-medio { background: rgba(234, 88, 12, .18);  color: #c2410c; }
.dias-badge.atraso-leve  { background: rgba(250, 204, 21, .28); color: #854d0e; }

/* `.atraso` (vermelho unico) fica para as OUTRAS telas que usam dias-badge -
   avisos, fechamento e margem de aumento -, onde a pergunta continua sendo
   so "venceu ou nao". Apagar aqui as apagaria junto. */
.dias-badge.atraso { background: rgba(239, 68, 68, .16); color: #b91c1c; }
.dias-badge.proximo { background: rgba(245, 158, 11, .18); color: #b45309; }
.dias-badge.folga { background: rgba(92, 107, 132, .12); color: var(--muted); }

.congela-flag {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 24px;
    border-radius: 7px;
    background: rgba(34, 211, 238, .25);
    color: #0e7490;
    font-size: 14px;
}

/* Cupom + contador de vendas (afiliados) */
.cupom-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 2px 10px 2px 0;
    white-space: nowrap;
}

.venda-badge {
    display: inline-grid;
    place-items: center;
    min-width: 22px;
    height: 20px;
    padding: 0 6px;
    border-radius: 999px;
    background: rgba(239, 68, 68, .14);
    border: 1px solid rgba(239, 68, 68, .35);
    color: #dc2626;
    font-weight: 800;
    font-size: 12px;
}

/* Card de detalhe do afiliado (vendas) */
.detalhe-card {
    background: var(--surface);
    border: 1px solid rgba(42, 6, 105, .35);
    border-radius: var(--radius);
    padding: 16px 18px 6px;
    margin: 0 0 22px;
    box-shadow: 0 4px 14px rgba(15, 23, 42, .06);
}

.detalhe-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px 24px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.detalhe-titulo {
    display: flex;
    align-items: center;
    gap: 8px 14px;
    flex-wrap: wrap;
}

.detalhe-titulo h3 { margin: 0; font-size: 17px; }

.chips-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.stat-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--chip);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 5px 12px;
    font-size: 12.5px;
    white-space: nowrap;
}

.stat-chip i {
    font-style: normal;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
}

.stat-chip.chip-saldo {
    background: rgba(22, 163, 74, .10);
    border-color: rgba(22, 163, 74, .35);
}

.stat-chip.chip-saldo b { color: var(--ok); }

tr.row-sel td { background: rgba(42, 6, 105, .08); }

.status-dot {
    display: inline-block;
    width: 13px;
    height: 13px;
    border-radius: 50%;
}
.status-dot.on { background: var(--ok); box-shadow: 0 0 6px rgba(5, 150, 105, .5); }
.status-dot.off { background: var(--err); }

/* ============================================================
   TICKETS - conversa (bolhas cliente x equipe)
   ============================================================ */
.talk { display: flex; flex-direction: column; gap: 12px; margin-top: 16px; }

.msg-bubble {
    max-width: 78%;
    padding: 13px 17px;
    border-radius: 13px;
    box-shadow: var(--shadow);
}

.msg-cliente {
    align-self: flex-start;
    background: rgba(245, 158, 11, .10);
    border: 1px solid rgba(245, 158, 11, .30);
    border-bottom-left-radius: 4px;
}

.msg-equipe {
    align-self: flex-end;
    background: rgba(42, 6, 105, .07);
    border: 1px solid rgba(42, 6, 105, .22);
    border-bottom-right-radius: 4px;
}

.msg-meta { display: flex; gap: 10px; align-items: baseline; margin-bottom: 6px; font-size: 13px; }
.msg-texto { font-size: 14px; line-height: 1.55; word-break: break-word; }
.msg-texto p { margin: 0 0 8px; }
.msg-texto p:last-child { margin-bottom: 0; }
.msg-texto ul, .msg-texto ol { margin: 6px 0; padding-left: 22px; }
.msg-texto img { max-width: 100%; border-radius: 8px; }
.msg-texto a { color: var(--accent); }

/* ---- BLOCO DE CODIGO NA CONVERSA -----------------------------------------

   O sanitizador deixa <pre> e <code> passarem de proposito (ver POLITICA_TICKET
   em TicketWriteRepository): quem manda uma linha de comando precisa que espaco
   e quebra cheguem do outro lado como foram escritos.

   So que o <pre> vinha SEM ESTILO NENHUM, e o padrao do navegador e
   `white-space: pre` - a linha nao quebra NUNCA. Um `nohup java -Duser.dir=...`
   de duzentos caracteres esticava o balao para fora do cartao, o cartao para
   fora da coluna, e a pagina inteira ganhava rolagem horizontal. Foi assim que
   apareceu no chamado 20260831200345.

   pre-wrap, e NAO overflow com barra de rolagem: as quebras que o cliente
   escreveu continuam valendo (e por isso o <pre> existe), e o que nao couber
   dobra para a linha de baixo. Barra de rolagem dentro de um balao de conversa
   e fácil demais de nao ver - quem atende leria meia linha de comando achando
   que era a linha inteira, que e justamente o tipo de erro que este chamado
   veio relatar.

   min-width: 0 no balao porque o flex/grid do pai da aos filhos largura minima
   igual ao conteudo: sem isto, o proprio <pre> continuaria mandando na largura
   mesmo com o wrap ligado.

   AS DUAS TELAS DO CLIENTE JA TINHAM ISTO - a publica (`.ch-fala pre`, no
   publico.css) e a do Portal (`.msg-body pre`). So a tela da EQUIPE ficou de
   fora, e por isso o mesmo chamado abria certo para o cliente e torto para
   quem atende.

   Elas resolvem com `font: inherit`, e aqui e MONOESPACADA de proposito - nao
   e descuido de padronizacao. La o <pre> e estrutural: envolve a mensagem
   INTEIRA para preservar as quebras de linha, e monoespacar tudo deixaria toda
   conversa com cara de terminal. Aqui ele so aparece quando o e-mail do cliente
   trouxe um de verdade, entao ele marca CODIGO - e alinhamento de coluna e
   metade da utilidade de ler uma linha de comando. */
.msg-texto pre,
.msg-texto code {
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
}

.msg-texto pre {
    max-width: 100%;
    margin: 8px 0;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--elevated);
    line-height: 1.5;
}

/* <code> solto no meio da frase: so a marca, sem virar um bloco. */
.msg-texto code {
    padding: 1px 5px;
    border-radius: 5px;
    background: var(--elevated);
}
.msg-texto pre code {
    padding: 0;
    background: none;
    font-size: inherit;
}

/* Tabela colada de um e-mail tambem estica o cartao - mesmo motivo, outra tag. */
.msg-texto table { max-width: 100%; }

.msg-bubble { min-width: 0; }

/* ============================================================
   ENVIO PELO CANAL SEGURO, dentro do balao da conversa.

   O cliente mandou chave PIX, comprovante ou CPF pelo campo
   separado da pagina publica. O conteudo NAO esta neste HTML -
   mora cifrado em ticket_sigilo e so vem por POST, para quem tem
   TICKETS_SIGILO_VER.

   VERDE-AGUA, e nao a cor do balao: e a unica coisa da conversa
   que precisa de um segundo gesto para ser lida. Se parecesse com
   o resto, o olho passaria por cima dela como passa por qualquer
   mensagem - e o ponto e justamente parar.
   ============================================================ */
.msg-sigilo {
    margin-top: 4px;
    padding: 12px 14px;
    border: 1px dashed rgba(13, 148, 136, .45);
    border-radius: 11px;
    background: rgba(13, 148, 136, .07);
}

.msg-sigilo-topo {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13.5px;
    color: #0f766e;
    margin-bottom: 8px;
}
.msg-sigilo-cadeado { font-size: 15px; line-height: 1; }

.msg-sigilo-nota {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--muted);
}
/* A nota depois do conteudo revelado ganha ar; a que fica sozinha, nao. */
.msg-sigilo-conteudo + .msg-sigilo-nota { margin-top: 8px; }

/* DEU ERRADO AO REVELAR (sessao vencida, token velho, servidor fora do ar).
   Vermelho e nao cinza: as outras notas desta area sao explicacoes que se
   lê uma vez, e esta e a resposta a um clique que acabou de falhar - se
   parecesse com elas, passaria por mais uma linha de instrucao e a pessoa
   ficaria clicando no botao sem entender por que nada acontece. */
.msg-sigilo-erro {
    margin-top: 8px;
    font-weight: 600;
    /* var(--err), o mesmo do .field-error - e nao um vermelho escrito aqui.
       A variavel muda com o tema (#dc2626 no claro, #f87171 no escuro); um
       hex fixo passaria em um dos dois e reprovaria no outro. */
    color: var(--err);
}

/* O <pre> preserva quebra de linha e espaco: dado de conta e chave PIX
   chegam colados de outro lugar, e reflow embaralha justamente os digitos
   que a pessoa vai copiar. `pre-wrap` para nao criar barra horizontal. */
.msg-sigilo-conteudo {
    margin: 0;
    padding: 11px 13px;
    border: 1px solid var(--line);
    border-radius: 9px;
    background: var(--surface);
    color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-word;
    /* Um comprovante colado inteiro tem trinta linhas; sem teto, ele
       empurraria o resto da conversa para fora da tela. */
    max-height: 340px;
    overflow: auto;
    -webkit-user-select: all;
    user-select: all;
}

.msg-sigilo-btn {
    margin-top: 2px;
    border-color: rgba(13, 148, 136, .45);
    color: #0f766e;
    background: var(--surface);
}
.msg-sigilo-btn:hover {
    background: rgba(13, 148, 136, .12);
    border-color: rgba(13, 148, 136, .6);
    color: #0d9488;
}

/* ============================================================
   TRIAGEM PENDENTE: o card que ocupa o lugar do editor quando o
   chamado veio da caixa de e-mail e ninguem classificou.

   AMBAR, e nao vermelho: nao ha erro nem risco aqui, ha uma
   etapa faltando. Vermelho na tela de quem atende dezenas de
   chamados por dia vira ruido, e no dia em que houver um
   problema de verdade ninguem olha.
   ============================================================ */
.card-triagem {
    border-color: rgba(180, 83, 9, .38);
    background: linear-gradient(180deg, rgba(245, 158, 11, .07), var(--surface) 60%);
}
.card-triagem h3 { color: var(--warn); }

.triagem-form {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0;
}
.triagem-form label { font-size: 13px; font-weight: 600; color: var(--muted); }
.triagem-form select {
    min-width: 240px;
    padding: 9px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink);
    font: inherit;
    font-size: 14px;
}
.triagem-form select:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* ---- O MODAL ----

   Usa a moldura dos outros popovers da tela; o que muda e a largura e o
   fio ambar no topo. 460px porque aqui ha um paragrafo de explicacao, e
   nao um par rotulo/valor - nos 400px do padrao a frase quebrava em cinco
   linhas curtas.

   `width`, e nao `max-width`: `.pop-modal` ja declara `width: min(400px,
   ...)`, e um `max-width` sozinho nao aumentaria nada. */
.pop-triagem {
    width: min(460px, calc(100vw * var(--escala-inv, 1) - 32px));
    overflow: hidden;   /* segura o fio do topo dentro do canto arredondado */
}

/* O mesmo fio que o card de triagem tem, na mesma cor: os dois falam da
   mesma pendencia, e a tela ganha a ligacao sem repetir texto. */
.pop-triagem .pop-head {
    border-top: 3px solid var(--warn);
    align-items: flex-start;
}
.pop-triagem .pop-head b {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    line-height: 1.4;
}
.triagem-selo { flex: none; font-size: 15px; color: var(--warn); }

/* `.pop-modal` tem padding zero de proposito (a barra de titulo vai de
   ponta a ponta). Quem espaça e o corpo - e o modal de triagem nao tinha
   nenhum, por isso o texto encostava nas bordas. */
.pop-corpo { padding: 16px 18px 18px; }

.triagem-lead {
    margin: 0 0 8px;
    font-size: 14px;
    line-height: 1.6;
}
.triagem-nota {
    margin: 0 0 18px;
    font-size: 12.5px;
    line-height: 1.55;
    color: var(--muted);
}
.triagem-rotulo {
    display: block;
    margin: 0 0 6px;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--muted);
}
.pop-triagem .pop-select { padding: 10px 12px; font-size: 14px; }

/* Botoes lado a lado e alinhados a direita. Empilhados e em 100% de
   largura, os dois pesavam igual - e o "Ler antes", que e a saida, parecia
   a acao principal por estar em cima. */
.triagem-acoes {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 18px;
}
@media (max-width: 420px) {
    .triagem-acoes { flex-direction: column-reverse; }
    .triagem-acoes .btn { width: 100%; }
}

[data-tema="escuro"] .card-triagem {
    border-color: rgba(251, 191, 36, .34);
    background: linear-gradient(180deg, rgba(251, 191, 36, .08), var(--surface) 60%);
}

/* ============================================================
   AVISO DA EQUIPE, acima do editor de resposta.

   O que se escreve na resposta vai para tres lugares fora daqui:
   o Portal do Cliente, a pagina publica do link (que circula por
   e-mail e vale como senha) e o corpo do e-mail enviado. Nenhum
   deles esta sob controle depois que sai.
   ============================================================ */
.aviso-sigilo-equipe {
    display: flex;
    gap: 11px;
    align-items: flex-start;
    margin: 0 0 14px;
    padding: 12px 14px;
    border: 1px solid rgba(180, 83, 9, .34);
    border-radius: var(--radius-sm);
    background: rgba(245, 158, 11, .09);
    font-size: 13px;
    line-height: 1.6;
    color: var(--ink);
}
.aviso-sigilo-equipe b { color: var(--warn); }
.aviso-sigilo-icone { flex: none; font-size: 16px; line-height: 1.3; }

/* O exemplo mascarado em fonte de largura fixa: e um modelo para copiar, e
   os asteriscos precisam ficar alinhados com o que substituem. */
.aviso-sigilo-exemplo {
    display: inline-block;
    padding: 1px 7px;
    border: 1px solid var(--line);
    border-radius: 6px;
    background: var(--surface);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    color: var(--ink);
    /* Sem `user-select: all`: este texto NAO e para ser copiado e colado -
       e um exemplo de formato. Facilitar a copia convidaria a mandar
       exatamente ele. */
}

[data-tema="escuro"] .aviso-sigilo-equipe {
    border-color: rgba(251, 191, 36, .34);
    background: rgba(251, 191, 36, .10);
}

/* Editor rich text (Quill) */
/* ALTURA DO EDITOR DE RESPOSTA.
   170px cabia umas 6 linhas: quem escrevia uma resposta de verdade - com
   passo a passo, ou com um print colado - trabalhava numa janelinha rolando
   sozinha, sem conseguir reler o que ja tinha escrito.

   `min-height`, e nao `height`: o editor continua crescendo se a resposta for
   maior ainda. max-height + overflow evita o oposto - uma resposta longa
   empurrando o botao Enviar para fora da tela. */
.editor-box {
    background: var(--surface);
    min-height: 510px;
    max-height: calc(70vh * var(--escala-inv, 1));
    overflow-y: auto;
    border-radius: 0 0 9px 9px;
}

/* Em tela baixa (notebook 768px de altura), 510px + barra + cabecalho nao
   sobra nada para o botao. Aqui a altura vira proporcional a janela. */
@media (max-height: 800px) {
    .editor-box { min-height: calc(55vh * var(--escala-inv, 1)); }
}
.ql-toolbar.ql-snow { border: 1px solid var(--line); border-radius: 9px 9px 0 0; background: var(--elevated); }
.ql-container.ql-snow { border: 1px solid var(--line); border-top: none; border-radius: 0 0 9px 9px; font-family: inherit; font-size: 14px; }

/* =========================================================
   REDIMENSIONAR IMAGEM COLADA NO EDITOR

   Um print de tela inteira entra com 1920px de largura e empurra
   o resto do texto. Antes so dava para apagar e recortar a imagem
   por fora; agora e so clicar nela.

   O `cursor: pointer` existe para a imagem PARECER clicavel - sem
   ele ninguem descobre que da para redimensionar, e o recurso vira
   um segredo entre mim e este comentario.
   ========================================================= */
.ql-editor img {
    max-width: 100%;
    height: auto;
    cursor: pointer;
}
.ql-editor img.img-selecionada {
    outline: 2px solid var(--primary, #25006b);
    outline-offset: 2px;
}

/* A barra flutua sobre o editor, ancorada na imagem pelo JS.
   position: fixed - e nao absolute - porque o .editor-box tem
   overflow-y: auto: em absolute, a barra seria cortada pela borda
   do editor quando a imagem estivesse perto do topo. */
.img-barra {
    position: fixed;
    z-index: 60;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 5px 6px;
    background: var(--elevated, #fff);
    border: 1px solid var(--line, #e6e9f0);
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(16, 24, 40, .14);
    font-size: 12px;
}
.img-barra button {
    border: 1px solid transparent;
    background: transparent;
    border-radius: 6px;
    padding: 4px 9px;
    font: inherit;
    color: var(--text, #16203a);
    cursor: pointer;
}
.img-barra button:hover { background: var(--surface, #f5f7fb); }
.img-barra button.ativo {
    background: var(--primary, #25006b);
    border-color: var(--primary, #25006b);
    color: #fff;
}
.img-barra .img-barra-medida {
    color: var(--muted, #6b7280);
    padding-left: 6px;
    margin-left: 2px;
    border-left: 1px solid var(--line, #e6e9f0);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

@media (max-width: 900px) {
    .msg-bubble { max-width: 95%; }
}

/* ============================================================
   MODAL DE CONFIRMACAO + LOADING NOS BOTOES
   ============================================================ */
.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 300;
    background: rgba(15, 23, 42, .45);
    backdrop-filter: blur(3px);
    display: grid;
    place-items: center;
    padding: 20px;
}

/* O atributo hidden precisa vencer o display:grid acima */
.modal-backdrop[hidden] { display: none; }

.modal {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 16px;
    box-shadow: 0 24px 60px rgba(16, 24, 40, .25);
    padding: 24px 26px;
    width: 100%;
    max-width: 440px;
    animation: modal-pop .16s ease-out;
}

@keyframes modal-pop {
    from { transform: scale(.96) translateY(6px); opacity: 0; }
    to   { transform: scale(1) translateY(0); opacity: 1; }
}

/* ---- MODAL DOS LINKS ATIVOS DA CENTRAL ----
   Os 440px do modal padrao servem a um recado; aqui ha uma TABELA de seis
   colunas para comparar linha a linha, e nessa largura ela viraria uma coluna
   de palavras quebradas. Fora isso, herda tudo do `.modal`. */
.modal.modal-largo { max-width: 760px; }

/* Aviso do que o botao vermelho faz, ANTES da lista.

   Fica em ambar e nao em vermelho pelo mesmo motivo do icone que abre este
   modal: ele explica, nao alarma. Quem chegou aqui pode so estar conferindo
   quantos links existem, e uma faixa vermelha no topo faria essa pessoa
   fechar a tela. */
.aviso-links {
    margin: 12px 0 14px;
    padding: 10px 13px;
    border: 1px solid rgba(180, 83, 9, .30);
    border-left: 3px solid rgba(180, 83, 9, .70);
    border-radius: 9px;
    background: rgba(180, 83, 9, .07);
    color: #92400e;
    font-size: 13px;
    line-height: 1.55;
}
.aviso-links strong { color: #7c2d12; }

[data-tema="escuro"] .aviso-links {
    /* No escuro o texto tem de clarear, e nao so o fundo escurecer: #92400e
       sobre superficie escura fica ilegivel. */
    border-color: rgba(251, 191, 36, .34);
    border-left-color: rgba(251, 191, 36, .72);
    background: rgba(251, 191, 36, .10);
    color: #fcd9a4;
}
[data-tema="escuro"] .aviso-links strong { color: #fde9c8; }

/* A LISTA ROLA, o modal nao cresce sem fim.

   `.modal` nao tem `max-height` e o `.modal-backdrop` e `position: fixed` sem
   overflow, com `body.modal-open { overflow: hidden }`. Com a dezena de links
   que um cliente de tres meses acumula, o modal passava da altura da tela e
   ficava CORTADO sem forma nenhuma de rolar - inclusive o botao Fechar do
   rodape. A rolagem tem de ficar na caixa da tabela, e nao no modal inteiro,
   para o titulo, o aviso ambar e o rodape continuarem sempre visiveis.

   `--escala-inv` acompanha os botoes de tamanho da interface do menu: sem ele,
   quem esta com a interface em 125% ganha um modal proporcionalmente mais
   alto que a tela. */
#linksAtivosTabelaBox {
    max-height: calc(52vh * var(--escala-inv, 1));
    overflow-y: auto;
}

.tabela-links { width: 100%; font-size: 13px; }
.tabela-links td, .tabela-links th { white-space: nowrap; }
/* A ultima coluna e so o botao: encolhe ao conteudo e cola na direita, para
   os cinco campos de dado ficarem juntos e o botao separado deles. */
.tabela-links td:last-child { width: 1%; text-align: right; }

/* Marca do link que nasceu da cobranca que esta na tela. Nao usa `.pill-*`
   (aquelas sao pilulas de copiar, com --fc e botao dentro) - aqui e so um
   rotulo. */
/* O botao Revogar no segundo estagio ("Confirmar?"). Escurece e ganha anel:
   tem de ficar claro que ele MUDOU, senao o segundo clique acontece por
   inercia e a confirmacao nao confirma nada. */
.btn.btn-stop.btn-armado {
    background: linear-gradient(135deg, #dc2626, #991b1b);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, .22);
}

.pill-desta {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 7px;
    border: 1px solid rgba(42, 6, 105, .30);
    border-radius: 999px;
    background: rgba(42, 6, 105, .08);
    color: #43159C;
    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
}
[data-tema="escuro"] .pill-desta {
    border-color: rgba(167, 139, 250, .38);
    background: rgba(167, 139, 250, .16);
    color: #ddd0ff;
}

.modal h3 { margin: 0 0 8px; font-size: 17px; font-weight: 800; }
.modal p { margin: 0 0 4px; color: var(--muted); font-size: 14px; line-height: 1.55; }
.modal p b { color: var(--ink); }

.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 20px;
}

body.modal-open { overflow: hidden; }

/* Campo de texto para COPIAR (link de pagamento, pix copia-e-cola).
   Monoespacada porque e um endereco longo que se confere caractere a
   caractere, e break-all porque ele nao tem espaco nenhum onde quebrar -
   sem isso a caixa estoura e o modal ganha rolagem lateral. */
.link-copiavel {
    width: 100%;
    margin: 12px 0 0;
    padding: 12px 14px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 10px;
    color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12.5px;
    line-height: 1.6;
    word-break: break-all;
    resize: vertical;
}

.link-copiavel[hidden] { display: none; }

.link-copiavel:focus {
    outline: 2px solid var(--brand, #43159C);
    outline-offset: 1px;
}

/* ==========================================================================
   IDENTIFICADORES DO EXTRATO DETALHADO (COBR / TXID / E2E).

   Cada identificador e uma linha: ETIQUETA fixa a esquerda + codigo. A
   etiqueta e colorida por TIPO - a mesma cor em todas as linhas da tabela -
   entao da para varrer a coluna procurando "os e2e" sem ler nada. O codigo
   em si fica neutro: com 30+ caracteres aleatorios, cor so atrapalharia.
   ========================================================================== */
.ids { min-width: 240px; }

.id-linha {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 2px 0;
}

.id-rotulo {
    flex-shrink: 0;
    width: 38px;
    text-align: center;
    font-size: 9px;
    font-weight: 800;
    letter-spacing: .06em;
    padding: 2px 0;
    border-radius: 5px;
}

/* Mesmas familias de cor do resto do sistema: roxo = nosso vinculo (e o
   codigo que liga a cobranca), ciano e cinza = identificadores do banco. */
.id-cobr { background: rgba(42, 6, 105, .10);   color: #2A0669; }
.id-tx   { background: rgba(8, 145, 178, .10);  color: #0e7490; }
.id-e2e  { background: rgba(92, 107, 132, .10); color: var(--muted); }

/* Um clique seleciona o codigo inteiro: sao 30+ caracteres, e arrastar o
   mouse por eles deixa pedaco de fora sem ninguem notar. A elipse segura a
   largura da tabela; o codigo completo esta no title e na selecao. */
.id-valor {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 11.5px;
    color: var(--ink);
    user-select: all;
    -webkit-user-select: all;
    cursor: text;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 300px;
}

/* ==========================================================================
   CABECALHO DE TABELA ORDENAVEL (Extrato).

   O <a> ocupa a celula inteira (display: flex) para a area de clique ser o
   cabecalho todo, e nao so as letras - errar o alvo num cabecalho de 11px e
   fácil, e o erro recarrega a pagina a toa.
   ========================================================================== */
.th-ord {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    color: inherit;
    text-decoration: none;
    /* Anula o padding do th e devolve no link: assim o clique cobre a celula
       inteira em vez de deixar uma borda morta em volta. */
    margin: -10px -12px;
    padding: 10px 12px;
    border-radius: 6px;
    white-space: nowrap;
}

.th-ord:hover { background: rgba(42, 6, 105, .07); }
.th-ord.ativo { color: var(--accent); }

/* A SETA FICA A MOSTRA, sempre.
   Antes ela so aparecia no hover, para nao poluir o cabecalho com seis setas
   cinzas. O custo disso e maior que o ganho: quem nunca passou o mouse por ali
   nao tem como saber que a coluna ordena, e uma funcao que ninguem descobre
   equivale a uma funcao que nao existe. Discreta (opacidade baixa) resolve o
   ruido sem esconder a possibilidade; a da coluna ativa vem opaca e colorida,
   e continua sendo a unica que salta. */
.th-seta {
    font-size: 10px;
    line-height: 1;
    opacity: .35;
    transition: opacity .12s;
}

.th-ord:hover .th-seta { opacity: .7; }
.th-ord.ativo .th-seta { opacity: 1; }

/* ==========================================================================
   FICHA DO CLIENTE NO MODAL (Clientes > icone do olho).

   Reusa .modal-backdrop e .modal - o escuro do fundo, o z-index, a animacao
   e a trava de rolagem sao os MESMOS do modal de confirmacao. O que muda
   aqui e so o tamanho e o miolo, que aqui e leitura e nao pergunta.

   O padding sai do .modal e passa para as duas faixas: assim o cabecalho
   fica parado no topo enquanto o conteudo rola por baixo dele. Com o padding
   no painel, o titulo subiria junto com o texto.
   ========================================================================== */
.modal-ficha {
    max-width: 780px;
    padding: 0;
    /* Nunca mais alto que a janela: numa ficha com plano longo e observacoes,
       sem este teto o painel cresce e os botoes de baixo saem da tela. */
    max-height: calc(88vh * var(--escala-inv, 1));
    display: flex;
    flex-direction: column;
}

.modal-ficha-topo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--line);
    flex: 0 0 auto;
}

/* ROTULO, e nao titulo: quem manda no topo da leitura e o NOME do cliente,
   dentro da ficha. Se esta faixa tambem trouxesse o nome, ele apareceria
   duas vezes com dois pesos diferentes a dois centimetros de distancia. */
.modal-ficha-topo h3 {
    margin: 0;
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--muted);
}

.modal-ficha-corpo {
    padding: 18px 20px 20px;
    overflow-y: auto;
    /* Rolagem so aqui dentro; a pagina atras continua parada. */
    -webkit-overflow-scrolling: touch;

    /* `flex: 1 1 auto` + `min-height: 0` sao os dois juntos que fazem a
       rolagem funcionar. Um filho de flex nasce com `min-height: auto`, que o
       proibe de encolher abaixo do proprio conteudo: sem esta linha, uma ficha
       comprida estoura o `max-height` do painel, a barra de rolagem nunca
       aparece e o fim da ficha fica fora da tela, inalcancavel. */
    flex: 1 1 auto;
    min-height: 0;
}

/* DESARMA o `.modal p`, que pinta todo paragrafo de cinza e existe para as
   perguntas do modal de confirmacao. Sem isto, o texto do plano e o das
   observacoes sairiam apagados como se fossem legenda - e a mensagem de
   erro perderia o vermelho. Precisa da mesma forca do seletor original
   (duas partes), por isso o `.modal-ficha-corpo p` e nao so `.ficha-texto`. */
.modal-ficha-corpo p {
    margin: 0;
    color: inherit;
    font-size: inherit;
}

/* ---- 1. Identificacao: nome, id, dominio e situacao ----------------------
   TAMBEM um card, como as secoes de baixo. Solto sobre o fundo do modal, o
   nome do cliente era o unico elemento da ficha sem moldura - parecia titulo
   da janela, e nao o primeiro dado. No roxo da marca, que nao se repete em
   nenhum bloco da grade: e o cartao que identifica, nao mais um assunto. */
.ficha-id {
    --fc: 42, 6, 105;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    padding: 14px 16px;
    border: 1px solid rgba(var(--fc), .22);
    border-radius: 12px;
    background: rgba(var(--fc), .05);
    margin-bottom: 12px;
}

/* min-width: 0 num filho de flex e o que permite ao nome cortar com "..."
   em vez de esticar a caixa e empurrar os badges para fora. */
.ficha-id-texto { min-width: 0; }

.ficha-id h4 {
    margin: 0 0 3px;
    font-size: 18px;
    font-weight: 800;
    line-height: 1.25;
    color: var(--ink);
    word-break: break-word;
}

.ficha-sub {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    font-size: 13px;
    color: var(--muted);
}

.ficha-ponto { opacity: .5; }

.ficha-selos {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    flex-shrink: 0;
}

/* ---- 2. Faixa de destaque: os quatro numeros do contrato ----------------- */
/* Fundo tenue em vez de quatro caixas com borda: a faixa precisa se separar
   do resto sem virar mais uma moldura dentro de um modal que ja e uma. Mesmo
   tom do .resumo-card das listagens, para o destaque ter uma cara so no
   sistema inteiro. */
.ficha-destaque {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 4px 10px;
    /* Mesmo roxo e mesma borda do cartao de identificacao logo acima: os dois
       formam o TOPO da ficha - quem e o cliente e quanto ele paga - e se leem
       como um par, antes da grade colorida por assunto comecar. */
    background: rgba(42, 6, 105, .05);
    border: 1px solid rgba(42, 6, 105, .22);
    border-radius: 12px;
    padding: 12px 16px;
    margin-bottom: 16px;
}

.ficha-num {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.ficha-num-rot {
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--muted);
}

.ficha-num b {
    font-size: 15px;
    font-weight: 800;
    color: var(--ink);
    line-height: 1.3;
    word-break: break-word;
}

/* O selo do data center desce para a linha de baixo do bloco Servidor em vez
   de disputar espaco com o nome. */
.ficha-num .badge { align-self: flex-start; margin-top: 2px; }

/* ---- 3. Grade de blocos ------------------------------------------------- */
/* Duas colunas no desktop, uma no celular. auto-fit com minimo de 250px: os
   blocos se acomodam sozinhos conforme a largura sobra, sem media query para
   cada tamanho. */
.ficha-grade {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 14px;
    align-items: start;
}

/* ---- CORES DOS BLOCOS ---------------------------------------------------
   Cada assunto tem a sua cor, para achar o bloco pelo canto do olho em vez
   de ler os quatro titulos. Sao PASTEIS de proposito - 5% de tinta: a cor
   precisa agrupar sem competir com o dado, que e o que se veio ler. Com
   fundo forte a ficha viraria um mostruario e o texto perderia contraste.

   Uma variavel so por bloco: `--fc` guarda os canais (R, G, B) e o fundo, a
   borda, o tracinho do titulo e o risco entre as linhas saem todos dela,
   cada um com a sua transparencia. Assim trocar a cor de uma secao e mexer
   em UM numero - e nenhuma das quatro partes pode ficar para tras de uma
   cor antiga.

   As cores repetem as que o sistema ja usa (o verde do --ok, o ambar do
   --warn, o vermelho do --err, o cinza do --muted), para a ficha nao
   introduzir uma paleta paralela. */
.ficha-bloco {
    --fc: 92, 107, 132;                  /* cinza do --muted: o padrao */
    border: 1px solid rgba(var(--fc), .28);
    border-radius: 12px;
    padding: 12px 14px 4px;
    background: rgba(var(--fc), .05);
}

.ficha-contato   { --fc: 37, 99, 235; }   /* azul     */
.ficha-cadastro  { --fc: 124, 58, 237; }  /* violeta  */
.ficha-endereco  { --fc: 180, 83, 9; }    /* ambar    */
.ficha-infra     { --fc: 5, 150, 105; }   /* verde    */
.ficha-acesso    { --fc: 190, 24, 93; }   /* rosa     */
.ficha-plano     { --fc: 8, 145, 178; }   /* ciano    */
.ficha-obs       { --fc: 92, 107, 132; }  /* cinza    */

/* Plano, observacoes e cancelamento atravessam a grade inteira: sao textos
   corridos, e numa coluna estreita viram uma tira ilegivel. */
.ficha-larga { grid-column: 1 / -1; }

/* Titulo da secao com um tracinho na frente, os dois na COR DO BLOCO: e o
   que amarra a etiqueta ao fundo pastel. Com titulo cinza em todos, a cor do
   fundo pareceria enfeite solto em vez de classificacao. */
.ficha-bloco h5 {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 4px;
    font-size: 10px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: rgba(var(--fc), .95);
}

.ficha-bloco h5::before {
    content: '';
    width: 12px;
    height: 2px;
    border-radius: 2px;
    background: rgba(var(--fc), .85);
    flex-shrink: 0;
}

/* ---- 4. Linhas de campo: rotulo a esquerda, valor a direita -------------- */
.ficha-lista { margin: 0; }

.ficha-linha {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 7px 0;
    /* O risco tambem sai da cor do bloco. Com o cinza do --line ele sumiria
       sobre o fundo tingido - as linhas do bloco ambar, em particular,
       ficariam sem separacao nenhuma. */
    border-bottom: 1px dashed rgba(var(--fc), .22);
}

/* A ultima linha nao leva risco: ele encostaria na borda do bloco e
   pareceria um erro de desenho. */
.ficha-linha:last-child { border-bottom: none; }

.ficha-linha dt {
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    white-space: nowrap;
    flex-shrink: 0;
}

/* min-width: 0 + break-word: e-mail comprido quebra dentro da propria coluna
   em vez de alargar o bloco e desalinhar a grade inteira. */
.ficha-linha dd {
    margin: 0;
    min-width: 0;
    font-size: 14px;
    color: var(--ink);
    text-align: right;
    word-break: break-word;
    line-height: 1.4;
}

/* .mono e .small perdem para `.ficha-linha dd` (duas partes contra uma) e o
   monoespacado sairia do mesmo corpo do texto comum - o que, em fonte
   monoespacada, parece maior e desalinha a coluna da direita. Estas duas
   linhas devolvem o tamanho de cada um. */
.ficha-linha dd.mono  { font-size: 12.5px; }
.ficha-linha dd.small { font-size: 12px; }

.ficha-linha dd a { color: var(--accent); text-decoration: none; }
.ficha-linha dd a:hover { text-decoration: underline; }

/* Campo em branco fica visivelmente vazio, e nao parecendo um valor: o
   travessao apagado diz "nao ha dado" sem ocupar a atencao de um dado real. */
.ficha-vazio { color: var(--muted); opacity: .55; }

/* Credencial: `user-select: all` faz UM clique selecionar o valor inteiro.
   Senha gerada nao se digita a mao e, arrastando o mouse, e facil deixar um
   caractere para tras - o erro so aparece do outro lado, como "senha
   invalida", sem ninguem desconfiar da copia. */
.ficha-segredo {
    user-select: all;
    -webkit-user-select: all;
    cursor: text;
}

/* white-space: pre-wrap preserva as quebras de linha que o proprio cliente
   digitou na descricao do plano - sem isso tudo vira um paragrafo so. */
.ficha-texto {
    margin: 6px 0 12px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--ink);
    white-space: pre-wrap;
    word-break: break-word;
}

/* O cancelamento entra na mesma mecanica das outras secoes - so troca o
   `--fc` - mas com a borda um pouco mais firme: entre sete pasteis, o
   vermelho sozinho nao chamaria atencao suficiente para uma informacao que
   muda a leitura de todo o resto da ficha. */
.ficha-cancel {
    --fc: 220, 38, 38;
    border-width: 1.5px;
}

/* O olho fica cinza como as outras acoes e so ganha cor no hover: ele
   aparece em TODAS as linhas, e colorido de saida a coluna inteira viraria
   uma parede de icones chamando atencao. */
.btn-icon.acao-ver:hover {
    color: var(--brand);
    border-color: var(--brand);
}

/* Spinner de loading nos botoes */
.btn-loading {
    pointer-events: none;
    opacity: .75;
    position: relative;
}

.btn-loading::after {
    content: '';
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-left: 8px;
    vertical-align: -2px;
    border: 2px solid rgba(255, 255, 255, .45);
    border-top-color: #fff;
    border-radius: 50%;
    animation: btn-spin .7s linear infinite;
}

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

/* Rodinha SOLTA, fora de botao (ex.: busca no Inter rodando em segundo plano).
   Reusa a animacao btn-spin em vez de criar outra: duas animacoes de rotacao no
   mesmo CSS acabam divergindo de velocidade e o resultado fica desalinhado. */
.spinner {
    display: inline-block;
    width: 13px;
    height: 13px;
    border: 2px solid rgba(42, 6, 105, .25);
    border-top-color: var(--roxo, #2a0669);
    border-radius: 50%;
    animation: btn-spin .7s linear infinite;
    flex: none;
}

/* ============================================================
   LOGIN
   ============================================================ */
.login-body {
    display: flex; align-items: center; justify-content: center;
    min-height: calc(100vh * var(--escala-inv, 1));
    /* Solido, igual ao resto do sistema - a tela de login nao pode ser a
       unica com o fundo manchado. */
    background: var(--bg);
}

.login-card {
    background: var(--surface);
    border: 1px solid var(--line);
    padding: 36px 34px;
    border-radius: 18px;
    width: 360px;
    box-shadow: 0 24px 60px rgba(16, 24, 40, .12);
}

.login-card h1 { font-size: 20px; margin: 0 0 4px; font-weight: 800; }
.login-card h1 span { background: linear-gradient(90deg, #2A0669, #0891b2); -webkit-background-clip: text; background-clip: text; color: transparent; }
.login-card .muted { font-size: 13px; margin: 0 0 8px; }

.login-card label { display: block; margin: 15px 0 0; font-size: 12.5px; color: var(--muted); font-weight: 600; }

.login-card input {
    width: 100%; margin-top: 6px; padding: 11px 13px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 10px;
    color: var(--ink);
    font-family: inherit; font-size: 14px;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}

.login-card input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(42, 6, 105, .13); background: var(--surface); }

.login-card button {
    width: 100%; margin-top: 22px; padding: 12px;
    background: linear-gradient(135deg, #43159C, #2A0669);
    color: #fff; border: none; border-radius: 10px;
    font-family: inherit; font-weight: 700; font-size: 14px;
    cursor: pointer;
    box-shadow: 0 8px 22px rgba(42, 6, 105, .3);
    transition: filter .15s, transform .05s;
}

.login-card button:hover { filter: brightness(1.08); }
.login-card button:active { transform: translateY(1px); }

/* ============================================================
   RESPONSIVO
   ============================================================ */
@media (max-width: 1080px) {
    .menu { display: none; }
    body.nav-open .menu {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        position: absolute;
        top: var(--topo-h); left: 0; right: 0;   /* abaixo das duas faixas */
        background: var(--surface);
        border-bottom: 1px solid var(--line);
        box-shadow: var(--shadow-pop);
        padding: 10px 12px 16px;
        max-height: calc(100vh * var(--escala-inv, 1) - var(--topo-h));
        overflow-y: auto;
        gap: 2px;
    }
    /* no painel branco do mobile, volta as cores escuras */
    body.nav-open .menu-link, body.nav-open .menu-item .menu-title {
        padding: 11px 12px;
        border-radius: 9px;
        color: var(--muted);
    }
    body.nav-open .menu-link:hover, body.nav-open .menu-item:hover .menu-title {
        background: var(--elevated);
        color: var(--ink);
    }
    body.nav-open .menu-link.active, body.nav-open .menu-item.active .menu-title {
        background: rgba(42, 6, 105, .1);
        color: var(--accent-ink);
        box-shadow: none;
    }
    /* SUBMENU POR CLIQUE, e nao aberto de saida.
       Antes era `display: block` fixo: os oito submenus abriam juntos e a
       gaveta virava uma lista de umas cinquenta linhas, sem como fechar.
       Hover nao resolve aqui - num celular o dedo toca, nao passa por cima.
       Quem poe e tira `.aberto` e o menu-lateral.js. */
    body.nav-open .menu-item .dropdown {
        display: none;
        position: static;
        box-shadow: none;
        border: none;
        padding: 0 0 6px 14px;
        min-width: 0;
    }
    body.nav-open .menu-item.aberto .dropdown { display: block; }
    body.nav-open .menu-item .dropdown::before { display: none; }
    /* A SETA VOLTA, e aponta para BAIXO. Antes ela sumia aqui, porque o
       submenu ja vinha aberto e nao havia nada a anunciar. Agora ele abre no
       clique, e a seta e o unico sinal de que aquele item TEM submenu -
       sem ela o titulo parece um link que nao faz nada. */
    body.nav-open .menu-item .menu-title::after {
        display: inline-block;
        margin-left: auto;
        transform: rotate(45deg);
        transition: transform .15s ease;
    }
    /* Aberto, a seta gira para cima: diz que clicar de novo fecha. */
    body.nav-open .menu-item.aberto .menu-title::after { transform: rotate(-135deg); }
    body.nav-open .menu-item .menu-title { cursor: pointer; }

    .hamburger { display: block; }
    /* Menu superior estreito: fica so o avatar. O nome e o "trocar minha
       senha" empurrariam o Sair para fora da barra. */
    .user-dados { display: none; }
    .grid-2 { grid-template-columns: 1fr; }
    main { padding: 18px 14px 34px; }
    .nav-inner { padding: 0 16px; }
    .brand-inner { padding: 0 16px; }
}

/* ============================================================
   MOBILE (compatibilidade total em telas pequenas)
   ============================================================ */
@media (max-width: 900px) {
    /* (o modo CARTAO, mais abaixo, substitui o antigo scroll horizontal) */
    .msg { max-width: 220px; white-space: normal; }

    /* Barras de filtro empilham e ocupam a largura toda */
    .filter-bar { gap: 10px; }
    .filter-bar input[type="text"],
    .filter-bar input[type="search"] { min-width: 0; flex: 1 1 100%; }
    .filter-bar .btn { flex: 1 1 auto; }
    .filter-bar .radio { flex: 1 1 auto; }

    /* Abas com scroll horizontal se nao couberem */
    .seg { max-width: 100%; overflow-x: auto; scrollbar-width: none; }

    /* Cards de resumo mais compactos */
    .resumo-card { gap: 16px 24px; padding: 12px 16px; }
    .resumo-valor { font-size: 16.5px; }

    /* Dashboard */
    .rank-row { grid-template-columns: 96px 1fr 56px; }
    .kpi-value { font-size: 23px; }

    /* Formularios: botoes em coluna e largura total */
    .form-actions { flex-direction: column-reverse; }
    .form-actions .btn { width: 100%; text-align: center; }
    .edit-hero { padding: 14px 16px; }
    .hero-title { white-space: normal; }
    .page-head { flex-wrap: wrap; gap: 4px 10px; }

    /* Inputs com 16px no toque: evita o zoom automatico do iOS */
    .field input, .field select, .field textarea,
    .filter-bar input, .login-card input { font-size: 16px; }

    /* Modal ocupa quase toda a tela */
    .modal { max-width: none; }
}

/* ============================================================
   Dashboard: cards menores 2 por linha, sempre a mesma altura
   ============================================================ */
.grid-eq { align-items: stretch; }

.grid-eq > .card {
    height: 400px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.grid-eq > .card > h3 { flex-shrink: 0; }

.grid-eq .chart-box,
.grid-eq .chart-box-sm { flex: 1; min-height: 0; height: auto; }

.grid-eq .rank {
    flex: 1;
    min-height: 0;
    max-height: none;
    overflow-y: auto;
    padding-right: 8px;
    scrollbar-width: thin;
}

.grid-eq .card-scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    scrollbar-width: thin;
}

@media (max-width: 900px) {
    .grid-eq > .card { height: auto; }
    .grid-eq .chart-box { flex: none; height: 230px; }
    .grid-eq .chart-box-sm { flex: none; height: 160px; }
    .grid-eq .rank { flex: none; max-height: 340px; }
    /* Tela estreita: o e-mail quebra em vez de sumir atras das reticencias */
    .rank-name { white-space: normal; word-break: break-word; }
}

/* Utilitarios de tabela */
.upper { text-transform: uppercase; }
.nowrap { white-space: nowrap; }

/* ============================================================
   Sistema > Perfis/Usuarios: grade de permissoes granulares
   ============================================================ */
.perm-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}

.perm-groups {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 12px;
}

.perm-group {
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--elevated);
    padding: 12px 14px;
}

.perm-group h4 {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin: 0 0 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--muted);
}

.perm-toggle-grupo {
    border: 1px solid var(--line);
    background: var(--surface);
    border-radius: 999px;
    padding: 2px 10px;
    font-size: 10.5px;
    font-weight: 700;
    color: var(--accent-ink);
    cursor: pointer;
}

.perm-group label {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 5px 0;
    font-size: 13.5px;
    cursor: pointer;
}

.perm-group input { margin-top: 3px; }

.perfil-opcao {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--elevated);
    padding: 11px 13px;
    cursor: pointer;
}

.perfil-opcao input { margin-top: 3px; }

/* ============================================================
   Relatorios: cards por provedor (aba TODOS)
   ============================================================ */
.prov-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}

.prov-card {
    display: flex;
    flex-direction: column;
    gap: 4px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 14px 16px;
    text-decoration: none;
    color: var(--ink);
    transition: border-color .15s, transform .15s;
}

.prov-card:hover { border-color: var(--accent); transform: translateY(-1px); }

.prov-nome {
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .07em;
    color: var(--accent-ink);
}

.prov-num { font-size: 13px; color: var(--muted); margin-bottom: 2px; }
.prov-num b { font-size: 17px; color: var(--ink); }

.prov-linha {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    font-size: 12.5px;
    color: var(--muted);
}

/* ============================================================
   Avisos: barra de progresso do lote (Enviar todos)
   ============================================================ */
.lote-card {
    background: var(--surface);
    border: 1px solid rgba(42, 6, 105, .35);
    border-radius: var(--radius);
    box-shadow: 0 4px 14px rgba(15, 23, 42, .06);
    padding: 14px 18px 16px;
    margin-bottom: 16px;
}

.lote-head {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 10px;
}

.lote-head h3 { margin: 0; font-size: 15.5px; }

.progress-wrap {
    height: 13px;
    background: var(--line-soft);
    border-radius: 999px;
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    width: 0;
    border-radius: 999px;
    background: linear-gradient(90deg, #43159C, #22d3ee);
    transition: width .5s ease;
}

.progress-bar.progress-done { background: linear-gradient(90deg, #059669, #34d399); }
.progress-bar.progress-warn { background: linear-gradient(90deg, #d97706, #f59e0b); }

/* Margem Aumento: abas de servidores ativos (podem ser muitas -> quebra linha) */
.seg-serv {
    display: flex;
    flex-wrap: wrap;
    margin: 0 0 12px;
}

.seg-serv a { padding: 6px 13px; font-size: 12px; }

/* ============================================================
   Hover forte em todas as listas/linhas interativas do sistema
   + linha SELECIONADA (checkbox) com cor propria
   ============================================================ */
/* Linhas de rank (dashboard) */
.rank-row { transition: background .12s; }
.rank-row:hover { background: rgba(42, 6, 105, .07); }

/* Opcoes clicaveis (perfis do usuario, permissoes) */
.perfil-opcao { transition: background .12s, border-color .12s; }
.perfil-opcao:hover { background: rgba(42, 6, 105, .10); border-color: var(--accent); }

.perm-group label { border-radius: 6px; transition: background .12s; }
.perm-group label:hover { background: rgba(42, 6, 105, .10); }

/* Paginacao */
.pagination a:hover { background: rgba(42, 6, 105, .14); }

/* Linha selecionada (ex.: Margem Aumento): verde, vence zebrado e hover */
tbody tr.row-checked,
tbody tr.row-checked:nth-child(even) { background: rgba(5, 150, 105, .14); }
tbody tr.row-checked:hover,
tbody tr.row-checked:nth-child(even):hover { background: rgba(5, 150, 105, .22); }

/* Formulario de filtro convivendo com outro form na mesma barra */
.filtro-inline {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}


/* ============================================================
   MODO CARTAO - tabelas no celular (ate 860px)

   Uma tabela de 13 colunas so cabe no telefone rolando de lado, e
   rolar de lado esconde justamente a coluna de acoes. Abaixo de
   860px cada LINHA vira um cartao: o valor fica a direita, o nome
   da coluna a esquerda (vem do data-label, posto pelo
   tabela-responsiva.js a partir do proprio <thead>).

   Regras de conteudo:
     .cel-titulo -> primeira celula com texto: vira o titulo do cartao
     .cel-acoes  -> celula so com botoes: vai para o rodape do cartao
     .cel-vazia  -> celula sem valor: sai do cartao (nao vira linha em branco)

   Acima de 860px NADA disto se aplica - a tabela continua igual.
   ============================================================ */
@media (max-width: 860px) {

    table, thead, tbody, tr, th, td { display: block; }

    table {
        background: none;
        border: none;
        box-shadow: none;
        border-radius: 0;
        overflow: visible;
    }

    /* A CAIXA QUE ROLA SAI DE CENA no modo cartao. Aqui cada <tr> ja e
       um cartao com a sua propria moldura e sombra; a caixa por fora
       desenharia uma segunda moldura em volta da pilha inteira. E nao
       ha o que rolar - o conteudo empilha e cabe na largura. */
    .tabela-rolavel {
        box-shadow: none;
        border-radius: 0;
        overflow: visible;
    }

    /* O cabecalho vira fonte de rotulos: some da tela, mas continua no DOM
       (o leitor de tela e o script dependem dele). */
    thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

    tbody tr {
        background: var(--surface);
        border: 1px solid var(--line);
        border-radius: var(--radius);
        box-shadow: var(--shadow);
        padding: 13px 15px;
        margin-bottom: 11px;
    }
    /* zebra e hover do desktop nao fazem sentido em cartao */
    tbody tr:nth-child(even) { background: var(--surface); }
    tbody tr:hover, tbody tr:nth-child(even):hover { background: var(--surface); }

    tbody td {
        border: none;
        padding: 5px 0;
        font-size: 13.5px;
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 14px;
        text-align: right !important;
    }

    /* rotulo a esquerda, valor a direita */
    tbody td[data-label]::before {
        content: attr(data-label);
        flex: 0 0 auto;
        max-width: 46%;
        text-align: left;
        color: var(--muted);
        font-size: 12px;
        font-weight: 600;
        line-height: 1.45;
    }

    /* titulo do cartao: nome do cliente, dominio, etc. */
    tbody td.cel-titulo {
        display: block;
        text-align: left !important;
        font-size: 15px;
        font-weight: 600;
        color: var(--ink);
        padding: 0 0 8px;
        margin-bottom: 6px;
        border-bottom: 1px solid var(--line-soft);
        word-break: break-word;
    }
    tbody td.cel-titulo .small,
    tbody td.cel-titulo .domain-link { font-weight: 400; }

    /* celula sem valor nao vira linha vazia no cartao */
    tbody td.cel-vazia { display: none; }

    /* numeracao da linha nao tem serventia em cartao (nao ha coluna para contar) */
    tbody td.ordem { display: none; }

    /* no cartao nao existem colunas: a largura de 1% da coluna do modelo some */
    tbody td { width: auto !important; }

    /* acoes agrupadas no rodape, ocupando a largura */
    tbody td.cel-acoes {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: stretch;
        padding: 11px 0 0;
        margin-top: 7px;
        border-top: 1px solid var(--line-soft);
    }
    tbody td.cel-acoes::before { content: none; }
    tbody td.cel-acoes > form { flex: 1 1 auto; display: flex; }
    tbody td.cel-acoes .btn,
    tbody td.cel-acoes .btn-icon,
    tbody td.cel-acoes > form > button { flex: 1 1 auto; min-height: 40px; }
    /* no cartao o icone ganha o nome do lado: nao da para descobrir por tooltip */
    tbody td.cel-acoes .btn-icon {
        width: auto;
        padding: 0 12px;
        gap: 7px;
    }
    tbody td.cel-acoes .btn-icon::after {
        content: attr(aria-label);
        font-size: 12.5px;
        font-weight: 600;
        white-space: nowrap;
    }

    /* "nenhum registro encontrado" continua uma faixa simples */
    tbody tr.linha-aviso {
        box-shadow: none;
        text-align: center;
        color: var(--muted);
    }
    tbody tr.linha-aviso td { display: block; text-align: center !important; padding: 6px 0; }
    tbody tr.linha-aviso td::before { content: none; }

    /* linha destacada continua legivel como cartao */
    tbody tr.linha-falha { border-color: rgba(220, 38, 38, .35); }
}


/* ============================================================
   CELULAR - toque, filtros, paginacao e area segura
   ============================================================ */
@media (max-width: 860px) {

    main { padding: 16px 14px 28px; }

    /* No telefone o logo encolhe e a faixa junto, mantendo a mesma folga.
       As variaveis mudam aqui e o cabecalho fixo e o painel do menu seguem. */
    :root { --brand-h: 78px; --topo-h: 140px; }
    .brand-inner { padding: 12px 16px; }
    .brand-logo img { height: 50px; }
    .brand-logo { font-size: 15px; letter-spacing: .1em; }

    /* Area segura do iPhone: sem isto o rodape fica atras da barra
       do navegador e o ultimo botao da lista nao da para tocar. */
    body.app { padding-bottom: env(safe-area-inset-bottom, 0); }
    .nav-inner { padding-left: max(14px, env(safe-area-inset-left));
                 padding-right: max(14px, env(safe-area-inset-right)); }

    /* --- alvos de toque: 44px e o minimo confortavel --- */
    .btn, .btn-sm { min-height: 44px; padding: 11px 16px; font-size: 14px; }
    .btn-icon { width: 44px; height: 44px; }
    .menu-link, .menu-item .menu-title, .dropdown a { min-height: 44px; display: flex; align-items: center; }
    .seg a { min-height: 42px; display: inline-flex; align-items: center; }

    /* --- filtros empilhados: campo inteiro, botao inteiro --- */
    .filter-bar {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        padding: 12px;
    }
    .filter-bar input[type="text"],
    .filter-bar input[type="search"],
    .filter-bar input[type="date"],
    .filter-bar select { width: 100%; min-width: 0; font-size: 16px; }  /* 16px evita o zoom do iOS */
    .filter-bar .btn { width: 100%; }
    .filter-bar > form.inline { display: flex; width: 100%; }
    .filter-bar > form.inline > .btn { width: 100%; }
    .filter-bar .radio { justify-content: space-between; }

    /* campos de formulario tambem em 16px, pelo mesmo motivo */
    .field input, .field select, .field textarea { font-size: 16px; min-height: 44px; }

    /* --- abas roláveis em vez de quebrar em varias linhas --- */
    .seg {
        display: flex;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        gap: 6px;
    }
    .seg::-webkit-scrollbar { display: none; }
    .seg a { white-space: nowrap; flex: 0 0 auto; }

    /* --- paginacao: botoes de verdade, nao links miudos --- */
    .pagination {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: center;
        margin-top: 16px;
    }
    .pagination a, .pagination .current {
        min-width: 44px;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 0 14px;
        font-size: 14px;
    }

    /* --- cabecalho da pagina respira --- */
    .page-head { flex-direction: column; align-items: flex-start; gap: 4px; }
    .page-head h2 { font-size: 20px; }

    /* --- cards de resumo: dois por linha em vez de espremidos --- */
    .resumo-card { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
    .resumo-item { min-width: 0; }
    .resumo-valor { font-size: 17px; }

    /* --- formularios em coluna unica --- */
    .form-grid, .form-grid.cols-2, .form-grid.cols-3,
    .form-grid.cols-4, .form-grid.cols-6 { grid-template-columns: 1fr; }
    .form-cols { grid-template-columns: 1fr; }

    /* --- modal ocupa a tela toda, com o botao ao alcance do polegar --- */
    .modal { max-width: none; width: 100%; border-radius: 16px; padding: 20px; }
    .modal-actions { flex-direction: column-reverse; gap: 8px; }
    .modal-actions .btn { width: 100%; }
}

/* Telas bem estreitas: um resumo por linha */
@media (max-width: 420px) {
    .resumo-card { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------
   CARTOES DAS ROTINAS DE AVISOS AUTOMATICOS (Sistema > Automacoes)

   Sao cartoes iguais aos das outras automacoes - mesma moldura, mesmo botao -
   com um recuo e uma barra a esquerda. O recuo diz o que o texto tambem diz:
   estas quatro dependem de "Avisos Automaticos" logo acima. Sem ele, a tela
   pareceria ter doze automacoes independentes, e alguem ligaria uma rotina
   com a chave mestra desligada esperando um e-mail que nunca sai.
   --------------------------------------------------------------------------- */
.card-rotina {
    margin: 0 0 14px 28px;
    border-left: 3px solid var(--brand);
}

/* A linha do horario, embaixo do botao. Separada por uma borda porque mudar a
   hora e desligar a rotina sao decisoes de peso diferente: um "Salvar" colado
   num "Desligar" convida ao clique errado. */
.agenda-horario {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--line-soft);
}

.agenda-form {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    flex-wrap: wrap;
}
.agenda-form input[type="time"],
.agenda-form select {
    padding: 7px 9px;
    font-size: 13.5px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
    color: inherit;
}
/* Largura fixa no campo de hora: sem isto o Chrome e o Safari dao tamanhos
   diferentes ao mesmo input, e as tres linhas saem desalinhadas. */
.agenda-form input[type="time"] { width: 108px; }

@media (max-width: 720px) {
    /* No celular o recuo come a largura util do cartao; fica so a barra. */
    .card-rotina { margin-left: 10px; }
    .agenda-form select { flex: 1; min-width: 150px; }
}

/* ============================================================================
   MENU LATERAL  (integrator.ui.menu = lateral)

   TUDO aqui esta escopado em `.nav-lateral`. Com a chave em "superior" essa
   classe nao existe no HTML e nenhuma regra abaixo pega - o layout de hoje
   continua byte a byte o mesmo. E o que torna este bloco um TESTE: some
   inteiro trocando uma palavra na configuracao, sem desfazer edicao nenhuma.

   A marcacao e a MESMA dos dois modos. O que muda:
     .brand-bar   deixa de atravessar a tela e vira o topo da barra
     .menu        deixa de ser linha e vira coluna
     .dropdown    deixa de cair para baixo e sai para o LADO
     main         ganha margem a esquerda, sem que as 50 telas saibam disso
   ============================================================================ */

:root {
    --lat-w: 260px;   /* aberta  */
    --lat-min: 64px;  /* recolhida: so o icone */
}

.nav-lateral {
    position: fixed;
    inset: 0 auto 0 0;              /* topo, esquerda e base */
    width: var(--lat-w);
    display: flex;
    flex-direction: column;
    box-shadow: 4px 0 22px rgba(42, 6, 105, .26);
    transition: width .16s ease;
    overflow: visible;              /* o submenu precisa escapar para o lado */
}

body.menu-recolhido .nav-lateral { width: var(--lat-min); }

/* O CONTEUDO DESLOCA SEM AS TELAS SABEREM.

   `:has()` le a barra a partir do body, entao nao foi preciso tocar em
   nenhum dos 50 templates - eles continuam com <main class="wide"> e nada
   mais. Sem isto, a alternativa era editar 50 arquivos para um teste.

   O DESLOCAMENTO E `padding-left` NO BODY, E NAO `margin-left` NO MAIN.
   A diferenca nao e de estilo - a margem estava QUEBRANDO a tela.

   `main` tem `width: 100%`, que com `box-sizing: border-box` ja e a largura
   inteira da janela. Somar 260px de margem a esquerda joga a borda direita
   para 260px FORA: numa janela de 1440px o conteudo terminava em 1700px.
   Pela especificacao a conta fica sobre-restringida e o navegador resolve
   dando `margin-right: -260px` - ou seja, o estouro e real, com barra de
   rolagem horizontal e 260px de tabela cortados.

   Isso valia de 901px a 1699px de largura, que e onde estao 1366, 1440 e
   1600 - as resolucoes mais comuns de notebook. Acima de 1700px o defeito
   nao aparecia porque LA o deslocamento ja era feito assim, pelo padding do
   body, com a margem do main zerada. O conserto existia; faltava valer para
   as telas menores tambem.

   Com o padding no body, a largura disponivel para o main ENCOLHE antes de
   ele calcular os 100% - e a conta fecha em qualquer largura. A barra nao se
   move junto porque e `position: fixed`, presa a janela e nao ao body. */
@media (min-width: 901px) {
    body:has(.nav-lateral) {
        padding-left: var(--lat-w);
        transition: padding-left .16s ease;
    }
    body:has(.nav-lateral).menu-recolhido { padding-left: var(--lat-min); }
}

/* Menos respiro lateral: a barra ja separa o conteudo da borda esquerda,
   e os 112px originais somados a ela comiam metade da largura util. */
body:has(.nav-lateral) main { padding-left: 34px; padding-right: 34px; }

/* ---- topo: marca + botao de recolher ---- */

.nav-lateral .brand-bar { flex: none; }

.nav-lateral .brand-inner {
    justify-content: space-between;
    padding: 16px 14px;
    min-height: 0;
    gap: 6px;
}

.nav-lateral .brand-logo img { height: 34px; }

/* Recolhida, o logo sai e sobra so o botao - centralizado, virando tambem
   o "abrir de volta". Esconder os dois deixaria a barra sem saida. */
body.menu-recolhido .nav-lateral .brand-logo { display: none; }
body.menu-recolhido .nav-lateral .brand-inner { justify-content: center; padding: 16px 0; }

.lateral-recolher {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid rgba(255, 255, 255, .22);
    border-radius: 8px;
    background: rgba(255, 255, 255, .06);
    color: #fff;
    cursor: pointer;
    padding: 0;
}

.lateral-recolher:hover { background: rgba(255, 255, 255, .16); }
.lateral-recolher svg { width: 16px; height: 16px; }
body.menu-recolhido .lateral-recolher svg { transform: rotate(180deg); }

/* No menu superior o botao nao existe (th:if), mas a regra fica como
   defesa: se alguem colar a marcacao noutro lugar, ele nao aparece solto. */
.nav-wrap:not(.nav-lateral) .lateral-recolher { display: none; }

/* ---- corpo: a lista ---- */

.nav-lateral .nav-inner {
    flex: 1;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 10px 0 0;
    /* SEM ROLAGEM, e isto NAO e esquecimento.

       `overflow-y: auto` com `overflow-x: visible` nao existe: pela
       especificacao, quando um eixo tem rolagem o outro deixa de ser
       `visible` e vira `auto` sozinho. O submenu, que sai em `left: 100%`
       e precisa de ~490px numa barra de 260px, seria cortado - e ainda
       apareceria uma barra de rolagem horizontal a cada passada do mouse.

       Escapar por `position` tambem nao resolve: o container de rolagem
       fica entre o submenu e o seu bloco de contencao, entao o corte vale.

       Rolagem vertical e submenu flutuante sao excludentes em CSS puro.
       Escolhi o submenu. Os 11 itens somam ~630px e cabem acima de 700px
       de altura; abaixo disso, o bloco @media (max-height: 760px) mais
       adiante troca o submenu por sanfona e ai sim liga a rolagem. */
    overflow: visible;
}

.nav-lateral .menu {
    /* display: flex EXPLICITO. Sem ele, o `.menu { display: none }` do
       bloco de <=1080px (menu superior vira gaveta) apaga a lista inteira
       da barra lateral: em 1024px - notebook comum - sobrava a marca, o
       usuario e nenhum item de menu. */
    display: flex;
    flex-direction: column;
    align-items: stretch;
    flex-wrap: nowrap;
    gap: 2px;
    padding: 0 10px;
}

.nav-lateral .menu-link,
.nav-lateral .menu-item .menu-title {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 11px 12px;
    border-radius: 10px;
    white-space: nowrap;
}

/* A seta do dropdown aponta para o LADO, nao para baixo: o submenu agora
   sai pela direita. Uma seta para baixo indicaria o lugar errado. */
.nav-lateral .menu-item .menu-title::after {
    content: "";
    margin-left: auto;
    width: 6px;
    height: 6px;
    border: solid currentColor;
    border-width: 0 1.6px 1.6px 0;
    transform: rotate(-45deg);
    opacity: .65;
}

.mi { width: 19px; height: 19px; flex: none; }

/* No menu SUPERIOR os icones nao entram: la o espaco e horizontal e
   escasso, e onze icones em linha viram poluicao. A marcacao e a mesma
   nos dois modos; quem decide se eles aparecem e esta regra. */
.nav-wrap:not(.nav-lateral) .mi { display: none; }

/* ---- recolhida: so o icone ---- */

body.menu-recolhido .nav-lateral .menu { padding: 0 8px; }

body.menu-recolhido .nav-lateral .menu-link > span,
body.menu-recolhido .nav-lateral .menu-item .menu-title > span { display: none; }

body.menu-recolhido .nav-lateral .menu-item .menu-title::after { display: none; }

body.menu-recolhido .nav-lateral .menu-link,
body.menu-recolhido .nav-lateral .menu-item .menu-title {
    justify-content: center;
    padding: 11px 0;
}

/* ---- submenu: sai para o lado ---- */

.nav-lateral .menu-item .dropdown {
    top: 0;
    left: 100%;
    margin-left: 8px;
    min-width: 230px;
    max-height: calc(80vh * var(--escala-inv, 1));
    overflow-y: auto;
}

/* A "ponte" invisivel que o menu superior usa para o mouse atravessar do
   item ate o dropdown fica no lado ERRADO aqui - ela apontava para baixo.
   Refeita na vertical, senao o submenu fecha no meio do caminho. */
.nav-lateral .menu-item .dropdown::before {
    top: 0;
    bottom: auto;
    left: -10px;
    right: auto;
    width: 10px;
    height: 100%;
}

/* ---- rodape: usuario e sair ---- */

.nav-lateral .nav-right {
    flex: none;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 12px 14px;
    margin-top: auto;
    border-top: 1px solid rgba(255, 255, 255, .14);
}

/* O formulario de logout so existe para carregar o token CSRF - ele nao deve
   ocupar largura nenhuma alem do botao que tem dentro. */
.nav-lateral .nav-right .inline { flex: none; }

/* RECOLHIDA (64px): sobra espaco para um icone e mais nada. O nome, o "trocar
   minha senha", os digitos do relogio e a palavra "Sair" saem; ficam o
   avatar, o escudo, o relogio e a porta - todos com balao de title dizendo o
   que sao. As formas continuam as mesmas, so sem texto: quem abre a barra de
   volta reconhece na hora onde estava. */
body.menu-recolhido .nav-lateral .user-dados,
body.menu-recolhido .nav-lateral .btn-sair span,
body.menu-recolhido .nav-lateral .sessao-relogio span { display: none; }

body.menu-recolhido .nav-lateral .nav-right { padding: 12px 8px; align-items: stretch; }
body.menu-recolhido .nav-lateral .conta-bloco { padding: 6px; gap: 6px; }
body.menu-recolhido .nav-lateral .user-chip { justify-content: center; padding: 4px; }
body.menu-recolhido .nav-lateral .conta-acoes { flex-direction: column; gap: 6px; }
body.menu-recolhido .nav-lateral .sessao-relogio { padding: 7px 0; }
body.menu-recolhido .nav-lateral .btn-sair { padding: 7px 0; width: 100%; }

/* O relogio recolhido perde os numeros, entao perde tambem o motivo de
   existir - EXCETO no alerta, quando a cor sozinha ja diz "acabando". */
body.menu-recolhido .nav-lateral .sessao-relogio { color: rgba(255, 255, 255, .55); }
body.menu-recolhido .nav-lateral .sessao-relogio.alerta { color: #fff; }

/* ---- celular: a lateral vira gaveta ---- */

/* ---- 901 a 1080px: a lista ja esta na barra, sem gaveta ---- */

@media (max-width: 1080px) {
    /* O painel branco flutuante e do menu SUPERIOR. Na lateral a lista ja
       mora na barra: aqui ele so precisa ser desfeito. */
    body.nav-open .nav-lateral .menu {
        position: static;
        top: auto; left: auto; right: auto;
        background: none;
        border: none;
        box-shadow: none;
        max-height: none;
        padding: 0 10px;
    }

    /* Sem :hover no toque, o submenu precisa nascer aberto - senao os seis
       grupos viram itens mortos no celular. */
    body.nav-open .nav-lateral .menu-item .dropdown {
        display: block;
        position: static;
        min-width: 0;
        margin: 2px 0 6px;
        padding: 0 0 6px 14px;
        max-height: none;
        background: rgba(255, 255, 255, .06);
        border: none;
        box-shadow: none;
    }

    body.nav-open .nav-lateral .menu-item .dropdown::before { display: none; }
    body.nav-open .nav-lateral .menu-item .menu-title::after { display: none; }
    body.nav-open .nav-lateral .menu-item .dropdown a { color: rgba(255, 255, 255, .88); }
    body.nav-open .nav-lateral .menu-item .dropdown .sub-group { color: #cfc0ee; }

    body.nav-open .nav-lateral .menu-link,
    body.nav-open .nav-lateral .menu-item .menu-title { color: rgba(255, 255, 255, .85); }
    body.nav-open .nav-lateral .menu-link.active,
    body.nav-open .nav-lateral .menu-item.active .menu-title { color: #2A0669; background: var(--sobre-marca); }

    /* TEXTO BRANCO SOBRE FUNDO CLARO - o item sumia ao passar o dedo.

       A gaveta do menu SUPERIOR e um painel branco, e por isso ela pinta o
       hover com fundo claro e letra escura (regra `body.nav-open` la em
       cima). A gaveta da LATERAL nao e branca: continua sendo a barra roxa.
       O fundo claro chegava ate aqui, mas a cor da letra nao - a regra da
       linha acima e mais especifica e mantinha o branco. Fundo claro com
       letra branca da exatamente nada visivel.

       O conserto e repetir aqui o hover que a barra usa no computador:
       veu branco por cima do roxo, letra branca. */
    body.nav-open .nav-lateral .menu-link:hover,
    body.nav-open .nav-lateral .menu-item:hover .menu-title {
        background: rgba(255, 255, 255, .14);
        color: #fff;
    }

    /* Mesma armadilha nos itens do submenu, que na gaveta ficam abertos em
       sanfona sobre o roxo. */
    body.nav-open .nav-lateral .menu-item .dropdown a { color: rgba(255, 255, 255, .88); }
    body.nav-open .nav-lateral .menu-item .dropdown a:hover {
        background: rgba(255, 255, 255, .14);
        color: #fff;
    }
    /* SOBRE-MARCA, e nao superficie: este item vive dentro da gaveta ROXA do
       celular. Com `--surface` ele acompanharia o tema e sumiria no escuro,
       justamente onde o realce do item atual precisa aparecer. */
    body.nav-open .nav-lateral .menu-item .dropdown a.active {
        background: var(--sobre-marca);
        color: #2A0669;
    }
    /* A BORDA precisa estar escrita aqui junto com o fundo. A regra base
       agora traz `border: 1px solid var(--brand)` - roxo cheio, que sobre a
       gaveta ROXA vira um contorno escuro em volta de uma pilula clara.
       Mesma borda da sanfona: veu branco, que acompanha o fundo. */
    body.nav-open .nav-lateral .menu-item .dropdown .sub-group {
        background: rgba(255, 255, 255, .12);
        border-color: rgba(255, 255, 255, .22);
        color: #cfc0ee;
    }

    /* Com os seis submenus abertos, a lista passa da altura da janela.
       Aqui a rolagem PODE existir sem estragar nada: o submenu ja e
       estatico, entao nao ha o que escapar para o lado. Sem isto, o fim
       do menu simplesmente nao e alcancavel no celular. */
    body.nav-open .nav-lateral .nav-inner { overflow-y: auto; overflow-x: hidden; }
    body.nav-open .nav-lateral .menu { overflow: visible; }

    .nav-lateral .user-dados { display: block; }
    .nav-lateral .hamburger { display: none; }   /* a lista ja esta visivel */
}

/* ---- ate 900px: a lateral vira gaveta ---- */

@media (max-width: 900px) {
    /* FORA DA TELA PELA POSICAO, e nao por transform.

       `transform` num ancestral vira bloco de contencao de `position: fixed`
       - e o hamburguer mora DENTRO do header. Com translateX(-100%) ele ia
       embora junto com a barra, e nao sobrava nenhuma forma de abrir o menu
       no celular. Trocar por `left` desfaz a armadilha. */
    .nav-lateral {
        left: calc(-1 * var(--lat-w));
        transition: left .18s ease;
    }

    body.nav-open .nav-lateral { left: 0; }

    /* Sem deslocamento: a gaveta COBRE o conteudo em vez de empurra-lo. Numa
       tela estreita, empurrar sobraria uma faixa de conteudo ilegivel ao lado.

       Nao ha nada a desfazer aqui - o `padding-left` do body esta dentro de
       `min-width: 901px` e simplesmente nao vale nesta faixa. Antes havia um
       `margin-left: 0` no main justamente porque a regra de cima nao tinha
       limite de largura e chegava ate o celular. */

    /* Os 34px do desktop sobram aqui: sem eles o celular perde 68px de
       largura util para uma folga que a gaveta ja da. */
    body:has(.nav-lateral) main { padding-left: 14px; padding-right: 14px; }

    /* O hamburguer flutua sobre o conteudo - a barra saiu do topo, entao
       ele nao tem mais onde se apoiar. Acompanha a gaveta ao abrir. */
    .nav-lateral .hamburger {
        display: inline-flex;
        position: fixed;
        top: 10px;
        left: 10px;
        z-index: 130;
        padding: 7px;
        border-radius: 9px;
        background: var(--barra);
        box-shadow: 0 4px 14px rgba(15, 10, 60, .3);
    }

    body.nav-open .nav-lateral .hamburger { left: calc(var(--lat-w) + 10px); }

    /* NO CELULAR A GAVETA ABRE SEMPRE INTEIRA.

       O estado recolhido fica no localStorage e atravessa os aparelhos: quem
       recolheu no computador abriria no telefone uma gaveta de 64px so com
       icones - e o tooltip que os explica depende de :hover, que no toque
       nao existe. Aqui a largura e restaurada e os rotulos voltam. */
    body.menu-recolhido .nav-lateral { width: var(--lat-w); }
    body.menu-recolhido .nav-lateral .brand-logo { display: inline-flex; }
    body.menu-recolhido .nav-lateral .brand-inner { justify-content: space-between; padding: 16px 14px; }
    body.menu-recolhido .nav-lateral .menu { padding: 0 10px; }
    body.menu-recolhido .nav-lateral .menu-link > span,
    body.menu-recolhido .nav-lateral .menu-item .menu-title > span { display: inline; }
    body.menu-recolhido .nav-lateral .menu-link,
    body.menu-recolhido .nav-lateral .menu-item .menu-title { justify-content: flex-start; padding: 11px 12px; }
    /* Abaixo de 1080px a barra ja nao fica recolhida - a classe pode ter
       sobrado no <body>, entao aqui tudo volta a aparecer. */
    body.menu-recolhido .nav-lateral .user-dados,
    body.menu-recolhido .nav-lateral .btn-sair span,
    body.menu-recolhido .nav-lateral .sessao-relogio span { display: block; }
    body.menu-recolhido .nav-lateral .user-chip { justify-content: flex-start; padding: 4px 6px 4px 4px; }
    body.menu-recolhido .nav-lateral .conta-acoes { flex-direction: row; }
    body.menu-recolhido .nav-lateral .nav-right { padding: 12px 14px; align-items: stretch; }

    /* O BOTAO DE RECOLHER SOME AQUI, e nao e capricho: abaixo desta largura
       todas as regras do modo recolhido sao desfeitas (e o que as linhas
       acima fazem). O clique continuava alternando a classe no <body>, so que
       nada mudava na tela - um botao que responde ao clique e nao faz nada e
       pior do que um botao ausente, porque a pessoa fica tentando.

       Recolher tambem nao faria sentido: aqui a barra ja e uma gaveta que
       abre e fecha inteira pelo hamburguer. */
    .nav-lateral .lateral-recolher { display: none; }
}

/* ---- janela baixa: submenu vira sanfona e a barra passa a rolar ----

   E a troca do B1 feita de proposito, e so quando a altura obriga: com
   pouca altura os ultimos itens ficariam inalcançaveis, e ai rolar importa
   mais do que o submenu flutuar.

   ERA 820px, E ISSO FICOU CURTO. A barra nao rola acima deste limite, e ela
   e `position: fixed` de topo a base: o que nao couber na altura da janela
   nao fica escondido "mais abaixo" - fica FORA, sem jeito de alcancar. E o
   ultimo item do menu e justamente Sistema, onde ficam Contas e Perfis de
   acesso. Foi o que sumiu quando o rodape cresceu.

   A CONTA, para quem precisar refazer depois de mexer no rodape:

       marca ................................  78
       respiro do topo da lista .............  10
       11 itens x (44 + 2 de intervalo) ..... 506
       rodape (aviso + bloco da conta) ...... 174
                                             ----
                                              768

   768px e o que a barra ocupa. Uma janela de navegador perde uns 120px para
   abas e barra de endereco, entao uma tela de 900px oferece ~780px de altura
   util - passa raspando, e qualquer barra de favoritos derruba o Sistema
   para fora. Dai 900: quem tem monitor de 1080 continua com o submenu
   flutuante, e quem esta num notebook de 900 ganha a rolagem antes de perder
   um item de menu.

   Perder o submenu flutuante incomoda; perder o acesso a uma tela impede o
   trabalho. Entre os dois, a escolha nao esta em duvida.

   ------------------------------------------------------------------
   SEM `:hover` NO SELETOR, e isto e o conserto de um defeito real.

   Estas regras eram `.menu-item:hover .dropdown`. Parecia inofensivo - o
   painel so aparece no hover mesmo -, mas o js/menu-lateral.js DEPENDE de
   ler `position` para saber se deve ou nao posicionar o painel a mao. Ele
   consulta no `pointerenter`, e nesse instante o `:hover` pode ainda nao ter
   sido aplicado: a leitura devolvia `absolute`, o script seguia em frente e
   gravava `position: fixed` INLINE - que vence qualquer media query.

   O resultado era o pior dos dois mundos: um painel FLUTUANDO com a
   aparencia da sanfona (fundo transparente a 6%, sem borda, sem sombra,
   `min-width: 0`), ou seja, um retangulo quase invisivel por cima do
   conteudo. Em monitor 1440x900 - altura util abaixo de 900 - era o
   comportamento normal do menu.

   Sem o `:hover`, a media query descreve o painel o tempo todo, o script le
   `static` e sai sem tocar em nada. O `display: none` de
   `.menu-item .dropdown` continua escondendo; nada aparece antes da hora.

   ESTE BLOCO TEM DE CONTINUAR NO FIM DO ARQUIVO. Sem o `:hover`, o seletor
   `.nav-lateral .menu-item .dropdown` ficou com a MESMA especificidade da
   regra que define o painel flutuante (secao "submenu: sai para o lado").
   Empate se decide por ordem: quem vem depois ganha. Mover este bloco para
   cima daquele devolve o submenu flutuante em tela baixa - sem erro nenhum
   aparecer.
   ------------------------------------------------------------------ */
@media (max-height: 900px) and (min-width: 901px) {
    .nav-lateral .nav-inner { overflow-y: auto; overflow-x: hidden; }

    .nav-lateral .menu-item .dropdown {
        /* FECHADO ATE CLICAREM. Nesta faixa a janela e baixa (notebook, ou
           navegador com muita barra), e o painel vira sanfona dentro da
           lista. Aberto de saida, a barra nao cabe em si mesma e passa a
           rolar - com o item procurado sempre fora da vista. Quem abre e o
           menu-lateral.js, no clique do titulo. */
        display: none;
        position: static;
        min-width: 0;
        margin: 2px 0 6px;
        padding: 0 0 6px 14px;
        max-height: none;
        background: rgba(255, 255, 255, .06);
        border: none;
        box-shadow: none;
    }

    .nav-lateral .menu-item.aberto .dropdown { display: block; }

    /* A seta aponta para BAIXO nesta faixa, e nao para o lado: aqui o submenu
       desce dentro da lista, e nao sai pela direita. Seta para o lado
       indicaria um painel que nao existe mais. */
    .nav-lateral .menu-item .menu-title {
        cursor: pointer;
    }
    .nav-lateral .menu-item .menu-title::after {
        transform: rotate(45deg);
        transition: transform .15s ease;
    }
    .nav-lateral .menu-item.aberto .menu-title::after { transform: rotate(-135deg); }

    .nav-lateral .menu-item .dropdown::before { display: none; }

    /* Tambem sem `:hover`, por coerencia com a regra de cima: nesta faixa a
       sanfona e o que o painel E, e nao um estado dele. Continuam ganhando
       da cor base (`.menu-item .dropdown a`, duas classes contra tres). */
    .nav-lateral .menu-item .dropdown a { color: rgba(255, 255, 255, .88); }

    /* ------------------------------------------------------------------
       BRANCO SOBRE BRANCO no hover e no item atual.

       Este bloco trocava so a COR DO TEXTO e deixava o FUNDO com quem
       estivesse mandando - e quem manda, numa tela de 1440px de largura, e o
       bloco `@media (min-width: 1081px)`, que pinta o hover de
       `var(--surface)` (branco) e o item atual de lilas claro. Foi desenhado
       para o painel FLUTUANTE, que e branco. Aqui a sanfona vive dentro da
       barra ROXA, e o texto ja e branco: fundo branco com letra branca nao
       mostra nada.

       Nao adiantava confiar na especificidade: `.menu-item .dropdown a:hover`
       e `.nav-lateral .menu-item .dropdown a` EMPATAM (tres classes e um
       elemento cada), e no empate ganha quem vem depois - a cor do texto era
       daqui, o fundo continuava de la. Dai a correcao ser pelo par completo,
       fundo e texto na mesma regra.

       Sao exatamente as mesmas tres regras que o bloco `@media (max-width:
       1080px)` ja aplica na gaveta do celular, onde a sanfona tambem abre
       sobre o roxo. Aquele bloco resolveu; este copiou so metade.
       ------------------------------------------------------------------ */
    .nav-lateral .menu-item .dropdown a:hover {
        background: rgba(255, 255, 255, .14);
        color: #fff;
    }

    /* SOBRE-MARCA, e nao `--surface`: o item atual vive dentro da barra roxa,
       e `--surface` acompanharia o tema - sumiria justamente no escuro, que e
       onde o realce precisa aparecer. Branco com letra roxa da 13:1. */
    .nav-lateral .menu-item .dropdown a.active {
        background: var(--sobre-marca);
        color: #2A0669;
    }

    /* A pilula do grupo precisa do FUNDO escrito aqui, e nao so da cor.

       A regra base pinta a pilula de roxo SOLIDO com letra branca - o que e o
       certo no painel flutuante do tema claro, e errado aqui: nesta faixa a
       sanfona ja mora dentro da barra roxa, e uma pilula roxa sobre roxo
       desaparece. Trocando so a cor da letra, o fundo solido continuaria vindo
       da base.

       (Este comentario dizia que o bloco `min-width: 1081px` deixava a pilula
       BRANCA. Nao deixa: aquela regra era codigo morto - mesma especificidade
       da base e escrita ANTES dela - e foi apagada. A confusao esta anotada la,
       no lugar onde ela ficava.) */
    .nav-lateral .menu-item .dropdown .sub-group {
        background: rgba(255, 255, 255, .12);
        border-color: rgba(255, 255, 255, .22);
        color: #cfc0ee;
    }

    /* O separador entre grupos vinha em roxo a 14% - invisivel sobre roxo. */
    .nav-lateral .menu-item .dropdown .grupo + .grupo {
        border-top-color: rgba(255, 255, 255, .14);
    }
}

/* ---- ajustes que a barra lateral desloca ----

   O layout de hoje foi desenhado com duas faixas no topo (--topo-h: 158px).
   Na lateral elas nao existem, e tres regras espalhadas pelo arquivo ainda
   contam com elas. Ficam aqui, no fim, escopadas em `:has(.nav-lateral)`:
   assim nao ha risco de mexer no modo superior. */

@media (min-width: 861px) {
    /* O cabecalho fixo das tabelas parava 158px abaixo do topo, deixando
       linhas passarem por cima dele. Sem faixa superior, o offset e zero. */
    body:has(.nav-lateral) thead th { top: 0; }
}

/* O DESLOCAMENTO DA BARRA SUBIU para o bloco `min-width: 901px`, la em cima,
   junto da propria barra. Este bloco tinha as mesmas quatro regras - e era o
   UNICO lugar onde elas existiam, e por isso o layout so fechava certo acima
   de 1700px. Ver o comentario longo em `body:has(.nav-lateral)`.

   O que ainda e exclusivo das telas largas fica aqui: centralizar as telas
   ESTREITAS (`main:not(.wide)`), que ganham um teto de 1500px logo acima.
   Sem o `margin: 0 auto`, esse teto empurraria tudo para a esquerda e
   deixaria o vazio todo do lado direito.

   Nao ha mais `margin-left` da barra para vencer - por isso a regra encolheu
   de quatro seletores para um. */
@media (min-width: 1700px) {
    body:has(.nav-lateral) main:not(.wide) { margin-left: auto; margin-right: auto; }
}

/* O submenu dos TRES ULTIMOS itens abre para CIMA. "Sistema" tem sete
   grupos (~420px) e e o ultimo da lista: aberto para baixo, some pela
   base da janela. Ancorar pelo rodape resolve sem JavaScript.

   E SO A REDE DE SEGURANCA. Quem manda no lugar do painel e o
   js/menu-lateral.js, que mede a janela e escolhe um topo que caiba. Esta
   regra vale enquanto o script nao roda - e por isso ele PRECISA zerar o
   `bottom` ao definir o `top`: com as duas bordas presas, a caixa estica de
   uma ate a outra e o submenu desce ate o fim da tela com tres itens dentro.
   Foi exatamente o que aconteceu. */
.nav-lateral .menu > :nth-last-child(-n+3) .dropdown { top: auto; bottom: 0; }

/* RECOLHIDA, o rotulo vira tooltip. Sem isto sobra so o icone, e a unica
   forma de descobrir o que e cada um e clicando. O texto sai do proprio
   <span> escondido, entao nao ha rotulo duplicado para manter em dia. */
body.menu-recolhido .nav-lateral .menu-link,
body.menu-recolhido .nav-lateral .menu-item .menu-title { position: relative; }

body.menu-recolhido .nav-lateral .menu-link:hover::before,
body.menu-recolhido .nav-lateral .menu-item:hover .menu-title::before {
    content: attr(data-rotulo);
    position: absolute;
    left: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    padding: 6px 10px;
    border-radius: 8px;
    background: #1B0344;
    color: #fff;
    font-size: 12.5px;
    font-weight: 600;
    white-space: nowrap;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
    z-index: 140;
    pointer-events: none;
}

/* Quem tem submenu ja mostra o proprio submenu ao lado: o tooltip
   competiria com ele no mesmo lugar. */
body.menu-recolhido .nav-lateral .menu-item:hover .menu-title::before { display: none; }


/* ============================================================
   CABECALHO DE BLOCO dentro da tabela  (Site > Planos)
   ============================================================

   A tabela de planos sai agrupada por tipo: um <tbody> por tipo, cada um
   comecando por esta linha.

   O DESENHO PRECISA GRITAR "AQUI COMECA OUTRA COISA". A primeira versao era
   um rotulo apagado com uma linha embaixo, e no meio de dez linhas de dados
   ela passava batido - a pessoa lia a tabela como uma lista continua e o
   agrupamento nao servia para nada. Sao tres sinais somados, e nenhum deles
   sozinho basta:

     1. um ESPACO acima (a borda grossa cor do cartao - ver abaixo);
     2. uma FAIXA com fundo proprio, diferente da linha zebrada;
     3. uma BARRA colorida na lateral esquerda, que e o que o olho pega ao
        percorrer a coluna de cima a baixo.

   Cores por variavel, e nao fixas: --chip, --accent e --surface trocam
   sozinhas no tema escuro. Roxo #2A0669 chumbado aqui ficaria invisivel
   sobre o fundo escuro.

   Especificidade DE PROPOSITO acima do necessario (`tbody tr.linha-grupo`, e
   nao `.linha-grupo`): as regras genericas de tabela mais acima pintam
   `tbody tr:nth-child(even)` e o `:hover` de qualquer linha. Sem vencer as
   duas, a faixa zebraria junto com os dados e reagiria ao mouse como se
   fosse clicavel. */
tbody tr.linha-grupo,
tbody tr.linha-grupo:nth-child(even),
tbody tr.linha-grupo:hover,
tbody tr.linha-grupo:nth-child(even):hover {
    background: transparent;
}

tbody tr.linha-grupo td {
    /* O ESPACO ENTRE BLOCOS e uma borda da cor do proprio cartao.
       Margem nao existe em <tr>, e padding aumentaria a faixa em vez de
       separa-la do bloco anterior. Como a tabela usa `border-collapse:
       separate`, esta borda e desenhada inteira e some visualmente contra o
       fundo - o resultado e um respiro limpo. */
    border-top: 16px solid var(--surface);
    border-bottom: 1px solid var(--line);
    border-left: 4px solid var(--accent);

    background: var(--chip);
    padding: 11px 12px 10px;

    font-size: 12px;
    font-weight: 700;
    letter-spacing: .10em;
    text-transform: uppercase;
    color: var(--accent-ink);
}

/* A contagem nao compete com o nome do tipo: peso normal, caixa baixa e a
   cor de texto secundario. Ela informa, nao anuncia. */
tbody tr.linha-grupo td .muted {
    margin-left: 8px;
    font-size: 11.5px;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: none;
    color: var(--muted);
}

/* O primeiro bloco encosta no cabecalho da tabela: o respiro que separa um
   bloco do anterior nao tem o que separar ali em cima. */
tbody:first-of-type tr.linha-grupo td { border-top-width: 0; }

@media (max-width: 860px) {
    /* A tabela vira cartao neste ponto, e o script tabela-responsiva marca
       toda linha de uma celula so com `linha-aviso` - estilo de estado vazio,
       centralizado e apagado. Para a divisoria isso estaria errado: ela e
       titulo do bloco que vem A SEGUIR, e centralizada no meio dos cartoes
       pareceria um aviso solto. Volta a ser um rotulo alinhado a esquerda,
       agora como faixa cheia, que no empilhamento vertical e o unico jeito de
       o corte ficar obvio. */
    tbody tr.linha-grupo,
    tbody tr.linha-grupo.linha-aviso {
        box-shadow: none;
        border: 0;
        text-align: left;
        margin: 18px 0 6px;
    }
    tbody tr.linha-grupo td,
    tbody tr.linha-grupo.linha-aviso td {
        display: block;
        text-align: left !important;
        border-top: 0;
        border-radius: var(--radius-sm);
        padding: 9px 12px;
    }
    tbody tr.linha-grupo td::before,
    tbody tr.linha-grupo.linha-aviso td::before { content: none; }

    /* No celular o primeiro bloco tambem ganha o respiro: ali ele nao encosta
       num cabecalho de tabela (nao ha), e sim na barra de filtros. */
    tbody:first-of-type tr.linha-grupo { margin-top: 6px; }
}
