@charset "UTF-8";
/* ============================================================================
 *  PRECS — estilo.css (tokens, tema e layout base)
 * ----------------------------------------------------------------------------
 *  Tokens de cor dos tres temas, reset, tipografia, grade do painel e media queries.
 *
 *  (1.1.8) Este arquivo NASCEU de um recorte do index.html, que tinha 5.900 linhas
 *  de CSS dentro do HTML (70% do arquivo). O recorte foi byte a byte, sem reordenar
 *  nada: o diff do movimento tinha que ser auditavel como "os mesmos bytes, em
 *  outro arquivo".
 *
 *  ORDEM DOS <link> IMPORTA. Este arquivo e o estilo-componentes.css declaram :root
 *  os dois, e o de componentes vence os empates — era assim quando os dois eram
 *  blocos <style> no mesmo documento, e inverter a ordem mudaria varios tokens em
 *  silencio. O teste-tokens.js trava essa ordem.
 *
 *  O QUE NAO ESTA AQUI: as regras de zoom por data-fonte e a animacao do splash
 *  continuam inline no index.html. Elas precisam valer no primeiro quadro, e o
 *  motivo esta escrito no proprio index.html, junto delas.
 * ========================================================================== */
    :root {
      /* ============================================================ */
      /* PRECS CLARO — o tema claro da MARCA (1.1.6)                  */
      /* ============================================================ */
      /* O tema claro é representado pela AUSÊNCIA de data-theme, então ele vive aqui, no
         :root. Até a 1.1.5 estes valores eram a paleta genérica da 3C Plus: superfícies
         azuladas (#F9FAFC / #F0F2F5), texto azul-acinzentado (#373753) e o ouro da marca
         rebaixado a #856828 só para conseguir passar no contraste. Resultado: quem trabalha
         em sala clara trabalhava SEM a identidade PRECS, enquanto os temas escuros a tinham.
         Agora as superfícies são QUENTES, na mesma família do grafite #131315 do tema precs,
         e o texto é um quase-preto quente. É o mesmo tema, do lado claro.

         REGRA QUE NÃO PODE SER ESQUECIDA: o ouro da marca NÃO PODE SER TEXTO aqui.
         Medido sobre estas superfícies: #B49552 dá 2,44:1 e #D3B26B dá 1,73:1, e o
         teste-contraste.js exige AA 4,5:1 sem exceção para texto grande. Por isso o dourado
         se divide em dois papéis, e a divisão é proposital:
           TEXTO  -> bronze #7A6320 (--precs-gold / --precs-gold-title, no bloco
                     html:not([data-theme]) mais abaixo), pior caso 4,94:1
           FORMA  -> ouro #B49552 (fio de borda do painel, divisor, ícone), isento do
                     mínimo de 4,5 porque a regra vale para texto e não para forma — é o
                     mesmo argumento que o comentário do --st-idle já usa neste arquivo.
         É essa divisão que faz o tema parecer PRECS: o contorno dourado do cartão é ouro
         de verdade, e só a letra é escura.

         Os números abaixo são o PIOR caso de cada token, sempre contra --bg-tertiary, que é
         o fundo mais escuro dos três. Mexer aqui sem refazer a conta quebra o CI. */
      --bg-primary: #F7F6F3;     /* off-white quente (era #F9FAFC, azulado) */
      --bg-secondary: #FFFFFF;   /* cartão segue branco: é onde se lê o negócio */
      --bg-tertiary: #EFEDE7;    /* fundo de chip e trilho */
      --border-color: #E3DFD4;
      /* PRECS (1.1.0) — TRÊS NÍVEIS DE TEXTO, e no claro eram dois.
         --text-secondary e --text-muted valiam o MESMO #6B7280 aqui, enquanto nos
         outros temas são distintos: todo par rótulo/valor que conta com essa
         distinção aparecia achatado só no tema claro. E os dois reprovavam AA, em labels
         de 0,62 a 0,7rem, que é onde vivem .pm-lbl, .pm-status e .precs-sup-th.
         (1.1.6) Os três foram reequilibrados para o quente junto com as superfícies; a
         hierarquia de três níveis e a folga de contraste continuam as mesmas:
           primary   #2A2722 -> 12,71:1
           secondary #55504A ->  6,81:1
           muted     #6B655C ->  4,93:1 */
      --text-primary: #2A2722;
      --text-secondary: #55504A;
      --text-muted: #6B655C;

      /* Cores de destaque */
      --accent-blue: #294ace;
      --accent-blue-hover: #1e3a9f;
      --accent-blue-light: rgba(41, 74, 206, 0.1);
      --accent-3cplus: #FFBB3A;
      --accent-3cplus-dark: #E5A730;
      --accent-manual: #E67C0B;
      --accent-green: #10B981;
      --accent-green-light: rgba(16, 185, 129, 0.1);
      --accent-red: #EF4444;
      --accent-red-light: rgba(239, 68, 68, 0.1);
      --accent-orange: #F59E0B;
      --accent-orange-light: rgba(245, 158, 11, 0.1);

      /* (1.1.125) A PALETA DE PESSOAS E ÁREAS: oito tons de luminância média, legíveis sobre o grafite e
         sobre o claro, declarados UMA vez e iguais em todo tema (como as cores de estado). Pintam o nome
         do autor no grupo (precsCorIndice, pelo e-mail), a pílula de área (precsIdCorArea) e os cartões
         do hub. Nenhum é o ouro da marca de propósito: o ouro fica para o que é da PRECS. */
      --precs-paleta-1: #3E9BD6;   /* azul     - operacional, comunicação interna */
      --precs-paleta-2: #E0745B;   /* coral    - marketing (o "laranja") */
      --precs-paleta-3: #3FA96F;   /* verde    - closer */
      --precs-paleta-4: #A96FD1;   /* roxo     - jurídico, Pessoas */
      --precs-paleta-5: #C27F13;   /* âmbar    - RH (o "amarelo") */
      --precs-paleta-6: #D45D8E;   /* rosa     - financeiro */
      --precs-paleta-7: #2FA79B;   /* teal     - SDR */
      --precs-paleta-8: #6F78D6;   /* índigo   - comercial */
      /* (1.1.135) Dois tons a mais, para nenhum setor dividir cor: TI no aço, gestão no bronze. A diretoria fica
         no ouro da marca (classe .precs-cor-0). O mapa setor -> cor é PRECS_AREA_COR, no app.js. */
      --precs-paleta-9: #7F93AD;   /* aço      - TI */
      --precs-paleta-10: #B0803F;  /* bronze   - gestão */

      /* PRECS (1.1.10) — DUAS FAMÍLIAS QUE FALTAVAM, e a falta delas custou os seis piores
         contrastes do painel, todos em produção para a operação inteira.
         Medidas por .github/scripts/teste-contraste-render.js, que mede PAR RENDERIZADO.

         O erro de base era tratar um token de acento como se ele servisse a dois papéis
         opostos. `--accent-red` é ao mesmo tempo o FUNDO de um botão sólido e a COR DE TEXTO
         de um selo — e uma cor não consegue ser as duas coisas com 4,5:1. O que existia era
         `color: #fff` cravado na regra do componente, o que ignora o tema por construção:
         no precs `--accent-blue` vale #C6A75E (dourado claro), e branco sobre ele dá 2,31:1.

         1) --on-accent-*  = a cor do TEXTO que fica EM CIMA de um acento preenchido.
            A regra que saiu da medição é simples: nesta paleta os acentos são tons médios a
            claros, então quase todos pedem tinta escura. A única exceção é o azul do tema
            claro (#294ace), que é escuro o bastante para levar branco a 7,08:1. Por isso
            --on-accent-blue é o único que muda por tema.

         2) --accent-*-text = a versão do acento que serve como TEXTO sobre superfície clara.
            Nos temas escuros o próprio acento já passa (o verde dá 9,02:1 sobre #1B1B1E),
            então lá estes tokens apontam de volta para o acento e nada muda. Nos três estados
            CLAROS eles precisam ser bem mais escuros: #10B981 sobre branco dá 2,54:1.

         Não mexer no valor dos --accent-* originais é deliberado: eles pintam borda, filete,
         ponto e tint em dezenas de lugares onde 4,5:1 não se aplica, e escurecê-los para
         resolver o texto apagaria a cor do estado na tela. */
      /* PRECS (1.1.10) — ESPAÇAMENTO DE LETRA DO MICRO-RÓTULO EM CAIXA ALTA.
         O painel tem 38 regras com `text-transform: uppercase`, e elas usavam DEZESSEIS valores
         diferentes de letter-spacing em DUAS unidades: .3px, .4px, .5px, .6px, .7px, 0.3px,
         0.5px, 0.6px, .04em, .05em, .06em, .07em, .08em, 0.03em, 0.05em, 0.08em. Todas fazem o
         mesmo trabalho — rótulo pequeno em caixa alta, que sem espaçamento vira um bloco
         ilegível — e nenhuma tinha motivo para ser diferente da vizinha. É o tipo de coisa que
         ninguém aponta e todo mundo sente: dois rótulos lado a lado com respiro diferente leem
         como se fossem componentes de origens diferentes.
         `em` E NÃO `px`, de propósito: o valor passa a acompanhar o tamanho da fonte, então o
         mesmo token serve ao rótulo de 0,62rem e ao de 0,9rem sem ficar apertado num e largo no
         outro. 0,04em é o equivalente aos dominantes (.4px e .5px) nos tamanhos em uso. */
      --ls-caps: 0.04em;

      /* PRECS (1.1.56) — A ESCALA TIPOGRÁFICA. O último eixo do painel a ganhar uma.
         O levantamento, medido em 03/09/2026 com os comentários removidos: **620 declarações
         de `font-size` em 106 valores distintos**, ou 45 valores se olharmos só os `rem` puros.
         E o problema não é o número, é ONDE ele se concentra: **32 desses 45 estão espremidos
         entre .52rem e .92rem**, vários separados por 0,02rem — que dá 0,32px na tela. Ninguém
         escolhe uma diferença de 0,32px; ela é sedimento. Mas ela faz dois rótulos vizinhos
         lerem como componentes de origens diferentes, que é palavra por palavra o diagnóstico
         que o `--ls-caps` recebeu logo acima, e pelo mesmo motivo.

         POR QUE A RAMPA É NUMÉRICA e não são nomes de papel. A tentação era `--fs-rotulo`,
         `--fs-corpo`, `--fs-texto`… e ela não sobrevive ao próprio diagnóstico: entre 9px e
         15px não existem sete PAPÉIS diferentes, existe um papel só — texto pequeno de apoio —
         com sete tamanhos que a história depositou. Dar sete nomes a isso seria codificar a
         doença com ar de decisão. Numérica, a rampa diz a verdade: são degraus vizinhos, e
         escolher entre `--fs-3` e `--fs-4` é escolher um degrau, não um significado.
         É o mesmo desenho do `--space-*`, que resolveu o mesmo problema no eixo do espaço.
         (A 1.1.54 chamou 1,125rem de `--fs-num` e 0,5625rem de `--fs-selo` ao registrar os dois
         primeiros candidatos a migrar. Eles são o `--fs-10` e o `--fs-1` daqui.)

         OS DEGRAUS SÃO INTEIROS EM PX na raiz de 16, e isso não é preciosismo: a migração é
         provada pelo `teste-tipografia.js --contra HEAD`, que exige deslocamento ≤ 0,50px até
         17px de corpo. Com tolerância dessa ordem, degrau fracionário não cabe — e a rampa de
         1px entre 9 e 18 é o que permite migrar 106 valores para 11 SEM MOVER NADA na tela.
         Consolidar de verdade (menos tamanhos, mais contraste entre eles) é mudança visual
         deliberada e vem depois, quando a composição mudar; esta leva só dá nome ao que existe.

         ACIMA DE 18px A RAMPA ABRE, e é de propósito: ali o tamanho já é composição e não
         ritmo de componente — mesmo corolário que o `--space-8` escreveu para o espaço. */
      --fs-1:  0.5625rem;  /*  9px — selo, pílula, rótulo de chip */
      --fs-2:  0.625rem;   /* 10px */
      --fs-3:  0.6875rem;  /* 11px */
      --fs-4:  0.75rem;    /* 12px — o mais usado do painel */
      --fs-5:  0.8125rem;  /* 13px */
      --fs-6:  0.875rem;   /* 14px */
      --fs-7:  0.9375rem;  /* 15px */
      --fs-8:  1rem;       /* 16px — o corpo do navegador */
      --fs-9:  1.0625rem;  /* 17px */
      --fs-10: 1.125rem;   /* 18px — número que se lê de relance */
      --fs-11: 1.5rem;     /* 24px — a saudação do menu */

      /* PRECS (1.1.57) — OS CINCO PAPEIS DE FONTE, agora com nome.
         O levantamento: 275 declaracoes de `font-family` para CINCO familias, escritas em
         VINTE grafias distintas — e as grafias diferem por coisas que nao mudam um pixel:
         `'Manrope','Poppins',sans-serif` contra `'Manrope', 'Poppins', sans-serif` (um espaco
         depois da virgula), `'Montserrat', sans-serif` contra `'Montserrat','Poppins',
         sans-serif` (uma cauda de fallback a mais). Vinte formas de dizer cinco coisas.

         AQUI O NOME E DE PAPEL, e nao uma rampa numerada como a dos tamanhos. A diferenca nao
         e de gosto, e do que a coisa E: entre 9px e 15px nao existem sete papeis, existe um
         com sete tamanhos — por isso os `--fs-*` sao numerados. Aqui e o contrario: sao
         exatamente cinco papeis, cada um com uma familia escolhida para ele, e o proprio
         projeto ja os tinha escrito em prosa no `20-operador.css`. Estes tokens so estao
         dando nome ao que ja estava decidido.

         A PRIMEIRA FAMILIA DE CADA CADEIA E PRESERVADA byte a byte — e o que o
         `teste-tipografia.js --contra HEAD` cobra, e com razao: a face que o navegador de fato
         renderiza e a primeira que ele encontra. As caudas de fallback sao unificadas, o que
         nao muda nada na tela (as cinco vem do mesmo `<link>` e estao sempre disponiveis) e
         acaba com as vinte grafias. */
      --font-titulo: 'Sora','Poppins',sans-serif;        /* saudacao, nome da campanha */
      --font-corpo:  'Poppins','Manrope',sans-serif;     /* texto corrido do painel */
      --font-rotulo: 'Montserrat','Poppins',sans-serif;  /* cabecalho de card, rotulo */
      --font-acao:   'Manrope','Poppins',sans-serif;     /* botao, CTA, selo */
      --font-num:    'JetBrains Mono',monospace;         /* numero lido digito a digito */

      /* PRECS (1.1.10) — ESCALA DE MOVIMENTO.
         O painel tinha 283 durações de transition/animation espalhadas em 43 valores distintos
         (.1s, .12s, .14s, .15s, .16s, .18s, .2s, .22s, .25s, .26s, .28s, .3s, .32s…). Isso é a
         assinatura de animação adicionada caso a caso: cada componente escolheu a sua, e o
         resultado é uma tela sem ritmo — dois cards vizinhos entrando em velocidades diferentes
         leem como duas interfaces.
         Três degraus cobrem a camada de interação, e os nomes dizem o PAPEL e não o número:
           --dur-1  microinteração: hover, press, troca de cor. Era o `.15s` dominante (72 usos).
           --dur-2  transição de UI: aparecer/desaparecer, entrada de balão.
           --dur-3  entrada deliberada: card novo, seção, modal — algo que o olho deve acompanhar.
         Movimento AMBIENTE (pulse do ponto, shimmer do skeleton, 1s ou mais) fica fora: ele não
         é reação a uma ação do operador e tem ritmo próprio.
         --ease-1 é a curva que o projeto já usava nas entradas mais cuidadas: sai rápido e
         desacelera no fim, que é o que dá a sensação de peso. */
      --dur-1: .15s;
      --dur-2: .2s;
      --dur-3: .3s;
      --ease-1: cubic-bezier(.2,.7,.3,1);
      /* PRECS (1.1.54) — AS OUTRAS DUAS CURVAS QUE O PROJETO JÁ USAVA, e que estavam sem nome.
         Levantamento: 76 declarações de `cubic-bezier` em três curvas, mais 8 de uso único.
         A `--ease-1` tinha token desde a 1.1.10 e onze usos, contra 39 cópias escritas à mão;
         as outras duas nunca tiveram nome, e uma delas — a de saída — o gate de estilo nem
         contava, porque ninguém sabia que ela era canônica.

         SÃO TRÊS E NÃO UMA porque o PAPEL é diferente, e o papel se vê na forma da curva:
           --ease-1  REAÇÃO. Hover, largura de barra, transform. Sai rápido e assenta.
           --ease-2  ENTRADA de conteúdo (precsLeadIn, precsHomeIn, precsEmptyIn). Freia longo
                     no fim, que é o que faz um card "pousar" em vez de simplesmente aparecer.
                     Estava em uso com duas grafias — `.16,1,.3,1` e `0.16, 1, 0.3, 1` — que
                     são o mesmo valor escrito de dois jeitos.
           --ease-3  SAÍDA (precsModalOut e o par dele). É a única das três que ACELERA no fim,
                     e é isso que faz o modal SUMIR em vez de desbotar. Justamente por isso ela
                     não pode ser dobrada em nenhuma das outras duas: as outras duas são
                     desacelerações, e trocar aqui mudaria a animação de verdade.

         NENHUMA DELAS MUDA DE VALOR AQUI: são os mesmos bytes que já estavam escritos em 76
         lugares. A prova está no `provar-substituicao.js`, que expande os três tokens dos dois
         lados e exige que o texto colapse idêntico.

         AS 8 CURVAS DE USO ÚNICO FICAM COMO ESTÃO (`.2,.9,.3,1`, `.2,.85,.3,1.12`, `0,0,.2,1`,
         `.4,0,.2,1`, `.2,.8,.3,1`). Dobrá-las em `--ease-1` mudaria a animação, e criar cinco
         tokens para oito usos seria transformar acidente em regra — o mesmo argumento que o
         bloco do raio, mais abaixo, já usou para dobrar as camadas de 10px e 9px em vez de
         institucionalizá-las. */
      --ease-2: cubic-bezier(.16,1,.3,1);
      --ease-3: cubic-bezier(.4,0,1,1);

      --on-accent-ink: #17140F;              /* tinta escura para acento claro */
      --on-accent-blue: #FFFFFF;             /* único que muda por tema (ver acima) */
      --on-accent-red: var(--on-accent-ink);
      --on-accent-manual: var(--on-accent-ink);
      --accent-green-text: #065F46;
      --accent-red-text: #B42318;
      --accent-manual-text: #92400E;
      /* (1.1.32) O LARANJA FALTAVA, e a falta era medivel. `--accent-orange` no claro e
         #F59E0B: sobre branco isso da cerca de 2,1:1, e o `--accent-orange-light` a 10% de
         opacidade nao ajuda em nada. Os tres irmaos acima ja tinham variante de texto; o
         laranja nao, e era justamente ele que pintava os avisos MAIS IMPORTANTES da aba de
         WhatsApp (qualidade "Media", entrega entre 85% e 95%, "WhatsApp desligado no
         painel", "sem operador no painel", "erro 141007", motivo de reprovacao de modelo).
         Mesma familia do `--accent-manual-text`, que e o ambar vizinho ja aprovado. */
      --accent-orange-text: #8A4B0A;

      /* PRECS (1.1.0) — UM TOKEN POR ESTADO DO TOAST. Havia duas cores por estado,
         porque as regras do toast nasceram em dois blocos distantes e cada bloco
         escolheu a sua: um toast de AVISO tinha contorno e ícone amarelos
         (--accent-3cplus) com filete lateral e barra de progresso LARANJA
         (--accent-orange); um de SUCESSO misturava #10B981 no contorno com #22c55e
         no filete. Aviso passou a --accent-orange, que é o token semântico: o
         --accent-3cplus é a cor da MARCA 3C e no tema precs vale ouro, então avisos
         ficavam indistinguíveis dos informativos justamente no tema padrão.
         Quem desenha toast usa SÓ estes quatro. */
      --toast-ok:   var(--accent-green);
      --toast-err:  var(--accent-red);
      --toast-warn: var(--accent-orange);
      --toast-info: var(--precs-gold, #B49552);

      /* (1.1.6) Sombra QUENTE. Era rgba(55,55,83,…), um roxo-azulado: sobre superfície
         quente ele lê como uma auréola cinza-lilás em volta do cartão, que é justamente o
         que se nota primeiro quando um tema "não fecha". O tom vem do próprio
         --text-primary (#2A2722). */
      --shadow: 0 4px 12px rgba(42, 39, 34, 0.10);
      --shadow-lg: 0 8px 24px rgba(42, 39, 34, 0.14);

      /* PRECS (1.1.0) — ELEVAÇÃO. Havia SETE geometrias de sombra espalhadas
         (0 2px 8, 0 2px 10, 0 4px 12, 0 4px 14, 0 6px 18, 0 8px 24, 0 10px 30) para
         o que semanticamente são três alturas. A cor fica de fora de propósito: um
         botão âmbar projeta sombra âmbar, então quem usa passa a própria cor —
         `box-shadow: var(--elev-2) color-mix(in srgb, var(--accent-3cplus) 40%, transparent)`.
         O que estes tokens padronizam é a GEOMETRIA, que é o que estava divergindo. */
      --elev-1: 0 2px 8px;      /* encostado na superfície: chip, badge, input em foco */
      --elev-2: 0 4px 12px;     /* solto acima do conteúdo: card, botão em hover */
      --elev-3: 0 8px 24px;     /* flutuando sobre a tela: modal, popover, barra DTMF */

      /* PRECS (1.1.0) — ESPAÇAMENTO. O arquivo tinha 24 valores distintos de padding
         (.05, .12, .15, .28, .32, .38, .66, .82rem…): cada card recebeu ajuste
         manual, e nada alinhava com nada. Escala de 4px, que é o passo que o resto
         da interface já usava sem nome. Os finos (--space-0/1) existem porque chip e
         etiqueta realmente precisam de menos que 8px; abaixo de 2px, use 0.

         PRECS (1.1.3) — A ESCALA PASSOU DE px PARA rem. Os números são os mesmos com
         a raiz em 16px, que é o padrão: 0,25rem = 4px. Nada se move.
         O motivo da troca é que o resto do arquivo espaça em `rem` e o <html> não
         fixa font-size, então esses valores acompanham o tamanho de fonte que o
         operador configurou no navegador. Com a escala em px, migrar as declarações
         para os tokens congelaria o espaçamento enquanto o texto continuaria
         crescendo — quem usa fonte grande por necessidade ficaria com o texto
         espremido no mesmo padding de antes. Em rem, token e resto do CSS crescem
         juntos, e aí a migração é segura.
         Corolário: NÃO volte para px sem antes trocar as ~250 declarações que hoje
         apontam para cá. */
      --space-0: 0.125rem;  /*  2px */
      --space-1: 0.25rem;   /*  4px */
      --space-2: 0.5rem;    /*  8px */
      --space-3: 0.75rem;   /* 12px */
      --space-4: 1rem;      /* 16px */
      --space-5: 1.25rem;   /* 20px */
      --space-6: 1.5rem;    /* 24px */
      /* (1.1.3) Dois degraus a mais, para o espaçamento de CASCA (padding do header,
         do main, respiro entre blocos grandes) também caber na escala. Sem eles, os
         2rem que aparecem 13 vezes ficariam de fora e a grade valeria só por dentro
         dos cards. Acima de 32px não há degrau: a essa altura o valor é composição de
         layout, não ritmo de componente. */
      --space-7: 1.75rem;   /* 28px */
      --space-8: 2rem;      /* 32px */

      /* (1.1.10) A ESCALA DE RAIO PASSOU A SER CUMPRIDA, e não só declarada.
         O levantamento antes da varredura: 179 declarações de border-radius em ONZE valores
         distintos, com só 84 usando token. O resto era literal — inclusive 7 `999px`, 4 `8px` e
         4 `6px`, que são a CÓPIA EXATA de tokens que já existiam três linhas acima. Mais 8
         fallbacks do tipo `var(--radius-inner, 8px)`, que o próprio comentário abaixo proíbe.
         E duas camadas sem nome, `10px` (11 usos) e `9px` (3), que tinham virado o raio de fato
         dos campos e de dois botões sem ninguém ter decidido isso.
         Depois: 153 das 179 são canônicas (os 4 tokens, mais os 31 `50%` dos elementos
         redondos, que é o valor certo para um círculo). As duas camadas sem nome foram DOBRADAS
         em --radius-inner em vez de virarem tokens novos — a diferença é de 1 a 2px, invisível
         na tela, e institucionalizar um quinto degrau seria transformar o acidente em regra.
         Sobraram 16 declarações em valores pequenos (4px, 7px, 5px, 2px) em elementos
         decorativos miúdos; ficam para uma próxima passada, com o olho de quem desenhou cada um.

         PRECS — tokens de raio de borda (centralizados; mesmos valores de antes,
         para não haver regressão visual). Usar nestes lugares e nos próximos.
         NÃO escreva fallback nestes tokens. Havia três que CONTRADIZIAM o token que
         fingiam usar — pill com 20px (vale 999px), inner com 10px (vale 8px) e card
         com 14px (vale 12px) — e fallback errado é pior que fallback nenhum: vira
         documentação falsa para quem ler depois. Eles estão definidos aqui no :root,
         valem para os 3 temas e nunca faltam. Escreva `var(--radius-card)` limpo. */
      --radius-card: 12px;
      --radius-inner: 8px;
      --radius-sm: 6px;
      --radius-pill: 999px;

      /* PRECS — tokens do card da lead (Pipedrive). Aqui vale o PRECS Claro; os temas
         escuros sobrescrevem nos próprios blocos.
         (1.1.6) Esquentados junto com as superfícies. Ficar no azulado enquanto o resto da
         tela virou quente deixaria justamente o card do negócio — o maior bloco de leitura
         da tela de trabalho — como a única ilha fria, e a diferença salta quando ele está
         lado a lado com o card de anotação. */
      --lead-surface: #FFFFFF;
      --lead-surface-2: #FAF9F5;
      --lead-border: #E3DFD4;
      --lead-border-2: #EAE6DC;
      --lead-title: #221F1A;     /* 15,59:1 no pior caso */
      --lead-text: #2E2A24;      /* 13,53:1 */
      /* PRECS (1.1.0) — era #8A97A3, e 2,83:1 sobre a superfície branca da lead é
         reprovação larga, não de fronteira: são os RÓTULOS dos campos do negócio
         (Nome, CPF, Precatório) num card que o operador lê durante a ligação, com o
         cliente na linha. Foi escurecido então, e na 1.1.6 acompanhou o quente:
         --lead-label 5,57:1 e --lead-muted 5,15:1, medidos contra as duas superfícies
         da lead (que é o par que o teste-contraste.js usa para estes quatro tokens). */
      --lead-label: #6A6459;
      /* Cores de ESTADO da campanha (ocioso/manual/chamada/TPA) — fonte única,
         usadas pela faixa, status, termômetro e cronômetros.

         PRECS (1.1.4) — --st-idle era #475569 (slate-600), um cinza ESCURO, e só aqui:
         nos outros três temas o ocioso é cinza claro (#CBD5E1 no dark, #C1C6CE no precs,
         #EDF1F7 no contraste) e o próprio fallback histórico do app.js é #9aa3b2. O tema
         claro era o único em que o operador via um bloco quase preto no termômetro, o que
         lia como "estado grave" em vez de "sem fazer nada" — e a porcentagem escrita
         dentro do segmento (#0d0f13, ver .precs-thermo-seg) ficava ilegível em cima dele.
         Agora é #8E99A8, o mesmo cinza neutro dos demais temas, um degrau mais escuro
         porque aqui ele é pintado sobre fundo CLARO: com #CBD5E1 o segmento desapareceria
         dentro do trilho (--bg-tertiary). Contra o trilho dá 2,57:1 — é forma, não texto,
         então o mínimo de 4,5 não se aplica — e a porcentagem escrita por cima passa de
         2,53:1 (ilegível, era o que havia) para 6,64:1. */
      /* (1.1.6) AS CORES DE ESTADO NÃO MUDARAM NO PRECS CLARO, de propósito e a pedido:
         azul, cinza, âmbar, verde e violeta são o vocabulário que o operador já leu mil
         vezes no termômetro e nos cronômetros, e trocá-las por tons quentes custaria a
         leitura instantânea de "em que estado eu estou" para ganhar coerência estética.
         Verificado que continuam legíveis sobre o quente: a porcentagem escrita dentro do
         segmento tem melhor caso entre 4,53:1 (--st-mtpa) e 10,00:1 (--st-interval). */
      --st-idle:#8E99A8; --st-manual:#f59e0b; --st-call:#22c55e; --st-tpa:#294ace; --st-mtpa:#8b5cf6; --st-interval:#eab308; --st-offline:#B4BAC4;
      --lead-muted: #6F6962;

      /* PRECS — TOKENS QUE ERAM USADOS E NUNCA DEFINIDOS. --accent-color aparece em 5
         lugares da tela de Ensaio de layout (ícone do título, contorno tracejado, borda
         e dica do slot ativo) e --success-color no mock "● Em chamada". Sem definição,
         os dois caíam SEMPRE no literal escrito à mão, então aquela tela ficava com o
         ouro travado em #B49552 e não acompanhava o tema: no claro, por exemplo, o resto
         da interface usava o ouro escuro e ela seguia com o ouro do tema escuro.
         Apontando para os tokens de tema, a tela passa a acompanhar os 3 temas. */
      --accent-color: var(--precs-gold);
      --success-color: var(--st-call);
    }

    /* ============================================================ */
    /* (1.1.6) AQUI VIVIA O TEMA ESCURO — data-theme="dark". REMOVIDO.
       Motivo: o tema `precs`, que é o PADRÃO da marca, também é escuro. Os dois eram um
       fundo quase-preto cada, e a única diferença real era a cor de destaque (amarelo 3C
       #FFBB3A no dark, ouro #B49552 no precs). Manter os dois custava um bloco de 50
       tokens, uma coluna em três testes de regressão e uma escolha a mais no menu, para
       oferecer ao operador duas variações do mesmo tema.
       Com ele fora, são TRÊS temas, e cada um responde a uma necessidade distinta:
         (sem atributo)          PRECS Claro   marca, sala clara, dois brilhos
         data-theme="precs"      PRECS         marca, padrão, escuro
         data-theme="contraste"  Contraste     acessibilidade
       QUEM TINHA 'dark' SALVO É MIGRADO PARA 'precs', e a migração não é opcional: sem
       ela o atributo continuaria sendo escrito no <html>, nenhum bloco casaria, e a página
       cairia nos tokens do :root SEM as regras escopadas em html:not([data-theme]) — um
       híbrido quebrado, pior que qualquer dos dois temas. A migração vive em três lugares
       (o script de boot no <head>, precsAplicarPrefsDoRamal e precsSetTema) e tem teste
       próprio em .github/scripts/teste-preferencias.js.
       O que se perdeu de fato: o amarelo 3C como cor de destaque de tema. Ele continua
       existindo como --accent-3cplus para o que é da 3C. */
    /* ============================================================ */

    /* (Aqui viviam os overrides de `body.manual-mode` do tema escuro. Removidos em 1.1.5
       junto com os outros seis: a classe NUNCA era ligada por ninguém. Ver o comentário
       do bloco `body.manual-mode` mais abaixo neste arquivo.) */

    /* ============================================================ */
    /* PRECS — TEMA PRECS (identidade da marca: grafite + ouro).    */
    /* Mesma estrutura do escuro, mas a cor de DESTAQUE deixa de ser */
    /* o amarelo 3C e passa a ser o OURO da marca (#B49552). Fundos  */
    /* usam o grafite real do site (precs.com.br).                  */
    /* Ativado por data-theme="precs" no <html>.                    */
    /* ============================================================ */
    html[data-theme="precs"] {
      /* fundos = grafite real do site PRECS */
      --bg-primary: #131315;
      --bg-secondary: #1B1B1E;
      --bg-tertiary: #232327;
      --border-color: #2C2C30;
      --text-primary: #F3F3F3;
      --text-secondary: #C1C6CE;
      /* PRECS (1.1.0) — era #8A887F, que dava 4,41:1 sobre --bg-tertiary (#232327):
         reprovava AA por pouco, e justamente no tema PADRÃO da marca. Clareado o
         mínimo para passar (4,83:1), mantendo o cinza QUENTE que combina com o
         ouro — um cinza neutro aqui destoaria da paleta. */
      --text-muted: #918F86;

      /* (1.1.43) A FAIXA DA CABEÇA DO CARD. `transparent` porque a superfície grafite já É a
         paleta: uma faixa aqui seria grafite sobre grafite. A tinta em ouro é o que este tema
         já fazia numa regra separada de `.panel-header`; o valor não mudou de lugar por
         estética, e sim para o teste poder cobrar de TODO tema uma decisão sobre a cabeça. */
      --panel-cabeca: transparent;
      --panel-cabeca-tinta: var(--precs-gold);

      /* OURO da marca como destaque principal (substitui o amarelo 3C) */
      --precs-gold: #B49552;         /* institucional */
      --precs-gold-soft: #D2AE52;
      --precs-gold-title: #D3B26B;   /* títulos */
      --precs-gold-hi: #FFC95B;      /* realce / hover */
      --precs-gold-light: rgba(180, 149, 82, 0.16);
      /* (1.1.42) O PAR OURO-FORMA / TINTA passou a ser DECLARADO, e não herdado do `:root`.
         Os valores são os mesmos de antes, então nada muda na tela. O que muda é o contrato:
         `--precs-gold-forma` é o ouro como SUPERFÍCIE (o botão de enviar do WhatsApp, o anel
         do segmento ativo, o balão próprio) e `--precs-wa-tinta-ouro` é a tinta que vai em
         cima dele. Eles são um PAR: trocar um sem o outro põe texto claro sobre superfície
         clara. Foi exatamente o que aconteceu no Bordô, que herdou o ouro do `:root` sem
         nunca ter decidido usá-lo — ver o `teste-temas.js`, que existe por causa disso. */
      --precs-gold-forma: #B49552;
      --precs-wa-tinta-ouro: #131315;
      --accent-3cplus: #B49552;
      --accent-3cplus-dark: #D2AE52;

      /* azul de ação fica discreto e levemente dourado-neutro */
      --accent-blue: #C6A75E;
      --accent-blue-hover: #D2AE52;
      --accent-blue-light: rgba(180, 149, 82, 0.16);

      /* CORES FUNCIONAIS preservadas (ocioso/manual/em chamada/TPA/sucesso/erro) */
      --accent-manual: #F59336;
      --accent-green: #2BD4A0;
      --accent-green-light: rgba(43, 212, 160, 0.16);
      --accent-red: #F26D6D;
      --accent-red-light: rgba(242, 109, 109, 0.16);
      --accent-orange: #F7A93B;
      --accent-orange-light: rgba(247, 169, 59, 0.16);

      /* (1.1.10) O azul de ação aqui é DOURADO CLARO (#C6A75E), então o texto em cima dele é
         escuro — era este par que dava 2,31:1 com o branco cravado na regra do .btn-primary,
         no tema que é o padrão do painel. Vermelho e âmbar já herdam a tinta escura do :root.
         E os tokens de TEXTO voltam a ser o próprio acento: sobre fundo grafite o verde dá
         9,02:1 e o vermelho 4,63:1, ou seja, aqui não havia problema para resolver. */
      --on-accent-blue: var(--on-accent-ink);
      --accent-green-text: var(--accent-green);
      --accent-red-text: var(--accent-red);
      --accent-manual-text: var(--accent-manual);
      --accent-orange-text: var(--accent-orange);

      /* estados da campanha: TPA num azul discreto (não o azul 3C cru), para não brigar com o ouro */
      --st-idle:#C1C6CE; --st-manual:#F59336; --st-call:#2BD4A0; --st-tpa:#5E6AD2; --st-mtpa:#A78BFA; --st-interval:#E8C46A; --st-offline:#56544F;
      /* métrica CPC harmoniza com o ouro (era o azul 3C cru #3B82F6) */
      --m-cpc:#8AA0E6;

      /* (1.1.54) O ANEL DE LUZ, e ele é a metade que faltava da profundidade em tema escuro.
         Sombra preta sobre fundo quase preto não escurece nada: medido, o card do PRECS se
         separa da página por 1,080 — praticamente colado —, e a sombra que deveria fazer essa
         separação é `rgba(0,0,0,.5)` sobre um #131315. Ela existe e não faz trabalho nenhum.
         No mundo físico um objeto sobre fundo escuro não se destaca pela sombra que projeta,
         e sim pela LUZ que pega na aresta de cima. É isso que o anel de 1px faz.
         NÃO É INVENÇÃO NOVA: o tema Contraste já embute exatamente esta forma no `--shadow`
         dele desde a 1.1.44 (`60-campanhas-e-tv.css:1062`), e é o único dos dez que o faz.
         Aqui a forma se generaliza para os outros dois escuros.
         Fica no `--shadow` e não num token próprio de propósito: `--shadow` já significa "como
         uma superfície elevada se separa do fundo NESTE tema", já está no contrato de 64 tokens
         que o teste-temas.js cobra, e um `--card-realce` paralelo seria um segundo mecanismo de
         elevação para o mesmo trabalho — a definição de dívida, pelo padrão deste arquivo.
         A SOMBRA TAMBÉM CRESCEU, e por um motivo que a primeira versão não tinha entendido:
         no PRECS o fundo é #131315 e NÃO preto, então sombra preta ainda escurece — o que ela
         não fazia era escurecer numa ÁREA grande o bastante para se ver. Subir o alfa satura
         rápido (0,5 dá 1,155 de separação na borda; 0,8 dá 1,194, quase nada a mais); o que
         funciona é ESPALHAR, e por isso o raio foi de 4px/12px para 10px/32px.
         O anel foi de 0,07 para 0,11 na mesma volta. Os dois valores da primeira calibragem
         eram conservadores demais, e quem apontou foi o Pedro olhando a tela: "parece que não
         mudou nada". Medido pelo teste-temas-render, o anel do card foi de 1,07 para 1,35. */
      --shadow: 0 0 0 1px rgba(255, 255, 255, 0.11), 0 10px 32px rgba(0, 0, 0, 0.62);
      --shadow-lg: 0 0 0 1px rgba(255, 255, 255, 0.11), 0 18px 48px rgba(0, 0, 0, 0.7);

      /* card da lead no tema PRECS */
      --lead-surface: #1B1B1E;
      --lead-surface-2: #131315;
      --lead-border: #2C2C30;
      --lead-border-2: #3A3A2E;
      --lead-title: #F3F3F3;
      --lead-text: #F3F3F3;
      --lead-label: #B49552;
      --lead-muted: #8A887F;
    }

    /* (Aqui viviam os overrides de `body.manual-mode` dos temas precs e contraste, e o
       filete âmbar do painel nos três temas escuros. Removidos em 1.1.5 — ver o
       comentário do bloco `body.manual-mode` mais abaixo neste arquivo.) */

    /* PRECS — toques de identidade exclusivos do tema PRECS */
    /* Cabeçalho de painel: título em ouro, maiúsculas espaçadas (igual ao site).
       (1.1.43) O `color` saiu daqui e virou `--panel-cabeca-tinta` no bloco de tokens do tema,
       logo acima. Mesma cor na tela; a diferença é que agora TODO tema decide a tinta da
       cabeça, e o teste cobra quem não decidir. */
    html[data-theme="precs"] .panel-header {
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      font-weight: 600;
      border-bottom: 1px solid rgba(180,149,82,0.18);
    }
    /* Linha de marca no topo do painel ativo já usa --precs-cor-estado;
       o anel de foco e divisores ganham o ouro */
    html[data-theme="precs"] .form-group input:focus {
      box-shadow: 0 0 0 3px var(--precs-gold-light);
      border-color: var(--precs-gold);
    }
    /* Borda da aba ativa em ouro (no escuro era amarelo 3C) */
    html[data-theme="precs"] .panel { border: 1px solid var(--panel-fio); }

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    /* PRECS — reserva o espaço da barra de rolagem sempre. Sem isto, quando a
       barra aparece/some (ex.: ao abrir modais ou trocar de tela) a largura útil
       muda e todo o conteúdo alinhado à direita (como o botão de Preferências no
       header) "pula" lateralmente.

       PRECS (1.1.4) — A CALHA SÓ PODE SER PINTADA PELO FUNDO DO CANVAS, e é por isso que
       o background está aqui no <html> e não só no <body>.

       A calha desses ~10px fica FORA da caixa do <body>, e o navegador recorta todo o
       conteúdo na borda do bloco-contenedor inicial. Medido, para ninguém repetir a
       tentativa: um elemento `position: fixed` com `width: 100vw` reporta
       getBoundingClientRect().right = 1400 numa janela de 1400px, e ainda assim não pinta
       um pixel na calha; pintar o <html> de azul, sim, pinta. Também não resolve com
       sombra sólida deslocada no header, nem com `calc(100vw - 100%)` (esse último é pior:
       o header roda com `zoom`, e dentro de elemento com zoom o Chrome ajusta a
       PORCENTAGEM e não o `vw`, então a conta deu -252,94px e o header ENCOLHEU).

       Sem background aqui, o canvas herdava o do <body> e a calha ficava sempre na cor
       neutra do fundo: durante a ligação, a tela toda tingida do estado e uma tira crua na
       direita, exatamente onde o olho lê "a página parou". Com o background no <html>, a
       tira acompanha o estado (ver html[data-tint] junto do #precs-tint).
       O <body> mantém o próprio background: ele cobre a área útil, e o do <html> aparece
       só na calha. */
    html {
      scrollbar-gutter: stable;
      background-color: var(--bg-primary);
      transition: background-color .55s ease, --precs-tint .55s ease;
    }

    body {
      font-family: 'Poppins', sans-serif;
      background: var(--bg-primary);
      color: var(--text-primary);
      min-height: 100vh;
      display: flex;
      flex-direction: column;
    }
    /* (1.1.49) EM CELULAR, `100dvh` NO LUGAR DE `100vh`, e a diferença é a barra de URL.
       Em Android e iOS, `vh` é a viewport GRANDE — a altura com a barra de endereço recolhida.
       Enquanto ela está visível (o estado em que a página abre), `100vh` é maior que a área
       visível, e um `min-height: 100vh` no `body` empurra ~56px de conteúdo para baixo da dobra
       e dá à página uma rolagem que não vem de conteúdo nenhum. `dvh` é a viewport DINÂMICA:
       acompanha a barra aparecendo e recolhendo.
       Só em aparelho, e a regra fica separada por isso: `dvh` muda de valor durante a rolagem, e
       numa estação isso seria layout se mexendo sem motivo — lá `vh` é estável e correto. */
    /* E A REDE CONTRA O TRANSBORDO LATERAL, que é rede e não conserto — os transbordos em si são
       caçados um por um pelo teste-aparelho, que reprova qualquer elemento passando da viewport.
       Isto existe para o que escapar: numa tela de 360px, um transbordo de 12px vira faixa vazia
       à direita e a página inteira rolando de lado, e quem rola de lado perde o rumo do que
       estava lendo (foi o print 5 de 02/09/2026).
       `clip` E NÃO `hidden`, e a escolha importa: `overflow-x: hidden` obriga o outro eixo a
       virar `auto`, o que transforma o `body` num contêiner de rolagem — e isso mudaria a
       referência de todo `position: sticky` de dentro dele, incluindo o cabeçalho grudado da
       tabela de operadores. `clip` recorta sem criar contêiner de rolagem e sem tocar no eixo
       vertical. */
    html[data-aparelho] body{ min-height: 100dvh; overflow-x: clip; }

    /* PRECS (1.1.5) — AQUI VIVIAM AS 7 REGRAS DE `body.manual-mode`, TODAS REMOVIDAS.
       Elas pintavam body, header, .logo e .panel com um véu âmbar de 4% a 14%, mais três
       overrides por tema escuro. Eram CÓDIGO MORTO: a classe nunca era ligada. Busca no
       repositório inteiro, antes de remover: zero `classList.add('manual-mode')` no
       app.js e nenhum `class="manual-mode"` no HTML. O modo manual de verdade vive em
       `AppState.isManualMode` e chega à tela por `precsCorEstado(PRECS_ESTADOS.MANUAL)`
       e `updateStatusBadge('manual')` — nenhum dos dois toca nessa classe.
       O motivo de remover AGORA, e não deixar dormindo: é exatamente a mesma ideia que o
       véu de estado do header implementa de verdade nesta versão (busque
       `--header-bg-estado`). Com as duas no arquivo, quem religasse a classe um dia teria
       dois véus concorrentes no mesmo header, um por estado e um por modo, e a cascata
       decidiria por ordem de linha.
       Elas não são perda: as porcentagens que usavam (4% a 14%) são justamente a faixa
       que preserva contraste, e essa medida foi reaproveitada na escolha do véu novo. */

    header {
      /* (1.1.5) o fundo vem de um TOKEN, não de --bg-secondary direto: fora da campanha
         ele VALE --bg-secondary, e dentro dela recebe o véu da cor do estado. Ver
         html[data-tint] no bloco do tint. */
      background: var(--header-bg-estado, var(--bg-secondary));
      border-bottom: 1px solid var(--border-color);
      padding: var(--space-4) var(--space-8);
      display: flex;
      align-items: center;
      justify-content: space-between;
      /* (1.1.54) O HEADER SAIU DO `--shadow`, e ele é a exceção que a leva do anel produziu.
         `--shadow` passou a embutir um anel de 1px (ver `00-base.css:422`), e anel é a
         linguagem de quem FLUTUA. O header não flutua: ele é cromo colado no topo da janela.
         O anel desenhava fio de luz nos quatro lados dele — inclusive no de baixo, encostado
         na `border-bottom`, o que produzia aresta dupla; e no de cima, contra o cromo do
         navegador, onde não há nada para se separar.
         Quem separa header de conteúdo aqui é a `border-bottom`, que já existe e é o separador
         certo para cromo preso à borda. A sombra que ele tinha antes (12px de raio a 50%) não
         fazia trabalho visível numa barra de largura total. */
      box-shadow: none;
      transition: background-color .45s ease, border-bottom-color .45s ease;
    }

    .logo {
      font-weight: 700;
      font-size: 1.25rem;
      color: var(--accent-blue);
      letter-spacing: -0.5px;
      display: flex;
      align-items: center;
      gap: var(--space-2);
    }
    /* Wrapper que GARANTE o círculo, independente da imagem */
    .logo-circle {
      width: 64px;
      height: 64px;
      border-radius: 50%;
      overflow: hidden;
      display: inline-block;
      flex: 0 0 auto;
      border: 1px solid #1a1a1a;
      box-shadow: var(--elev-1) rgba(0, 0, 0, 0.1);
      background: var(--accent-3cplus, #FFBB3A);
    }
    .logo-circle img,
    .logo-image {
      width: 100%;
      height: 100%;
      aspect-ratio: 1 / 1;
      object-fit: cover;
      object-position: center;
      display: block;
      border: none;
      box-shadow: none;
    }

    /* dentro do avatar da chamada a logo ocupa todo o círculo do avatar */
    .call-avatar .logo-image {
      width: 100%;
      height: 100%;
      border: none;
      box-shadow: none;
    }

    .logo span {
      color: var(--text-secondary);
      font-weight: 400;
    }

    .header-right {
      display: flex;
      align-items: center;
      gap: var(--space-4);
    }

    .status-badge {
      display: flex;
      align-items: center;
      gap: var(--space-2);
      padding: var(--space-2) var(--space-3);
      border-radius: var(--radius-pill);
      font-size: 0.8rem;
      font-weight: 500;
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
    }

    /* (1.1.10) O selo é TEXTO colorido sobre um tint da mesma cor — a combinação mais
       apertada que existe, porque fundo e texto puxam para o mesmo lado. Medido: o
       "Desconectado" dava 3,30:1 no claro e 2,99:1 no claro suave. A BORDA segue no acento
       cheio, que é o que mantém o selo reconhecível de longe; o ponto (`.status-dot`) usa
       currentColor e escurece junto com a letra, e isso é desejável — ponto e texto são a
       mesma informação, e um ponto claro ao lado de letra escura leria como dois estados. */
    .status-badge.connected {
      border-color: var(--accent-green);
      color: var(--accent-green-text);
      background: var(--accent-green-light);
    }

    .status-badge.disconnected {
      border-color: var(--accent-red);
      color: var(--accent-red-text);
      background: var(--accent-red-light);
    }

    .status-badge.manual {
      border-color: var(--accent-3cplus);
      color: var(--accent-3cplus-dark);
      background: rgba(255, 187, 58, 0.15);
    }

    /* (1.1.10) A BOLINHA VOLTOU A SER REDONDA EM QUALQUER DENSIDADE.
       Eram dois problemas somados, e os dois deformavam para ELIPSE:
         • ela é filha de um flex (.status-badge) sem `flex` declarado, então podia ser
           ESMAGADA na horizontal quando o selo apertava — altura mantida, largura reduzida;
         • 8px sob `zoom` viram 6,8px (densidade normal) e 5,76px (compacta). Em subpixel o
           navegador arredonda largura e altura de forma independente, e 7×6 não é círculo.
       `flex: 0 0 auto` tira o esmagamento e `aspect-ratio: 1` garante o quadrado mesmo se a
       largura for limitada por qualquer motivo. */
    .status-dot {
      width: 8px;
      height: 8px;
      flex: 0 0 auto;
      aspect-ratio: 1;
      border-radius: 50%;
      background: currentColor;
      animation: pulse 2s infinite;
    }

    @keyframes pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.4; }
    }
    /* PRECS (1.1.0) — o bloqueio de movimento reduzido para o ponto de status existia,
       mas SÓ para `.status-badge.connected .status-dot`, e aquela regra neutraliza o
       precsDotPulse, que é outra animação. O `pulse` daqui seguia rodando nos estados
       desconectado e manual — ou seja, quem pediu menos movimento no sistema
       continuava com o indicador que mais olha piscando o turno inteiro, e piscando
       exatamente quando algo está errado. Este bloqueio é na origem e cobre os três. */
    @media (prefers-reduced-motion: reduce) {
      .status-dot { animation: none; }
    }

    main {
      flex: 1;
      display: flex;
      padding: var(--space-8) var(--space-4);        /* menos folga lateral: cards encostam mais nas bordas */
      gap: var(--space-8);
      max-width: 2200px;         /* aproveita melhor monitores largos */
      margin: 0 auto;
      width: 100%;
    }

    /* (1.1.54) LUZ DE CIMA, e é ela que faz o card virar objeto em vez de retângulo.
       O anel do `--shadow` (ver `00-base.css:422`) dá a ARESTA; isto dá o VOLUME. São as duas
       metades do mesmo problema: sobre fundo escuro nada se destaca pela sombra que projeta,
       e sim pela luz que pega em cima.
       O gradiente é BRANCO e universal de propósito, e isso não é preguiça — é o que o torna
       seguro por construção: sobre o card branco dos temas claros, branco a 5% é um no-op
       EXATO (255 continua 255); sobre o grafite #1B1B1E do PRECS ele levanta o topo e some em
       200px. Um token por tema daria o mesmo resultado nos escuros, custaria uma linha no
       contrato de 64 do teste-temas.js e teria que ser declarado dez vezes para fazer efeito
       em quatro.
       200px e não a altura toda: a luz precisa DECAIR para ler como luz. Espalhada pelo card
       inteiro ela vira "o fundo do card é mais claro", que é a mudança de superfície que este
       arquivo já recusou noutro lugar (clarear `--bg-secondary` deixaria o card mais claro que
       o `--bg-tertiary` que ele contém).
       O `background-image` não muda `background-color`, então o `teste-contraste.js` — que
       mede TOKEN contra TOKEN — não enxerga esta linha. Quem cobra aqui é o
       `teste-contraste-render.js`, que compõe o fundo real subindo a árvore. */
    .panel {
      background-color: var(--bg-secondary);
      background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0) 200px);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-card);
      overflow: hidden;
      box-shadow: var(--shadow);
    }

    /* PRECS (1.1.0) — TÍTULO SÓ PARA LEITOR DE TELA. O documento não tinha nenhum
       <h1>, então quem navega por cabeçalhos não tinha mapa nenhum da página: as 4
       seções (login, menu do dia, campanha ativa, supervisão) são telas inteiras e
       nenhuma se anunciava. O h1 é invisível de propósito — a identidade visual de
       cada tela já é dada pela marca e pelo card, e um título grande no topo
       roubaria a altura que o notebook não tem.
       clip-path + 1px é o padrão que some da tela SEM sumir da árvore de
       acessibilidade; `display:none` ou `visibility:hidden` removeriam o h1 do leitor
       também, que é o oposto do que se quer aqui. */
    .precs-sr-only {
      position: absolute;
      width: 1px; height: 1px;
      margin: -1px; padding: 0; border: 0;
      overflow: hidden;
      clip-path: inset(50%);
      white-space: nowrap;
    }

    /* Os .panel-header são o segundo nível da hierarquia. Levam role="heading" e
       aria-level="2" em vez de virarem <h2> de verdade porque a regra abaixo não
       define `margin`: trocar a tag traria a margem do agente de usuário e
       descolaria o cabeçalho do topo do card, em 14 lugares e nos 3 temas. A árvore
       que o leitor de tela recebe é idêntica. Trocar pela tag nativa é candidato
       para depois de 10/08, junto com um `margin: 0` aqui. */
    /* (1.1.43) A CABEÇA DO CARD É ONDE O TEMA CLARO MORA.
       Nos temas ESCUROS a paleta cabe na superfície: o Bordô é vinho porque `--bg-primary` É
       #1C0D10, e o Zebrado escuro funciona porque o preto domina de verdade. Nos CLAROS a
       superfície não pode carregar a paleta — branco é branco —, então sobrava o fio de 1px e o
       texto, e os três claros convergiam para a mesma imagem: "o bordô claro não tem cor de
       bordô nos cards" e "o Zebrado claro não mudou muito" (Pedro, 01/09/2026).
       Esta faixa é a resposta, e ela é o único lugar do card onde um tema pode pôr ÁREA de cor
       sem tocar em conteúdo. Por isso o token é `transparent` em cinco dos oito temas: não é
       enfeite aplicado a todos, é a saída dos claros temáticos.
       O par de tokens vive no bloco de cada tema e é cobrado pelo teste-temas.js. */
    /* PRECS (1.1.57) — OS TRES CABECALHOS DO MENU NAO ESTAVAM NA MESMA LINHA, e o culpado
       era o botao. Medido em px de CSS, com os tres cards lado a lado:

         card                  altura do cabecalho   base do titulo   corpo comeca
         Meu desempenho              60px                236,8            258,6
         Selecione uma campanha      50,8px              232,2            249,4
         Ultimos leads               50,8px              232,2            249,4

       O "Ver estatisticas" tem 26,8px de altura, e com `padding: 16px` em cima e embaixo o
       cabecalho dele vai a 60px. O `align-items: center` entao empurra o TITULO 4,6px para
       baixo, e o corpo inteiro do card 9,2px. Tres titulos lado a lado em alturas diferentes e
       o tipo de coisa que ninguem aponta e todo mundo sente.
       O CONSERTO E EXATO, nao aproximado: 12 + 26,8 + 12 = 50,8, que e a altura dos outros
       dois. Por isso `--space-3` e nao um valor escolhido no olho.
       ESCOPADO ao menu de proposito: `.panel-header` com botao existe tambem na tela de
       campanha ativa (o botao de modo TV), e la nao ha tres cabecalhos lado a lado para
       desalinhar — mexer neles seria mudar o que ninguem reclamou. */
    #campaigns-section .panel-header:has(button) { padding-block: var(--space-3); }
    .panel-header {
      padding: var(--space-4) var(--space-5);
      border-bottom: 1px solid var(--border-color);
      font-weight: 600;
      font-size: 0.9rem;
      background: var(--panel-cabeca, transparent);
      color: var(--panel-cabeca-tinta, var(--text-secondary));
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      display: flex;
      align-items: center;
      gap: var(--space-2);
    }

    .panel-body {
      padding: var(--space-5);
    }

    /* ============================================ */
    /* SECTION: Login */
    /* ============================================ */
    .section {
      display: none;
      width: 100%;
    }

    .section.active {
      display: block;
      animation: precsSecFade var(--dur-3) ease;   /* entrada suave ao trocar de tela */
    }
    @keyframes precsSecFade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
    /* badge "Conectado": pulso lento reforçando que está tudo ativo */
    /* PRECS (1.1.57) — O HALO DEIXOU DE SER VERDE CRAVADO. Ele era `rgba(43,212,160,.5)`
       escrito à mão dentro do keyframe, e keyframe não aceita `var()` no lugar de uma cor
       inteira sem que o valor seja resolvido no elemento — por isso a cor ficou literal em
       2021 e ninguém mexeu.
       O problema: o painel tem 16 paletas e esse verde é o do PRECS. No Rubi, no Topázio e nos
       claros o ponto de "Conectado" é pintado por `--accent-green` (que muda), mas o HALO em
       volta dele continuava naquele verde — duas cores diferentes para o mesmo sinal, na mesma
       pastilha.
       A saída é `currentColor`: o `.status-dot` já herda a cor do estado do `.status-badge`
       (`background: currentColor`, logo acima), então o halo passa a nascer da mesma fonte que
       o ponto. `color-mix` resolve a opacidade sem precisar de um token novo. */
    .status-badge.connected .status-dot { animation: precsDotPulse 2.2s ease-in-out infinite; }
    @keyframes precsDotPulse {
      0%,100% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 50%, transparent); }
      50%     { box-shadow: 0 0 0 5px color-mix(in srgb, currentColor 0%, transparent); }
    }
    @media (prefers-reduced-motion: reduce) {
      .section.active { animation: none; }
      .status-badge.connected .status-dot { animation: none; }
    }

    /* (Etapa 2) A tela de entrada com a conta Google usa o MESMO cartao do login, entao herda
       a mesma largura. Por id e nao por classe porque e o que a regra original ja era. */
    #login-section,
    #entrada-section {
      max-width: 400px;
      margin: auto;
    }
    /* PRECS — acento dourado da marca no topo do card de login */
    .precs-login-panel { border-top: 3px solid var(--precs-gold, #B49552); }
    .precs-login-brand { text-align: center; margin-bottom: var(--space-5); }
    .precs-login-brand svg { display: inline-block; }
    .precs-login-brand-sub {
      font-size: .8rem; color: var(--text-secondary); margin-top: var(--space-2); line-height: 1.4;
    }

    .form-group {
      margin-bottom: var(--space-4);
    }

    .form-group label {
      display: block;
      font-size: 0.85rem;
      font-weight: 500;
      color: var(--text-secondary);
      margin-bottom: var(--space-2);
    }

    .form-group input {
      width: 100%;
      padding: var(--space-3) var(--space-4);
      background: var(--bg-primary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-inner);
      color: var(--text-primary);
      font-family: 'JetBrains Mono', monospace;
      font-size: 0.9rem;
      transition: border-color var(--dur-2), box-shadow var(--dur-2);
    }

    /* (1.1.45) O `outline:none` passou a valer só para o foco que NÃO é de teclado.
       Como estava, ele vencia a regra global de `:focus-visible` por especificidade (0,2,1
       contra 0,1,0) e apagava o anel de 2px também para quem chega por Tab — trocando-o por
       uma faixa de 3px a 10% de alfa, abaixo do perímetro que a WCAG 2.2 SC 2.4.11 pede e do
       critério que o próprio projeto fixou em 1.1.10 (box-shadow é HALO POR FORA do outline,
       os dois somam). São os campos de login: a primeira tela do dia e a mais usada por
       teclado no painel inteiro. No clique a aparência não muda. */
    .form-group input:focus {
      border-color: var(--accent-blue);
      box-shadow: 0 0 0 3px var(--accent-blue-light);
    }
    .form-group input:focus:not(:focus-visible) { outline: none; }

    /* (1.1.45) O erro de login, junto dos campos. Usa `--accent-red-text` e não
       `--accent-red`: o vermelho de SINAL foi calibrado para preencher forma (o filete, o
       ponto de estado) e nos temas claros ele não fecha 4,5:1 como texto — a variante de
       tinta existe exatamente para isso, e foi a mesma correção que o cabeçalho do card em
       alerta precisou. */
    .precs-login-erro {
      margin-bottom: var(--space-3);
      padding: var(--space-2) var(--space-3);
      border-radius: var(--radius-sm);
      border: 1px solid var(--accent-red-text, var(--accent-red));
      background: var(--accent-red-light);
      color: var(--accent-red-text, var(--accent-red));
      font-size: 0.82rem;
      font-weight: 600;
    }

    .form-group input::placeholder {
      color: var(--text-muted);
      opacity: 0.45;   /* PRECS: placeholder mais apagado — não parecer campo já preenchido */
    }

    /* (1.1.46) O `transition: all` SAIU DAS SETE REGRAS QUE O TINHAM, e este bloco vale para
       todas elas: `.btn`, `.btn-icon-manual`, `.campaign-item`, `.mode-btn`, `.dial-btn`,
       `.qualification-item` e `.precs-tel-btn` — todas neste arquivo, nenhuma no resto do CSS.

       O QUE `all` ANIMAVA SEM NINGUEM PEDIR:
        • GEOMETRIA. `width`, `height`, `padding` e `font-size` entram no `all`, e estes sete
          seletores sao repintados por JS (a lista de campanhas, a qualificacao do TPA, o botao
          de discar). Trocar o conteudo de um card fazia a caixa deslizar até o tamanho novo em
          0,2s — e é dai que vem o "pulo" que varias regras vizinhas corrigem à mão.
        • O ANEL DE FOCO. `outline` e `outline-offset` tambem estao no `all`, entao o anel de
          2px aparecia com fade de 0,2s ao receber Tab. Indicador de foco tem de ser imediato:
          quem navega por teclado precisa saber ONDE esta, e nao ve-lo surgir.

       As listas foram MEDIDAS, e nao adivinhadas: para cada seletor, varri as regras de estado
       dele (`:hover`, `:active`, `:disabled`, `:focus-visible`, `.selected`, `.active`) e
       coletei as propriedades que mudam de fato. `background` entra como shorthand de
       proposito — o `.campaign-item` e o `.dial-btn` trocam GRADIENTE, e `background-color`
       sozinho deixaria isso de fora. `outline` ficou fora nas sete.

       O `transition: all` esta no baseline-estilo.json com contagem ZERO. Se voltar, a catraca
       reprova, e a mensagem dela diz o que usar no lugar. */
    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: var(--space-2);
      padding: var(--space-3) var(--space-6);
      border: none;
      border-radius: var(--radius-inner);
      font-family: inherit;
      font-size: 0.9rem;
      font-weight: 600;
      cursor: pointer;
      transition: background var(--dur-2), border-color var(--dur-2), color var(--dur-2), box-shadow var(--dur-2), transform var(--dur-2), opacity var(--dur-2), filter var(--dur-2);
    }
    /* (1.1.57) A GUARDA DE MOVIMENTO DO `.btn`, que nunca existiu. São sete propriedades em
       transição, incluindo `transform`, na classe de MAIOR alcance do painel — o `Sair` do
       header, o `Conectar` do login, os botões dos modais. Achado ao listar, um a um, o que
       cada bloco de movimento reduzido de fato desliga. */
    @media (prefers-reduced-motion: reduce) { .btn { transition: none; } }

    .btn-primary {
      background: var(--accent-blue);
      /* (1.1.10) Era `#FFFFFF` cravado, o que ignora o tema por construção. No precs
         --accent-blue vale #C6A75E (dourado claro) e branco em cima dava 2,31:1 — em
         "Conectar", "Ligar", "Enviar Qualificação" e "Buscar negócio", no tema padrão. */
      color: var(--on-accent-blue);
    }

    /* PRECS (1.1.0) — LARGURA TOTAL É OPT-IN, e era o contrário. O .btn-primary
       nascia com width:100% porque o primeiro uso foi o botão de login, que ocupa a
       coluna inteira. Só que largura total não é característica de "primário": é
       característica daquele lugar. O resultado é que todo uso seguinte teve que
       DESFAZER o padrão, cada um à sua maneira — um style inline reescrevendo também
       o padding do .btn, um `width:auto` no cadastro, um `flex:1` no Ensaio.
       Invertido: o botão nasce com a largura do conteúdo e quem precisa da coluna
       inteira pede com .btn-block. Hoje são dois: o login e o Enviar Qualificação. */
    .btn-block { width: 100%; }

    .btn-primary:hover {
      background: var(--accent-blue-hover);
      box-shadow: var(--elev-2) color-mix(in srgb, var(--accent-blue) 30%, transparent);
    }

    /* (1.1.10) DESABILITADO DEIXA DE SER "O MESMO BOTÃO DESBOTADO".
       Era `opacity:0.5`, e opacidade mistura TEXTO E FUNDO com o que está atrás ao mesmo
       tempo — os dois caminham para a cor da página e o contraste ENTRE eles desaba. Era isso
       que fazia o "Enviar Qualificação" aparecer num lavanda pálido que lê como defeito, e não
       como "ainda não posso".
       Agora o estado tem cor própria: superfície neutra e texto no token apagado. Além de
       legível, o par (--text-muted sobre --bg-tertiary) é um dos que o teste-contraste.js já
       varre nos 5 estados de cor — ou seja, o desabilitado passou a ser um par TESTADO, em vez
       de uma mistura que ninguém media. E a diferença entre poder e não poder clicar ficou
       óbvia, que é o trabalho deste estado. */
    .btn-primary:disabled {
      opacity: 1;
      background: var(--bg-tertiary);
      color: var(--text-muted);
      box-shadow: none;
      cursor: not-allowed;
    }

    .btn-3cplus {
      background: var(--accent-3cplus);
      color: var(--text-primary);
      width: 100%;
    }

    .btn-3cplus:hover {
      background: var(--accent-3cplus-dark);
      box-shadow: var(--elev-2) rgba(255, 187, 58, 0.4);
    }

    .btn-icon-manual {
      width: 42px;
      height: 42px;
      padding: 0;
      border-radius: 50%;
      background: var(--accent-manual);
      /* (1.1.10) Era `white`. Âmbar preenchido com ícone branco dava 2,90:1 no claro e
         1,90:1 no contraste — o pior par medido no painel, e no tema de acessibilidade. */
      color: var(--on-accent-manual);
      font-size: 1.2rem;
      display: flex;
      align-items: center;
      justify-content: center;
      border: none;
      cursor: pointer;
      transition: background var(--dur-2), color var(--dur-2), box-shadow var(--dur-2), transform var(--dur-2);
      box-shadow: var(--elev-1) rgba(230, 124, 11, 0.3);
    }

    .btn-icon-manual:hover {
      transform: scale(1.1);
      box-shadow: var(--elev-2) rgba(230, 124, 11, 0.5);
    }

    .btn-icon-manual.active {
      background: var(--accent-blue);
      /* Trocou o fundo de âmbar para azul, então a tinta acompanha: no claro o azul é escuro
         e pede branco, nos outros temas ele é dourado/claro e pede tinta escura. */
      color: var(--on-accent-blue);
      box-shadow: var(--elev-1) rgba(41, 74, 206, 0.3);
    }
    /* svg como bloco: sai do baseline inline (que causava o leve desalinho que
       só "consertava" no hover, quando o scale forçava um novo layer). */
    .btn-icon-manual svg { display: block; }

    .btn-secondary {
      background: var(--bg-tertiary);
      color: var(--text-primary);
      border: 1px solid var(--border-color);
    }

    .btn-secondary:hover {
      background: var(--border-color);
    }

    .btn-danger {
      background: transparent;
      /* (1.1.10) Contorno, não preenchido: aqui o vermelho é TEXTO sobre a superfície do
         painel, então usa a variante de texto (nos claros ela é bem mais escura). */
      color: var(--accent-red-text);
      border: 1px solid var(--accent-red);
    }

    .btn-danger:hover {
      background: var(--accent-red-light);
    }

    /* PRECS — hierarquia durante a chamada: Desligar é a ação principal quando
       se está em ligação, então ganha PESO (preenchido sólido, não contorno).
       Ligar segue sólido azul; assim as duas ações-chave têm o mesmo destaque
       no momento em que cada uma importa. */
    #hangup-btn.btn-danger {
      background: var(--accent-red);
      /* (1.1.10) O BOTÃO MAIS URGENTE DO DISCADOR, e ele reprovava nos CINCO estados de cor:
         3,76:1 nos claros, 2,92:1 no precs, 2,51:1 no contraste. A regressão veio do próprio
         polimento descrito no comentário acima — a passagem de contorno para sólido não
         refez a conta de contraste, e branco sobre vermelho médio não chega a 4,5:1 em
         nenhuma das paletas. Tinta escura resolve nos cinco de uma vez e fica CONSISTENTE,
         que é melhor que branco em três e escuro em dois. */
      color: var(--on-accent-red);
      border-color: var(--accent-red);
      box-shadow: var(--elev-2) color-mix(in srgb, var(--accent-red) 35%, transparent);
    }
    /* (1.1.10) O HOVER CLAREIA, e antes escurecia. A inversão é consequência direta de o
       texto ter virado tinta escura: misturar 12% de PRETO no fundo derrubava o contraste de
       4,88:1 para 3,89:1 — ou seja, o botão passava a reprovar exatamente quando o mouse
       estava em cima dele, que é o instante em que se lê o rótulo antes de clicar. Com 12% de
       BRANCO o realce continua existindo (o fundo muda de tom de forma visível) e o contraste
       SOBE em vez de cair. Regra geral para esta paleta: acento com tinta escura clareia no
       hover; acento com tinta clara escurece. */
    #hangup-btn.btn-danger:hover {
      background: color-mix(in srgb, var(--accent-red) 88%, #fff);
      border-color: color-mix(in srgb, var(--accent-red) 88%, #fff);
      box-shadow: var(--elev-3) color-mix(in srgb, var(--accent-red) 45%, transparent);
    }

    .btn-sm {
      padding: var(--space-2) var(--space-3);
      font-size: 0.8rem;
    }

    /* PRECS — "Sair da Campanha". Três queixas, nesta ordem:
       1) era invisível (texto --text-muted em 0.75rem sobre cinza, ~10px sob o zoom:0.85
          do main) e operador perguntou onde ficava;
       2) com contorno avermelhado, fundo próprio e centralizado, virou convidativo —
          "dá vontade de clicar", e sair da campanha no meio do turno não é o que a gente
          quer convidar;
       3) alinhado à direita para tirar o convite, ficou torto no rodapé.
       O que resolve não é cor nem posição: é PESO. O botão mantém a linha própria depois do
       separador, o ícone de saída, o rótulo por extenso e o centro do rodapé — quem procura
       acha em um segundo e a caixa fecha alinhada. O que sai é o peso visual: sem
       preenchimento e com contorno neutro, ele não compete com nada. O vermelho continua
       existindo, mas só aparece no hover/foco, quando a intenção de clicar já está
       declarada. */
    .precs-sair-btn {
      background: transparent;
      color: var(--text-muted);
      border: 1px solid var(--border-color);
      /* 400 e não 500 (1.1.2): a família aqui é Manrope, que baixa 400;600;700. O 500
         escrito antes caía em 400 de qualquer jeito — o botão sempre foi renderizado
         assim. Trocar o número não muda um pixel; muda o CSS deixar de descrever um
         peso que nunca existiu. A intenção original (mais leve que o .btn, que é 600)
         segue valendo. */
      font-weight: 400;
      transition: color var(--dur-1) ease, border-color var(--dur-1) ease, background-color var(--dur-1) ease;
    }
    .precs-sair-btn:hover {
      color: var(--accent-red);
      border-color: color-mix(in srgb, var(--accent-red) 55%, var(--border-color));
      background: color-mix(in srgb, var(--accent-red) 8%, transparent);
    }
    .precs-sair-btn:focus-visible {
      color: var(--accent-red);
      border-color: var(--accent-red);
      outline: 2px solid var(--precs-gold, #B49552);
      outline-offset: 2px;
    }
    .precs-sair-btn svg { display: block; flex: none; }
    @media (prefers-reduced-motion: reduce) {
      .precs-sair-btn { transition: none; }
    }

    /* ============================================ */
    /* SECTION: Campaigns */
    /* ============================================ */
    #campaigns-section {
      max-width: 600px;
      /* PRECS — CENTRALIZAÇÃO QUE NÃO GERA SCROLL.
         Aqui era `margin: auto`, e dentro de um container flex (o <main>) o auto
         centraliza nos DOIS eixos. Isso produzia o pior de dois mundos ao mesmo
         tempo: com o menu vazio sobrava um vão morto acima do hero, e quando os
         cards laterais ganhavam conteúdo real (gráfico do dia, donut, últimas
         leads) a centralização empurrava metade do excedente para FORA da tela,
         deixando a tela do menu rolável — sendo que ela é a tela onde o operador
         só precisa escolher a campanha.
         `margin: 0 auto` centraliza apenas na horizontal, e `align-self: safe
         center` faz a vertical do jeito certo: centraliza enquanto cabe e passa a
         alinhar pelo TOPO quando não cabe, em vez de estourar para os dois lados.
         Navegador que não conhecer `safe` ignora a linha e cai em stretch, que
         também começa no topo — os dois desfechos são aceitáveis. */
      margin: 0 auto;
      /* PRECS — ALINHA NO TOPO, não centraliza.
         O `safe center` resolvia o scroll (centraliza enquanto cabe, alinha no topo
         quando não cabe), mas cobrava um preço que só aparece medindo: com o conteúdo
         caindo dentro da tela, ele centralizava — e o "centralizado" deixava ~110px
         mortos acima do hero enquanto o card "Meu desempenho" rolava por dentro logo
         abaixo. Espaço vazio em cima e conteúdo cortado embaixo, ao mesmo tempo.
         Com `start`, todo o espaço que existe vai para os cards: o hero sobe e a
         altura disponível medida por precsAjustarAlturaMenu cresce na mesma medida. */
      align-self: start;
    }

    /* PRECS — com cards laterais visíveis, a section alarga e o grid vira
       colunas lado a lado: campanhas | meu desempenho | últimas leads, todas
       alinhadas pelo topo. grid-auto-flow:column com larguras nos filhos:
       card oculto (display:none) NÃO cria trilha vazia — o layout se adapta
       sozinho a qualquer combinação de cards visíveis. */
    #campaigns-section:has(.precs-hist-col[style*="block"]) {
      /* 1480 (era 1460): acompanha o alargamento dos dois cards laterais (Meu
         desempenho 460, Últimas leads 440). Orçamento: 460 + ~524 da coluna de
         campanhas + 440 + 40 de folgas = 1464. Continua abaixo do limite de 1506px
         que uma tela de 1280 oferece sob o zoom do painel, então o layout de 3
         colunas segue valendo até o breakpoint de 1200px. */
      /* (1.1.57) 1.480 → 1.540: acompanha o card de últimas leads indo de 440 para 480.
         Orçamento: 460 + 560 + 480 + 40 = 1.540, contra os 1.563px que a estação de 1366
         oferece na densidade normal — 23px de folga. */
      max-width: 1540px;
    }
    .precs-campaigns-grid {
      display: grid;
      grid-auto-flow: column;
      grid-auto-columns: max-content;
      gap: var(--space-5);
      align-items: stretch;   /* cards laterais crescem para a mesma altura */
      justify-content: center;
    }
    /* o card central (ação principal) mantém a altura natural, alinhado ao topo */
    .precs-campaigns-col { width: min(560px, 94vw); min-width: 0; align-self: start; }
    /* PRECS (1.0.34) — a lista de campanhas é a AÇÃO da tela, mas tinha exatamente o
       mesmo peso visual dos dois cards informativos ao lado, então o olho não sabia onde
       começar. Um filete dourado no topo resolve sem mudar layout nem tamanho: só diz
       "é por aqui". Usa o token de tema, então acompanha os 3 temas. */
    .precs-campaigns-col { position: relative; overflow: hidden; }
    .precs-campaigns-col::before {
      content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px;
      background: linear-gradient(90deg,
                  var(--precs-gold, #B49552),
                  var(--precs-gold-title, #D3B26B),
                  var(--precs-gold, #B49552));
    }
    .precs-hist-col {
      min-width: 0;
      align-self: stretch;   /* Meu desempenho e Últimas leads: mesma altura */
      padding: 0;
      overflow: hidden;   /* mantém o border-radius do card no conteúdo interno */
    }
    /* Meu desempenho preenche a altura: o gráfico cresce para ocupar o espaço */
    #precs-meudia-card {
      /* 420 → 460: sugestão do Pedro, e resolve pelo lado certo. O conteúdo deste card
         é quase todo horizontal (4 métricas lado a lado, 7 barras da semana, donut com
         legenda), então cada px de largura tira px de ALTURA — que é o recurso escasso
         aqui. Orçamento conferido: 460 + 524 (coluna de campanhas) + 420 (últimas
         leads) + 40 de folgas = 1444, dentro do max-width de 1460 da seção. */
      width: min(460px, 94vw); display: flex; flex-direction: column;
      align-self: start;                 /* não estica com o grid */
      /* PRECS — ALTURA = O ESPAÇO QUE DE FATO EXISTE, MEDIDO.
         Três tentativas até aqui, e vale registrar por quê. `78vh` media a JANELA
         INTEIRA e ignorava tudo que está acima do card (header, hero, folgas), então
         o menu estourava a tela. Trocar por `calc(100vh - 340px)` acertou a direção e
         errou o número: 340px era uma estimativa, e com o hero da 1.0.34 o card ficou
         30px menor que o próprio conteúdo, nascendo com rolagem interna — que é
         justamente o que o Pedro não quer, porque este card existe para ser lido de
         relance.
         Estimar a altura do que está acima é o erro em si: ela muda com o tamanho da
         foto, com a frase do dia, com o nível de fonte e com o zoom. Então quem mede
         é o JS (precsAjustarAlturaMenu), uma vez na carga e a cada resize, gravando
         --precs-menu-alt. O valor abaixo é só o fallback do primeiro quadro, antes de
         o JS rodar.
         A altura continua INDEPENDENTE do conteúdo, que é o que impede o menu de
         "pular" ao trocar o dia no gráfico. Sobrando espaço, sobra em branco no fim do
         card — igual à 1.0.33, que é o comportamento que o Pedro aprovou. */
      height: var(--precs-menu-alt, clamp(320px, calc(100vh - 300px), 820px));
    }
    #precs-meudia-card .panel-body { flex: 1; display: flex; flex-direction: column; overflow-y: auto; min-height: 0; }
    /* Últimas leads: altura natural (não estica junto do Meu Desempenho).
       440px (era 420): o item agora mostra o IDENTIFICADOR do negócio junto do botão
       do Pipedrive, e essa informação precisa caber na mesma linha do telefone e da
       qualificação sem apertar as reticências. Orçamento das 3 colunas conferido
       contra o max-width da seção (ver #campaigns-section). */
    /* PRECS (1.1.57) — 440px → 500px, e o número saiu de uma conta, não de gosto.
       Com a qualificação por extenso a linha do telefone deixou de caber: medida em px de CSS,
       ela pede 427,1px (telefone e dois botões 162,8 + pílula 167,6 + link do Pipedrive 80,7 +
       dois gaps de 8) contra 397,6px de espaço — faltavam 29,5px, e a pílula descia junto com
       o selo do Pipedrive.
       500 É O TETO, e quem o define é a estação: em 1366x768, sob o zoom de 0,85, o `main`
       oferece 1.563px de CSS úteis. Com 460 + 560 + 500 + 40 de folgas fecha em 1.560 — sobram
       3px. Com 530 estouraria em 27px, e a tela do operador é a que não pode estourar.
       (1.1.57, segunda volta) 500 → 480. O 500 foi calculado contra a densidade NORMAL e
       deixava 3px de folga em 1366 — que é arredondamento, não margem: qualquer coisa que
       crescesse 4px estouraria a estação. Com 480 a folga vai a 23px.
       O QUE ISSO NÃO COBRE, e fica dito: "Conhecido - PASSOU telefone", "Retorno Manual
       (contato correto)" e "Conhecido - NÃO PASSOU telefone" pedem card de ~496, ~513 e ~525px.
       Essas três seguem quebrando para a segunda linha — que agora é uma quebra limpa, não um
       truncamento. Sete das dez cabem numa linha só. */
    #precs-ultima-lead-card { width: min(480px, 94vw); align-self: start; }
    /* Telas estreitas: empilha tudo centralizado (como antes).
       PRECS — o limite era 1460px, e isso empilhava as 3 colunas justamente no
       notebook de 1366px, que é a estação mais comum da operação: o menu virava uma
       pilha de ~1380px de altura e passava a rolar, na tela em que o operador só
       precisa escolher a campanha. Medido: cada card ocupa ~357px reais (420px sob o
       zoom de 0,85 do painel), então três colunas mais as folgas somam ~1150px e
       cabem com sobra em 1366. O limite desceu para 1200px, que é onde as três
       colunas realmente deixam de caber. Acima disso ninguém rola; abaixo, empilha
       como antes. */
    /* PRECS (1.1.2) — o `:not([data-fonte="auto"])` que qualificava estas duas regras
       saiu junto com o modo AUTO (ver o bloco do zoom, mais abaixo). Ele já era
       sempre verdadeiro, porque data-fonte só assume compacto, normal ou confortável;
       o par de regras equivalentes para "auto", que empilhava a 1024px, foi removido
       pelo mesmo motivo. Nada muda no que a tela faz. */
    /* PRECS (1.1.57) — A DENSIDADE CONFORTÁVEL EM NOTEBOOK ESTOURAVA A TELA, e o defeito é
       antigo — só apareceu quando medi a matriz inteira que a operação de fato usa: duas
       resoluções (1366x768 e 1920x1080) × três densidades.

         resolução    densidade      zoom   largura útil   3 colunas   sobra
         1366x768     compacto       0,72        1851        1540       311
         1366x768     normal         0,85        1563        1540        23
         1366x768     CONFORTÁVEL    1,00        1324        1540      −216   ← transborda
         1920x1080    qualquer uma     —        1878+        1540      338+

       O empilhamento existe e mora no `@media (max-width: 1200px)` logo abaixo, mas ele nunca
       dispara aqui: a media query lê a largura do VIEWPORT, que continua sendo 1366. Quem
       encolhe o espaço é o `zoom` do `main`, e zoom é invisível para media query. Em compacto o
       zoom de 0,72 dá 1851px de espaço; em confortável ele é 1 e sobram 1324 — a MESMA tela,
       com 527px de diferença, e a media query não vê nenhum dos dois.
       Por isso a regra abaixo cruza largura COM densidade, em vez de só largura: 1.540 de
       conteúdo pedem ~1.600 de viewport quando o zoom é 1. Acima disso, confortável cabe em
       três colunas (é o caso do 1920) e nada muda. */
    @media (max-width: 1600px) {
      html[data-fonte="confortavel"] .precs-campaigns-grid { grid-auto-flow: row; justify-items: center; }
      html[data-fonte="confortavel"] #campaigns-section:has(.precs-hist-col:not([style*="none"])) { max-width: 600px; }
      html[data-fonte="confortavel"] #precs-meudia-card { height: auto; }
    }
    @media (max-width: 1200px) {
      .precs-campaigns-grid { grid-auto-flow: row; justify-items: center; }
      #campaigns-section:has(.precs-hist-col[style*="block"]) { max-width: 600px; }
    }
    /* (1.1.101) O EMPILHAMENTO PASSA A OLHAR O ESPAÇO EFETIVO, e não a janela. As duas media
       queries acima leem a largura do VIEWPORT, e o comentário da 1.1.57 já dizia que o zoom é
       invisível para elas. Relato da Vitória, 18/09/2026, com print: janela de 1.212px (meia
       tela, WhatsApp do lado), banda alta pela altura, zoom 0,92 — o viewport passava do 1200
       por 12px, a media query não disparava, e as três colunas de 1.540 saíam pela direita com
       barra de rolagem horizontal.
       `@container` mede a SEÇÃO, que vive dentro do `main` escalado: a inline-size dela já é o
       espaço efetivo, em qualquer densidade e em qualquer janela. Mesmo desenho e mesma
       justificativa de segurança do `painel` (campaign-active-section), logo abaixo neste
       arquivo: não há `position:fixed` descendente aqui, todo `fixed` do projeto vive no <body>.
       Os limiares são o orçamento das colunas (460 + 560 + 480 + 2×20 = 1.540 com o card de
       desempenho; 560 + 480 + 20 = 1.060 sem ele), e o `:has` separa os dois casos para não
       empilhar cedo quem só tem dois cards. */
    #campaigns-section { container-type: inline-size; container-name: menu; }
    @container menu (max-width: 1539px) {
      .precs-campaigns-grid:has(> .precs-hist-col:not([style*="none"])) { grid-auto-flow: row; justify-items: center; }
      .precs-campaigns-grid:has(> .precs-hist-col:not([style*="none"])) > #precs-meudia-card { height: auto; }
    }
    @container menu (max-width: 1079px) {
      .precs-campaigns-grid { grid-auto-flow: row; justify-items: center; }
      #precs-meudia-card { height: auto; }
    }

    .campaign-list {
      display: flex;
      flex-direction: column;
      gap: var(--space-3);
    }

    .campaign-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: var(--space-4) var(--space-5);
      background: var(--bg-primary);
      border: 2px solid var(--border-color);
      border-radius: var(--radius-inner);
      cursor: pointer;
      transition: background var(--dur-2), border-color var(--dur-2), color var(--dur-2), box-shadow var(--dur-2), transform var(--dur-2), opacity var(--dur-2);
    }

    /* PRECS (1.1.4) — o `:not(.precs-campanha-entrando)` nos DOIS blocos de hover deste
       card (este e o do polimento, mais abaixo) existe porque hover e "entrando" têm a
       MESMA especificidade e o hover vem depois no arquivo: com o mouse parado em cima do
       item — que é sempre o caso, a pessoa acabou de clicar ali — o hover reescrevia o
       `background` e apagava o realce dourado e a varredura do estado de entrada. */
    .campaign-item:hover:not(.precs-campanha-entrando) {
      border-color: var(--accent-blue);
      background: var(--accent-blue-light);
      box-shadow: var(--shadow);
      transform: translateY(-2px);
    }
    /* Estado: campanha sendo selecionada (mostra spinner, borda destacada).
       PRECS (1.1.4) — ganhou a VARREDURA: uma faixa dourada que preenche o card da
       esquerda para a direita enquanto a campanha conecta. O spinner já dizia "estou
       trabalhando", mas ficava sozinho num canto; a varredura usa o card inteiro, que é
       o objeto que a pessoa acabou de clicar, e dá a sensação de estar ENTRANDO nele.
       É `background-color` + `background-image`, e não o atalho `background`, porque o
       atalho zeraria a camada de imagem que a animação usa. */
    .campaign-item.precs-campanha-entrando {
      border-color: var(--precs-gold, var(--accent-blue));
      background-color: var(--precs-gold-light, var(--accent-blue-light));
      background-image: linear-gradient(90deg,
        color-mix(in srgb, var(--precs-gold, #B49552) 26%, transparent),
        color-mix(in srgb, var(--precs-gold, #B49552) 6%, transparent));
      background-repeat: no-repeat;
      background-size: 0% 100%;
      animation: precsCampVarre .55s var(--ease-2) forwards;
      box-shadow: var(--shadow);
      cursor: progress;
    }
    @keyframes precsCampVarre { to { background-size: 100% 100%; } }
    /* ao entrar, esconde a flecha e mostra SÓ o loader (a flecha ia pro meio) */
    .campaign-item.precs-campanha-entrando .campaign-arrow { display: none; }
    .campaign-item.precs-campanha-entrando::after {
      content: '';
      width: 18px; height: 18px;
      border: 2px solid var(--precs-gold, var(--accent-blue));
      border-top-color: transparent;
      border-radius: 50%;
      animation: precsSpin 0.7s linear infinite;
      flex-shrink: 0; margin-left: auto;
    }
    @keyframes precsSpin { to { transform: rotate(360deg); } }
    @media (prefers-reduced-motion: reduce) {
      .campaign-item.precs-campanha-entrando::after { animation: none; }
      /* sem a varredura, o card ainda precisa nascer preenchido: `animation: none`
         sozinho deixaria o background-size em 0% e o realce dourado não apareceria. */
      .campaign-item.precs-campanha-entrando { animation: none; background-size: 100% 100%; }
    }
    /* As demais campanhas ficam apagadas enquanto uma está sendo selecionada.
       (1.1.4) recuam um fio junto com o apagar: o conjunto "afunda" e o card escolhido
       fica sozinho no plano da frente, sem precisar aumentar o card escolhido. */
    .campaign-item.precs-campanha-desativada {
      opacity: 0.4;
      transform: scale(0.985);
      pointer-events: none;
    }

    .campaign-info {
      display: flex;
      align-items: center;
      gap: var(--space-4);
    }

    .campaign-name {
      font-weight: 600;
      /* (1.1.56) 16px → 17px. O nome da campanha é o rótulo da AÇÃO desta tela e estava no
         mesmo degrau da seta ao lado e do título do modal de frases. Um degrau já o separa. */
      font-size: var(--fs-9);
    }

    /* PRECS (1.0.34) — selo "última usada". Discreto de propósito: é uma DICA para o olho
       achar a campanha do dia a dia mais rápido, não um destaque que compita com a ação
       de clicar. Fica dentro do nome, então acompanha o texto sem alterar a altura da
       linha. O item ganha um filete dourado à esquerda, no mesmo idioma visual do filete
       das qualificações. */
    .campaign-ultima {
      display: inline-block; vertical-align: middle;
      margin-left: var(--space-2); padding: var(--space-0) var(--space-2);
      font-size: var(--fs-2); font-weight: 700; text-transform: uppercase; letter-spacing: var(--ls-caps);
      font-family: var(--font-acao);
      color: var(--precs-gold-title, #D3B26B);
      background: color-mix(in srgb, var(--precs-gold, #B49552) 14%, transparent);
      border: 1px solid color-mix(in srgb, var(--precs-gold, #B49552) 45%, transparent);
      border-radius: var(--radius-pill);
      line-height: 1.4;
      /* (1.1.57) `relative` + `overflow` para o brilho de baixo ficar preso na pílula. */
      position: relative;
      overflow: hidden;
    }
    /* PRECS (1.1.57) — O SELO GANHOU UM BRILHO, E ELE TEM FIM.
       Até aqui este selo era 100% estático: sem animação, sem transição, sem hover. Ele é a
       dica que faz o olho achar a campanha do dia a dia, e não tinha nada que puxasse o olho.
       O IDIOMA É O QUE JÁ EXISTE: uma faixa clara que atravessa da esquerda para a direita — a
       mesma varredura do `precsCampVarre` que pinta o card ao entrar na campanha. Reusar o
       gesto que a tela já fala é melhor do que inventar um segundo.
       TRÊS PASSADAS E PARA, e essa é a parte que importa num painel que o operador abre dezenas
       de vezes por dia: brilho infinito encanta na primeira vez e irrita na quinquagésima. Como
       o card é repintado toda vez que se entra no menu, a animação recomeça na chegada — que é
       exatamente quando a dica serve — e depois fica quieta.
       A PAUSA VIVE DENTRO DO KEYFRAME (0% a 55% parado), porque `animation-delay` só atrasa a
       PRIMEIRA passada; para espaçar as três, o descanso tem que ser parte do ciclo. */
    .campaign-ultima::after {
      content: ''; position: absolute; inset: 0;
      background: linear-gradient(100deg,
        transparent 25%,
        color-mix(in srgb, var(--precs-gold) 55%, transparent) 50%,
        transparent 75%);
      transform: translateX(-130%);
      animation: precsSeloBrilho 2.8s var(--ease-1) 3;
      pointer-events: none;
    }
    @keyframes precsSeloBrilho {
      0%, 55%   { transform: translateX(-130%); }
      90%, 100% { transform: translateX(130%); }
    }
    @media (prefers-reduced-motion: reduce) { .campaign-ultima::after { animation: none; opacity: 0; } }
    /* Usa ::before, e NÃO ::after, de propósito: o ::after do .campaign-item já é o
       spinner de "entrando na campanha" (.precs-campanha-entrando::after). Se o filete
       usasse ::after, os dois brigariam justamente no item mais clicado, e o spinner de
       entrada é mais importante que o selo. Com ::before os dois convivem.

       PRECS (1.1.4) — O FILETE VAZAVA A BORDA ARREDONDADA nos cantos de cima e de baixo.
       A causa era o `border-radius: inherit`: raio herdado vale 10px, mas o filete tem
       3px de largura, e o CSS reduz proporcionalmente o raio que não cabe na caixa — o
       canto do filete virava quase reto enquanto o canto do card seguia curvo, então
       sobrava um dentinho de ouro para fora da linha da borda (era o que aparecia na
       lupa: um traço reto colado num canto redondo).
       A correção não é achar o raio certo — é deixar o CARD recortar o filete. Com
       `overflow: hidden` no item, o recorte acontece na curva real do card, então o
       filete termina exatamente onde a borda vira, em qualquer raio. Por isso o raio
       aqui é 0: quem faz a curva é o pai.
       O overflow é seguro neste card: tudo (selo, ID, seta, spinner) vive dentro dele, e
       o anel de :focus-visible é box-shadow/outline, que overflow não corta. */
    .campaign-item-ultima { position: relative; overflow: hidden; }
    .campaign-item-ultima::before {
      content: ''; position: absolute; inset: 0 auto 0 0; width: 3px;
      background: var(--precs-gold, #B49552);
      border-radius: 0;
      pointer-events: none;
    }

    .campaign-id {
      font-size: var(--fs-5);
      color: var(--text-muted);
      font-family: var(--font-num);
    }

    /* PRECS (1.1.4) — A SETA VIROU BOTÃO REDONDO. Era um "→" solto no canto direito,
       do tamanho do texto e na cor de rótulo: lia como enfeite, não como "clique aqui".
       Agora é um alvo circular de 30px com fundo e contorno próprios — o mesmo idioma
       dos outros botões-ícone do painel — e no hover ele se acende em ouro (ver o bloco
       de polimento abaixo). O elemento continua sendo o mesmo <div class="campaign-arrow">
       do app.js: quem clica é o card inteiro, o círculo é só onde o olho pousa. */
    .campaign-arrow {
      width: 30px; height: 30px; flex: none;
      display: inline-flex; align-items: center; justify-content: center;
      border-radius: 50%;
      border: 1px solid var(--border-color);
      background: var(--bg-tertiary);
      color: var(--text-muted);
      font-size: var(--fs-8); line-height: 1;
      transition: background-color .16s ease, border-color .16s ease, color .16s ease, transform .16s ease;
    }

    .loading-campaigns {
      text-align: center;
      padding: var(--space-8);
      color: var(--text-muted);
    }

    /* (1.1.54) A FAIXA DE ARRANQUE ("Preparando o sistema…"), que era estilo inline puro.
       Ela vivia com OITO declarações no atributo `style` do próprio `#system-ready-status`
       (index.html:1269), mais duas nos filhos. Isso é invisível para o gate de estilo — a
       catraca lê as oito folhas, não o HTML — e portanto era dívida que crescia sem contador.
       A regra é a MESMA: os valores foram trazidos um a um, sem recalibrar nada, e o
       comparar-estilo-computado prova que nenhuma propriedade mudou.
       A UMA MUDANÇA DELIBERADA é a estrela: ela tinha `fill="#D3B26B"` cravado no SVG, o ouro
       de título do tema PRECS escrito à mão. Num painel em Zebrado — onde não existe ouro
       nenhum — a faixa de arranque aparecia com uma estrela dourada, e no Bordô claro, onde o
       acento é vinho, idem. Passa a `currentColor`, que aqui é `--accent-orange`: a mesma cor
       da borda e do estado que a faixa comunica, em todos os dez temas.
       O `display:none` fica INLINE de propósito: quem o alterna é o `checkSystemReady`
       (app.js:14022 e :14032), e visibilidade escrita por JS é comportamento. Trazê-la para cá
       obrigaria o JS a mexer em classe, que é mudança de comportamento numa leva de
       acabamento. */
    .precs-boot-faixa {
      padding: var(--space-4);
      margin-bottom: var(--space-4);
      border-radius: var(--radius-inner);
      background: var(--accent-orange-light);
      border: 1px solid var(--accent-orange);
      color: var(--text-primary);
      text-align: center;
    }
    .precs-boot-faixa-tit {
      font-weight: 600;
      margin-bottom: var(--space-1);
      display: flex;
      align-items: center;
      justify-content: center;
      gap: var(--space-2);
    }
    /* Só a ESTRELA pega o âmbar. O texto ao lado continua em `--text-primary`, herdado da
       faixa: pintar a linha inteira de âmbar rebaixaria o contraste da frase que a faixa
       existe para dizer. */
    .precs-boot-faixa .precs-btn-star { color: var(--accent-orange); }
    /* PRECS (1.1.57) — O COLAPSO DA FAIXA DE ARRANQUE.
       `max-height` e não `height` porque a altura real depende do texto de estado, que muda
       durante o boot ("Conectando…", "Carregando…"): um valor fixo teria que ser reestimado a
       cada texto novo, que é o mesmo erro do `calc(100vh - 340px)` do card ao lado.
       O `overflow:hidden` é o que faz o conteúdo desaparecer junto com a caixa; sem ele o texto
       vazaria por cima da lista enquanto a altura fecha.
       As quatro propriedades da transição são as quatro que ocupam espaço vertical — altura,
       as duas margens/paddings e a opacidade. Deixar `padding` de fora deixaria 32px de resto. */
    .precs-boot-faixa {
      overflow: hidden;
      max-height: 200px;
      transition: max-height var(--dur-3) var(--ease-3),
                  opacity var(--dur-3) var(--ease-3),
                  margin-bottom var(--dur-3) var(--ease-3),
                  padding var(--dur-3) var(--ease-3);
    }
    .precs-boot-faixa.precs-boot-faixa-sai {
      max-height: 0; opacity: 0; margin-bottom: 0;
      padding-top: 0; padding-bottom: 0;
    }
    @media (prefers-reduced-motion: reduce) { .precs-boot-faixa { transition: none; } }
    .precs-boot-faixa-sub {
      font-size: var(--fs-6);
      color: var(--text-secondary);
    }

    /* ============================================ */
    /* SECTION: Campaign Active (Dialer Mode) */
    /* ============================================ */
    #campaign-active-section {
      max-width: 100%;
      /* PRECS — ÂNCORA VERTICAL: antes usávamos 'margin:auto', que centralizava a
         seção no meio do <main> (flex). Como a altura do conteúdo muda em etapas
         durante as transições (gráfico+histórico saem → mailing+pipe entram →
         Desligar some no TPA), o bloco se recentralizava a cada mudança e o card
         da campanha "andava" várias vezes. Com 'margin:0 auto' o item passa a
         ESTICAR na vertical (align-items:stretch do main) e o conteúdo fica
         ancorado no TOPO — o card central não se desloca mais entre estados. */
      margin: 0 auto;
      width: 100%;
    }
    /* Section da campanha ativa: fluxo natural em coluna. A página rola
       normalmente quando o conteúdo (mailing + pipe) excede a viewport. */
    #campaign-active-section.active {
      display: flex;
      flex-direction: column;
    }
    /* Linha do topo em GRID: laterais 1fr (expandem até as bordas), centro
       fixo em 720px. Como as duas laterais têm largura igual (1fr), o card
       central fica SEMPRE no meio absoluto da tela. */
    /* Painel real: 3 colunas independentes (flex). Cada coluna empilha seus
       cards verticalmente com gap próprio — por isso campanha e pipe ficam
       próximos mesmo que a coluna vizinha (qualificação) seja mais alta. */
    .precs-topo-linha {
      display: flex;
      align-items: flex-start;
      justify-content: center;
      gap: var(--space-8);
    }
    .precs-topo-linha > .precs-col {
      display: flex;
      flex-direction: column;
      gap: var(--space-4);                 /* respiro pequeno entre cards da MESMA coluna */
      min-width: 0;
    }
    /* Coluna 1 (esquerda) e 3 (direita): largura lateral generosa. */
    .precs-topo-linha > .precs-col[data-col="1"],
    .precs-topo-linha > .precs-col[data-col="3"] {
      flex: 1 1 0;
      max-width: 560px;
    }
    /* (1.1.10) O `position: relative` que morava aqui saiu, e a troca é segura: a regra de
       sticky das colunas (mais abaixo) tem especificidade MENOR que este seletor, então o
       relative vencia e a coluna 1 era a única que não grudava — medido, ela sumia da tela ao
       rolar enquanto as outras ficavam. `sticky` é elemento posicionado igual a `relative`,
       então continua servindo de bloco de contenção para qualquer filho absoluto daqui. */
    .precs-topo-linha > .precs-col[data-col="1"] { align-items: flex-start; }
    .precs-topo-linha > .precs-col[data-col="3"] { align-items: flex-end; }
    /* Coluna 2 (centro): largura fixa de conteúdo. */
    .precs-topo-linha > .precs-col[data-col="2"] {
      flex: 0 0 720px;
      max-width: 720px;
      align-items: stretch;
    }
    .precs-topo-linha .precs-col > [data-card-key] {
      width: 100%;
      min-width: 0;
    }
    .precs-topo-linha .precs-col[data-col="1"] > [data-card-key],
    .precs-topo-linha .precs-col[data-col="3"] > [data-card-key] { max-width: 560px; }

    /* ====================================================================== */
    /* (1.1.10) AS COLUNAS CURTAS ACOMPANHAM A ROLAGEM                        */
    /* ---------------------------------------------------------------------- */
    /*  O PROBLEMA: a coluna das anotações do Pipedrive é bem mais alta que as outras duas.
        Para ler o histórico do credor o operador rola a página, e as colunas 1 e 2 acabam
        antes — sobra uma área vazia grande à esquerda enquanto ele lê à direita, e o card da
        campanha (que carrega os cronômetros e o DESLIGAR) sai da tela no meio de uma ligação.

        A PRIMEIRA TENTATIVA GRUDOU UM CARD SÓ, e estava errada. Grudar o card da campanha,
        que tem irmãos ABAIXO na mesma coluna, faz a anotação subir POR BAIXO dele conforme a
        rolagem — o card fica flutuando em cima do outro e lê como tela quebrada. Foi o que o
        Pedro viu na 1ª versão. O erro foi ter escolhido justamente o card com vizinho.

        A UNIDADE CERTA É A COLUNA. Ela se move inteira, com todos os cards dentro, então não
        existe sobreposição possível: não há com quem colidir. Sem z-index, sem exceções.

        E RESOLVE SOZINHO O LAYOUT CUSTOMIZÁVEL, que era a dúvida difícil — o operador pode
        mover cards entre colunas, então não dá para saber de antemão qual coluna será a alta.
        A regra vai nas TRÊS, e o próprio `sticky` decide:
          • coluna mais CURTA que a linha → tem folga para deslizar, e gruda;
          • coluna que define a altura da linha → não tem folga nenhuma, e o navegador a trata
            como estática. É o comportamento de hoje, sem nenhum caso especial.
        Ou seja: quem gruda é sempre "a coluna que sobrou espaço", qualquer que seja o arranjo
        que o operador montou. `align-self: flex-start` é obrigatório para isso — é ele que
        mantém a caixa da coluna na altura do conteúdo, criando a folga que o sticky usa.

        POR QUE `position: sticky` E NÃO JAVASCRIPT: sticky é resolvido pelo compositor do
        navegador, sem listener de scroll e sem reflow por quadro. A versão com JS ouvindo
        `scroll` e aplicando `transform` é que seria pesada — engasga em máquina fraca, que era
        justamente a preocupação. Aqui o custo é zero.

        `top` é dividido por --precs-escala porque o `main` roda com `zoom` (0,72/0,85/1): sem
        dividir, a folga no topo mudaria de tamanho a cada densidade. */
    .precs-topo-linha > .precs-col {
      position: sticky;
      top: calc(var(--space-4) / var(--precs-escala, 1));
      align-self: flex-start;
    }
    /* Sem sticky quando o operador pediu menos movimento: grudar é movimento. */
    @media (prefers-reduced-motion: reduce) {
      .precs-topo-linha > .precs-col { position: static; }
    }

    /* (1.1.10) ATÉ ONDE ESSA PROMESSA VALE, medido em 1366×768 (a estação mais comum), com
       mailing de 18 campos e o botão Desligar na tela:
         compacto (zoom 0,72) → não rola. Coluna 2 termina em 612/768 no TPA.
         normal   (zoom 0,85) → não rola. Coluna 2 termina em 718/768 no TPA.
         confortável (zoom 1) → ROLA: 850/768 em chamada e 868/768 no TPA.
       O texto abaixo dizia "a página não rola" sem qualificar, e isso é falso no confortável.
       Ficou assim de propósito, e não é descuido: quem escolhe fonte grande numa tela de 768px
       está pedindo mais pixels do que existem, e as saídas seriam piores que rolar 100px —
       limitar a coluna 2 com rolagem interna esconderia a qualificação num lugar que ninguém
       procura, e sobrepor a densidade escolhida seria desfazer na mão do operador a
       preferência que ele acabou de marcar.
       O que NÃO pode acontecer é o Desligar sair da tela, e essa é a invariante travada no
       teste-nota-na-chamada.js: medido, ele fica em 460/768 no compacto, 540/768 no normal e
       634/768 no confortável — dentro nos três. No TPA não há chamada para desligar, então o
       que fica abaixo da dobra ali é o
       rodapé do card de anotação — cujo campo já rola por dentro (max-height em
       .precs-nota-input). Se alguém for mexer nisto, é esse o limite a preservar.

       O mailing pode ser alto: estende até quase a altura da tela e rola SÓ
       por dentro. O desconto é header + os dois respiros do <main>.

       PRECS (1.1.96) — O 130px SAIU, E ELE ESTAVA ERRADO POR 8px EM TODA TELA.
       O desconto certo é `header` + `padding` do <main> (2 × --space-8 = 64px). Com o header
       medido em 74px na escala 1, a conta é 138 e não 130: o card passava 8px da janela e a
       página inteira ganhava barra de rolagem. Isso ficou escondido enquanto "normal" valia
       zoom 0,85 — só o `confortável` chegava na escala 1, e lá o teste já tolerava transbordo.
       Com a escala passando a depender da tela (ver o bloco de 1.1.96 em index.html), a escala
       1 virou o caso COMUM do monitor de 1920, e os 8px apareceram na tela de todo mundo.

       E O NÚMERO NÃO VOLTA COMO LITERAL. Duas razões, e as duas já mordidas:
       1. o desconto NÃO é constante — o header e o padding recebem o `zoom` da densidade, então
          eles valem 138px na escala 1 e 117px na 0,85. Um literal fora da divisão acerta uma
          banda e erra a outra, que é exatamente o que 130 fazia;
       2. a altura do header já é MEDIDA em `--precs-header-h` (precsMedirHeader, app.js:7958),
          e o comentário de 1.1.33 neste projeto já reclamou da "TERCEIRA cópia da constante".
       Daí a forma: o header sai em pixel REAL (o rect já vem com o zoom aplicado, por isso ele
       entra ANTES da divisão), e o padding sai em unidade de autor (por isso DEPOIS). O
       fallback de 74px cobre o primeiro quadro, antes de o JS medir.
       PRECS (1.0.30) — a DIVISÃO por --precs-escala é obrigatória: o main roda com
       zoom (0.72/0.85/1), que multiplica o resultado do calc, enquanto 100vh segue
       medindo a viewport inteira. Sem dividir, o card parava a ~85% da altura útil
       no modo normal (e a ~72% no compacto): sobrava faixa preta embaixo, o
       conteúdo era cortado no meio de um campo e PROTOCOLO/DURAÇÃO eram empurrados
       fora do corte. NÃO remover o var() daqui. */
    .precs-topo-linha .precs-col > [data-card-key="mailing"] {
      max-height: calc((100vh - var(--precs-header-h, 74px)) / var(--precs-escala, 1) - var(--space-8) * 2);
      display: flex;
      flex-direction: column;
      overflow: hidden;          /* o scroll vive na lista interna, não aqui */
    }
    /* O card de mailing é um "container": os cards internos (protocolo/duração)
       empilham quando a COLUNA fica estreita — reage à largura real, não à tela. */
    .precs-topo-linha .precs-col > [data-card-key="mailing"] { container-type: inline-size; }
    @container (max-width: 330px) { .call-details { grid-template-columns: 1fr; } }

    .campaign-header {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: var(--space-4);
      padding-bottom: 0;
      /* sem border-bottom: o separador da seção é o border-top de .precs-tempos.
         No modo manual/em chamada o campaign-status-info some e as duas linhas
         colavam (o "traço a mais"). Fica só uma linha, acima de Tempos. */
    }

    .campaign-header-info {
      display: flex;
      align-items: center;
      gap: var(--space-4);
    }

    .campaign-header-icon {
      width: 50px;
      height: 50px;
      border-radius: var(--radius-inner);
      background: linear-gradient(135deg, var(--accent-blue), var(--accent-3cplus));
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.5rem;
    }

    .campaign-header-name {
      font-size: 1.5rem;
      font-weight: 700;
      color: var(--text-primary);
    }

    .campaign-header-status {
      font-size: 0.85rem;
      /* (1.1.10) "● Conectado à campanha", texto de 13,6px reais sobre a superfície do
         header. O verde de acento sobre fundo claro dava 2,54:1 (2,29:1 no claro suave). */
      color: var(--accent-green-text);
    }

    .mode-buttons {
      display: flex;
      justify-content: center;
      gap: var(--space-4);
      margin-top: var(--space-6);
    }

    .mode-btn {
      flex: 0 1 300px;
      padding: var(--space-8) var(--space-6);
      background: var(--bg-primary);
      border: 2px solid var(--border-color);
      border-radius: var(--radius-card);
      cursor: pointer;
      transition: background var(--dur-2), border-color var(--dur-2), color var(--dur-2), box-shadow var(--dur-2), transform var(--dur-2);
      text-align: center;
    }

    .mode-btn:hover {
      border-color: var(--accent-3cplus);
      background: color-mix(in srgb, var(--accent-3cplus) 10%, transparent);
      box-shadow: var(--shadow);
      transform: translateY(-2px);
    }

    .mode-btn-icon {
      font-size: 2.5rem;
      margin-bottom: var(--space-3);
    }

    .mode-btn-title {
      font-size: 1.1rem;
      font-weight: 600;
      margin-bottom: var(--space-1);
    }

    .mode-btn-desc {
      font-size: 0.85rem;
      color: var(--text-muted);
    }

    /* ============================================ */
    /* SECTION: Manual Mode */
    /* ============================================ */
    #manual-mode-section {
      max-width: 500px;
      margin: auto;
    }

    .manual-header {
      text-align: center;
      margin-bottom: var(--space-8);
    }

    .manual-header-icon {
      font-size: 3rem;
      margin-bottom: var(--space-2);
    }

    .manual-header-title {
      font-size: 1.5rem;
      font-weight: 700;
      color: var(--accent-3cplus-dark);
    }

    .manual-header-subtitle {
      color: var(--text-secondary);
      font-size: 0.9rem;
    }

    .dialer {
      background: var(--bg-primary);
      border-radius: 16px;
      padding: var(--space-8);
      border: 2px solid rgba(255, 187, 58, 0.4);
    }

    .dialer-input {
      width: 100%;
      padding: var(--space-5);
      font-size: 1.75rem;
      font-family: 'JetBrains Mono', monospace;
      font-weight: 600;
      text-align: center;
      background: var(--bg-secondary);
      border: 2px solid var(--border-color);
      border-radius: var(--radius-card);
      color: var(--text-primary);
      margin-bottom: var(--space-6);
      letter-spacing: 2px;
    }

    /* (1.1.45) Mesmo conserto do bloco dos campos de login: o `outline:none` fica só para o
       foco que não vem do teclado, e o anel global de 2px volta para quem chega por Tab.
       Este é o campo de discagem manual, usado dezenas de vezes por turno. */
    .dialer-input:focus {
      border-color: var(--accent-3cplus);
      box-shadow: 0 0 0 3px rgba(255, 187, 58, 0.25);
    }
    .dialer-input:focus:not(:focus-visible) { outline: none; }

    .dialer-input::placeholder {
      color: var(--text-muted);
      letter-spacing: normal;
    }

    .dial-btn {
      width: 100%;
      padding: var(--space-5);
      font-size: 1.1rem;
      font-weight: 700;
      background: linear-gradient(135deg, var(--accent-3cplus), var(--accent-3cplus-dark));
      color: var(--text-primary);
      border: none;
      border-radius: var(--radius-card);
      cursor: pointer;
      transition: background var(--dur-2), color var(--dur-2), box-shadow var(--dur-2), transform var(--dur-2), opacity var(--dur-2), filter var(--dur-2);
      display: flex;
      align-items: center;
      justify-content: center;
      gap: var(--space-3);
    }

    .dial-btn:hover {
      transform: translateY(-2px);
      box-shadow: 0 8px 20px rgba(255, 187, 58, 0.4);
    }

    /* (1.1.10) Mesmo tratamento do .btn-primary:disabled, pelo mesmo motivo — o "Ligar"
       travado (sem negócio vinculado na manual) ficava desbotado em vez de claramente inativo. */
    .dial-btn:disabled {
      opacity: 1;
      background: var(--bg-tertiary);
      color: var(--text-muted);
      cursor: not-allowed;
      transform: none;
      box-shadow: none;
    }

    .manual-actions {
      margin-top: var(--space-6);
      text-align: center;
    }

    /* ============================================ */
    /* Call Info Panel */
    /* ============================================ */
    .dashboard-grid {
      display: grid;
      grid-template-columns: 1fr 350px;
      gap: var(--space-8);
      width: 100%;
    }

    .call-placeholder {
      text-align: center;
      padding: 3rem;
      color: var(--text-muted);
    }

    .call-placeholder-icon {
      font-size: 3rem;
      margin-bottom: var(--space-4);
      opacity: 0.5;
    }

    .call-active {
      display: none;
    }

    .call-header {
      display: flex;
      align-items: center;
      gap: var(--space-4);
      margin-bottom: var(--space-6);
      padding-bottom: var(--space-6);
      border-bottom: 1px solid var(--border-color);
    }
    /* (1.1.100) O BOTÃO INTEGRAÇÃO SUMIA COM NOME DE CREDOR COMPRIDO, e a causa nasceu na 1.1.96.
       O cabeçalho é `.call-meta{flex:1}` à esquerda e `#precs-integracao-wrap` à direita. O nome
       do credor (1.1.96) é `white-space:nowrap` com reticências — mas reticência só corta se o PAI
       puder encolher, e um filho flex sem `min-width:0` tem mínimo igual ao conteúdo: `.call-meta`
       crescia até a largura do nome inteiro e empurrava o botão para FORA do card (medido a
       1920px: botão terminando em x=720 num card que acaba em x=594). Relato das operadoras em
       18/09/2026, "o botão de integração em chamada ativa não está vindo", com print em TPA: o
       selo "Negócio #" na tela e o botão sumido — porque o selo está dentro do `.call-meta` e o
       botão é o irmão que foi empurrado. O `flex:0 0 auto` no wrap é o outro lado da mesma
       garantia: o botão nunca encolhe nem estica por causa do vizinho. */
    .call-header .call-meta { min-width: 0; }
    .call-header #precs-integracao-wrap { flex: 0 0 auto; }

    .call-avatar {
      width: 64px;   
      height: 64px;  
      border-radius: 50%;
      background: linear-gradient(135deg, var(--accent-blue), var(--accent-3cplus));
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.5rem;
      font-weight: 700;
      color: white;
      overflow: hidden;
    }
    .call-meta h2 {
      font-size: 1.5rem;
      font-weight: 700;
      font-family: 'JetBrains Mono', monospace;
      color: var(--text-primary);
      margin-bottom: var(--space-1);
    }

    .call-meta span {
      color: var(--text-secondary);
      font-size: 0.9rem;
    }

    .call-details {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: var(--space-4);
    }

    /* (1.1.10) RITMO VERTICAL DO CAMPO DO MAILING.
       Medido antes de mexer, em 1366×768: cada campo ocupava 61px REAIS para duas linhas
       curtas — rótulo de 0,7rem e valor de 0,95rem —, com 16px de padding vertical contra 8px
       de separação entre um card e o próximo. Duas consequências:
         • o ritmo ficava invertido (o respiro DENTRO do card maior que a distância ATÉ o
           vizinho), o que faz a coluna ler como pilha de caixas soltas em vez de uma lista;
         • e, mais concreto, custava altura numa coluna que o operador VARRE durante a ligação.
           Com 12px o campo cai para ~53px e cabe cerca de um campo a mais na mesma tela.
       O padding HORIZONTAL fica em 16px: ali não é respiro, é espaço para o botão de copiar,
       que é posicionado absoluto à direita. */
    .detail-card {
      background: var(--bg-primary);
      border-radius: var(--radius-inner);
      padding: var(--space-3) var(--space-4);
      border: 1px solid var(--border-color);
    }

    .detail-label {
      font-size: 0.7rem;
      font-weight: 600;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      line-height: 1.2;
      margin-bottom: var(--space-1);
    }

    .detail-value {
      font-size: 0.95rem;
      font-weight: 600;
      line-height: 1.35;
      color: var(--text-primary);
    }

    .detail-value.mono {
      font-family: 'JetBrains Mono', monospace;
    }
    /* Card do mailing com botão de copiar no canto. O valor não encosta no
       botão (padding à direita) e o botão fica discreto até o hover do card. */
    .precs-mailing-card {
      position: relative;
      padding-right: 2.6rem;
    }
    .precs-mailing-card .detail-value { word-break: break-word; }
    .precs-mailing-copy {
      position: absolute;
      top: 50%;
      right: 0.6rem;
      transform: translateY(-50%);
      width: 30px;
      height: 30px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 0;
      border: 1px solid var(--border-color);
      border-radius: var(--radius-sm);
      background: var(--bg-secondary);
      color: var(--text-secondary);
      cursor: pointer;
      opacity: 0.85;
      transition: opacity var(--dur-1), color var(--dur-1), border-color var(--dur-1), background var(--dur-1), transform var(--dur-1);
    }
    .precs-mailing-card:hover .precs-mailing-copy { opacity: 1; }
    /* PRECS — hover nos cards de informação (mailing + campos do pipe): micro-
       elevação e realce dourado, no mesmo espírito dos cards do menu principal. */
    .precs-mailing-card, .precs-lead-campo {
      transition: transform .16s ease, border-color .16s ease, box-shadow .16s ease, background .16s ease;
    }
    /* Pipe: campos ficam numa GRADE com espaçamento — micro-elevação funciona bem. */
    .precs-lead-campo:hover {
      transform: translateY(-2px);
      border-color: color-mix(in srgb, var(--precs-gold,#B49552) 60%, transparent) !important;
      box-shadow: var(--shadow-lg);
    }
    /* Mailing: cards EMPILHADOS (borda compartilhada). Não deslocamos para não
       "comer" a borda de cima; realçamos com anel dourado + leve tinta. */
    .precs-mailing-card:hover {
      border-color: color-mix(in srgb, var(--precs-gold,#B49552) 60%, transparent) !important;
      box-shadow: 0 0 0 1px color-mix(in srgb, var(--precs-gold,#B49552) 45%, transparent);
      background: color-mix(in srgb, var(--precs-gold,#B49552) 6%, transparent);
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-mailing-card, .precs-lead-campo { transition: none; }
      .precs-lead-campo:hover { transform: none; }
    }
    .precs-mailing-copy:hover {
      color: var(--accent-blue);
      border-color: var(--accent-blue);
      background: var(--accent-blue-light);
      transform: translateY(-50%) scale(1.08);
    }
    .precs-mailing-copy svg { display: block; }
    /* Feedback de "copiado": botão fica verde com o ✓ por ~1.2s */
    .precs-copiado-ok {
      color: var(--st-call) !important;
      border-color: var(--st-call) !important;
      background: color-mix(in srgb, var(--st-call) 12%, transparent) !important;
    }

    /* (1.1.78) O MESMO AVISO PARA ZONA CLICÁVEL QUE NÃO É BOTÃO (a linha do histórico de
       ligações). A regra é a mesma do estado acima; o que muda é não tocar no conteúdo.

       SEM `transform`: a linha vive numa lista rolável, e escalar uma linha empurra as
       vizinhas. O aviso é a cor indo embora, que é curto o bastante para ler como resposta
       ao clique e discreto o bastante para não competir com o toast. */
    .precs-copiado-flash { animation: precsCopiaFlash .6s var(--ease-3); }
    @keyframes precsCopiaFlash {
      0%   { background-color: color-mix(in srgb, var(--st-call) 26%, transparent); }
      100% { background-color: transparent; }
    }
    @media (prefers-reduced-motion: reduce){ .precs-copiado-flash { animation: none; } }
    /* Card de detalhe que ocupa a linha inteira (ex.: Telefone no mailing) */
    .precs-detail-full { grid-column: 1 / -1; }
    /* (1.1.96) O NOME DO CREDOR, FIXO NO CABEÇALHO DO MAILING.
       Ele fica logo abaixo do telefone e ACIMA da lista que rola, porque a lista pode começar
       abaixo da dobra e porque rolar atrás de outro campo tirava o nome de vista no meio da
       conversa (ver o comentário em renderClientData, no app.js).
       Peso e tamanho colocam o nome logo abaixo do telefone na hierarquia, e não ao lado dele:
       o telefone é o que identifica a LIGAÇÃO, o nome é quem está do outro lado. O corte com
       reticências é obrigatório e não cosmético — nome de credor comprido cabia na coluna
       estreita empurrando o cabeçalho para três linhas, e o cabeçalho é a medida de onde a
       lista começa.
       `[hidden]` precisa vir declarado porque o display aqui é de AUTOR: sem esta linha o nó
       vazio renderiza como caixa entre o telefone e "Chamada conectada" em toda ligação sem
       nome no mailing (é a pegadinha registrada em `hidden-nao-esconde-com-display-de-autor`). */
    .precs-mailing-credor {
      display: block;
      margin-top: var(--space-1);
      font-family: var(--font-titulo);
      font-size: var(--fs-7);
      font-weight: 600;
      color: var(--text-primary);
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .precs-mailing-credor[hidden] { display: none; }
    /* Dados do mailing em lista vertical: uma informação por linha, nunca
       lado a lado (espelha o 3C, evita confundir o operador). Com muitos
       campos, rola internamente em vez de empurrar o card do Pipe pra baixo. */
    .precs-mailing-lista {
      display: flex;
      flex-direction: column;
      gap: var(--space-2);
      /* Sem altura fixa: ocupa o espaço que sobrar dentro do card (que já é
         limitado pela viewport) e rola por dentro quando passar disso. */
      flex: 1;
      min-height: 0;
      overflow-y: auto;
      /* PRECS (1.0.30) — era 0.25rem (4px): menos que a largura de uma barra de
         rolagem. Somado ao zoom de 0.85, a barra nativa virava um fio e o
         operador jurava que "não tem como scrollar" — rolava, sem nunca anunciar
         que rolava. scrollbar-gutter reserva a calha para o conteúdo não saltar
         quando a barra aparece e desaparece. */
      padding-right: var(--space-2);
      scrollbar-gutter: stable;
    }
    /* Esmaecido no rodapé = "tem mais coisa abaixo". A barra diz QUE rola; isto
       diz que AINDA TEM. A classe é ligada por JS (precsAtualizarFadeMailing)
       comparando scrollHeight com clientHeight: em CSS puro não há como saber se
       um elemento tem sobra para rolar, e aplicar sempre apagaria o último campo
       de uma lista curta que já cabe inteira. */
    .precs-mailing-lista.precs-tem-mais {
      /* prefixo -webkit primeiro: o Chrome só passou a aceitar mask-image sem
         prefixo em versões recentes, e os postos não estão todos na mesma. */
      -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
      mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-mailing-lista.precs-tem-mais { -webkit-mask-image: none; mask-image: none; }
    }

    /* Barra de rolagem na identidade da marca (dourado institucional), larga o
       bastante para ser vista mesmo sob o zoom do painel.
       PRECS (1.1.0) — pelos TOKENS de ouro, não pelos literais. O ouro não é uma cor
       só: no tema claro ele é escurecido (#856828) justamente para passar contraste
       sobre fundo claro. Com #B49552 cravado, esta barra ficava com o ouro do tema
       ESCURO em cima do fundo claro, e era o único elemento da tela fora do tom. */
    .precs-mailing-lista::-webkit-scrollbar       { width: 10px; }
    .precs-mailing-lista::-webkit-scrollbar-track { background: transparent; }
    .precs-mailing-lista::-webkit-scrollbar-thumb {
      /* background-COLOR, não o shorthand: com `background: var(...)` na mesma regra
         que `background-clip`, o Chrome serializa os longhands vazios no CSSOM. Não
         muda o que aparece na tela, mas a regra fica ilegível para inspeção e para
         teste automatizado. O longhand não tem esse problema. */
      background-color: var(--precs-gold, #B49552);
      border-radius: var(--radius-pill);
      border: 2px solid transparent;
      background-clip: padding-box;
    }
    .precs-mailing-lista::-webkit-scrollbar-thumb:hover { background-color: var(--precs-gold-title, #D3B26B); }

    /* Rodapé "mais N campos": a pista que FALA, ao lado das duas que só sugerem
       (esmaecido e barra dourada). flex:none para não disputar altura com a lista. */
    .precs-mailing-mais {
      flex: none;
      display: flex; align-items: center; justify-content: center; gap: var(--space-1);
      width: 100%; margin-top: var(--space-2); padding: var(--space-2);
      background: color-mix(in srgb, var(--precs-gold, #B49552) 12%, transparent);
      border: 1px solid color-mix(in srgb, var(--precs-gold, #B49552) 32%, transparent);
      border-radius: var(--radius-inner);
      color: var(--precs-gold-title, var(--precs-gold, #B49552));
      font-family: 'Manrope','Poppins',sans-serif;
      font-size: .74rem; font-weight: 600; letter-spacing: .01em;
      cursor: pointer;
      transition: background-color var(--dur-1) ease, border-color var(--dur-1) ease;
    }
    .precs-mailing-mais[hidden] { display: none; }
    .precs-mailing-mais:hover {
      background: color-mix(in srgb, var(--precs-gold, #B49552) 20%, transparent);
      border-color: var(--precs-gold, #B49552);
    }
    .precs-mailing-mais:focus-visible {
      outline: 2px solid var(--precs-gold, #B49552); outline-offset: 2px;
    }
    .precs-mailing-mais svg { animation: precsMailingSeta 1.8s ease-in-out infinite; }
    @keyframes precsMailingSeta { 0%,100% { transform: translateY(0); } 50% { transform: translateY(2px); } }
    @media (prefers-reduced-motion: reduce) {
      .precs-mailing-mais svg { animation: none; }
      .precs-mailing-mais { transition: none; }
    }

    /* Quando o mailing está limitado pela altura da tela, esta seção é quem
       absorve a sobra de espaço e repassa para a lista interna rolar. */
    #client-data-section {
      display: flex;
      flex-direction: column;
      flex: 1;
      min-height: 0;
      /* PRECS (1.0.30) — cinto de segurança: se algum dia a cadeia flex quebrar
         (ex.: alguém trocar o display:flex por block), o corte vira ROLAGEM aqui
         em vez de conteúdo perdido atrás do overflow:hidden do card. Com a lista
         interna rolando normalmente, esta regra nunca é exercida. */
      overflow-y: auto;
    }

    /* ============================================ */
    /* Qualifications Panel */
    /* ============================================ */
    .qualifications-panel {
      width: 350px;
    }

    .qualification-list {
      display: flex;
      flex-direction: column;
      gap: var(--space-2);
      max-height: 400px;
      overflow-y: auto;
    }

    .qualification-item {
      display: flex;
      align-items: center;
      gap: var(--space-3);
      padding: var(--space-3) var(--space-4);
      background: var(--bg-primary);
      border: 2px solid var(--border-color);
      border-radius: var(--radius-inner);
      cursor: pointer;
      transition: background var(--dur-2), border-color var(--dur-2), box-shadow var(--dur-2), transform var(--dur-2);
    }

    .qualification-item:hover {
      border-color: var(--qual-cor, var(--accent-blue));
      background: var(--bg-secondary);
    }

    /* PRECS — o item SELECIONADO usa --qual-cor-anel, não --qual-cor. As duas são a
       MESMA cor na quase totalidade dos casos; elas só divergem quando a cor da
       qualificação não tem contraste com o fundo do tema, que é exatamente o caso de
       "Mudo" e "Caixa Postal" (preto) nos temas escuro, precs e contraste: ali o anel,
       a borda e a tinta ficavam invisíveis e não se distinguia o item escolhido do
       resto. O filete de cor à esquerda, o ponto do histórico, o donut e as pílulas
       continuam em --qual-cor, então PRETO SEGUE PRETO na interface. Quem calcula a
       variante é precsCorQualVisivel, no render (app.js). */
    .qualification-item.selected {
      border-color: var(--qual-cor-anel, var(--qual-cor, var(--accent-blue)));
      background: color-mix(in srgb, var(--qual-cor-anel, var(--qual-cor, #294ace)) 12%, transparent);
      box-shadow: 0 0 0 1px var(--qual-cor-anel, var(--qual-cor, var(--accent-blue))), 0 4px 14px color-mix(in srgb, var(--qual-cor-anel, var(--qual-cor, #294ace)) 30%, transparent);
      font-weight: 600;
    }
    /* O `.qualification-item { position: relative }` que morava aqui saiu em 1.1.0:
       era duplicata exata da regra que fica junto do filete de cor (busque
       `.qualification-item::before`), que declara o mesmo position e ainda o
       overflow que o filete exige. Duas linhas para o mesmo efeito. */

    /* PRECS — radio das qualificações em SVG. O card fica dentro de um main com
       zoom:0.85; um círculo em CSS (18px -> 15,3px) sofria arredondamento subpixel
       e virava OVAL de forma intermitente. O SVG escala limpo, sem deformar.
       NÃO voltar para border + border-radius aqui. */
    .qualification-radio {
      flex: 0 0 auto;
      align-self: center;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      line-height: 0;
      color: var(--border-color);
      transition: color var(--dur-2);
    }
    .qualification-radio svg { display: block; width: 18px; height: 18px; }
    .qualification-radio .qr-dot { opacity: 0; transition: opacity var(--dur-1); }
    /* O ponto do radio é indicador de SELEÇÃO, então acompanha o anel: preto sobre
       fundo preto não mostrava que o item estava marcado. */
    .qualification-item.selected .qualification-radio { color: var(--qual-cor-anel, var(--qual-cor, var(--accent-blue))); }
    .qualification-item.selected .qualification-radio .qr-dot { opacity: 1; }

    .qualification-name {
      font-size: 0.9rem;
      font-weight: 500;
    }

    /* PRECS — Checklist de tarefas do TPA. Ao selecionar a qualificação, abre
       (com animação) um dropdown com as ações a concluir no Pipedrive; o operador
       marca cada uma e só então o botão "Enviar Qualificação" libera. O wrapper
       .qualification-slot agrupa o item + a checklist; a checklist é irmã do item
       (não filha, para não quebrar o layout flex-row do .qualification-item). */
    .qualification-slot { display: flex; flex-direction: column; }

    /* PRECS — a abertura da checklist era `max-height: 0 -> 360px`. O problema desse
       truque é que o easing corre sobre os 360px, não sobre a altura REAL: numa lista de
       ~90px a parte visível terminava nos primeiros 25% do tempo e o resto da duração
       passava sem nada acontecer. Lê como abertura rápida e travada, e o fechamento fica
       pior ainda (demora para "começar" a sumir).
       Agora usa grid com `grid-template-rows: 0fr -> 1fr`, que interpola a altura EXATA
       do conteúdo, seja ela qual for. O easing passa a valer do começo ao fim de verdade.
       O `overflow:hidden` e o `min-height:0` migraram para o filho, que é o que o grid
       precisa para conseguir colapsar. Se o navegador não interpolar 0fr/1fr, degrada
       para abrir e fechar instantâneo, sem quebrar layout. */
    .qual-checklist {
      display: grid;
      grid-template-rows: minmax(0, 0fr);
      opacity: 0;
      margin-top: 0;
      overflow: hidden;
      transition: grid-template-rows .30s var(--ease-2),
                  opacity .18s ease,
                  margin-top .30s var(--ease-2);
    }
    /* Dois detalhes que só apareceram medindo no navegador, e que valem registro para
       ninguém "simplificar" isto depois:
       1. `grid-template-rows: 0fr` NÃO colapsa sozinho. O mínimo automático da linha
          ainda considera o conteúdo, e a checklist fechada media 16,9px (o padding e a
          borda do <ul>), o que empurrava a lista de qualificações. A forma que colapsa
          de verdade é `minmax(0, 0fr)`, com o mínimo explícito em 0.
       2. O `overflow:hidden` fica no CONTAINER, e o `min-height:0` no filho é o que
          permite o grid comprimi-lo.
       Com os dois: fechada mede 0,0px e aberta mede a altura real do conteúdo. */
    .qual-checklist > * { min-height: 0; }
    /* expande quando o item IRMÃO está selecionado */
    .qualification-item.selected + .qual-checklist {
      grid-template-rows: minmax(0, 1fr);
      opacity: 1;
      margin-top: 6px;
    }
    .qual-checklist .qc-list {
      list-style: none; margin: 0; padding: var(--space-2) var(--space-3);
      display: flex; flex-direction: column; gap: var(--space-2);
      border: 1.5px solid color-mix(in srgb, var(--qual-cor, var(--accent-blue)) 55%, var(--border-color));
      border-radius: var(--radius-inner);
      background: color-mix(in srgb, var(--qual-cor, #294ace) 6%, var(--bg-primary));
    }
    /* (1.1.7) `flex-wrap` entrou para o .qc-motivo (o porquê de uma tarefa dispensada)
       poder cair na linha de baixo. Com os dois filhos de sempre (marcador e rótulo)
       nada muda: eles cabem e não quebram. */
    .qc-task { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
    /* Motivo da tarefa DISPENSADA. Nó IRMÃO do rótulo, e não texto dentro dele: o
       .qc-label é a chave de casamento de precsNotaSincronizarTarefa (o comentário está
       lá). Quebra a linha inteira para o motivo ficar embaixo da tarefa em vez de
       espremido ao lado dela numa coluna estreita. */
    .qc-motivo {
      flex-basis: 100%;
      margin-left: 1.9rem;
      font-size: 0.72rem;
      line-height: 1.3;
      color: var(--text-muted);
      font-style: italic;
    }
    .qc-check {
      flex: 0 0 auto; width: 24px; height: 24px; padding: 0;
      display: inline-flex; align-items: center; justify-content: center;
      background: transparent; border: 0; cursor: pointer;
      color: var(--text-secondary); border-radius: var(--radius-pill); line-height: 0;
      transition: color .18s ease, transform .12s ease;
    }
    .qc-check:hover { color: var(--qual-cor, var(--accent-blue)); }
    .qc-check:focus-visible { outline: 2px solid var(--precs-gold, #B49552); outline-offset: 2px; }
    .qc-check .qc-ic { display: block; }
    .qc-check .qc-ring { transition: stroke .18s ease; }
    .qc-check .qc-tick {
      stroke: var(--st-call, #22c55e);
      stroke-dasharray: 16; stroke-dashoffset: 16;
      transition: stroke-dashoffset .28s ease;
    }
    /* feito: anel + check verdes, com o traço desenhando (dashoffset → 0).
       PRECS — o `transform: scale(1.04)` que existia aqui SAIU. Era ele que fazia a
       bolinha "sair do lugar" ao marcar e desmarcar: sob o zoom:0.85 do main, crescer 4%
       num alvo de 24px cai em subpixel, e o arredondamento desloca o círculo em cerca de
       1px, o que se lê como tremida. É a mesma armadilha já documentada em
       .precs-tempo-dot, onde um círculo CSS virava oval sob zoom.
       O feedback de "marcado" não depende disso: o anel e o check ficam verdes e o traço
       do check é DESENHADO (stroke-dashoffset). O pulso de confirmação virou uma
       animação que começa e termina em scale(1), então o estado de repouso é
       pixel-idêntico ao de antes de clicar, marcado ou não. */
    .qc-task.done .qc-check { color: var(--st-call, #22c55e); }
    .qc-task.done .qc-check .qc-ic { animation: qcMarcou .34s var(--ease-2); }
    @keyframes qcMarcou {
      0%   { transform: scale(1); }
      45%  { transform: scale(1.18); }
      100% { transform: scale(1); }
    }
    .qc-task.done .qc-check .qc-ring { stroke: var(--st-call, #22c55e); }
    .qc-task.done .qc-check .qc-tick { stroke-dashoffset: 0; }
    .qc-label { font-size: 0.82rem; line-height: 1.25; color: var(--text-primary); }
    .qc-task.done .qc-label { color: var(--text-secondary); }
    /* aviso quando a checklist é opcional (não trava o envio) */
    .qc-hint {
      list-style: none; font-size: 0.74rem; font-style: italic;
      color: var(--text-secondary); opacity: .85;
      margin-top: var(--space-0); padding-top: var(--space-2);
      border-top: 1px dashed var(--border-color);
    }

    /* entrada escalonada das tarefas quando a checklist expande */
    .qualification-item.selected + .qual-checklist .qc-task {
      animation: precsHomeIn .28s var(--ease-2) both;
    }
    .qualification-item.selected + .qual-checklist .qc-task:nth-child(1){ animation-delay:.05s; }
    .qualification-item.selected + .qual-checklist .qc-task:nth-child(2){ animation-delay:.10s; }
    .qualification-item.selected + .qual-checklist .qc-task:nth-child(3){ animation-delay:.15s; }
    .qualification-item.selected + .qual-checklist .qc-task:nth-child(n+4){ animation-delay:.20s; }

    /* PRECS (1.0.28) — cabeçalho flutuante do Teclado (DTMF), ancorado sobre o
       painel do softphone da 3C (posicionado por JS junto do iframe revelado). */
    #precs-dtmf-bar {
      position: fixed; z-index: 10051;
      display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
      background: var(--bg-secondary); color: var(--text-primary);
      border: 2px solid var(--precs-gold, #B49552); border-bottom: 0;
      border-radius: 12px 12px 0 0; padding: var(--space-2) var(--space-3);
      font-family: 'Montserrat','Poppins',sans-serif; font-size: 0.85rem;
      box-shadow: var(--elev-3) rgba(0,0,0,.35);
    }
    .precs-dtmf-bar-tit { font-weight: 600; }
    .precs-dtmf-bar-x {
      background: transparent; border: 1px solid var(--border-color); color: var(--text-secondary);
      border-radius: var(--radius-sm); padding: var(--space-1) var(--space-2); font-size: 0.8rem; cursor: pointer;
      transition: color var(--dur-1), border-color var(--dur-1), background var(--dur-1);
    }
    /* PRECS — era `var(--st-call, #ef4444)`. O token --st-call é o VERDE de "em
       chamada", mas o fallback escrito à mão é vermelho, o que revela a intenção: o
       autor queria vermelho de fechar. Como o token sempre existe, o fallback nunca
       entrava e o botão "Fechar ✕" ficava VERDE no hover. Trocado pelo token certo. */
    .precs-dtmf-bar-x:hover { color: #fff; background: var(--accent-red); border-color: transparent; }

    /* PRECS — botão "i" de ajuda por qualificação + popover explicativo */
    /* botão "i" espelha o botão de copiar do mailing: cara de botão de verdade,
       borda + fundo, e hover azul (accent-blue) coerente em todos os temas */
    .qual-info-btn{
      flex:0 0 auto; box-sizing:border-box; align-self:center; line-height:0;
      width:28px; height:28px; padding:0;
      display:inline-flex; align-items:center; justify-content:center;
      border:1px solid var(--border-color); border-radius:var(--radius-sm);
      background:var(--bg-secondary); color:var(--text-secondary);
      cursor:pointer;
      transition:color var(--dur-1), border-color var(--dur-1), background var(--dur-1), transform var(--dur-1);
    }
    .qual-info-btn svg{ display:block; }
    /* (1.1.10) ESTE FICA PEQUENO DE PROPÓSITO, e é a exceção da regra de alvo de 24px.
       O "i" de ajuda mora DENTRO do .qualification-item, que é clicável e é a ação que
       importa: escolher a qualificação da ligação. Expandir a área do "i" por pseudo-elemento
       (o que foi feito em .precs-tel-btn e .precs-tempos-share) roubaria alguns pixels da
       borda do item, trocando "alvo pequeno para abrir ajuda" por "clique que abre ajuda
       quando o operador quis qualificar". O segundo é pior: acontece em cada ligação, no TPA,
       com pressa. Se um dia precisar crescer, o caminho é dar folga no PADDING do item para
       abrir espaço morto em volta do botão — não invadir o item. */
    /* (1.1.45) O `outline:none` daqui SAIU, e ele estava dentro do próprio bloco de
       `:focus-visible`, sem substituto: o botão "i" ficava sem anel nenhum ao receber foco,
       cancelando a regra global de 2px dourados. Era o único caso que rebaixava um controle
       do CICLO DA LIGAÇÃO, e contradizia a regra que o projeto escreveu para si em 1.1.10.
       No `:hover` ele nunca fez nada (não há outline no hover), então a remoção só devolve o
       anel a quem chega por teclado. O realce de cor e o `scale` continuam nos dois estados. */
    .qual-info-btn:hover, .qual-info-btn:focus-visible{
      color:var(--accent-blue); border-color:var(--accent-blue);
      background:var(--accent-blue-light); transform:scale(1.08);
    }
    .qual-info-btn:active{ transform:scale(1); }
    .precs-qual-pop{
      position:fixed; z-index:10001; display:none; max-width:92vw;
      background:var(--bg-secondary); border:1px solid var(--border-color);
      border-radius:var(--radius-card); box-shadow:var(--shadow-lg);
      padding:var(--space-3) var(--space-4); font-size:.8rem; color:var(--text-primary);
      animation:pmEntra .16s ease;
    }
    .precs-qual-pop.open{ display:block; }
    .pqp-tit{ display:flex; align-items:center; gap:var(--space-2); font-weight:700; font-size:.86rem;
      margin-bottom:var(--space-2); font-family:'Poppins','Manrope',sans-serif; line-height:1.25; }
    .pqp-dot{ width:9px; height:9px; border-radius:50%; flex:0 0 auto; }
    .pqp-sec{ margin-top:var(--space-2); }
    .pqp-lbl{ font-size:.64rem; text-transform:uppercase; letter-spacing: var(--ls-caps);
      color:var(--precs-gold,#B49552); font-weight:700; margin-bottom:var(--space-0);
      font-family:'Montserrat','Poppins',sans-serif; }
    .pqp-txt{ color:var(--text-secondary); line-height:1.42; margin-top:var(--space-0); }
    .pqp-txt b{ color:var(--text-primary); font-weight:600; }
    .pqp-sdr{ margin-top:var(--space-1); padding-top:var(--space-1); border-top:1px dashed var(--border-color); }
    @media (prefers-reduced-motion: reduce){ .precs-qual-pop{ animation:none; } }

    .qualification-id {
      font-size: 0.75rem;
      color: var(--text-muted);
      font-family: 'JetBrains Mono', monospace;
    }

    .qualification-actions {
      margin-top: var(--space-4);
      padding-top: var(--space-4);
      border-top: 1px solid var(--border-color);
    }

    .no-qualifications {
      text-align: center;
      padding: var(--space-8);
      color: var(--text-muted);
    }

    /* ============================================ */
    /* Events Log */
    /* ============================================ */
    .events-panel {
      margin-top: var(--space-8);
    }

    .events-log {
      max-height: 200px;
      overflow-y: auto;
      font-family: 'JetBrains Mono', monospace;
      font-size: 0.8rem;
    }

    .event-item {
      display: flex;
      gap: var(--space-3);
      padding: var(--space-2) 0;
      border-bottom: 1px solid var(--border-color);
    }

    .event-item:last-child {
      border-bottom: none;
    }

    .event-time {
      color: var(--text-muted);
      flex-shrink: 0;
    }

    .event-type {
      color: var(--accent-blue);
      flex-shrink: 0;
      min-width: 180px;
    }

    .event-data {
      color: var(--text-secondary);
      word-break: break-all;
    }

    /* ============================================ */
    /* User Info */
    /* ============================================ */
    .user-info {
      display: flex;
      align-items: center;
      gap: var(--space-4);
    }

    .user-details {
      text-align: right;
    }
    /* avatar do operador (foto mapeada por ramal ou iniciais) — anel dourado */
    .precs-avatar {
      flex: none; width: 36px; height: 36px; border-radius: 50%;
      overflow: hidden; display: inline-flex; align-items: center; justify-content: center;
      background: var(--bg-tertiary);
      box-shadow: 0 0 0 2px var(--precs-gold, #B49552), 0 2px 6px rgba(0,0,0,.3);
    }
    .precs-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
    .precs-avatar-ini {
      font-family: var(--font-acao); font-weight: 700; font-size: .82rem;
      color: var(--precs-gold, #B49552);
      background: color-mix(in srgb, var(--precs-gold,#B49552) 16%, var(--bg-tertiary));
    }

    .user-name {
      font-weight: 600;
      font-size: 0.9rem;
    }
    /* PRECS (1.1.2) — FAIXA NO HEADER, como filete embaixo do nome.
       Mesmo tratamento que a saudação do menu já usa (.precs-greet-faixa), e não um
       segundo desenho: o contorno da foto continua PADRONIZADO em dourado, que é a
       decisão registrada em app.js (precsIniciarWelcome), e nada de barra de BJJ em
       SVG, que já foi testada no hero e lia como barra de progresso.
       O motivo de existir aqui: o hero só aparece no menu, então durante o expediente
       inteiro, dentro da campanha, não sobrava nenhum traço do operador na tela.
       Filete de 2px e não 3px porque o nome do header tem 0,9rem contra 1,75rem da
       saudação; na proporção, o 3px daqui ficaria pesado.
       O inline-block é o que faz o filete ter a largura do NOME, e não a da coluna:
       .user-details é alinhada à direita e um bloco esticaria a linha inteira. Isso
       foi testado: com `display:block` o filete atravessa a largura da razão social e
       para de ler como faixa, vira divisória entre as duas linhas.
       ESPAÇAMENTO COLADO (margin 0 e line-height 1,15): a primeira versão tinha 3px de
       respiro e ficou solta. O nome do header é curto (primeiro nome) e a razão social
       embaixo é larga, então um filete curto com folga dos dois lados lia como um
       traço perdido no meio do bloco em vez de sublinhado do nome. Encostado no nome,
       ele volta a pertencer a ele. */
    .user-details { line-height: 1.15; }
    .user-company { margin-top: 1px; }
    .precs-user-nome { display: inline-block; }
    .precs-user-faixa::after {
      content: "";
      display: block;
      height: 2px;
      width: 100%;
      margin: 0;
      border-radius: var(--radius-pill);
      background: var(--precs-faixa-cor, var(--precs-gold, #B49552));
      box-shadow: 0 0 0 .5px color-mix(in srgb, var(--text-primary) 26%, transparent);
    }

    .user-company {
      font-size: 0.8rem;
      color: var(--text-secondary);
    }
    /* PRECS (1.1.5) — RAMAL no header, na mesma linha da razão social (era um chip no topo
       do menu). Monospace porque é número que se lê dígito por dígito, e um tom abaixo da
       empresa para não competir com ela — sem sair de --text-secondary, que é o token que o
       CI mede contra o fundo tingido do header (ver --header-bg-estado). */
    .user-ramal {
      font-family: 'JetBrains Mono', monospace;
      font-size: 0.74rem;
    }
    /* Sem `opacity` aqui de propósito: opacidade abaixa o contraste EFETIVO e sairia do
       número que o CI mediu para --text-secondary. O que separa o ramal da razão social é
       o desenho da letra (monospace) e o tamanho, não transparência. */

    /* ============================================ */
    /* Toast Notifications */
    /* ============================================ */
    /* PRECS (1.1.0) — z-index ACIMA de todos os overlays, de propósito. Os modais
       vão de 2000 (Preferências) a 10000 (Confirmação, Frases, loader de tela), e
       vários deles disparam toast: "Frase adicionada ao seu foco do dia" saía atrás
       do fundo escurecido com blur do próprio modal que a pediu, então a
       confirmação simplesmente não chegava ao operador. Toast é a camada mais alta
       da interface por definição: é o retorno de uma ação, e não existe motivo para
       algo cobri-lo. Se aparecer overlay novo, ele fica ABAIXO deste número. */
    .toast-container {
      position: fixed;
      top: 6rem;
      right: 1rem;
      z-index: 10100;
      display: flex;
      flex-direction: column;
      gap: var(--space-2);
      max-width: 320px;
    }

    .toast {
      padding: var(--space-4) var(--space-6);
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-inner);
      box-shadow: var(--shadow-lg);
      display: flex;
      align-items: center;
      gap: var(--space-3);
      animation: slideIn var(--dur-3) ease;
      color: var(--text-primary);
    }

    /* Contorno e véu de fundo saem do MESMO token de estado (ver --toast-* no :root),
       então não há como as duas metades do toast discordarem de cor outra vez. */
    .toast.success {
      border-color: var(--toast-ok);
      background: linear-gradient(90deg, color-mix(in srgb, var(--toast-ok) 15%, var(--bg-secondary)), var(--bg-secondary));
    }

    .toast.error {
      border-color: var(--toast-err);
      background: linear-gradient(90deg, color-mix(in srgb, var(--toast-err) 15%, var(--bg-secondary)), var(--bg-secondary));
    }

    .toast.warning {
      border-color: var(--toast-warn);
      background: linear-gradient(90deg, color-mix(in srgb, var(--toast-warn) 15%, var(--bg-secondary)), var(--bg-secondary));
    }
    .toast.info {
      border-color: var(--toast-info);
      background: linear-gradient(90deg, color-mix(in srgb, var(--toast-info) 15%, var(--bg-secondary)), var(--bg-secondary));
    }
    /* ícone em chip colorido por tipo + texto mais legível */
    .toast-ico {
      flex: none; width: 22px; height: 22px; border-radius: 50%;
      display: flex; align-items: center; justify-content: center;
      font-size: .78rem; font-weight: 700; line-height: 1;
      background: color-mix(in srgb, var(--accent-blue) 22%, transparent);
      color: var(--accent-blue);
    }
    .toast-msg { font-size: .85rem; line-height: 1.35; }
    /* PRECS (1.0.34) — contador de repetição. Fica vazio quando a mensagem apareceu uma
       única vez (:empty esconde), e mostra "2x", "3x" quando o MESMO aviso repete. Isso
       substituiu o empilhamento: seis toasts idênticos viravam uma parede vermelha na
       lateral da tela e escondiam a interface. */
    .toast-cnt {
      margin-left: auto; flex: none;
      font-size: .68rem; font-weight: 700; letter-spacing: .02em;
      font-family: 'JetBrains Mono', monospace;
      color: var(--text-muted);
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-pill);
      padding: .05rem var(--space-1);
    }
    .toast-cnt:empty { display: none; }
    /* (02/10/2026) O aviso com rosto: quem mexeu no cronograma aparece com a foto no lugar do ícone */
    .toast-ico.toast-av { width: 26px; height: 26px; background: transparent; }
    .toast-ico.toast-av .precs-sup-av { width: 26px; height: 26px; }
    .toast-msg b { color: var(--text-primary); }
    /* (02/10/2026) O toast sai do caminho: clique fecha, o ✕ aparece no hover, e "Fechar todos" quando há pilha. */
    .toast { cursor: pointer; transition: transform var(--dur-2) var(--ease-2), border-color var(--dur-2) var(--ease-1); }
    .toast:hover { transform: translateX(calc(-1 * var(--space-1))); }
    .toast-x {
      flex: none; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
      border: 0; border-radius: 50%; background: transparent; color: var(--text-muted); font: inherit; font-size: var(--fs-3); cursor: pointer;
      opacity: .55; transition: opacity var(--dur-1) var(--ease-1), background-color var(--dur-1) var(--ease-1), color var(--dur-1) var(--ease-1);
    }
    .toast:hover .toast-x, .toast-x:focus-visible { opacity: 1; }
    .toast-x:hover { background: var(--bg-tertiary); color: var(--text-primary); }
    .toast-todos {
      align-self: flex-end; border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: var(--bg-secondary); color: var(--text-secondary);
      font-family: var(--font-acao); font-size: var(--fs-3); font-weight: 600; padding: var(--space-1) var(--space-3); cursor: pointer; box-shadow: var(--shadow);
      animation: slideIn var(--dur-3) ease; transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1);
    }
    .toast-todos:hover { color: var(--text-primary); border-color: var(--precs-gold); }
    @media (prefers-reduced-motion: reduce) { .toast, .toast-x, .toast-todos { transition: none; } .toast-todos { animation: none; } .toast:hover { transform: none; } }
    .toast.success .toast-ico { background: color-mix(in srgb, var(--toast-ok) 22%, transparent);   color: var(--toast-ok); }
    .toast.error   .toast-ico { background: color-mix(in srgb, var(--toast-err) 22%, transparent);  color: var(--toast-err); }
    .toast.warning .toast-ico { background: color-mix(in srgb, var(--toast-warn) 22%, transparent); color: var(--toast-warn); }
    .toast.info    .toast-ico { background: color-mix(in srgb, var(--toast-info) 22%, transparent); color: var(--toast-info); }

    @keyframes slideIn {
      from {
        transform: translateX(100%);
        opacity: 0;
      }
      to {
        transform: translateX(0);
        opacity: 1;
      }
    }

    /* PRECS (1.1.0) — a scrollbar global vive num único lugar, e é o bloco por volta
       de "SCROLLBAR (definição única)" mais abaixo. Havia um segundo bloco AQUI,
       removido: mesma especificidade, declarado antes, então perdia inteiro para o
       de baixo e nunca pintou nada. Pior que morto, era enganoso — pedia 8px e
       trilha cinza contra os 9px e trilha transparente que valiam de fato, e quem
       ajustasse a scrollbar por aqui não veria efeito nenhum. */

    /* ============================================ */
    /* Loading Spinner */
    /* ============================================ */
    .spinner {
      width: 18px;
      height: 18px;
      border: 2px solid var(--border-color);
      border-top-color: var(--accent-blue);
      border-radius: 50%;
      animation: precsSpin 0.8s linear infinite;
    }

    .spinner.yellow {
      border-top-color: var(--accent-3cplus);
    }

    /* PRECS — spinner que herda a cor do botão (currentColor). Fica elegante em
       botões coloridos (dourado, laranja) onde o .spinner azul destoava. */
    .precs-spin {
      display: inline-block; width: 16px; height: 16px;
      border: 2px solid currentColor; border-top-color: transparent;
      border-radius: 50%; animation: precsSpin .7s linear infinite;
      opacity: .9; vertical-align: middle;
    }

    /* O "@keyframes spin" que ficava aqui era idêntico ao "precsSpin" definido junto
       do loader da marca: dois nomes para o mesmo "to { transform: rotate(360deg) }".
       Consolidado no nome com prefixo, que é a convenção do arquivo. */

    /* (1.1.45) O ÚLTIMO BURACO DE MOVIMENTO REDUZIDO.
       Varrendo os 78 @keyframes do projeto contra o bloco `reduce` mais próximo, estes dois
       eram o único par sem cobertura — os outros cinco indicadores de carga já tinham
       (.og-spin, .precs-btn-star, .precs-bl-letter, .pm-loader e a varredura do card de
       campanha). Girar indicador de carga é a exceção clássica da diretriz, então a gravidade
       é baixa; o que não se sustenta é a INCOERÊNCIA com os próprios pares do mesmo produto.
       A rotação para e a borda superior fica marcada, para o anel continuar dizendo
       "trabalhando" sem se mexer: `animation: none` sozinho deixaria só um círculo parado,
       indistinguível de enfeite. */
    @media (prefers-reduced-motion: reduce) {
      .spinner, .precs-spin { animation: none; border-top-style: dashed; }
    }

    /* ============================================ */
    /* Responsive */
    /* ============================================ */
    /* PRECS — Atendimento em duas colunas           */
    /* Espelha o layout do 3C: mailing à esquerda,   */
    /* qualificação à direita (só no TPA).           */
    /* ============================================ */
    /* PRECS — Colunas laterais do topo (mailing e qualificação)     */
    /* Espelha o layout do 3C: mailing à esquerda, campanha no centro */
    /* e qualificação à direita (só no TPA).                          */
    /* ============================================ */
    /* Cada coluna é um card independente, com largura própria (não estica) */
    .precs-col-card {
      background: var(--bg-secondary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-card);
      padding: var(--space-5);
      box-shadow: var(--shadow);
      flex: 0 1 auto;
      align-self: flex-start;     /* alinha pelo topo, junto com a campanha */
    }
    /* Mailing (esquerda) e qualificação (direita): preenchem a célula do grid */
    #call-info-campaign { width: 100%; }
    #qualifications-campaign { width: 100%; }
    /* No card lateral, a lista de qualificação mostra tudo sem scroll interno
       (há espaço de sobra na lateral). */
    #qualifications-campaign .qualification-list {
      max-height: none;
      overflow-y: visible;
    }
    /* (1.1.10) MESMO PAPEL, MESMA CAIXA. Esta classe e o .panel-header são as duas formas de
       "título de card" do painel, com o mesmo peso e o mesmo tamanho — e apareciam lado a lado
       com caixas diferentes: "DADOS DO CLIENTE" e "CAMPANHA ATIVA" em maiúscula (.panel-header)
       contra "Qualificações" em capitalização normal (esta). Na mesma tela, no mesmo nível de
       hierarquia. Faltavam três declarações para as duas serem a mesma coisa: caixa alta,
       espaçamento de letra e o token de cor. */
    .precs-col-titulo {
      display: flex;
      align-items: center;
      gap: var(--space-2);
      font-weight: 600;
      font-size: 0.9rem;
      color: var(--text-secondary);
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      margin-bottom: var(--space-4);
      padding-bottom: var(--space-3);
      border-bottom: 1px solid var(--border-color);
    }
    /* Pipe: largura/posicionamento vêm do grid (.precs-topo-linha). Aqui só
       estilo visual herdado do .panel. */

    /* PRECS — linha do telefone com mini-botões (copiar / WhatsApp) */
    .precs-tel-linha {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--space-2);
    }
    /* Variante inline (card Pipedrive): número à esquerda, botões logo após.
       O número pode encolher (min-width:0 + quebra) para os botões nunca
       saírem do card mesmo com número longo. */
    .precs-tel-linha--inline {
      justify-content: flex-start;
      flex-wrap: wrap;
      gap: var(--space-2);
      padding-right: var(--space-1);
    }
    .precs-tel-linha--inline > span:first-child {
      min-width: 0;
      word-break: break-all;
      flex: 0 1 auto;
    }
    .precs-tel-acoes {
      display: flex;
      align-items: center;
      gap: var(--space-1);
      flex-shrink: 0;
    }
    .precs-tel-btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 30px;
      height: 30px;
      padding: 0;
      border: 1px solid var(--border-color);
      border-radius: var(--radius-sm);
      background: var(--bg-secondary);
      color: var(--text-secondary);
      cursor: pointer;
      transition: background var(--dur-1) ease, border-color var(--dur-1) ease, color var(--dur-1) ease, transform var(--dur-1) ease;
    }
    .precs-tel-btn svg { display: block; }
    /* (1.1.10) A EXPANSÃO DE ÁREA DE CLIQUE POR PSEUDO-ELEMENTO FOI RETIRADA.
       ------------------------------------------------------------------------------------
       A ideia era chegar aos 24×24 reais de WCAG 2.2 SC 2.5.8 sem mexer no tamanho visual
       (o `zoom` de 0,85/0,72 encolhe o alvo: 30px declarados dão 21,6px no compacto).
       Custou três defeitos em produção no mesmo dia, e nenhum deles era óbvio:
         1. `::after` colidiu com o sistema de tooltip do projeto ([data-tip]:hover::after) e
            quebrou o balão do botão de resumo;
         2. o comentário que documentava a mudança ficou malformado (dois terminadores de
            comentário), o parser descartou até recuperar e ENGOLIU o `position: relative` que
            o `::before` precisa. E note a ironia: a primeira escrita DESTE comentário repetiu
            o mesmo erro, por escrever o terminador literalmente aqui dentro. Não escreva
            terminador de comentário CSS dentro de comentário CSS;
         3. sem `position: relative`, o `::before` passou a se resolver contra um ancestral
            posicionado distante — virou um overlay invisível do tamanho da coluna, e o ÚLTIMO
            botão do DOM ganhava o hit-test. Sintoma relatado: passar o mouse no primeiro
            registro de "Últimos leads trabalhados" acendia o último.
       Três regressões visíveis por um ganho que ninguém pediu. Sai.
       O CAMINHO CERTO, quando isso voltar à pauta: crescer o CONTROLE (min-width/min-height no
       botão, absorvendo a diferença no gap da linha) ou dar padding ao container para abrir
       espaço morto em volta. Os dois mexem no layout, e por isso é decisão do Pedro, não efeito
       colateral de um conserto de acessibilidade. */
    .precs-tel-btn:hover {
      border-color: var(--accent-blue);
      background: var(--accent-blue-light);
      color: var(--accent-blue);
      transform: translateY(-1px);
    }
    .precs-tel-btn-wa { color: #25D366; }
    .precs-tel-btn-wa:hover {
      border-color: #25D366;
      background: rgba(37, 211, 102, 0.12);
      color: #25D366;
    }
    .precs-tel-btn:active { transform: translateY(0); }

    /* PRECS — botão "Integração" (abre a lead no Pipedrive). Mesma família
       dourada dos demais botões PRECS (Buscar, Ver estatísticas). */
    .precs-integracao-btn {
      display: inline-flex;
      align-items: center;
      gap: var(--space-2);
      padding: var(--space-2) var(--space-3);
      border: none;
      border-radius: var(--radius-inner);
      background: var(--accent-blue);
      /* (1.1.42) Era `#fff` cravado, e no Zebrado isso ficava BRANCO SOBRE QUASE-BRANCO: o
         `--accent-blue` daquele tema vale `#E8E8E8`, porque num tema preto-e-branco o azul de
         ação vira claro. O `.btn-primary` (linha 763) já tinha sido corrigido para este mesmo
         token, com um comentário descrevendo este mesmo defeito; o Integração ficou de fora da
         varredura da época. `--on-accent-blue` é o único token de tinta que muda por tema. */
      color: var(--on-accent-blue);
      font-family: 'Manrope','Poppins',sans-serif;
      font-size: 0.78rem;
      font-weight: 700;
      cursor: pointer;
      white-space: nowrap;
      box-shadow: var(--elev-1) color-mix(in srgb, var(--accent-blue) 30%, transparent);
      transition: filter var(--dur-1), transform .12s, box-shadow var(--dur-1);
    }
    .precs-integracao-btn:hover {
      filter: brightness(1.08);
      transform: translateY(-1px);
    }
    .precs-integracao-btn:active { transform: translateY(0); }
    .precs-integracao-btn svg { display: block; }

    /* ============================================ */
    /* Tela estreita: empilha em 1 coluna, Campanha Ativa SEMPRE no topo,
       depois mailing, depois qualificação — igual ao layout antigo. */
    /* Modos de tamanho MANUAIS empilham em telas estreitas (zoom fixo pode não
       caber). O modo AUTO NÃO empilha aqui: o zoom se encarrega de encaixar. */
    /* Notebooks ~1366px: as 3 colunas ainda cabem — encolhemos o centro e os
       gaps em vez de empilhar cedo. Só empilha de fato abaixo de 1180px EFETIVOS.

       PRECS (1.1.0) — POR QUE HÁ UM BLOCO POR MODO, e não um só com :not([auto]).
       O main roda com zoom (0.72/0.85/1, regra em ~2003), mas media query mede a
       VIEWPORT, que o zoom não afeta. O layout recebe `viewport / escala` px de
       espaço, ~18% mais que a query enxerga no modo normal. É o mesmo descasamento
       que obriga a DIVISÃO por --precs-escala no max-height do mailing (~938).
       Media query não aceita var(), então a conta vai nos próprios limites:
       limite_real = limite_efetivo x escala.
         empilhar  = 1180 efetivos -> 850 (0.72) | 1003 (0.85) | 1180 (1)
         aperto    = 1500 efetivos -> 1080 (0.72) | 1275 (0.85) | 1500 (1)
       Antes, com 1180/1500 crus para todos, um note de 1366px reais entregava
       1607px efetivos ao layout: cabia nas 3 colunas folgadas, e ainda assim o
       centro encolhia para 600px. E o empilhamento disparava a 1180px reais, que
       são 1388 efetivos — onde as 3 colunas caem confortavelmente. Ao mexer nos
       números, refaça a conta pelos dois valores efetivos acima. */
    /* ============================================================
       PRECS (1.1.44) — OS SEIS BLOCOS ACIMA VIRARAM DOIS, e a conta de escala morreu.
       ============================================================
       O texto acima descreve o problema com precisão e o remédio dele era o único
       disponível na época: como `@media` mede a viewport crua e o layout vive num espaço
       multiplicado pelo `zoom`, a conta `limite_real = limite_efetivo × escala` foi para os
       próprios limites, e a mesma regra passou a existir três vezes — uma por densidade.
       Nove regras escritas, três de verdade, e um aviso escrito para quem mexesse: "refaça a
       conta pelos dois valores efetivos".

       CONTAINER QUERY NÃO PRECISA DA CONTA. Ela mede a caixa que o elemento de fato recebe, e
       essa caixa JÁ está no espaço escalado: num notebook de 1366 com densidade normal, a
       seção mede 1607px de inline-size, que é exatamente o "efetivo" que o comentário acima
       calculava à mão. Então os dois limites viram os dois números efetivos, uma vez só, e
       passam a valer para qualquer densidade — inclusive uma que ninguém criou ainda.

       O CONTÊINER É A SEÇÃO E NÃO A LINHA, e isso não é escolha de estilo: um elemento não
       consulta o próprio tamanho. Se `.precs-topo-linha` fosse o contêiner, as duas regras que
       mexem NELA (o `gap` e o `flex-direction` do empilhamento) consultariam um ancestral que
       não existe e nunca casariam. A seção é o pai imediato e tem a mesma largura.

       POR QUE A CONTENÇÃO É SEGURA AQUI: `container-type` implica `contain: layout`, que faz do
       elemento um bloco de contenção para `position: fixed` descendente — a armadilha clássica.
       Não há nenhum aqui: este projeto já reparenta todo `fixed` para o `<body>` justamente
       porque o `zoom` do `main` quebra a ancoragem (ver `precsWaDrawerAncorar` no app.js). O
       `sticky` das colunas continua valendo, porque ele se ancora no scroller e não no bloco de
       contenção — e há asserção de layout medindo isso.
       ============================================================ */
    #campaign-active-section { container-type: inline-size; container-name: painel; }

    /* APERTO: as 3 colunas ainda cabem, então encolhe o centro e os respiros em vez de
       empilhar cedo. O piso de 1181 preserva a semântica dos blocos antigos (abaixo dele quem
       manda é o empilhamento, logo em seguida). */
    @container painel (max-width: 1500px) and (min-width: 1181px) {
      .precs-topo-linha { gap: var(--space-5); }
      .precs-topo-linha > .precs-col[data-col="2"] { flex: 0 0 600px; max-width: 600px; }
      .precs-topo-linha > .precs-col[data-col="1"],
      .precs-topo-linha > .precs-col[data-col="3"] { max-width: 460px; }
    }

    /* EMPILHAMENTO: uma coluna só, Campanha Ativa no topo. Declarações idênticas às dos três
       blocos que existiam; o `!important` continua sendo necessário porque a base declara
       `flex` e `align-items` com a mesma especificidade. */
    @container painel (max-width: 1180px) {
      .precs-topo-linha { flex-direction: column; align-items: center; gap: var(--space-5); }
      .precs-topo-linha > .precs-col,
      .precs-topo-linha > .precs-col[data-col="1"],
      .precs-topo-linha > .precs-col[data-col="2"],
      .precs-topo-linha > .precs-col[data-col="3"] {
        flex: 0 0 auto !important; width: 100%; max-width: 720px; align-items: center !important;
      }
      .precs-topo-linha .precs-col[data-col="1"] > [data-card-key],
      .precs-topo-linha .precs-col[data-col="3"] > [data-card-key] { max-width: 720px; }
      .precs-topo-linha .precs-col > [data-card-key="mailing"] { max-height: none; }
    }

    /* (1.1.44) O ENSAIO PASSOU A RECEBER O ZOOM DO PAINEL (ver o palco no
       estilo-componentes.css), então o limite CRU deixou de servir: ele estaria errado em duas
       das três densidades, que é exatamente o defeito que os seis blocos acima existiam para
       contornar. Vira container query no palco, e com o MESMO 1180 do painel — um preview fiel
       tem de empilhar onde a tela de verdade empilha. */
    @container ensaio (max-width: 1180px) {
      .precs-ensaio-grid { flex-direction: column; align-items: stretch; }
      .precs-ensaio-col, .precs-ensaio-col[data-col="2"] { flex: 0 0 auto; }
    }
    /* (Aqui existia o empilhamento das colunas para o modo AUTO, a 1024px. Removido
       com o resto do modo: data-fonte nunca vale "auto", então a regra nunca casava.
       As três densidades vivas já têm o próprio empilhamento no bloco acima.) */

    /* ============================================ */
    @media (max-width: 1024px) {
      .dashboard-grid {
        grid-template-columns: 1fr;
      }
      
      .qualifications-panel {
        width: 100%;
      }

      .mode-buttons {
        flex-direction: column;
      }
    }


/* ==========================================================================
   (Etapa 2, 22/09/2026) A TELA DE ENTRADA COM A CONTA GOOGLE
   --------------------------------------------------------------------------
   Reaproveita o painel do login (`.precs-login-panel`): mesma moldura, mesmo brand, e o botao
   do Google no lugar do formulario. O chip "entrou como" mora no painel do ramal, acima do
   formulario, e diz quem esta na estacao antes de a senha ser pedida.
   ========================================================================== */
.precs-entrada-google{
  display: flex;
  justify-content: center;
  min-height: 48px;
  margin: var(--space-4) 0 var(--space-3);
}
.precs-entrada-chip{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
}
.precs-entrada-chip[hidden]{ display: none; }
.precs-entrada-chip-foto,
.precs-entrada-chip-ini{
  width: 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  flex: 0 0 auto;
  object-fit: cover;
}
.precs-entrada-chip-ini{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--precs-gold-light);
  color: var(--precs-gold-title);
  font-family: var(--font-titulo);
  font-weight: 700;
  font-size: var(--fs-4);
}
.precs-entrada-chip-txt{
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}
.precs-entrada-chip-txt b{
  font-family: var(--font-titulo);
  font-size: var(--fs-4);
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.precs-entrada-chip-txt small{
  font-family: var(--font-rotulo);
  font-size: var(--fs-2);
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.precs-entrada-chip-sair{
  flex: 0 0 auto;
  padding: var(--space-0) var(--space-2);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-acao);
  font-size: var(--fs-2);
  cursor: pointer;
}
.precs-entrada-chip-sair:hover{ border-color: var(--precs-gold); color: var(--precs-gold-title); }

/* (Etapa 2) O par hidden/display declarado, porque .precs-prefs-group pode ter display de autor
   e display de autor vence o [hidden] do navegador (licao registrada quatro vezes neste projeto). */
.precs-prefs-group[hidden]{ display: none; }

/* ==========================================================================
   (Etapa 2, 22/09/2026) O HUB: a primeira tela depois da conta Google
   --------------------------------------------------------------------------
   Mesmos tokens do tema da pessoa: nenhuma paleta propria. A estrela de quatro pontas da logo
   aparece grande e sutil atras da saudacao e pequena como marcador de cada cartao. Os cartoes
   sao <button> de verdade (teclado e leitor de tela de graca) com a borda dourada no topo, a
   mesma do painel de login. Grade por minmax, sem @media de largura (regra do teste-aparelho).
   ========================================================================== */
#hub-section{ max-width: 1040px; margin: auto; }
.precs-hub{ position: relative; padding: var(--space-6) var(--space-4) var(--space-8); }
.precs-hub-saudacao{
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-6);
}
.precs-hub-foto{
  width: 52px;
  height: 52px;
  border-radius: var(--radius-pill);
  object-fit: cover;
  outline: 2px solid var(--precs-gold);
  outline-offset: 2px;
  flex: 0 0 auto;
}
.precs-hub-ini{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--precs-gold-light);
  color: var(--precs-gold-title);
  font-family: var(--font-titulo);
  font-weight: 700;
  font-size: var(--fs-9);
}
.precs-hub-saud-txt{ flex: 1 1 auto; min-width: 0; }
.precs-hub-ola{ font-family: var(--font-titulo); font-size: var(--fs-11); color: var(--text-primary); }
.precs-hub-ola b{ color: var(--precs-gold-title); font-weight: 700; }
.precs-hub-email{ font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-muted); margin-top: var(--space-0); }
.precs-hub-trocar{
  flex: 0 0 auto;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-acao);
  font-size: var(--fs-3);
  cursor: pointer;
}
.precs-hub-trocar:hover{ border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-hub-cartoes{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-4);
}
.precs-hub-cartao{
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  min-height: 168px;
  padding: var(--space-5) var(--space-4) var(--space-4);
  border: 1px solid var(--border-color);
  border-top: 3px solid var(--precs-gold);
  border-radius: var(--radius-card);
  background: var(--bg-secondary);
  color: var(--text-primary);
  text-align: left;
  cursor: pointer;
  transition: transform var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1),
              background var(--dur-2) var(--ease-1);
}
/* (1.1.122) CADA CARTÃO COM A SUA COR ("todos têm a mesma cor dourada com estrela, mas têm pesos
   diferentes", Pedro, 23/09/2026): Discador no verde de estado (a linha viva), comunicação interna
   no ouro da marca, Pessoas no azul. A cor vive numa variável por cartão e pinta a régua de cima, o
   ícone, a estrela e o brilho do hover. E o hover cresce de verdade: sobe 4px, a régua engrossa, o
   ícone avança e a estrela gira. */
.precs-hub-cartao{ --precs-cartao-cor: var(--precs-gold); --precs-cartao-tinta: var(--precs-gold-title); }
.precs-hub-cartao[data-id="discador"]{ --precs-cartao-cor: var(--accent-green); --precs-cartao-tinta: var(--accent-green-text, var(--accent-green)); }
/* (1.1.125) Comunicação interna no AZUL e Pessoas no ROXO da paleta ("o card do hub do comunicação
   interna ainda está dourado, podemos alterar a cor dele e do Pessoas", Pedro, 23/09/2026). A 1.1.124
   tinha posto o chat em --accent-blue, que no tema PRECS vale #C6A75E, um dourado claro: a tela não
   mudava. O ouro continua o padrão de cartão novo. */
.precs-hub-cartao[data-id="chat"]{ --precs-cartao-cor: var(--precs-paleta-1); --precs-cartao-tinta: var(--precs-paleta-1); }
.precs-hub-cartao[data-id="pessoas"]{ --precs-cartao-cor: var(--precs-paleta-4); --precs-cartao-tinta: var(--precs-paleta-4); }
.precs-hub-cartao[data-id="consumo"]{ --precs-cartao-cor: var(--precs-paleta-3); --precs-cartao-tinta: var(--precs-paleta-3); }   /* (1.1.143) o verde do Pipedrive */
.precs-hub-cartao{ border-top-color: var(--precs-cartao-cor); }
.precs-hub-cartao .precs-hub-cartao-ico{
  color: var(--precs-cartao-tinta);
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--precs-cartao-cor) 14%, transparent);
  transition: transform var(--dur-3) var(--ease-2), background var(--dur-2) var(--ease-1);
}
.precs-hub-cartao:hover:not(:disabled) .precs-hub-cartao-ico{ background: color-mix(in srgb, var(--precs-cartao-cor) 26%, transparent); }
.precs-hub-cartao .precs-hub-cartao-estrela{ color: var(--precs-cartao-cor); transition: transform var(--dur-3) var(--ease-2), opacity var(--dur-2) var(--ease-1); opacity: .7; }
.precs-hub-cartao:hover:not(:disabled){
  transform: translateY(-4px);
  border-color: var(--precs-cartao-cor);
  background: color-mix(in srgb, var(--precs-cartao-cor) 9%, var(--bg-secondary));
}
.precs-hub-cartao:hover:not(:disabled) .precs-hub-cartao-estrela{ transform: rotate(90deg) scale(1.25); opacity: 1; }
.precs-hub-cartao:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 3px; }
.precs-hub-cartao.breve{ cursor: default; opacity: .62; }
.precs-hub-cartao-estrela{ position: absolute; top: var(--space-3); right: var(--space-3); color: var(--precs-gold); }
.precs-hub-cartao-ico{ color: var(--precs-gold-title); }
.precs-hub-cartao-tit{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-titulo);
  font-weight: 700;
  font-size: var(--fs-8);
}
.precs-hub-breve{
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--precs-gold-light);
  color: var(--precs-gold-title);
  font-family: var(--font-rotulo);
  font-weight: 600;
  font-size: var(--fs-2);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
}
.precs-hub-cartao-txt{ font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-secondary); }
.precs-hub-selos{ display: flex; flex-wrap: wrap; gap: var(--space-1); margin-top: auto; }
.precs-hub-selo,
.precs-entrada-ramal-chip{
  padding: var(--space-0) var(--space-2);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-family: var(--font-num);
  font-size: var(--fs-3);
  font-variant-numeric: tabular-nums;
}
.precs-hub-vazio{
  padding: var(--space-5);
  border: 1px dashed var(--border-color);
  border-radius: var(--radius-card);
  font-family: var(--font-rotulo);
  font-size: var(--fs-4);
  color: var(--text-muted);
  text-align: center;
}

/* Os atalhos de ramal no painel do login: chips clicaveis, o do campo aceso em ouro. */
.precs-entrada-ramais{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  margin: 0 0 var(--space-3);
}
.precs-entrada-ramais[hidden]{ display: none; }
.precs-entrada-ramais-rot{
  font-family: var(--font-rotulo);
  font-size: var(--fs-2);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--text-muted);
  margin-right: var(--space-1);
}
.precs-entrada-ramal-chip{ cursor: pointer; }
.precs-entrada-ramal-chip:hover{ border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-entrada-ramal-chip.ativo{ background: var(--precs-gold-light); border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-entrada-ramal-chip:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 1px; }

/* ==========================================================================
   (Etapa 2, 22/09/2026) PESSOAS: a administracao do diretorio
   --------------------------------------------------------------------------
   Uma linha por pessoa, em grade: quem, area, ramais, ferramentas, ativa, acao. Salvar e por
   linha e so aparece quando algo mudou. Mesmos tokens de tudo; sem @media de largura, a grade
   quebra por minmax quando aperta.
   ========================================================================== */
#pessoas-section{ max-width: 1240px; margin: auto; }
.precs-pessoas{ padding: var(--space-5) var(--space-4) var(--space-8); }
.precs-pessoas-topo{ display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }
.precs-pessoas-tit{ font-family: var(--font-titulo); font-weight: 700; font-size: var(--fs-11); color: var(--text-primary); flex: 1 1 auto; }
.precs-pessoas-voltar,
.precs-pessoas-btn{
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  color: var(--text-secondary);
  font-family: var(--font-acao);
  font-size: var(--fs-3);
  cursor: pointer;
}
.precs-pessoas-voltar:hover,
.precs-pessoas-btn:hover:not(:disabled){ border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-pessoas-btn.salvar{ background: var(--precs-gold-light); border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-pessoas-btn:disabled{ opacity: .5; cursor: default; }
.precs-pessoas-btn[hidden]{ display: none; }
.precs-pessoas-busca{
  min-width: 240px;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: var(--font-rotulo);
  font-size: var(--fs-4);
}
.precs-pessoas-dica{ font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-muted); margin-bottom: var(--space-4); }
.precs-pessoas-lista{ display: flex; flex-direction: column; gap: var(--space-2); }
.precs-pessoas-linha{
  display: grid;
  grid-template-columns: minmax(220px, 1.4fr) minmax(120px, .8fr) minmax(140px, .9fr) minmax(300px, 1.9fr) auto;   /* (1.1.135) quem, área, ramais, Acesso, ações */
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-inner);
  background: var(--bg-secondary);
}
.precs-pessoas-linha.inativa{ opacity: .55; }
.precs-pessoas-linha.nova{ border-style: dashed; }
.precs-pessoas-quem{ display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.precs-pessoas-foto{ width: 32px; height: 32px; border-radius: var(--radius-pill); object-fit: cover; flex: 0 0 auto; }
.precs-pessoas-ini{
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--precs-gold-light); color: var(--precs-gold-title);
  font-family: var(--font-titulo); font-weight: 700; font-size: var(--fs-5);
}
.precs-pessoas-nome{ display: flex; flex-direction: column; min-width: 0; }
.precs-pessoas-nome b{ font-family: var(--font-titulo); font-size: var(--fs-4); color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-pessoas-nome small{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-pessoas-papel{
  align-self: flex-start;
  margin-top: var(--space-0);
  padding: 0 var(--space-2);
  border: 1px solid var(--accent-red);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--accent-red) 14%, transparent);
  color: var(--accent-red);
  font-weight: 700;
  font-family: var(--font-rotulo);
  font-size: var(--fs-2);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
}
.precs-pessoas-campo{ display: flex; flex-direction: column; gap: var(--space-0); min-width: 0; }
.precs-pessoas-campo > span{ font-family: var(--font-rotulo); font-size: var(--fs-2); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.precs-pessoas-inp{
  width: 100%;
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: var(--font-rotulo);
  font-size: var(--fs-4);
}
.precs-pessoas-inp:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 1px; }
.precs-pessoas-email{ min-width: 260px; }
.precs-pessoas-chks{ display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); }
.precs-pessoas-chk{ display: inline-flex; align-items: center; gap: var(--space-1); font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-secondary); cursor: pointer; white-space: nowrap; }
.precs-pessoas-chk input,
.precs-pessoas-ativo input{ accent-color: var(--precs-gold); width: 16px; height: 16px; cursor: pointer; }
.precs-pessoas-ativo{ align-items: center; }
.precs-pessoas-acao{ display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); min-width: 92px; }
.precs-pessoas-ok{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--accent-green-text); }
.precs-pessoas-ok[hidden]{ display: none; }

/* (Etapa 2) A moldura do botao da Google e o selo "conectado" do cartao Discador. */
.precs-entrada-moldura{
  display: flex;
  justify-content: center;
  margin: var(--space-4) 0 var(--space-3);
  padding: var(--space-2);
  border-radius: var(--radius-inner);
  background: var(--bg-tertiary);
  overflow: hidden;
}
.precs-entrada-moldura .precs-entrada-google{ margin: 0; }
.precs-hub-selo.vivo{
  background: var(--accent-green-light);
  border-color: var(--accent-green);
  color: var(--accent-green-text);
}
.precs-hub-breve.vivo{ background: var(--accent-green-light); color: var(--accent-green-text); }

/* ==========================================================================
   (Etapa 2, 22/09/2026) POLIMENTO DE PESSOAS: inputs maiores, foco em ouro, linha com entrada
   animada e hover, botao salvar com peso, e o "salvo" que acende e apaga.
   ========================================================================== */
.precs-pessoas-linha{
  animation: precsPessoasEntra var(--dur-3) var(--ease-2) both;
  transition: border-color var(--dur-2) var(--ease-1), background var(--dur-2) var(--ease-1);
}
.precs-pessoas-linha:hover{ border-color: var(--precs-gold); background: var(--bg-tertiary); }
@keyframes precsPessoasEntra{ from{ opacity: 0; transform: translateY(6px); } to{ opacity: 1; transform: none; } }
.precs-pessoas-inp{
  padding: var(--space-2) var(--space-3);
  font-family: var(--font-corpo);
  font-size: var(--fs-5);
  transition: border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1);
}
.precs-pessoas-inp:hover{ border-color: var(--text-muted); }
.precs-pessoas-inp:focus-visible{ outline: none; border-color: var(--precs-gold); background: var(--bg-secondary); }
.precs-pessoas-inp::placeholder{ color: var(--text-muted); opacity: .7; }
.precs-pessoas-busca{ padding: var(--space-2) var(--space-4); }
.precs-pessoas-busca:focus-visible{ outline: none; border-color: var(--precs-gold); }
.precs-pessoas-btn.salvar{
  padding: var(--space-2) var(--space-4);
  font-weight: 600;
  animation: precsPessoasEntra var(--dur-2) var(--ease-2) both;
}
.precs-pessoas-btn.salvar:hover:not(:disabled){ background: var(--precs-gold); color: var(--bg-primary); }
.precs-pessoas-chk{ padding: var(--space-0) var(--space-2); border-radius: var(--radius-pill); transition: background var(--dur-1) var(--ease-1); }
.precs-pessoas-chk:hover{ background: var(--bg-tertiary); }
.precs-pessoas-chk input,
.precs-pessoas-ativo input{ width: 18px; height: 18px; }
.precs-pessoas-ok{ animation: precsPessoasEntra var(--dur-2) var(--ease-2) both; font-weight: 600; }
.precs-pessoas-tit{ letter-spacing: -.01em; }

/* ==========================================================================
   (Etapa 3, previa) COMUNICACAO INTERNA: trilho de salas, palco e compositor desligado.
   Mesma linguagem do modo WhatsApp (duas colunas), mesmos tokens. Sem @media de largura.
   ========================================================================== */
#chat-section{ max-width: 1240px; margin: auto; }
/* ==========================================================================
   (Etapa 3, fase 1, 23/09/2026) A COMUNICAÇÃO INTERNA: tela cheia
   --------------------------------------------------------------------------
   Duas colunas (salas | conversa) com a altura da janela menos o header, para o fio rolar
   dentro dele e o compositor ficar sempre à mão. Sem moldura de card por dentro: a régua é o
   painel do WhatsApp, que o operador já conhece, na paleta da casa. Tokens só; nenhum z-index.
   ========================================================================== */
.precs-chat{
  display: grid;
  grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
  height: calc(100vh - var(--precs-header-h, 64px) - var(--space-4));
  min-height: 480px;
  border-top: 1px solid var(--border-color);
  background: var(--bg-primary);
}
.precs-chat-trilho{
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--border-color);
  background: var(--bg-secondary);
}
.precs-chat-trilho-topo{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-color);
}
.precs-chat-tit{ display: inline-flex; align-items: center; gap: var(--space-2); flex: 1 1 auto; min-width: 0; font-family: var(--font-titulo); font-weight: 700; font-size: var(--fs-6); color: var(--text-primary); line-height: 1; }   /* (1.1.148) quebra em duas linhas no trilho de 300px; cortava "Comunicação interna" pela metade */
.precs-chat-tit-estrela{ color: var(--precs-gold); display: inline-flex; }
.precs-chat-mais,
.precs-chat-voltar,
.precs-chat-voltar-lista,
.precs-chat-x{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  flex: 0 0 auto;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1);
}
.precs-chat-mais:hover, .precs-chat-voltar:hover, .precs-chat-voltar-lista:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-chat-x:hover{ color: var(--accent-red); border-color: var(--accent-red); }
.precs-chat-x, .precs-chat-voltar-lista{ display: none; }   /* só no painel lateral */
.precs-chat-busca-wrap{
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-3) var(--space-4);
  padding: 0 var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  color: var(--text-muted);
}
.precs-chat-busca-wrap[hidden]{ display: none; }
.precs-chat-busca{
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--space-2) 0;
  border: 0;
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font-corpo);
  font-size: var(--fs-4);
  outline: none;
}
.precs-chat-campo{ display: flex; flex-direction: column; gap: var(--space-1); margin: var(--space-3) var(--space-4) 0; }
.precs-chat-campo span{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--ls-caps); }
.precs-chat-campo .precs-chat-busca{ padding: var(--space-2) var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-inner); background: var(--bg-tertiary); }
.precs-chat-salas, .precs-chat-painel{ flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
.precs-chat-salas[hidden], .precs-chat-painel[hidden]{ display: none; }
.precs-chat-sala{
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-bottom: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-primary);
  text-align: left;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease-1);
}
.precs-chat-sala:hover{ background: var(--bg-tertiary); }
.precs-chat-sala.ativa{ background: var(--precs-gold-light); }
.precs-chat-sala.estatica{ cursor: default; }
.precs-chat-sala.estatica:hover{ background: transparent; }
.precs-chat-sala-foto, .precs-chat-cab-foto, .precs-chat-msg-foto{
  width: 42px; height: 42px; flex: 0 0 auto;
  border-radius: var(--radius-pill);
  object-fit: cover;
}
.precs-chat-ini{
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-tertiary); color: var(--precs-gold-title);
  font-family: var(--font-titulo); font-weight: 700; font-size: var(--fs-6);
}
.precs-chat-sala-txt{ display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.precs-chat-sala-txt b{ font-family: var(--font-titulo); font-size: var(--fs-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-chat-sala-txt small{ font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-chat-sala-txt small.vazia{ color: var(--text-muted); }
.precs-chat-sala-autor{ color: var(--text-muted); }
.precs-chat-sala.nova .precs-chat-sala-txt small{ color: var(--text-primary); }
.precs-chat-sala-lado{ display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); flex: 0 0 auto; }
.precs-chat-sala-lado time{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-muted); }
.precs-chat-sala.nova .precs-chat-sala-lado time{ color: var(--precs-gold-title); }
.precs-chat-sala-badge{
  min-width: 20px; height: 20px; padding: 0 var(--space-1);
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--precs-gold-forma, var(--precs-gold));
  color: var(--precs-wa-tinta-ouro, var(--bg-primary));
  font-family: var(--font-acao); font-weight: 700; font-size: var(--fs-2);
}
.precs-chat-adm{ display: inline-flex; align-items: center; margin-left: var(--space-1); padding: 0 var(--space-1); border: 1px solid var(--accent-red); border-radius: var(--radius-pill); background: color-mix(in srgb, var(--accent-red) 14%, transparent); color: var(--accent-red); font-family: var(--font-acao); font-size: var(--fs-1); font-style: normal; font-weight: 700; text-transform: uppercase; letter-spacing: var(--ls-caps); }
.precs-chat-voce{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-muted); font-style: normal; margin-left: var(--space-1); }
.precs-chat-marca{ width: 20px; height: 20px; flex: 0 0 auto; border: 1px solid var(--border-color); border-radius: var(--radius-pill); }
.precs-chat-marca.on{ background: var(--precs-gold); border-color: var(--precs-gold); }
.precs-chat-mini{
  padding: var(--space-0) var(--space-2);
  border: 1px solid var(--border-color); border-radius: var(--radius-pill);
  background: transparent; color: var(--text-secondary);
  font-family: var(--font-acao); font-size: var(--fs-2); cursor: pointer;
}
.precs-chat-mini:hover{ border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-chat-mini.vermelho:hover{ border-color: var(--accent-red); color: var(--accent-red); }
.precs-chat-aviso{ padding: var(--space-5) var(--space-4); font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); text-align: center; }
.precs-chat-aviso.erro{ color: var(--accent-red-text, var(--accent-red)); }
.precs-chat-painel-topo{ display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-color); font-family: var(--font-titulo); font-size: var(--fs-5); color: var(--text-primary); }
.precs-chat-painel-topo .precs-chat-voltar-lista{ display: inline-flex; }
.precs-chat-painel-lista{ display: flex; flex-direction: column; }
.precs-chat-painel-acoes{ display: flex; align-items: center; justify-content: flex-end; gap: var(--space-3); padding: var(--space-3) var(--space-4); }
.precs-chat-painel-conta{ margin-right: auto; font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); }
.precs-chat-painel-btn{
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border-color); border-radius: var(--radius-pill);
  background: var(--bg-tertiary); color: var(--text-secondary);
  font-family: var(--font-acao); font-size: var(--fs-3); cursor: pointer;
}
.precs-chat-painel-btn:hover{ border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-chat-painel-btn.primario{ background: var(--precs-gold); border-color: var(--precs-gold); color: var(--precs-wa-tinta-ouro, var(--bg-primary)); }
.precs-chat-painel .precs-chat-cit{ margin: var(--space-3) var(--space-4) 0; }

/* A conversa */
.precs-chat-palco{ display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--bg-primary); }
.precs-chat-cab{ display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border-color); background: var(--bg-secondary); }
.precs-chat-cab-txt{ display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.precs-chat-cab-txt b{ font-family: var(--font-titulo); font-size: var(--fs-6); color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-chat-cab-txt small{ font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); }
.precs-chat-cab-btn{
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-color); border-radius: var(--radius-pill);
  background: transparent; color: var(--text-secondary);
  font-family: var(--font-acao); font-size: var(--fs-3); cursor: pointer;
}
.precs-chat-cab-btn:hover{ border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-chat-fio{ flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: var(--space-4) var(--space-5); display: flex; flex-direction: column; gap: var(--space-1); }
.precs-chat-vazio{ margin: auto; max-width: 460px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
.precs-chat-vazio-estrela{ color: var(--precs-gold); opacity: .5; }
.precs-chat-vazio-estrela svg{ width: 44px; height: 44px; }
.precs-chat-vazio b{ font-family: var(--font-titulo); font-size: var(--fs-6); color: var(--text-primary); }
.precs-chat-vazio span{ font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-secondary); }
.precs-chat-mais-antigas{ align-self: center; margin-bottom: var(--space-3); padding: var(--space-1) var(--space-4); border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: transparent; color: var(--text-secondary); font-family: var(--font-acao); font-size: var(--fs-3); cursor: pointer; white-space: nowrap; }
.precs-chat-mais-antigas:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-chat-dia{ display: flex; justify-content: center; margin: var(--space-3) 0; }
.precs-chat-dia span{ padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); background: var(--bg-tertiary); color: var(--text-secondary); font-family: var(--font-rotulo); font-size: var(--fs-3); }
.precs-chat-msg{ display: flex; align-items: flex-end; gap: var(--space-2); max-width: min(78%, 720px); }
.precs-chat-msg.cabeca{ margin-top: var(--space-2); }
.precs-chat-msg.minha{ align-self: flex-end; flex-direction: row-reverse; }
.precs-chat-msg-foto{ width: 30px; height: 30px; font-size: var(--fs-3); }
.precs-chat-msg-foto.vazia{ background: transparent; }
.precs-chat-msg.minha .precs-chat-msg-foto{ display: none; }
.precs-chat-bolha{
  position: relative;
  min-width: 0;
  padding: var(--space-2) var(--space-6) var(--space-4) var(--space-3);
  /* (1.1.121) Formato de BALÃO: cantos largos e um canto curto no lado de quem fala, como no
     WhatsApp ("as mensagens não têm formato de balão, estão quadradas", Pedro). */
  border-radius: 18px 18px 18px 6px;
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: var(--font-corpo);
  font-size: var(--fs-4);
  word-wrap: break-word;
  overflow-wrap: anywhere;
  /* (1.1.142) LARGURA MÍNIMA para a hora (e os tiques) caberem numa linha: o balão de UMA letra encolhia a 45px e
     "16:43" quebrava em "16:" e "43" ("o horário fica estranho", Pedro, 25/09/2026). Em px, porque a hora é --fs-1 fixo
     e o corpo do balão muda por tela (12px no monitor, 17px no celular): a conta é hora + tiques + as duas margens. */
  min-width: 84px;
}
.precs-chat-msg.minha .precs-chat-bolha{ background: var(--precs-gold-light); border-radius: 18px 18px 6px 18px; }
.precs-chat-msg.cabeca:not(.minha) .precs-chat-bolha{ border-top-left-radius: 6px; border-bottom-left-radius: 18px; }
.precs-chat-msg.minha.cabeca .precs-chat-bolha{ border-top-right-radius: 6px; border-bottom-right-radius: 18px; }
.precs-chat-msg-txt.apagada{ font-style: italic; color: var(--text-muted); }
.precs-chat-msg-autor{ --precs-cor: var(--precs-gold-title); font-family: var(--font-acao); font-size: var(--fs-2); font-weight: 600; color: var(--precs-cor); margin-bottom: var(--space-0); cursor: pointer; }
.precs-chat-msg-autor:hover{ text-decoration: underline; }
.precs-chat-msg-txt{ white-space: pre-wrap; }
.precs-chat-msg-hora{ position: absolute; right: var(--space-3); bottom: var(--space-1); font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); white-space: nowrap;   /* (1.1.142) a hora nunca quebra */ }
.precs-chat-hash{ color: var(--precs-gold-title); font-weight: 600; }
.precs-chat-enc{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-muted); font-style: italic; margin-bottom: var(--space-0); }
.precs-chat-cit{
  display: flex; flex-direction: column; gap: var(--space-0);
  margin-bottom: var(--space-2); padding: var(--space-1) var(--space-3);
  border-left: 3px solid var(--precs-gold);
  border-radius: var(--radius-inner);
  background: color-mix(in srgb, var(--text-primary) 6%, transparent);
  font-size: var(--fs-3);
}
.precs-chat-cit b{ font-family: var(--font-acao); color: var(--precs-gold-title); font-size: var(--fs-2); }
.precs-chat-cit span{ color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-chat-deals{ display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.precs-chat-deal{
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-1);
  border: 1px solid var(--border-color); border-radius: var(--radius-pill);
  background: var(--bg-secondary); color: var(--text-primary); text-decoration: none;
  transition: border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1);
}
.precs-chat-deal:hover{ border-color: var(--pipe-verde, var(--accent-green)); background: color-mix(in srgb, var(--pipe-verde, var(--accent-green)) 12%, transparent); }
.precs-chat-deal-ico{
  width: 26px; height: 26px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--pipe-verde, var(--accent-green)); color: var(--bg-primary);
  font-family: var(--font-acao); font-weight: 700; font-size: var(--fs-4);
}
.precs-chat-deal.busca .precs-chat-deal-ico{ opacity: .6; }
.precs-chat-deal.morto{ cursor: default; }
.precs-chat-deal.morto:hover{ border-color: var(--border-color); background: var(--bg-secondary); }
.precs-chat-deal-txt{ display: flex; flex-direction: column; line-height: 1; }
.precs-chat-deal-txt b{ font-family: var(--font-acao); font-size: var(--fs-3); }
.precs-chat-deal-txt small{ font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); }
/* (1.1.121) A SETA DO MENU no canto de cima da bolha, visível no hover, como no WhatsApp. */
.precs-chat-msg-menu{
  position: absolute; top: var(--space-1); right: var(--space-1);
  width: 22px; height: 22px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--bg-primary) 55%, transparent); color: var(--text-secondary);
  cursor: pointer; opacity: 0;
  transition: opacity var(--dur-1) var(--ease-1), color var(--dur-1) var(--ease-1);
}
.precs-chat-msg:hover .precs-chat-msg-menu, .precs-chat-msg:focus-within .precs-chat-msg-menu, .precs-chat-msg-menu:focus-visible{ opacity: 1; }
.precs-chat-msg-menu:hover{ color: var(--precs-gold-title); }
.precs-chat-menu{
  inset: auto; margin: 0; min-width: 170px; padding: var(--space-1) 0;
  border: 1px solid var(--border-color); border-radius: var(--radius-inner);
  background: var(--bg-secondary); color: var(--text-primary);
  box-shadow: var(--shadow-lg);
}
.precs-chat-menu:popover-open{ animation: precsChatLinhaEntra var(--dur-2) var(--ease-2) both; }
.precs-chat-menu-item{
  display: block; width: 100%; padding: var(--space-2) var(--space-4);
  border: 0; background: transparent; color: var(--text-primary); text-align: left;
  font-family: var(--font-acao); font-size: var(--fs-3); cursor: pointer;
}
.precs-chat-menu-item:hover{ background: var(--bg-tertiary); color: var(--precs-gold-title); }
.precs-chat-menu-item.vermelho:hover{ color: var(--accent-red); }
.precs-chat-cit.edicao{ border-left-color: var(--precs-gold-title); }
.precs-chat-enviar.editando{ background: var(--precs-gold); color: var(--precs-wa-tinta-ouro, var(--bg-primary)); }
.precs-chat-citando{ display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-4) 0; }
.precs-chat-citando[hidden]{ display: none; }
.precs-chat-citando .precs-chat-cit{ flex: 1 1 auto; margin: 0; }
.precs-chat-cit-x{ width: 28px; height: 28px; flex: 0 0 auto; border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: transparent; color: var(--text-secondary); cursor: pointer; }
.precs-chat-compositor{ display: flex; align-items: flex-end; gap: var(--space-2); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--border-color); background: var(--bg-secondary); }
.precs-chat-inp{
  flex: 1 1 auto;
  min-width: 0;
  max-height: 140px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-card);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: var(--font-corpo);
  font-size: var(--fs-4);
  resize: none;
  overflow-y: hidden;
}
.precs-chat-inp:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 1px; }
.precs-chat-inp:disabled{ opacity: .6; }
.precs-chat-enviar{
  width: 40px; height: 40px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--precs-gold);
  border-radius: var(--radius-pill);
  background: var(--precs-gold-light);
  color: var(--precs-gold-title);
  cursor: pointer;
  transition: transform var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1), color var(--dur-1) var(--ease-1);
}
.precs-chat-enviar:hover:not(:disabled){ transform: translateY(-1px); background: var(--precs-gold); color: var(--precs-wa-tinta-ouro, var(--bg-primary)); }
.precs-chat-enviar:disabled{ opacity: .5; cursor: default; }
@media (prefers-reduced-motion: reduce){ .precs-chat-enviar:hover:not(:disabled){ transform: none; } }

/* ==========================================================================
   (1.1.114) OS QUATRO BOTÕES DO HEADER, CADA UM COM A SUA COR
   --------------------------------------------------------------------------
   "Podemos colorir os ícones: o do Whats verde, a estrela PRECS dourada, preferências cinza"
   (Pedro, 22/09/2026). Hub e comunicação interna no ouro da marca; WhatsApp no verde oficial
   dele (o mesmo #25D366 do ícone no topo da lista e do botão de telefone); preferências fica
   no cinza que já tinha. O hover e o aceso continuam os do `.precs-theme-btn` (40-temas.css);
   aqui só a cor do ícone, e o aceso do WhatsApp na cor dele em vez do ouro.
   ========================================================================== */
/* O verde da marca do WhatsApp e o branco do disco do G da Google são CONSTANTES da marca de
   terceiros, iguais nos três temas (o mesmo raciocínio da moldura de ambiente, no baseline): por
   isso são tokens próprios e não tokens de tema. */
html{ --precs-wa-marca: #25D366; --precs-g-disco: #fff; }
/* (30/09/2026) O azul da Meta, da aba META da supervisao. Igual em todo tema, como o verde acima. */
html{ --precs-meta-marca: #0866FF; }
/* (30/09/2026) A aba Estrategias da supervisao: laranja, o terceiro canal de cor da faixa depois do verde do WhatsApp e do azul da Meta. */
html{ --precs-est-marca: #F08A3C; }
/* (02/10/2026) As duas abas da casa ganharam marca própria, como Estratégias, WhatsApp e Meta: "agora não têm muito
   destaque" (Pedro). Teal para quem está logado (gente), índigo para as campanhas (as listas). */
html{ --precs-oper-marca: #2FA79B; --precs-camp-marca: #6F78D6; }
#precs-hub-btn, #precs-chat-btn{ color: var(--precs-gold); }
#precs-prefs-btn{ color: var(--text-secondary); }   /* a engrenagem no cinza, e não no branco do texto */
#precs-wa-btn{ color: var(--precs-wa-marca); }
#precs-wa-btn.on{
  color: var(--precs-wa-marca);
  border-color: var(--precs-wa-marca);
  background: color-mix(in srgb, var(--precs-wa-marca) 16%, transparent);
}
#precs-hub-btn:hover svg{ transform: rotate(90deg); }
#precs-chat-btn:hover svg{ transform: scale(1.14); }
@media (prefers-reduced-motion: reduce){
  #precs-hub-btn:hover svg, #precs-chat-btn:hover svg{ transform: none; }
}

/* (1.1.114) O BOTÃO DE ENTRADA DA CASA, e a dica embaixo. O G da Google vive num disco branco
   (é assim que a marca dela pede o logo colorido); o resto é a paleta do painel. */
.precs-entrada-btn{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  width: 100%;
  margin: var(--space-5) 0 var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--precs-gold);
  border-radius: var(--radius-pill);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: var(--font-acao);
  font-size: var(--fs-5);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1),
              color var(--dur-1) var(--ease-1), transform var(--dur-1) var(--ease-1);
}
.precs-entrada-btn:hover{
  background: var(--precs-gold-light);
  border-color: var(--precs-gold-title);
  color: var(--precs-gold-title);
  transform: translateY(-1px);
}
.precs-entrada-btn:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 2px; }
.precs-entrada-btn-g{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  border-radius: var(--radius-pill);
  background: var(--precs-g-disco);
}
.precs-entrada-dica{
  text-align: center;
  font-family: var(--font-rotulo);
  font-size: var(--fs-3);
  color: var(--text-muted);
  margin-bottom: var(--space-2);
}
.precs-entrada-dica b{ color: var(--text-secondary); font-weight: 600; }
.precs-entrada-moldura[hidden]{ display: none; }
@media (prefers-reduced-motion: reduce){
  .precs-entrada-btn, .precs-entrada-btn:hover{ transition: none; transform: none; }
}

/* ==========================================================================
   (1.1.114) A COMUNICAÇÃO INTERNA COMO PAINEL LATERAL, À ESQUERDA
   --------------------------------------------------------------------------
   Espelho do painel do WhatsApp (30-whatsapp.css, `data-wa-drawer`): mesmo topo medido
   (`--precs-header-h`), mesma camada (`--precs-camada-drawer`), mesma sombra, entrada pela
   esquerda. Dentro dele o chat vira UMA coluna: as salas em fila horizontal no topo, a conversa
   embaixo. O "voltar" some (a tela do discador continua atrás) e o X aparece.
   ========================================================================== */
html[data-chat-drawer] #chat-section.section{
  display: block;
  position: fixed;
  top: var(--precs-header-h);
  left: 0;
  bottom: 0;
  width: min(400px, 94vw);
  z-index: var(--precs-camada-drawer);
  background: var(--bg-primary);
  border-right: 1px solid var(--border-color);
  box-shadow: 18px 0 40px -12px var(--precs-wa-drawer-sombra);
  animation: precsChatDrawerEntra var(--dur-3) var(--ease-2);
}
@keyframes precsChatDrawerEntra{
  from{ opacity: .4; transform: translateX(-26px); }
  to{ opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce){
  html[data-chat-drawer] #chat-section.section{ animation: none; }
}
/* (1.1.116, refeito na 1.1.117) DENTRO DO PAINEL LATERAL: uma coluna, UMA coisa por vez
   (lista OU conversa, por `data-chat-vista`), o X aparece e o "voltar" some. */
html[data-chat-drawer] .precs-chat{ display: flex; flex-direction: column; height: 100%; min-height: 0; border-top: 0; }
html[data-chat-drawer] .precs-chat-trilho{ flex: 1 1 auto; border-right: 0; }
html[data-chat-drawer] .precs-chat-palco{ flex: 1 1 auto; }
html[data-chat-drawer] .precs-chat-voltar{ display: none; }
/* (1.1.123) O X SAIU dos dois painéis laterais: clicar na tela do discador, o Esc e o botão do
   header fecham ("o botão de fechar não faz mais sentido", Pedro, 23/09/2026). Os nós continuam
   no DOM para os testes antigos, escondidos. */
html[data-chat-drawer] .precs-chat-x{ display: none; }
html[data-wa-drawer] .precs-wa-drawer-x, html[data-wa-drawer] .precs-wa-topo-x{ display: none; }
html[data-chat-drawer] .precs-chat-cab .precs-chat-voltar-lista{ display: inline-flex; }
html[data-chat-drawer] .precs-chat-cab{ background: var(--bg-secondary); }
html[data-chat-drawer] .precs-chat-fio{ padding: var(--space-3); }
html[data-chat-drawer] .precs-chat-msg{ max-width: 92%; }
html[data-chat-drawer][data-chat-vista="thread"] .precs-chat-trilho{ display: none; }
html[data-chat-drawer][data-chat-vista="lista"] .precs-chat-palco{ display: none; }

/* (1.1.114) O botão de excluir em Pessoas: discreto até o primeiro clique, vermelho na confirmação. */
.precs-pessoas-btn.excluir{ color: var(--text-muted); }
.precs-pessoas-btn.excluir:hover:not(:disabled){ color: var(--accent-red); border-color: var(--accent-red); }
.precs-pessoas-btn.excluir.confirmar{
  color: var(--accent-red);
  border-color: var(--accent-red);
  background: color-mix(in srgb, var(--accent-red) 12%, transparent);
}

/* (1.1.116) O AVISO da entrada ("Confirmando a sua conta…") é dourado, e não o vermelho de erro. */
.precs-login-erro.aviso{
  border-color: var(--precs-gold);
  background: var(--precs-gold-light);
  color: var(--precs-gold-title);
}
/* (1.1.116) A conta Google no header (fora do discador), e a área como selo no hub. */
.precs-conta .precs-avatar .precs-avatar-ini{ width: 100%; height: 100%; display: inline-flex; align-items: center; justify-content: center; }
.precs-conta-trocar{
  border: 1px solid var(--border-color);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-acao);
}
.precs-conta-trocar:hover{ border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-hub-email{ display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); }
/* (1.1.125) A pílula lê --precs-cor: a classe .precs-cor-N (fim do arquivo) dá a cor da área; sem classe,
   fica no ouro. ADMIN é vermelho e pesado ("pode ficar em vermelho ou dar mais ênfase", Pedro). */
.precs-hub-area{
  --precs-cor: var(--precs-gold-title);
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2);
  border: 1px solid var(--precs-cor);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--precs-cor) 14%, transparent);
  color: var(--precs-cor);
  font-family: var(--font-acao);
  font-size: var(--fs-2);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--ls-caps);
}
.precs-hub-area.admin{ --precs-cor: var(--accent-red); font-weight: 700; }
.precs-hub-area.mini{ font-size: var(--fs-1); padding: 0 var(--space-1); }

/* ==========================================================================
   (1.1.119) POLIMENTO ANTES DO TESTE: hub, painéis do chat, saída do painel lateral
   ========================================================================== */
/* Os cartões do hub entram em escada, curta. */
@keyframes precsHubEntra{ from{ opacity: 0; transform: translateY(8px); } to{ opacity: 1; transform: none; } }
.precs-hub-saudacao{ animation: precsHubEntra var(--dur-3) var(--ease-2) both; }
.precs-hub-cartao{ animation: precsHubEntra var(--dur-3) var(--ease-2) both; }
.precs-hub-cartao:nth-child(2){ animation-delay: 60ms; }
.precs-hub-cartao:nth-child(3){ animation-delay: 120ms; }
.precs-hub-cartao:nth-child(4){ animation-delay: 180ms; }
.precs-hub-cartao-ico{ transition: transform var(--dur-2) var(--ease-2); }
.precs-hub-cartao:hover:not(:disabled) .precs-hub-cartao-ico{ transform: translateY(-3px) scale(1.12) rotate(-6deg); }

/* O painel por cima da lista (nova conversa, grupo, encaminhar, membros) entra de lado, e as
   linhas chegam em escada; a marca de seleção é um círculo que vira um check dourado. "A animação
   de ao clicar em nova conversa está toda dura" (Pedro, 23/09/2026). */
@keyframes precsChatPainelEntra{ from{ opacity: 0; transform: translateX(14px); } to{ opacity: 1; transform: none; } }
@keyframes precsChatLinhaEntra{ from{ opacity: 0; transform: translateY(6px); } to{ opacity: 1; transform: none; } }
.precs-chat-painel:not([hidden]){ animation: precsChatPainelEntra var(--dur-3) var(--ease-2) both; }
.precs-chat-painel-lista .precs-chat-sala{ animation: precsChatLinhaEntra var(--dur-3) var(--ease-2) both; }
.precs-chat-painel-lista .precs-chat-sala:nth-child(2){ animation-delay: 30ms; }
.precs-chat-painel-lista .precs-chat-sala:nth-child(3){ animation-delay: 60ms; }
.precs-chat-painel-lista .precs-chat-sala:nth-child(4){ animation-delay: 90ms; }
.precs-chat-painel-lista .precs-chat-sala:nth-child(5){ animation-delay: 120ms; }
.precs-chat-painel-lista .precs-chat-sala:nth-child(6){ animation-delay: 140ms; }
.precs-chat-painel-lista .precs-chat-sala:nth-child(n+7){ animation-delay: 180ms; }
.precs-chat-painel .precs-chat-busca-wrap{ margin: var(--space-3) var(--space-4); }
.precs-chat-painel .precs-chat-campo .precs-chat-busca:focus-visible,
.precs-chat-painel .precs-chat-busca-wrap:focus-within{ border-color: var(--precs-gold); outline: none; }
.precs-chat-sala.pessoa.sel{ background: var(--precs-gold-light); }
.precs-chat-marca{
  position: relative;
  transition: background var(--dur-2) var(--ease-2), border-color var(--dur-2) var(--ease-2), transform var(--dur-2) var(--ease-2);
}
.precs-chat-marca::after{
  content: "";
  position: absolute;
  left: 6px; top: 2px;
  width: 5px; height: 10px;
  border: solid var(--precs-wa-tinta-ouro, var(--bg-primary));
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform var(--dur-2) var(--ease-2);
}
.precs-chat-marca.on{ transform: scale(1.08); }
.precs-chat-marca.on::after{ transform: rotate(45deg) scale(1); }
.precs-chat-painel-btn.primario{ transition: transform var(--dur-1) var(--ease-1), filter var(--dur-1) var(--ease-1); }
.precs-chat-painel-btn.primario:hover{ transform: translateY(-1px); color: var(--precs-wa-tinta-ouro, var(--bg-primary)); }

/* A SAÍDA do painel lateral: reta e curta, como a do WhatsApp. */
@keyframes precsChatDrawerSai{ from{ opacity: 1; transform: none; } to{ opacity: 0; transform: translateX(-26px); } }
html[data-chat-drawer] #chat-section.section.chat-drawer-saindo{ animation: precsChatDrawerSai var(--dur-2) linear forwards; }
/* Dentro do painel, nada herda moldura: cabeçalho e conversa colados nas bordas. */
html[data-chat-drawer] .precs-chat-cab,
html[data-chat-drawer] .precs-chat-palco,
html[data-chat-drawer] .precs-chat-trilho{ margin: 0; border-radius: 0; }
html[data-chat-drawer] .precs-chat-cab{ position: sticky; top: 0; }
@media (prefers-reduced-motion: reduce){
  .precs-hub-saudacao, .precs-hub-cartao, .precs-chat-painel:not([hidden]), .precs-chat-painel-lista .precs-chat-sala,
  html[data-chat-drawer] #chat-section.section.chat-drawer-saindo{ animation: none; }
  .precs-hub-cartao:hover:not(:disabled) .precs-hub-cartao-ico, .precs-chat-marca.on{ transform: none; }
}

/* (1.1.120) A estrela do hub, de volta: mais alta, atrás da saudação, discreta. */
.precs-hub-estrela{
  position: absolute;
  top: calc(var(--space-8) * -1 - var(--space-4));
  right: var(--space-4);
  width: 220px;
  height: 220px;
  color: var(--precs-gold);
  opacity: .06;
  pointer-events: none;
}
.precs-hub-estrela svg{ width: 100%; height: 100%; }

/* (1.1.120) Pessoas: quem acabou de entrar, o check que "acende", o Salvar que desliza. */
.precs-pessoas-linha.recem{ border-left: 3px solid var(--precs-gold); }
.precs-pessoas-papel.novo{ background: var(--accent-green-light); border-color: var(--accent-green); color: var(--accent-green-text); }
.precs-pessoas-chk input,
.precs-pessoas-ativo input{ transition: transform var(--dur-2) var(--ease-2); }
.precs-pessoas-chk input:checked,
.precs-pessoas-ativo input:checked{ transform: scale(1.12); }
.precs-pessoas-chk:has(input:checked){ color: var(--text-primary); }
.precs-pessoas-btn.excluir{ transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-pessoas-btn.excluir.confirmar{ animation: precsPessoasEntra var(--dur-2) var(--ease-2) both; }
@media (prefers-reduced-motion: reduce){
  .precs-pessoas-chk input:checked, .precs-pessoas-ativo input:checked{ transform: none; }
  .precs-pessoas-btn.excluir.confirmar{ animation: none; }
}

/* ==========================================================================
   (1.1.121) A TELA CHEIA DE PONTA A PONTA, O PAPEL DE PAREDE DO WHATSAPP, E AS ENTRADAS
   ========================================================================== */
html[data-chat-cheio] main{ padding: 0; max-width: none; gap: 0; }
/* O teto de 1240px da section (leitura confortavel no hub) sai na tela cheia: e o que deixava 68px de faixa de cada lado. */
html[data-chat-cheio] #chat-section{ max-width: none; margin: 0; }
html[data-chat-cheio] body{ overflow: hidden; }
html[data-chat-cheio] .precs-chat{
  height: calc((100vh - var(--precs-header-h, 64px)) / var(--precs-escala, 1));
  min-height: 0; border-top: 0;
}
/* O papel de parede é o MESMO do modo WhatsApp: os tokens que o operador escolhe nas
   preferências (`data-wa-papel` na raiz) valem aqui também. O desenho mora num filho absoluto
   sem z-index; cabeçalho, fio e compositor ficam `relative` e por isso pintam por cima. */
.precs-chat-palco{ position: relative; isolation: isolate; background: var(--precs-wa-papel-fundo, var(--bg-primary)); }
.precs-chat-papel{
  position: absolute; inset: 0; pointer-events: none;
  color: var(--text-primary);
  opacity: var(--precs-wa-papel-forca, .05); background: currentColor;
  -webkit-mask-image: var(--precs-wa-textura); mask-image: var(--precs-wa-textura);
  -webkit-mask-size: var(--precs-wa-papel-escala, 78px) var(--precs-wa-papel-escala, 78px);
  mask-size: var(--precs-wa-papel-escala, 78px) var(--precs-wa-papel-escala, 78px);
  -webkit-mask-repeat: repeat; mask-repeat: repeat;
}
.precs-chat-cab, .precs-chat-fio, .precs-chat-citando, .precs-chat-compositor{ position: relative; }
.precs-chat-fio{ background: transparent; }
/* As mensagens novas entram; as antigas ficam paradas a cada repintura. */
@keyframes precsChatMsgEntra{ from{ opacity: 0; transform: translateY(10px) scale(.98); } to{ opacity: 1; transform: none; } }
.precs-chat-msg.entra{ animation: precsChatMsgEntra var(--dur-3) var(--ease-2) both; }
.precs-chat-msg.entra .precs-chat-deal{ animation: precsChatLinhaEntra var(--dur-3) var(--ease-2) both; animation-delay: 120ms; }
@media (prefers-reduced-motion: reduce){
  .precs-chat-msg.entra, .precs-chat-msg.entra .precs-chat-deal, .precs-chat-menu:popover-open{ animation: none; }
}
/* Pessoas: quem nunca entrou */
.precs-pessoas-papel.nunca{ background: transparent; border-color: var(--border-color); color: var(--text-muted); }

/* (1.1.122) O cabeçalho da sala como alvo (abre os dados do grupo) e o painel de dados. */
.precs-chat-cab-alvo{ display: flex; align-items: center; gap: var(--space-3); min-width: 0; flex: 1 1 auto; border-radius: var(--radius-inner); padding: var(--space-1); margin: calc(-1 * var(--space-1)); cursor: pointer; transition: background var(--dur-1) var(--ease-1); }
.precs-chat-cab-alvo:hover{ background: var(--bg-tertiary); }
.precs-chat-cab-alvo.fixo{ cursor: default; }
.precs-chat-cab-alvo.fixo:hover{ background: transparent; }
.precs-chat-cab-alvo:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 1px; }
.precs-chat-dados{ display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-5) var(--space-4) var(--space-3); border-bottom: 1px solid var(--border-color); text-align: center; }
.precs-chat-dados-foto{ width: 84px; height: 84px; border-radius: var(--radius-pill); object-fit: cover; font-size: var(--fs-10); }
.precs-chat-dados .precs-chat-campo{ width: 100%; margin: 0; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--space-2); }
.precs-chat-dados .precs-chat-campo span{ width: 100%; text-align: left; }
.precs-chat-dados .precs-chat-campo .precs-chat-busca{ flex: 1 1 160px; }
.precs-chat-dados-nome{ font-family: var(--font-titulo); font-size: var(--fs-7); color: var(--text-primary); }
.precs-chat-dados small{ font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); }
.precs-chat-painel-btn.vermelho{ color: var(--accent-red); border-color: color-mix(in srgb, var(--accent-red) 50%, var(--border-color)); }
.precs-chat-painel-btn.vermelho:hover, .precs-chat-painel-btn.vermelho.confirmar{ background: color-mix(in srgb, var(--accent-red) 14%, transparent); border-color: var(--accent-red); color: var(--accent-red); }

/* (1.1.123) ÁUDIO: o microfone, a barra de gravação e a bolha de áudio. */
.precs-chat-mic{
  width: 40px; height: 40px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border-color); border-radius: var(--radius-pill);
  background: var(--bg-tertiary); color: var(--text-secondary); cursor: pointer;
  transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1);
}
.precs-chat-mic:hover:not(:disabled){ color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-chat-mic:disabled{ opacity: .5; cursor: default; }
.precs-chat-mic.gravando{ color: var(--accent-red); border-color: var(--accent-red); background: color-mix(in srgb, var(--accent-red) 12%, transparent); }
.precs-chat-grav{ flex: 1 1 auto; display: flex; align-items: center; gap: var(--space-3); padding: 0 var(--space-3); min-height: 40px; }
.precs-chat-grav[hidden]{ display: none; }
.precs-chat-grav-ponto{ width: 10px; height: 10px; border-radius: var(--radius-pill); background: var(--accent-red); animation: precsChatPulsa 1s ease-in-out infinite; }
@keyframes precsChatPulsa{ 0%, 100%{ opacity: 1; } 50%{ opacity: .25; } }
.precs-chat-grav-t{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-primary); }
.precs-chat-grav-txt{ font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); flex: 1 1 auto; }
.precs-chat-inp[hidden]{ display: none; }
.precs-chat-audio{ display: flex; align-items: center; gap: var(--space-2); min-width: 240px; max-width: 380px; padding: var(--space-1) 0; }
/* (1.1.140) O play SEM a bola dourada: só o ícone em ouro; no hover, um disco discreto ("não precisa dessa bola
   enorme dourada em volta", Pedro, 25/09/2026). */
.precs-chat-audio-play{
  width: 30px; height: 30px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--radius-pill);
  background: transparent; color: var(--precs-gold-title); cursor: pointer;
  transition: background var(--dur-1) var(--ease-1), transform var(--dur-1) var(--ease-2);
}
.precs-chat-audio-play:hover{ background: var(--precs-gold-light); transform: scale(1.08); }
.precs-chat-audio-play:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 1px; }
/* (1.1.126) O player com cara de WhatsApp: a foto de quem gravou com o selo de microfone, a onda que se
   preenche no ouro e é clicável, o tempo corrido e a velocidade. Um áudio por vez (PRECS_CHAT.audio). */
.precs-chat-audio-quem{ position: relative; flex: 0 0 auto; width: 44px; height: 44px; }
.precs-chat-audio-foto{ width: 44px; height: 44px; border-radius: var(--radius-pill); object-fit: cover; font-size: var(--fs-4); }
.precs-chat-audio-mic{ position: absolute; right: 0; bottom: 0; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-pill); background: var(--bg-secondary); color: var(--precs-gold-title); outline: 2px solid var(--bg-tertiary); }
.precs-chat-audio.tocando .precs-chat-audio-mic{ color: var(--accent-green); }
.precs-chat-audio-corpo{ flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: var(--space-0); }
.precs-chat-audio-onda{ position: relative; display: flex; align-items: center; gap: var(--space-0); height: 26px; cursor: pointer; }
.precs-chat-audio-onda i{ display: block; flex: 1 1 0; min-width: 0; border-radius: var(--radius-sm); background: var(--text-muted); opacity: .5; transition: background var(--dur-1) var(--ease-1), opacity var(--dur-1) var(--ease-1); }
.precs-chat-audio-onda i.feita{ background: var(--precs-gold-title); opacity: 1; }
.precs-chat-audio-cursor{ position: absolute; top: 50%; left: var(--precs-audio-pct, 0%); width: 12px; height: 12px; flex: none; min-width: 12px; border-radius: var(--radius-pill); background: var(--precs-gold-title); transform: translate(-50%, -50%); opacity: 0; transition: left var(--dur-1) linear, opacity var(--dur-1) var(--ease-1); }
.precs-chat-audio.ativo .precs-chat-audio-cursor{ opacity: 1; }
.precs-chat-audio-rodape{ display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.precs-chat-audio-dur{ font-family: var(--font-num); font-size: var(--fs-2); color: var(--text-secondary); }
.precs-chat-audio-vel{ padding: 0 var(--space-2); border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: var(--bg-tertiary); color: var(--text-secondary); font-family: var(--font-num); font-size: var(--fs-1); cursor: pointer; }
.precs-chat-audio-vel:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-chat-audio-espera{ display: block; width: 14px; height: 14px; border-radius: var(--radius-pill); border: 2px solid currentColor; border-right-color: transparent; animation: precsChatGira .8s linear infinite; }
@keyframes precsChatGira{ to{ transform: rotate(360deg); } }
.precs-chat-msg.minha .precs-chat-bolha .precs-chat-audio{ padding-right: var(--space-2); }
.precs-chat-foto-btn{ position: relative; }
@media (prefers-reduced-motion: reduce){ .precs-chat-grav-ponto{ animation: none; } }

/* (1.1.124) Mensagem de sistema (histórico do grupo), menção, seletor de @ */
.precs-chat-sis{ display: flex; justify-content: center; align-items: center; gap: var(--space-2); margin: var(--space-1) 0; }
.precs-chat-sis span{ padding: var(--space-0) var(--space-3); border-radius: var(--radius-pill); background: color-mix(in srgb, var(--precs-gold) 10%, var(--bg-tertiary)); color: var(--text-secondary); font-family: var(--font-rotulo); font-size: var(--fs-2); }
.precs-chat-sis time{ font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); }
.precs-chat-sis.entra{ animation: precsChatLinhaEntra var(--dur-3) var(--ease-2) both; }
.precs-chat-mencao-tag{ color: var(--precs-gold-title); font-weight: 600; }
.precs-chat-msg.mencionado .precs-chat-bolha{ box-shadow: inset 3px 0 0 var(--precs-gold); }
.precs-chat-mencao{ min-width: 240px; }
.precs-chat-mencao .precs-chat-menu-item{ display: flex; flex-direction: column; gap: 0; }
.precs-chat-mencao .precs-chat-menu-item small{ font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); }
.precs-chat-mencao .precs-chat-menu-item.ativo{ background: var(--bg-tertiary); }
.precs-chat-painel-topo.sub{ border-top: 1px solid var(--border-color); font-size: var(--fs-3); color: var(--text-secondary); }
@media (prefers-reduced-motion: reduce){ .precs-chat-sis.entra{ animation: none; } }

/* ==========================================================================
   (1.1.125) A COR POR PESSOA E POR ÁREA, reações, emoji, imagem, contato, painel
   ========================================================================== */
/* As oito classes vêm do JS (precsCorIndice pelo e-mail; precsIdCorArea pela área) e só trocam a variável:
   quem a lê é a pílula (.precs-hub-area), o nome do autor (.precs-chat-msg-autor) e o que vier. Ficam
   DEPOIS das regras que declaram o padrão, para vencer no empate de especificidade. */
.precs-cor-1{ --precs-cor: var(--precs-paleta-1); }
.precs-cor-2{ --precs-cor: var(--precs-paleta-2); }
.precs-cor-3{ --precs-cor: var(--precs-paleta-3); }
.precs-cor-4{ --precs-cor: var(--precs-paleta-4); }
.precs-cor-5{ --precs-cor: var(--precs-paleta-5); }
.precs-cor-6{ --precs-cor: var(--precs-paleta-6); }
.precs-cor-7{ --precs-cor: var(--precs-paleta-7); }
.precs-cor-8{ --precs-cor: var(--precs-paleta-8); }
/* (1.1.135) A classe 0 é o OURO (diretoria): sem esta regra a pílula e o filtro "Diretoria" ficavam sem cor
   declarada (a var não resolvia e o chip saía branco). E os dois tons novos. */
.precs-cor-0{ --precs-cor: var(--precs-gold-title); }
.precs-cor-9{ --precs-cor: var(--precs-paleta-9); }
.precs-cor-10{ --precs-cor: var(--precs-paleta-10); }

/* O painel: o "voltar" diz para onde volta, e a seta do hub some enquanto um painel está aberto. */
.precs-chat-painel-voltar{ display: inline-flex; align-items: center; gap: var(--space-1); height: 28px; padding: 0 var(--space-3) 0 var(--space-2); flex: 0 0 auto; border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: transparent; color: var(--text-secondary); font-family: var(--font-acao); font-size: var(--fs-2); cursor: pointer; transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1); }
.precs-chat-painel-voltar:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
#chat-section[data-painel] .precs-chat-trilho-topo .precs-chat-voltar{ display: none; }
.precs-chat-sala.membro{ cursor: pointer; }
.precs-chat-sala.membro:hover{ background: var(--bg-tertiary); }
.precs-chat-sala.membro small.vazia{ display: inline-flex; align-items: center; gap: var(--space-1); }
.precs-chat-membro-menu{ display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex: 0 0 auto; border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: transparent; color: var(--text-secondary); cursor: pointer; transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1); }
.precs-chat-membro-menu:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }

/* Reações: fichas embaixo da bolha; a minha com a borda dourada. E as rápidas no alto do menu. */
.precs-chat-reacoes{ display: flex; flex-wrap: wrap; gap: var(--space-1); margin-top: var(--space-1); padding-right: var(--space-5); }
.precs-chat-reacao{ display: inline-flex; align-items: center; gap: var(--space-1); height: 22px; padding: 0 var(--space-2); border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: var(--bg-secondary); color: var(--text-secondary); font-family: var(--font-num); font-size: var(--fs-2); cursor: pointer; transition: transform var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1); }
.precs-chat-reacao:hover{ transform: translateY(-1px); border-color: var(--precs-gold); }
.precs-chat-reacao.minha{ border-color: var(--precs-gold); background: var(--precs-gold-light); color: var(--precs-gold-title); }
.precs-chat-menu-reacoes{ display: flex; gap: var(--space-0); padding: var(--space-1) var(--space-2) var(--space-2); margin-bottom: var(--space-1); border-bottom: 1px solid var(--border-color); }
.precs-chat-menu-reacoes button{ width: 30px; height: 30px; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--text-primary); font-size: var(--fs-6); cursor: pointer; transition: transform var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-chat-menu-reacoes button:hover{ transform: scale(1.25); background: var(--bg-tertiary); }
.precs-chat-menu-reacoes button.mais{ color: var(--text-secondary); font-family: var(--font-acao); }

/* O seletor de emoji: grade curada, rolável. */
.precs-chat-emoji{ width: 340px; max-height: 320px; overflow-y: auto; padding: var(--space-2); }
.precs-chat-emoji-grupo small{ display: block; padding: var(--space-1) var(--space-2); font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--ls-caps); }
.precs-chat-emoji-grade{ display: grid; grid-template-columns: repeat(8, 1fr); }
.precs-chat-emoji-grade button{ height: 36px; border: 0; border-radius: var(--radius-inner); background: transparent; font-size: var(--fs-7); cursor: pointer; transition: transform var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-chat-emoji-grade button:hover{ transform: scale(1.2); background: var(--bg-tertiary); }

/* A imagem na bolha e o visor. */
.precs-chat-img{ display: block; width: min(320px, 70vw); max-height: 360px; margin: var(--space-0) 0 var(--space-1); padding: 0; border: 0; border-radius: var(--radius-inner); overflow: hidden; background: color-mix(in srgb, var(--text-primary) 6%, transparent); cursor: zoom-in; }
.precs-chat-img img{ display: block; width: 100%; height: 100%; object-fit: cover; }
.precs-chat-img-espera{ display: block; width: 100%; height: 100%; }
@keyframes precsChatPulsa{ from{ opacity: .35; } to{ opacity: .7; } }
.precs-chat-img.carregando .precs-chat-img-espera{ animation: precsChatPulsa 1.2s var(--ease-1) infinite alternate; }
.precs-chat-img.falhou{ cursor: default; }
.precs-chat-img.falhou .precs-chat-img-espera{ display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-family: var(--font-rotulo); font-size: var(--fs-2); }
.precs-chat-visor{ position: fixed; inset: 0; width: 100vw; height: 100vh; max-width: none; max-height: none; margin: 0; padding: var(--space-5); border: 0; background: color-mix(in srgb, var(--bg-primary) 88%, transparent); cursor: zoom-out; }
.precs-chat-visor:popover-open{ display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-3); }
.precs-chat-visor img{ max-width: 100%; max-height: calc(100vh - 120px); border-radius: var(--radius-inner); box-shadow: var(--shadow-lg); cursor: default; }
.precs-chat-visor-pe{ display: flex; align-items: center; gap: var(--space-3); font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-secondary); cursor: default; }
.precs-chat-visor-pe a{ text-decoration: none; }

/* O cartão de contato: centrado (é o padrão do popover), com o fundo escurecido pelo ::backdrop. */
.precs-chat-contato{ position: relative; width: min(360px, 92vw); margin: auto; padding: var(--space-6) var(--space-5) var(--space-4); border: 1px solid var(--border-color); border-radius: var(--radius-card); background: var(--bg-secondary); color: var(--text-primary); box-shadow: var(--shadow-lg); text-align: center; }
.precs-chat-contato:popover-open{ display: flex; flex-direction: column; align-items: center; gap: var(--space-2); animation: precsChatLinhaEntra var(--dur-3) var(--ease-2) both; }
.precs-chat-contato::backdrop{ background: color-mix(in srgb, var(--bg-primary) 55%, transparent); }
.precs-chat-contato-x{ position: absolute; top: var(--space-2); right: var(--space-2); width: 28px; height: 28px; border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: transparent; color: var(--text-secondary); cursor: pointer; }
.precs-chat-contato-x:hover{ color: var(--accent-red); border-color: var(--accent-red); }
.precs-chat-contato-foto-wrap{ display: inline-flex; border-radius: var(--radius-pill); outline: 2px solid var(--precs-gold); outline-offset: 3px; margin-bottom: var(--space-2); }
.precs-chat-contato-foto{ width: 160px; height: 160px; border-radius: var(--radius-pill); object-fit: cover; font-size: var(--fs-11); }
.precs-chat-contato-nome{ font-family: var(--font-titulo); font-size: var(--fs-7); color: var(--text-primary); }
.precs-chat-contato-selos{ display: flex; gap: var(--space-2); justify-content: center; flex-wrap: wrap; }
.precs-chat-contato-linha{ display: flex; align-items: center; justify-content: center; gap: var(--space-2); font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-secondary); }
.precs-chat-contato-linha span{ color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--ls-caps); font-size: var(--fs-1); }
.precs-chat-contato-linha a{ color: var(--text-primary); text-decoration: none; }
.precs-chat-contato-linha a:hover{ color: var(--precs-gold-title); }
.precs-chat-contato-linha code{ font-family: var(--font-num); color: var(--text-primary); }
.precs-chat-contato-acoes{ margin-top: var(--space-2); }
@media (prefers-reduced-motion: reduce){ .precs-chat-img.carregando .precs-chat-img-espera{ animation: none; } .precs-chat-contato:popover-open{ animation: none; } }

/* ==========================================================================
   (1.1.126) O CHAT NO BOLSO, o histórico do grupo e o menu de mídia
   ========================================================================== */
/* `html[data-aparelho]` é o critério de celular do painel (largura <= 620 ou altura <= 480, precsAplicarAparelho),
   o mesmo que a vista de bolso das campanhas usa no lugar de @media. Uma coluna, uma coisa por vez (lista OU
   conversa, por data-chat-vista, como no painel lateral), o "voltar às salas" no cabeçalho, balões mais largos
   e os popovers no tamanho da tela. A parede de TV (data-tv) fica de fora. */
html[data-aparelho]:not([data-tv]) .precs-chat{ display: flex; flex-direction: column; height: calc(var(--precs-vv-h, 100dvh) - var(--precs-header-h, 64px)); min-height: 0; border-top: 0; }   /* (1.1.138) --precs-vv-h: a janela visual, que o teclado encolhe */
html[data-aparelho]:not([data-tv]) .precs-chat-trilho{ flex: 1 1 auto; border-right: 0; }
html[data-aparelho]:not([data-tv]) .precs-chat-palco{ flex: 1 1 auto; min-height: 0; }
html[data-aparelho]:not([data-tv]) .precs-chat-cab .precs-chat-voltar-lista{ display: inline-flex; }
html[data-aparelho]:not([data-tv])[data-chat-vista="thread"] .precs-chat-trilho{ display: none; }
html[data-aparelho]:not([data-tv])[data-chat-vista="lista"] .precs-chat-palco{ display: none; }
html[data-aparelho]:not([data-tv]) .precs-chat-fio{ padding: var(--space-3); }
html[data-aparelho]:not([data-tv]) .precs-chat-msg{ max-width: 90%; }
html[data-aparelho]:not([data-tv]) .precs-chat-compositor{ padding: var(--space-2) var(--space-3); }
html[data-aparelho]:not([data-tv]) .precs-chat-img{ width: min(260px, 72vw); }
html[data-aparelho]:not([data-tv]) .precs-chat-emoji{ width: min(340px, 94vw); }
html[data-aparelho]:not([data-tv]) .precs-chat-audio{ min-width: 200px; }
html[data-aparelho]:not([data-tv]) header{ padding: var(--space-2) var(--space-3); gap: var(--space-2); flex-wrap: wrap; }
html[data-aparelho]:not([data-tv]) .header-right{ gap: var(--space-2); flex-wrap: wrap; justify-content: flex-end; }
html[data-aparelho]:not([data-tv]) .precs-hub{ padding: var(--space-4) var(--space-3) var(--space-6); }
/* O interruptor do histórico nos Dados do grupo, e a nota para quem não é admin. */
.precs-chat-alterna{ display: inline-flex; align-items: center; gap: var(--space-2); margin-top: var(--space-1); font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-secondary); cursor: pointer; }
.precs-chat-alterna input{ accent-color: var(--precs-gold); }
.precs-chat-dados-nota{ color: var(--text-muted); }

/* ==========================================================================
   (1.1.127) O SINO DO PUSH e o APP NO BOLSO fora do chat
   ========================================================================== */
/* O sino herda a forma dos botões do trilho; `[hidden]` precisa vencer o display de autor daquela regra. */
.precs-chat-sino[hidden]{ display: none; }
.precs-chat-sino.on{ color: var(--precs-gold-title); border-color: var(--precs-gold); background: var(--precs-gold-light); }
/* Fora do chat, no celular: o header em duas linhas com a conta compacta, o hub e o Pessoas em UMA coluna,
   a entrada sem teto de largura. `html[data-aparelho]` é o critério de celular do painel (sem @media). */
html[data-aparelho]:not([data-tv]) .logo .precs-brand-logo{ width: 96px; height: auto; }
html[data-aparelho]:not([data-tv]) .user-info{ gap: var(--space-2); }
html[data-aparelho]:not([data-tv]) .user-details{ display: none; }
html[data-aparelho]:not([data-tv]):not([data-chat-cheio]) main{ padding: var(--space-3); gap: var(--space-4); }
html[data-aparelho]:not([data-tv]) .precs-hub{ padding: var(--space-4) var(--space-2) var(--space-6); }
html[data-aparelho]:not([data-tv]) .precs-hub-saudacao{ flex-wrap: wrap; }
html[data-aparelho]:not([data-tv]) .precs-hub-cartoes{ grid-template-columns: minmax(0, 1fr); }
html[data-aparelho]:not([data-tv]) .precs-pessoas-linha{ grid-template-columns: minmax(0, 1fr); }
html[data-aparelho]:not([data-tv]) #entrada-section{ max-width: none; }

/* ==========================================================================
   (1.1.129) Balões mais nítidos no celular; o selo da 3C escondido para quem não tem ramal
   ========================================================================== */
/* No celular o grafite do balão sumia no grafite do fundo ("deixar mais nítido os balões de conversa no celular,
   não dá para ver muito por causa do tema", o supervisor, 24/09/2026). Só no bolso: a estação continua igual. */
html[data-aparelho]:not([data-tv]) .precs-chat-bolha{ background: color-mix(in srgb, var(--text-primary) 9%, var(--bg-secondary)); border: 1px solid color-mix(in srgb, var(--text-primary) 16%, transparent); }
html[data-aparelho]:not([data-tv]) .precs-chat-msg.minha .precs-chat-bolha{ background: color-mix(in srgb, var(--precs-gold) 30%, var(--bg-secondary)); border-color: color-mix(in srgb, var(--precs-gold) 45%, transparent); }
html[data-aparelho]:not([data-tv]) .precs-chat-msg-hora{ color: var(--text-secondary); }
html[data-aparelho]:not([data-tv]) .precs-chat-dia span{ color: var(--text-primary); }
html[data-aparelho]:not([data-tv]) .precs-chat-sis span{ color: var(--text-primary); }
/* O selo de conexão do ramal (3C) não diz nada a quem entrou pela conta Google sem o discador. */
.status-badge.precs-sem-ramal{ display: none; }

/* ==========================================================================
   (1.1.131) O header do celular numa linha; transições e rolagem lisas; o hub vivo; o cartão do Pipedrive
   ========================================================================== */
/* O TOPO NUMA LINHA SÓ no celular ("os botões todos na mesma linha, alinhados à esquerda, e diminuir o
   Desconectado que pega todo o espaço", Pedro, 24/09/2026): logo menor, botões de 36px encostados à esquerda,
   a conta só com a foto, e o selo do ramal desconectado fora (no telefone ninguém opera o discador). */
html[data-aparelho]:not([data-tv]) header{ flex-wrap: nowrap; justify-content: flex-start; padding: var(--space-2) var(--space-3); gap: var(--space-3); }
html[data-aparelho]:not([data-tv]) .logo .precs-brand-logo{ width: 78px; }
html[data-aparelho]:not([data-tv]) .header-right{ flex: 1 1 auto; min-width: 0; flex-wrap: nowrap; justify-content: flex-start; gap: var(--space-1); }
html[data-aparelho]:not([data-tv]) .precs-theme-btn{ width: 36px; height: 36px; }
html[data-aparelho]:not([data-tv]) .user-info{ margin-left: auto; gap: var(--space-1); }
html[data-aparelho]:not([data-tv]) .precs-avatar{ width: 32px; height: 32px; }
html[data-aparelho]:not([data-tv]) .precs-conta-trocar{ padding: 0 var(--space-2); font-size: var(--fs-1); }
html[data-aparelho]:not([data-tv]) .status-badge{ font-size: var(--fs-1); padding: var(--space-1) var(--space-2); }
html[data-aparelho]:not([data-tv]) .status-badge.disconnected{ display: none; }
html[data-aparelho]:not([data-tv]) .precs-hub-cartao:hover:not(:disabled){ transform: none; }
/* Liso: a troca de tela com a curva da casa; a rolagem do fio e das listas sem "puxar" a página junto; sem o
   flash cinza do toque. Tudo respeita prefers-reduced-motion. */
.section.active{ animation-timing-function: var(--ease-2); }
.precs-chat-fio, .precs-chat-salas, .precs-chat-painel, .precs-chat-emoji{ overscroll-behavior: contain; scroll-behavior: smooth; }
html[data-aparelho]:not([data-tv]) *{ -webkit-tap-highlight-color: transparent; }
html[data-aparelho]:not([data-tv]) button, html[data-aparelho]:not([data-tv]) a{ touch-action: manipulation; }
/* O HUB VIVO: a estrela grande gira devagar e respira; a estrela de cada cartão pisca de vez em quando, cada uma
   no seu compasso (--i vem do JS). "Alguma animação cotidiana para a tela não ficar morta" (Pedro). */
@keyframes precsHubGira{ to{ transform: rotate(360deg); } }
@keyframes precsHubRespira{ from{ opacity: .05; } to{ opacity: .1; } }
@keyframes precsHubPisca{ 0%, 88%, 100%{ opacity: .7; transform: none; } 92%{ opacity: 1; transform: scale(1.35) rotate(25deg); } 96%{ opacity: .85; transform: scale(1.1) rotate(45deg); } }
/* (1.1.134) A estrela fica PARADA e reta ("não gostei, podem manter a estrela alinhada", Pedro, 24/09/2026); só
   respira. A vida passa para os cartões: um brilho atravessa cada um de vez em quando, no compasso de --i. */
.precs-hub-estrela{ animation: precsHubRespira 7s ease-in-out infinite alternate; }
.precs-hub-cartao{ overflow: hidden; }
.precs-hub-cartao::after{ content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: linear-gradient(115deg, transparent 42%, color-mix(in srgb, var(--precs-cartao-cor) 12%, transparent) 50%, transparent 58%);
  transform: translateX(-130%); animation: precsHubBrilho 16s var(--ease-1) infinite; animation-delay: calc(var(--i, 0) * 3.7s); }
@keyframes precsHubBrilho{ 0%, 78%{ transform: translateX(-130%); } 92%, 100%{ transform: translateX(130%); } }
.precs-hub-cartao .precs-hub-cartao-estrela svg{ animation: precsHubPisca 9s var(--ease-1) infinite; animation-delay: calc(var(--i, 0) * 2.3s); }
@media (prefers-reduced-motion: reduce){ .precs-hub-estrela, .precs-hub-cartao::after, .precs-hub-cartao .precs-hub-cartao-estrela svg{ animation: none; } }
/* O cartão do Pipedrive com detalhes recolhidos: a seta abre dono, funil, valor, organização e última mudança. */
.precs-chat-deal-caixa{ position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }
/* (1.1.132) A seta fica NA LINHA do cartão (nas capturas de todos os temas ela caía para baixo): com a base de
   flex em 0 o cartão encolhe com reticências e a seta cabe ao lado; os detalhes (100%) quebram para a linha de baixo. */
.precs-chat-deal-caixa .precs-chat-deal{ flex: 1 1 0; min-width: 0; }
.precs-chat-deal-caixa .precs-chat-deal-txt{ min-width: 0; }
.precs-chat-deal-caixa .precs-chat-deal-txt b, .precs-chat-deal-caixa .precs-chat-deal-txt small{ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-chat-deal-caixa .precs-chat-deal-detalhes{ flex-basis: 100%; }
.precs-chat-deal-mais{ display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex: 0 0 auto; border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; transition: transform var(--dur-2) var(--ease-2), color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1); }
.precs-chat-deal-mais:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-chat-deal-caixa.aberto .precs-chat-deal-mais{ transform: rotate(180deg); }
.precs-chat-deal-detalhes{ flex: 1 1 100%; width: 100%; display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-2); margin-top: var(--space-1); padding: var(--space-2); border: 1px solid var(--border-color); border-radius: var(--radius-inner); background: var(--bg-secondary); animation: precsChatLinhaEntra var(--dur-3) var(--ease-2) both; }
.precs-chat-deal-campo{ display: flex; flex-direction: column; gap: var(--space-0); min-width: 0; }
.precs-chat-deal-campo > span{ font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--ls-caps); }
.precs-chat-deal-campo b{ font-family: var(--font-acao); font-size: var(--fs-3); color: var(--text-primary); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-chat-deal-campo b small{ font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); font-weight: 400; }
.precs-chat-deal-dono{ display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; }
.precs-chat-deal-foto{ width: 26px; height: 26px; flex: 0 0 auto; border-radius: var(--radius-pill); object-fit: cover; font-size: var(--fs-2); }
.precs-chat-deal-etapas{ display: flex; gap: var(--space-0); margin-bottom: var(--space-0); }
.precs-chat-deal-etapas i{ display: block; flex: 1 1 0; height: 6px; border-radius: var(--radius-pill); background: var(--border-color); }
.precs-chat-deal-etapas i.feita{ background: color-mix(in srgb, var(--pipe-verde, var(--accent-green)) 55%, var(--border-color)); }
.precs-chat-deal-etapas i.atual{ background: var(--pipe-verde, var(--accent-green)); box-shadow: var(--shadow); }
.precs-chat-deal-ganho{ color: var(--accent-green-text); }
.precs-chat-deal-perdido{ color: var(--accent-red-text); }
@media (prefers-reduced-motion: reduce){ .precs-chat-deal-detalhes{ animation: none; } }

/* ==========================================================================
   (1.1.133) O menu da conversa, os filtros da lista, fixadas/silenciadas/arquivadas, filtros do Pessoas
   ========================================================================== */
.precs-chat-filtros{ display: flex; flex-wrap: wrap; gap: var(--space-1); padding: 0 var(--space-4) var(--space-2); }
.precs-chat-filtro{ display: inline-flex; align-items: center; gap: var(--space-1); height: 26px; padding: 0 var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: transparent; color: var(--text-secondary); font-family: var(--font-acao); font-size: var(--fs-2); cursor: pointer; transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-chat-filtro:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-chat-filtro.on{ background: var(--precs-gold-light); border-color: var(--precs-gold); color: var(--precs-gold-title); }
.precs-chat-filtro small{ font-family: var(--font-num); font-size: var(--fs-1); color: var(--text-muted); }
.precs-chat-filtro.on small{ color: var(--precs-gold-title); }
.precs-chat-filtro.mais{ width: 26px; padding: 0; justify-content: center; }
.precs-chat-filtro-x{ margin-left: var(--space-1); color: var(--text-muted); font-size: var(--fs-1); }
.precs-chat-filtro-x:hover{ color: var(--accent-red); }
/* Os filtros do Pessoas herdam as pílulas de área: a cor do setor vem de .precs-cor-N. */
.precs-pessoas-filtros{ padding: 0 0 var(--space-3); }
/* (1.1.140) O ouro só nos chips SEM setor (Todos, Admins, Ainda não entraram): nos de setor a cor é a do setor, e esta
   regra (0,3,0) vencia a classe .precs-cor-N (0,1,0) e pintava "Comercial" selecionado de dourado. */
.precs-pessoas-filtros .precs-chat-filtro.on:not([class*="precs-cor-"]){ --precs-cor: var(--precs-gold-title); }
.precs-pessoas-filtros .precs-chat-filtro[class*="precs-cor-"]{ color: var(--precs-cor); border-color: color-mix(in srgb, var(--precs-cor) 50%, var(--border-color)); }
.precs-pessoas-filtros .precs-chat-filtro[class*="precs-cor-"].on{ background: color-mix(in srgb, var(--precs-cor) 16%, transparent); border-color: var(--precs-cor); color: var(--precs-cor); }
/* A linha da sala como <div role=button>: o menu (⋯) aparece no hover (sempre no celular); fixada com o pino;
   silenciada com o sino cortado e o contador apagado. */
.precs-chat-sala{ position: relative; }
.precs-chat-sala-menu{ display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; flex: 0 0 auto; border: 1px solid transparent; border-radius: var(--radius-pill); background: transparent; color: var(--text-muted); cursor: pointer; opacity: 0; transition: opacity var(--dur-1) var(--ease-1), color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1); }
.precs-chat-sala:hover .precs-chat-sala-menu, .precs-chat-sala:focus-within .precs-chat-sala-menu, .precs-chat-sala-menu:focus-visible{ opacity: 1; }
.precs-chat-sala-menu:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
html[data-aparelho]:not([data-tv]) .precs-chat-sala-menu{ opacity: .7; }
.precs-chat-sala-selos{ display: inline-flex; align-items: center; gap: var(--space-1); }
.precs-chat-sala-pino, .precs-chat-sala-mudo{ color: var(--text-muted); }
.precs-chat-sala.fixada .precs-chat-sala-pino{ color: var(--precs-gold-title); }
.precs-chat-sala-badge.muda{ background: var(--bg-tertiary); color: var(--text-muted); }
.precs-chat-sala.muda .precs-chat-sala-txt small{ color: var(--text-muted); }
.precs-chat-arquivadas{ display: flex; align-items: center; gap: var(--space-2); width: 100%; padding: var(--space-3) var(--space-4); border: 0; border-bottom: 1px solid var(--border-color); background: transparent; color: var(--text-secondary); font-family: var(--font-acao); font-size: var(--fs-3); cursor: pointer; text-align: left; }
.precs-chat-arquivadas:hover{ color: var(--precs-gold-title); background: var(--bg-tertiary); }
.precs-chat-arquivadas small{ font-family: var(--font-num); font-size: var(--fs-2); color: var(--text-muted); }
.precs-chat-menu-sub{ padding: var(--space-2) var(--space-4) var(--space-0); font-family: var(--font-rotulo); font-size: var(--fs-1); color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--ls-caps); border-top: 1px solid var(--border-color); margin-top: var(--space-1); }

/* ==========================================================================
   (1.1.134) Hover das pílulas, o diálogo da lista, a imagem que falhou
   ========================================================================== */
.precs-hub-area{ transition: transform var(--dur-1) var(--ease-2), background var(--dur-1) var(--ease-1), box-shadow var(--dur-1) var(--ease-1); cursor: default; }
.precs-hub-area:hover{ transform: translateY(-1px) scale(1.05); background: color-mix(in srgb, var(--precs-cor) 28%, transparent); box-shadow: var(--shadow); }
@media (prefers-reduced-motion: reduce){ .precs-hub-area:hover{ transform: none; } }
.precs-chat-dialog{ text-align: left; }
.precs-chat-dialog:popover-open{ align-items: stretch; }
.precs-chat-dialog .precs-chat-contato-nome{ text-align: left; }
.precs-chat-dialog-txt{ margin: 0; font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-secondary); }
.precs-chat-dialog-txt em{ color: var(--precs-gold-title); font-style: normal; }
.precs-chat-dialog-inp{ width: 100%; padding: var(--space-2) var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-inner); background: var(--bg-tertiary); }
.precs-chat-dialog-inp:focus-visible{ outline: none; border-color: var(--precs-gold); }
.precs-chat-dialog-acoes{ display: flex; justify-content: flex-end; gap: var(--space-2); }
.precs-chat-img.falhou{ cursor: pointer; }
.precs-chat-img.falhou .precs-chat-img-espera{ padding: var(--space-3); text-align: center; }

/* ==========================================================================
   (1.1.135) Tiques nas minhas mensagens, a foto do hub que abre, Pessoas repaginado (coluna Acesso e o
   modal de permissões), voltar/Atualizar com ícone, filtro ativo nítido
   ========================================================================== */
/* OS TIQUES do WhatsApp: um traço é enviada; dois em cinza, alguém leu; dois em azul, todos os outros leram. */
.precs-chat-tique{ display: inline-flex; align-items: center; margin-left: var(--space-1); color: var(--text-muted); }
.precs-chat-tique svg{ display: block; }
.precs-chat-tique.lida{ color: var(--precs-paleta-1); }
.precs-chat-msg.minha .precs-chat-msg-hora{ display: inline-flex; align-items: center; }

/* A foto da saudação (e a da conta no header) é botão: cresce no hover e abre o visor. */
.precs-hub-foto-wrap{ display: inline-flex; flex: 0 0 auto; border-radius: var(--radius-pill); cursor: pointer; transition: transform var(--dur-2) var(--ease-2), filter var(--dur-1) var(--ease-1); }
.precs-hub-foto-wrap:hover, .precs-hub-foto-wrap:focus-visible{ transform: scale(1.06); filter: brightness(1.06); outline: none; }
.precs-hub-foto-wrap:focus-visible .precs-hub-foto{ outline-color: var(--precs-gold-title); }
.precs-conta .precs-avatar.precs-avatar-abre{ cursor: pointer; }
@media (prefers-reduced-motion: reduce){ .precs-hub-foto-wrap:hover{ transform: none; } }

/* PESSOAS: o topo, os botões com ícone, o hover da linha */
.precs-pessoas-topo{ gap: var(--space-2) var(--space-3); margin-bottom: var(--space-3); }
.precs-pessoas-voltar,
.precs-pessoas-btn{ display: inline-flex; align-items: center; gap: var(--space-1); height: 34px; padding: 0 var(--space-3); font-size: var(--fs-3); transition: color var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-pessoas-voltar{ background: transparent; }
.precs-pessoas-voltar svg{ transition: transform var(--dur-2) var(--ease-2); }
.precs-pessoas-voltar:hover svg{ transform: translateX(-3px); }
.precs-pessoas-voltar:hover,
.precs-pessoas-atualizar:hover:not(:disabled){ background: var(--precs-gold-light); }
.precs-pessoas-atualizar:disabled svg{ animation: precsPessoasGira .9s linear infinite; }
@keyframes precsPessoasGira{ to{ transform: rotate(360deg); } }
.precs-pessoas-linha:hover{ border-color: color-mix(in srgb, var(--precs-gold) 70%, var(--border-color)); background: color-mix(in srgb, var(--precs-gold) 6%, var(--bg-secondary)); box-shadow: var(--shadow); }
.precs-pessoas-linha:hover .precs-pessoas-nome b{ color: var(--precs-gold-title); }

/* A coluna ACESSO: o resumo é o botão que abre o modal */
.precs-pessoas-perm{ display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); width: 100%; min-height: 40px; padding: var(--space-1) var(--space-2); border: 1px dashed var(--border-color); border-radius: var(--radius-inner); background: transparent; color: var(--text-secondary); cursor: pointer; text-align: left; transition: border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-pessoas-perm:hover{ border-color: var(--precs-gold); border-style: solid; background: var(--bg-tertiary); }
.precs-pessoas-perm:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 1px; }
.precs-pessoas-resumo{ display: flex; flex-wrap: wrap; gap: var(--space-1); min-width: 0; }
.precs-pessoas-chip{ display: inline-flex; align-items: center; gap: var(--space-1); height: 22px; padding: 0 var(--space-2); border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: transparent; color: var(--text-muted); font-family: var(--font-rotulo); font-size: var(--fs-2); font-style: normal; white-space: nowrap; }
.precs-pessoas-chip::before{ content: ''; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--border-color); }
.precs-pessoas-chip.on{ border-color: var(--accent-green); background: var(--accent-green-light); color: var(--accent-green-text); }
.precs-pessoas-chip.on::before{ background: var(--accent-green); }
.precs-pessoas-chip.aviso{ border-color: var(--accent-red); background: var(--accent-red-light); color: var(--accent-red); }
.precs-pessoas-chip.aviso::before{ background: var(--accent-red); }
.precs-pessoas-chip.fora{ border-color: var(--precs-paleta-1); color: var(--precs-paleta-1); }
.precs-pessoas-chip.fora::before{ background: var(--precs-paleta-1); }
.precs-pessoas-perm-rot{ display: inline-flex; align-items: center; gap: var(--space-0); flex: 0 0 auto; font-family: var(--font-acao); font-size: var(--fs-2); color: var(--precs-gold-title); }
.precs-pessoas-perm-rot svg{ transition: transform var(--dur-1) var(--ease-2); }
.precs-pessoas-perm:hover .precs-pessoas-perm-rot svg{ transform: translateX(2px); }

/* O MODAL DE PERMISSÕES: cartas verdes (tem) ou transparentes (não tem) */
.precs-pessoas-perm-modal{ width: min(600px, 94vw); text-align: left; }
.precs-pessoas-perm-modal:popover-open{ align-items: stretch; gap: var(--space-3); }
.precs-pessoas-perm-quem{ display: flex; align-items: center; gap: var(--space-3); }
.precs-pessoas-perm-quem .precs-pessoas-foto{ width: 48px; height: 48px; font-size: var(--fs-7); }
.precs-pessoas-perm-quem > div{ display: flex; flex-direction: column; min-width: 0; }
.precs-pessoas-perm-quem small{ font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-pessoas-perm-sub{ margin-top: var(--space-1); font-family: var(--font-rotulo); font-size: var(--fs-2); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.precs-pessoas-cartas{ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
html[data-aparelho]:not([data-tv]) .precs-pessoas-cartas{ grid-template-columns: minmax(0, 1fr); }
.precs-pessoas-carta{ position: relative; display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-6) var(--space-3) var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-inner); background: transparent; color: var(--text-secondary); text-align: left; cursor: pointer; transition: border-color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1), transform var(--dur-1) var(--ease-2); }
.precs-pessoas-carta:hover:not(:disabled){ border-color: var(--text-muted); transform: translateY(-1px); }
.precs-pessoas-carta:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 2px; }
.precs-pessoas-carta:disabled{ cursor: default; }
.precs-pessoas-carta.travada{ opacity: .6; }
.precs-pessoas-carta-ico{ display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 38px; height: 38px; border-radius: var(--radius-pill); background: var(--bg-tertiary); color: var(--text-muted); transition: background var(--dur-1) var(--ease-1), color var(--dur-1) var(--ease-1); }
.precs-pessoas-carta-ico svg{ width: 20px; height: 20px; }
.precs-pessoas-carta-txt{ display: flex; flex-direction: column; gap: var(--space-0); min-width: 0; }
.precs-pessoas-carta-txt b{ font-family: var(--font-titulo); font-size: var(--fs-4); color: var(--text-primary); }
.precs-pessoas-carta-txt small{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-muted); }
.precs-pessoas-carta-marca{ position: absolute; top: var(--space-2); right: var(--space-2); display: inline-flex; width: 18px; height: 18px; border: 1px solid var(--border-color); border-radius: var(--radius-pill); color: transparent; transition: background var(--dur-1) var(--ease-1), border-color var(--dur-1) var(--ease-1), color var(--dur-1) var(--ease-1); }
.precs-pessoas-carta-marca svg{ width: 100%; height: 100%; }
/* (1.1.136) A carta acesa tem a COR DO CARTÃO DO HUB ("o comunicação interna é azul, então quando ativo ficar azul;
   Pessoas roxo", Pedro, 24/09/2026); Ativa e Fora do prédio ficam no verde de estado. */
.precs-pessoas-carta{ --precs-carta-cor: var(--accent-green); --precs-carta-tinta: var(--accent-green-text); }
.precs-pessoas-carta[data-f="chat"]{ --precs-carta-cor: var(--precs-paleta-1); --precs-carta-tinta: var(--precs-paleta-1); }
.precs-pessoas-carta[data-f="pessoas"]{ --precs-carta-cor: var(--precs-paleta-4); --precs-carta-tinta: var(--precs-paleta-4); }
.precs-pessoas-carta.on{ border-color: var(--precs-carta-cor); background: color-mix(in srgb, var(--precs-carta-cor) 12%, transparent); }
.precs-pessoas-carta.on .precs-pessoas-carta-ico{ background: color-mix(in srgb, var(--precs-carta-cor) 22%, transparent); color: var(--precs-carta-tinta); }
.precs-pessoas-carta.on .precs-pessoas-carta-txt small{ color: var(--text-secondary); }
.precs-pessoas-carta.on .precs-pessoas-carta-marca{ background: var(--precs-carta-cor); border-color: var(--precs-carta-cor); color: var(--precs-wa-tinta-ouro, var(--bg-primary)); }
.precs-pessoas-carta.pulsa{ animation: precsCartaPulsa var(--dur-3) var(--ease-2) both; }
.precs-pessoas-carta.pulsa .precs-pessoas-carta-marca{ animation: precsCartaMarca var(--dur-3) var(--ease-2) both; }
@keyframes precsCartaPulsa{ 0%{ transform: scale(1); } 40%{ transform: scale(1.03); } 100%{ transform: scale(1); } }
@keyframes precsCartaMarca{ 0%{ transform: scale(.6); } 60%{ transform: scale(1.25); } 100%{ transform: scale(1); } }
.precs-pessoas-perm-modal .precs-chat-dialog-acoes{ animation: precsPessoasEntra var(--dur-2) var(--ease-2) both; }
@media (prefers-reduced-motion: reduce){ .precs-pessoas-carta:hover:not(:disabled){ transform: none; } .precs-pessoas-atualizar:disabled svg{ animation: none; } .precs-pessoas-carta.pulsa, .precs-pessoas-carta.pulsa .precs-pessoas-carta-marca, .precs-pessoas-perm-modal .precs-chat-dialog-acoes{ animation: none; } }

/* O FILTRO ATIVO nítido ("as cores de filtro ativo ou não têm que ficar mais nítidas", Pedro, 24/09/2026):
   o ativo é preenchido (ouro, ou a cor do setor no Pessoas) com a tinta do fundo; o inativo é só contorno. */
.precs-chat-filtro{ color: var(--text-muted); }
.precs-chat-filtro:hover{ color: var(--text-primary); }
.precs-chat-filtro.on,
.precs-chat-filtro.on:hover{ background: var(--precs-gold); border-color: var(--precs-gold); color: var(--precs-wa-tinta-ouro, var(--bg-primary)); font-weight: 600; }
.precs-chat-filtro.on small,
.precs-chat-filtro.on .precs-chat-filtro-x{ color: inherit; opacity: .85; }
.precs-pessoas-filtros .precs-chat-filtro[class*="precs-cor-"]{ color: var(--precs-cor); }
.precs-pessoas-filtros .precs-chat-filtro[class*="precs-cor-"].on{ background: var(--precs-cor); border-color: var(--precs-cor); color: var(--bg-primary); }

/* ==========================================================================
   (1.1.136) SAÍDA ANIMADA de tudo que entra animado, e o hover dos membros do grupo
   ========================================================================== */
/* Os popovers (menu, emoji, menção, contato, diálogos, permissões) entram com precsChatLinhaEntra; com `saindo`
   (posto por precsPopEsconder, que espera o animationend) fazem o caminho de volta. O visor da imagem ganhou
   a entrada que não tinha, e a saída. O painel "Dados do grupo" entra da direita e agora sai para a direita. */
@keyframes precsChatSai{ from{ opacity: 1; transform: none; } to{ opacity: 0; transform: translateY(6px); } }
@keyframes precsChatVisorEntra{ from{ opacity: 0; } to{ opacity: 1; } }
@keyframes precsChatVisorSai{ from{ opacity: 1; } to{ opacity: 0; } }
@keyframes precsChatPainelSai{ from{ opacity: 1; transform: none; } to{ opacity: 0; transform: translateX(14px); } }
.precs-chat-contato.saindo:popover-open,
.precs-chat-menu.saindo:popover-open{ animation: precsChatSai var(--dur-2) var(--ease-1) both; }
.precs-chat-visor:popover-open{ animation: precsChatVisorEntra var(--dur-2) var(--ease-2) both; }
.precs-chat-visor.saindo:popover-open{ animation: precsChatVisorSai var(--dur-2) var(--ease-1) both; }
.precs-chat-painel.saindo:not([hidden]){ animation: precsChatPainelSai var(--dur-2) var(--ease-1) both; }
@media (prefers-reduced-motion: reduce){
  .precs-chat-contato.saindo:popover-open, .precs-chat-menu.saindo:popover-open, .precs-chat-visor:popover-open,
  .precs-chat-visor.saindo:popover-open, .precs-chat-painel.saindo:not([hidden]){ animation: none; }
}
/* O hover de um membro em "Dados do grupo": a faixa inteira, sem moldura, e o foco só pelo teclado. */
.precs-chat-painel-lista .precs-chat-sala.membro{ border-radius: 0; margin: 0; outline: none; }
.precs-chat-painel-lista .precs-chat-sala.membro:hover{ background: color-mix(in srgb, var(--precs-gold) 9%, transparent); }
.precs-chat-painel-lista .precs-chat-sala.membro:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: -2px; }

/* ==========================================================================
   (1.1.137) iPhone sem zoom no campo, área segura, a barra do áudio em dois modos, a prévia da imagem
   ========================================================================== */
/* O Safari do iPhone dá zoom em campo com fonte menor que 16px ao focar: no celular os campos de texto do chat e
   do Pessoas usam --fs-8 (16px). E o compositor respeita a barra de gestos (área segura) de baixo. */
html[data-aparelho]:not([data-tv]) .precs-chat-inp,
html[data-aparelho]:not([data-tv]) .precs-chat-busca,
html[data-aparelho]:not([data-tv]) .precs-chat-dialog-inp,
html[data-aparelho]:not([data-tv]) .precs-pessoas-inp,
html[data-aparelho]:not([data-tv]) .precs-pessoas-busca{ font-size: var(--fs-8); }
html[data-aparelho]:not([data-tv]) .precs-chat-compositor{ padding-bottom: calc(var(--space-2) + env(safe-area-inset-bottom, 0px)); }
/* A barra do áudio: GRAVANDO (onda vermelha ao vivo) e PRONTO (ouvir; a onda se enche de ouro com o progresso). */
.precs-chat-grav-onda{ display: inline-flex; align-items: center; gap: var(--space-0); height: 28px; flex: 1 1 auto; min-width: 0; overflow: hidden; color: var(--text-muted); }
.precs-chat-grav-onda i{ display: block; width: 3px; flex: 0 0 auto; height: calc(4px + 22px * var(--n, .1)); border-radius: var(--radius-pill); background: currentColor; transition: height var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-chat-grav[data-modo="gravando"] .precs-chat-grav-onda{ color: var(--accent-red); }
.precs-chat-grav-onda i.feita{ background: var(--precs-gold); }
.precs-chat-grav-play{ width: 36px; height: 36px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; border: 1px solid var(--precs-gold); border-radius: var(--radius-pill); background: var(--precs-gold-light); color: var(--precs-gold-title); cursor: pointer; transition: background var(--dur-1) var(--ease-1); }
.precs-chat-grav-play:hover{ background: var(--precs-gold); color: var(--precs-wa-tinta-ouro, var(--bg-primary)); }
.precs-chat-grav-play svg.pausa{ display: none; }
.precs-chat-grav-play.tocando svg.toca{ display: none; }
.precs-chat-grav-play.tocando svg.pausa{ display: block; }
.precs-chat-grav-rot{ font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--text-muted); white-space: nowrap; }
.precs-chat-grav audio{ display: none; }
.precs-chat-grav[data-modo="pronto"]{ animation: precsChatLinhaEntra var(--dur-2) var(--ease-2) both; }
html[data-aparelho]:not([data-tv]) .precs-chat-grav-rot{ display: none; }
/* No celular a barra do áudio precisa da largura toda: somem o clipe, o emoji e (no modo pronto) o microfone; o
   "descartar" vira só o ícone. */
html[data-aparelho]:not([data-tv]) .precs-chat-compositor:has(.precs-chat-grav:not([hidden])) #precs-chat-anexo-btn,
html[data-aparelho]:not([data-tv]) .precs-chat-compositor:has(.precs-chat-grav:not([hidden])) #precs-chat-emoji-btn,
html[data-aparelho]:not([data-tv]) .precs-chat-compositor:has(.precs-chat-grav[data-modo="pronto"]) #precs-chat-mic{ display: none; }
.precs-chat-grav-descartar{ display: inline-flex; align-items: center; gap: var(--space-1); }
html[data-aparelho]:not([data-tv]) .precs-chat-grav-descartar span{ display: none; }
/* A prévia da imagem, acima do compositor, com o campo virando a legenda. */
.precs-chat-previa{ display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-4) 0; animation: precsChatLinhaEntra var(--dur-2) var(--ease-2) both; }
.precs-chat-previa[hidden]{ display: none; }
.precs-chat-previa img{ width: 56px; height: 56px; flex: 0 0 auto; object-fit: cover; border: 1px solid var(--border-color); border-radius: var(--radius-inner); }
.precs-chat-previa span{ flex: 1 1 auto; min-width: 0; font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-secondary); }
.precs-chat-previa span b{ color: var(--text-primary); }
@media (prefers-reduced-motion: reduce){ .precs-chat-grav-onda i{ transition: none; } .precs-chat-grav[data-modo="pronto"], .precs-chat-previa{ animation: none; } }

/* ==========================================================================
   (1.1.138) O chat no celular com a cara do WhatsApp: balão enxuto, fonte de 17px, direta sem nome e sem foto
   ========================================================================== */
html[data-aparelho]:not([data-tv]) .precs-chat-bolha{ padding: var(--space-2) var(--space-5) var(--space-3) var(--space-3); font-size: var(--fs-9); }
html[data-aparelho]:not([data-tv]) .precs-chat-msg-txt{ font-size: var(--fs-9); }
html[data-aparelho]:not([data-tv]) .precs-chat-msg-autor{ font-size: var(--fs-4); }
html[data-aparelho]:not([data-tv]) .precs-chat-msg-hora{ font-size: var(--fs-2); right: var(--space-2); }
html[data-aparelho]:not([data-tv]) .precs-chat-msg{ gap: var(--space-1); }
html[data-aparelho]:not([data-tv]) .precs-chat-fio{ gap: var(--space-1); }
/* Na conversa direta a foto sai da linha (o nome já saiu do balão, no app.js) e o balão ganha a largura dela. */
.precs-chat-fio[data-tipo="dm"] .precs-chat-msg-foto{ display: none; }

/* ==========================================================================
   (1.1.139) O envio otimista: a provisória (relógio) e a que falhou (alerta + tentar de novo)
   ========================================================================== */
.precs-chat-tique.pendente{ color: var(--text-muted); opacity: .8; }
.precs-chat-tique.falhou{ color: var(--accent-red); }
.precs-chat-msg.pendente .precs-chat-bolha{ opacity: .78; }
.precs-chat-msg.falhou{ cursor: pointer; }
.precs-chat-msg.falhou .precs-chat-bolha{ border: 1px solid var(--accent-red); }
.precs-chat-msg-falha{ margin-top: var(--space-1); font-family: var(--font-rotulo); font-size: var(--fs-2); color: var(--accent-red); }

/* ==========================================================================
   (1.1.140) O olhinho da senha
   ========================================================================== */
.precs-senha-caixa{ position: relative; }
.precs-senha-caixa input{ padding-right: 44px; }
.precs-senha-olho{ position: absolute; top: 50%; right: var(--space-2); transform: translateY(-50%); width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--text-muted); cursor: pointer; transition: color var(--dur-1) var(--ease-1), background var(--dur-1) var(--ease-1); }
.precs-senha-olho:hover{ color: var(--precs-gold-title); background: var(--precs-gold-light); }
.precs-senha-olho .olho-fechado{ display: none; }
.precs-senha-olho.on .olho-aberto{ display: none; }
.precs-senha-olho.on .olho-fechado{ display: block; }
.precs-senha-olho.on{ color: var(--precs-gold-title); }

/* ==========================================================================
   (1.1.141) A FIGURINHA: WebP de até 512px, sem balão, como no WhatsApp
   ========================================================================== */
.precs-chat-msg.figurinha .precs-chat-bolha{ background: transparent; border: 0; padding: 0 0 var(--space-4) 0; }
.precs-chat-msg.figurinha .precs-chat-img{ width: 160px; max-width: 60vw; border-radius: var(--radius-inner); background: transparent; }
.precs-chat-msg.figurinha .precs-chat-img img{ object-fit: contain; }
.precs-chat-msg.figurinha .precs-chat-msg-hora{ right: 0; }
.precs-chat-msg.figurinha .precs-chat-msg-menu{ right: 0; }
html[data-aparelho]:not([data-tv]) .precs-chat-msg.figurinha .precs-chat-bolha{ background: transparent; border: 0; }

/* ==========================================================================
   (1.1.142) O CELULAR NÃO ANDA DE LADO NEM DÁ ZOOM NO TOQUE DUPLO
   `overflow-x: clip` no <html> (o body já tinha, e o iPhone rola a raiz, não o body) e `touch-action:
   manipulation`, que tira o zoom do toque duplo sem tirar a pinça (acessibilidade). O que sobrava de largura
   vinha dos painéis da supervisão, corrigidos no 10-supervisao.css.
   ========================================================================== */
html[data-aparelho]:not([data-tv]){ overflow-x: clip; touch-action: manipulation; }

/* ==========================================================================
   (1.1.143) CONSUMO PIPEDRIVE: a tela das três abas. Cartões, o número grande, as barras em DOM.
   Tudo em token; os gráficos são colunas de DOM (o mesmo desenho em qualquer máquina, e o teste mede).
   ========================================================================== */
/* (1.1.143 -> 1.1.147) CONSUMO PIPEDRIVE, reescrito. O Painel ganhou um hero (anel do orcamento, numero que cresce,
   tiles com icone), as secoes entram em cascata quando a tela abre ou troca de aba (`.entra`, posta pelo JS e
   retirada no refresh de um minuto), as barras sobem e a linha do saldo se traca. Tudo sai de token; nenhuma
   duracao canonica a mao; `prefers-reduced-motion` desliga o movimento inteiro. As classes que o Casos do
   Calculo usa (kpi, selos, ficha, caso, tabela, det, notas) seguem aqui com o mesmo nome. */
.precs-consumo{ max-width: 1180px; margin: 0 auto; }
.precs-consumo-abas{ flex: 0 1 auto; }
.precs-consumo-aba{ display: inline-flex; align-items: center; gap: var(--space-2); height: var(--space-8); padding: 0 var(--space-4); font-size: var(--fs-5); transition: background var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1), transform var(--dur-2) var(--ease-2); }
.precs-consumo-aba svg{ flex: 0 0 auto; transition: transform var(--dur-3) var(--ease-2); }
.precs-consumo-aba.on svg{ transform: scale(1.15); }
.precs-consumo-corpo{ display: flex; flex-direction: column; gap: var(--space-4); container-type: inline-size; }
.precs-consumo-cab{ display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.precs-consumo-rotulo{ font-family: var(--font-rotulo); font-size: var(--fs-3); font-weight: 700; letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.precs-consumo-h{ font-family: var(--font-titulo); font-size: calc(var(--fs-11) * 1.3); font-weight: 700; color: var(--text-primary); margin: 0; }
.precs-consumo-sub{ font-family: var(--font-corpo); font-size: var(--fs-7); color: var(--text-secondary); max-width: 70ch; margin: 0; }
.precs-consumo-sub2{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-muted); }
.precs-consumo-meta{ display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-secondary); }
.precs-consumo-meta b{ color: var(--text-muted); font-weight: 600; margin-right: var(--space-1); }
.precs-consumo-idade{ font-style: normal; margin-left: var(--space-1); color: var(--text-muted); }
.precs-consumo-idade.velha{ color: var(--accent-orange); }
.precs-consumo-idade.morta{ color: var(--accent-red); }
.precs-consumo-reserva{ color: var(--accent-orange); }
.precs-consumo-controles{ display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.precs-consumo-seg{ display: inline-flex; gap: var(--space-1); }
.precs-consumo-seg-btn{ font-family: var(--font-acao); font-size: var(--fs-5); font-weight: 600; padding: var(--space-2) var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: var(--bg-secondary); color: var(--text-secondary); cursor: pointer; transition: background var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1); }
.precs-consumo-seg-btn:hover{ color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-consumo-seg-btn.on{ background: var(--precs-gold-light); color: var(--precs-gold-title); border-color: var(--precs-gold); }
.precs-consumo-seg-btn:disabled{ opacity: .5; cursor: default; }
.precs-consumo-campo{ display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-rotulo); font-size: var(--fs-3); font-weight: 700; text-transform: uppercase; letter-spacing: var(--ls-caps); color: var(--text-muted); }
.precs-consumo-campo select{ font-family: var(--font-corpo); font-size: var(--fs-6); text-transform: none; letter-spacing: 0; padding: var(--space-2) var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-inner); background: var(--bg-secondary); color: var(--text-primary); }
.precs-consumo-busca{ flex: 1 1 260px; }
.precs-consumo-linha-nota{ font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-muted); margin-left: auto; text-align: right; }
.precs-consumo-grade{ display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: var(--space-4); }
.precs-consumo-card{ background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: var(--radius-card); padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; transition: border-color var(--dur-2) var(--ease-1); }
.precs-consumo-card:hover{ border-color: color-mix(in srgb, var(--precs-gold) 45%, var(--border-color)); }
.precs-consumo-card-topo{ display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.precs-consumo-card-cab{ display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.precs-consumo-card-ico{ flex: 0 0 auto; width: var(--space-8); height: var(--space-8); display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-inner); background: color-mix(in srgb, var(--precs-sec-cor, var(--precs-gold)) 18%, transparent); color: var(--precs-sec-cor, var(--precs-gold-title)); }
.precs-consumo-card-tit{ font-family: var(--font-titulo); font-size: var(--fs-10); font-weight: 700; color: var(--precs-gold-title); }
/* o hero */
.precs-consumo-hero{ display: grid; grid-template-columns: auto minmax(0, 1fr) minmax(260px, 34%); gap: var(--space-6); align-items: center; padding: var(--space-6); border: 1px solid var(--border-color); border-radius: var(--radius-card);
  background: linear-gradient(135deg, color-mix(in srgb, var(--precs-gold) 10%, var(--bg-secondary)), var(--bg-secondary) 55%); }
.precs-consumo-hero.metade{ background: linear-gradient(135deg, color-mix(in srgb, var(--accent-orange) 9%, var(--bg-secondary)), var(--bg-secondary) 55%); }
.precs-consumo-hero.atencao{ background: linear-gradient(135deg, color-mix(in srgb, var(--accent-red) 10%, var(--bg-secondary)), var(--bg-secondary) 55%); }
.precs-consumo-hero-anel{ display: flex; justify-content: center; }
.precs-consumo-anel{ position: relative; width: 168px; height: 168px; flex: 0 0 auto; }
.precs-consumo-anel svg{ width: 100%; height: 100%; display: block; }
.precs-consumo-anel-trilho{ fill: none; stroke: var(--bg-tertiary); stroke-width: 9; }
.precs-consumo-anel-arco{ fill: none; stroke: var(--precs-gold-title); stroke-width: 9; stroke-linecap: round; transform: rotate(-90deg); transform-origin: 50% 50%; transition: stroke-dashoffset 1.1s var(--ease-2); }
.precs-consumo-anel.metade .precs-consumo-anel-arco{ stroke: var(--accent-orange); }
.precs-consumo-anel.atencao .precs-consumo-anel-arco{ stroke: var(--accent-red); }
.precs-consumo-anel-miolo{ position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-0); text-align: center; }
.precs-consumo-num{ font-family: var(--font-num); font-variant-numeric: tabular-nums; font-size: calc(var(--fs-11) * 1.5); font-weight: 700; color: var(--text-primary); line-height: 1; }
.precs-consumo-anel-rot{ font-family: var(--font-rotulo); font-size: var(--fs-3); font-weight: 700; letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.precs-consumo-hero-meio{ display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.precs-consumo-hero-topo{ display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.precs-consumo-hero-num{ display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; }
.precs-consumo-hero-num b{ font-family: var(--font-num); font-variant-numeric: tabular-nums; font-size: calc(var(--fs-11) * 2.1); font-weight: 700; color: var(--text-primary); line-height: 1; }
.precs-consumo-hero-num span{ font-family: var(--font-rotulo); font-size: var(--fs-6); color: var(--text-muted); }
.precs-consumo-estado{ display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-rotulo); font-size: var(--fs-3); font-weight: 700; letter-spacing: var(--ls-caps); padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); background: var(--bg-tertiary); color: var(--text-muted); }
.precs-consumo-estado i{ width: var(--space-2); height: var(--space-2); border-radius: var(--radius-pill); background: currentColor; animation: precsConsumoPulsa 2.2s ease-in-out infinite; }
.precs-consumo-estado.folga{ color: var(--accent-green); }
.precs-consumo-estado.metade{ color: var(--accent-orange); }
.precs-consumo-estado.atencao{ color: var(--accent-red); }
.precs-consumo-trilho{ height: var(--space-2); border-radius: var(--radius-pill); background: var(--bg-tertiary); overflow: hidden; display: flex; }
.precs-consumo-trilho-atrib{ height: 100%; background: var(--precs-paleta-6); border-radius: var(--radius-pill); transform-origin: left center; transition: width .7s var(--ease-2); }
.precs-consumo-trilho-rot{ display: flex; justify-content: space-between; font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-muted); }
.precs-consumo-fatias{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-0); font-family: var(--font-rotulo); font-size: var(--fs-6); color: var(--text-secondary); }
.precs-consumo-fatias li{ display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) var(--space-2); margin: 0 calc(-1 * var(--space-2)); border-radius: var(--radius-sm); cursor: pointer; transition: background var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1); }
.precs-consumo-fatias li:hover{ background: color-mix(in srgb, var(--precs-gold) 10%, transparent); color: var(--text-primary); }
.precs-consumo-fatias li.on{ color: var(--text-primary); background: var(--precs-gold-light); }
.precs-consumo-fatias li span{ flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.precs-consumo-fatias li b{ font-family: var(--font-num); font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text-primary); }
.precs-consumo-fatia-cor{ display: inline-block; width: var(--space-3); height: var(--space-3); border-radius: var(--radius-sm); vertical-align: middle; background: var(--precs-paleta-6); flex: 0 0 auto; }
.precs-consumo-tabela .precs-consumo-fatia-cor{ margin-right: var(--space-2); }
.precs-consumo-fatia-cor[style*="--slot:1"], .precs-consumo-fatia-cor[style*="--slot:2"]{ background: var(--precs-paleta-5); }
.precs-consumo-fatia-cor[style*="--slot:3"], .precs-consumo-fatia-cor[style*="--slot:4"]{ background: var(--text-muted); }
.precs-consumo-fatia-cor[style*="--slot:5"]{ background: var(--precs-paleta-1); }
.precs-consumo-hero-kpis, .precs-consumo-tiles{ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
.precs-consumo-tiles{ grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); flex: 1 1 auto; }
.precs-consumo-tile{ display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-inner); background: var(--bg-primary); min-width: 0; transition: transform var(--dur-3) var(--ease-2), border-color var(--dur-2) var(--ease-1); }
.precs-consumo-tile:hover{ transform: translateY(-2px); border-color: color-mix(in srgb, var(--precs-gold) 50%, var(--border-color)); }
.precs-consumo-tile-ico{ flex: 0 0 auto; width: var(--space-8); height: var(--space-8); display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-pill); background: var(--precs-gold-light); color: var(--precs-gold-title); }
.precs-consumo-tile.bom .precs-consumo-tile-ico{ background: color-mix(in srgb, var(--accent-green) 18%, transparent); color: var(--accent-green); }
.precs-consumo-tile.alerta .precs-consumo-tile-ico{ background: color-mix(in srgb, var(--accent-orange) 18%, transparent); color: var(--accent-orange); }
.precs-consumo-tile-txt{ display: flex; flex-direction: column; gap: var(--space-0); min-width: 0; }
.precs-consumo-tile b{ font-family: var(--font-num); font-variant-numeric: tabular-nums; font-size: calc(var(--fs-11) * 1.15); font-weight: 700; color: var(--text-primary); line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.precs-consumo-tile b small{ font-family: var(--font-rotulo); font-size: var(--fs-4); font-weight: 600; color: var(--text-muted); margin-left: var(--space-0); }
.precs-consumo-tile-txt > span{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-muted); }   /* (1.1.153) `>`: o span da contagem dentro do <b> herdava isto e o numero saia pequeno */
.precs-consumo-tile em{ font-style: normal; font-weight: 700; }
.precs-consumo-tile em.bom{ color: var(--accent-green); }
.precs-consumo-tile em.ruim{ color: var(--accent-red); }
/* os kpis do Casos do Calculo (a grade antiga, que a aba de casos ainda usa) */
.precs-consumo-kpis{ display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-3); }
.precs-consumo-kpi{ display: flex; flex-direction: column; gap: var(--space-1); padding: var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-inner); background: var(--bg-primary); min-width: 0; }
.precs-consumo-kpi b{ font-family: var(--font-num); font-variant-numeric: tabular-nums; font-size: var(--fs-11); font-weight: 700; color: var(--text-primary); }
.precs-consumo-kpi b.txt{ font-family: var(--font-corpo); font-size: var(--fs-5); }
.precs-consumo-kpi span{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-muted); }
.precs-consumo-kpi span.bom{ color: var(--accent-green); }
.precs-consumo-kpi span.ruim{ color: var(--accent-red); }
.precs-consumo-chips{ display: flex; gap: var(--space-2); flex-wrap: wrap; }
.precs-consumo-chip{ font-family: var(--font-rotulo); font-size: var(--fs-3); font-weight: 700; letter-spacing: var(--ls-caps); text-transform: uppercase; padding: var(--space-1) var(--space-2); border-radius: var(--radius-pill); background: var(--bg-tertiary); color: var(--text-secondary); }
.precs-consumo-chip.pico{ background: var(--precs-gold-light); color: var(--precs-gold-title); }
.precs-consumo-chip.agora{ background: color-mix(in srgb, var(--precs-paleta-1) 18%, transparent); color: var(--precs-paleta-1); }
/* as barras */
.precs-consumo-barras, .precs-consumo-ciclos{ display: flex; align-items: flex-end; gap: var(--space-1); height: 180px; }
.precs-consumo-col, .precs-consumo-ciclo{ flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: stretch; height: 100%; border: 0; background: transparent; padding: 0; color: inherit; cursor: default; }
.precs-consumo-ciclo{ cursor: pointer; border-radius: var(--radius-sm); transition: background var(--dur-2) var(--ease-1); }
.precs-consumo-ciclo:hover{ background: color-mix(in srgb, var(--precs-gold) 8%, transparent); }
.precs-consumo-col-trilha{ flex: 1 1 auto; display: flex; align-items: flex-end; }
.precs-consumo-col-barra{ width: 100%; background: var(--precs-gold-forma, var(--precs-gold)); border-radius: var(--radius-inner) var(--radius-inner) 0 0; min-height: 1px; transform-origin: bottom center; transition: height var(--dur-3) var(--ease-2), background var(--dur-2) var(--ease-1); }
.precs-consumo-col:hover .precs-consumo-col-barra{ background: var(--precs-gold-hi, var(--precs-gold-title)); }
.precs-consumo-col.pico .precs-consumo-col-barra, .precs-consumo-ciclo.on .precs-consumo-col-barra{ background: var(--precs-gold-hi, var(--precs-gold-title)); }
.precs-consumo-col.agora .precs-consumo-col-barra{ background: var(--precs-paleta-1); }
.precs-consumo-ciclo.aberto .precs-consumo-col-barra{ opacity: .7; }
.precs-consumo-col-rot{ font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); text-align: center; margin-top: var(--space-1); white-space: nowrap; overflow: hidden; }
.precs-consumo-barras.horas .precs-consumo-col:nth-child(even) .precs-consumo-col-rot{ visibility: hidden; }
.precs-consumo-rodape{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-muted); }
.precs-consumo-vazio{ padding: var(--space-6); text-align: center; font-family: var(--font-rotulo); color: var(--text-muted); }
.precs-consumo-nota{ font-family: var(--font-corpo); font-size: var(--fs-6); color: var(--text-secondary); margin: 0; padding: var(--space-3); border-left: 3px solid var(--precs-gold); background: var(--bg-tertiary); border-radius: var(--radius-sm); }
/* as tabelas */
.precs-consumo-tabela{ width: 100%; border-collapse: collapse; font-family: var(--font-corpo); font-size: var(--fs-6); }
.precs-consumo-tabela th{ text-align: left; font-family: var(--font-rotulo); font-size: var(--fs-3); font-weight: 700; letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); padding: var(--space-2); border-bottom: 1px solid var(--border-color); }
.precs-consumo-tabela td{ padding: var(--space-2); border-bottom: 1px solid var(--border-color); vertical-align: top; color: var(--text-secondary); transition: background var(--dur-2) var(--ease-1); }
.precs-consumo-tabela tbody tr:hover td{ background: color-mix(in srgb, var(--precs-gold) 6%, transparent); }
.precs-consumo-tabela td b{ color: var(--text-primary); }
.precs-consumo-tabela .num, .precs-consumo-tabela th.num{ text-align: right; font-family: var(--font-num); font-variant-numeric: tabular-nums; }
.precs-consumo-tabela tr.cust td{ color: var(--text-primary); }
.precs-consumo-tabela code{ font-family: var(--font-num); font-size: var(--fs-5); color: var(--precs-gold-title); }
.precs-consumo-fin{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-muted); }
.precs-consumo-selo{ font-family: var(--font-rotulo); font-size: var(--fs-3); font-weight: 700; padding: var(--space-0) var(--space-2); border-radius: var(--radius-pill); background: var(--bg-tertiary); color: var(--text-muted); white-space: nowrap; }
.precs-consumo-selo.pessoal{ color: var(--accent-orange); }
.precs-consumo-selo.disponivel{ color: var(--accent-green); }
.precs-consumo-selo.nao_contratado, .precs-consumo-selo.vazio{ color: var(--text-muted); }
.precs-consumo-det{ border-top: 1px solid var(--border-color); padding: var(--space-2) 0; }
.precs-consumo-det summary{ cursor: pointer; font-family: var(--font-acao); font-weight: 600; color: var(--text-primary); }
/* o mapa */
.precs-consumo-mapa-topo{ display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: stretch; }
.precs-consumo-kit{ flex: 1 1 360px; display: flex; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-5); border: 1px solid var(--precs-gold); border-radius: var(--radius-card); text-decoration: none; color: var(--text-primary);
  background: linear-gradient(135deg, color-mix(in srgb, var(--precs-gold) 16%, var(--bg-secondary)), var(--bg-secondary)); transition: transform var(--dur-3) var(--ease-2), border-color var(--dur-2) var(--ease-1); }
.precs-consumo-kit:hover{ transform: translateY(-2px); border-color: var(--precs-gold-hi, var(--precs-gold-title)); }
.precs-consumo-kit:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 2px; }
.precs-consumo-kit-ico{ flex: 0 0 auto; width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-pill); background: var(--precs-gold-light); color: var(--precs-gold-title); }
.precs-consumo-kit-txt{ display: flex; flex-direction: column; gap: var(--space-0); min-width: 0; flex: 1 1 auto; }
.precs-consumo-kit-txt b{ font-family: var(--font-titulo); font-size: var(--fs-10); font-weight: 700; color: var(--precs-gold-title); }
.precs-consumo-kit-txt span{ font-family: var(--font-corpo); font-size: var(--fs-6); color: var(--text-secondary); }
.precs-consumo-kit-btn{ flex: 0 0 auto; font-family: var(--font-acao); font-size: var(--fs-6); font-weight: 700; padding: var(--space-2) var(--space-4); border-radius: var(--radius-pill); background: var(--precs-gold-forma, var(--precs-gold)); color: var(--precs-wa-tinta-ouro); white-space: nowrap; }
/* o mapa de calor, o saldo, as origens, os casos e a ficha */
.precs-consumo-calor{ display: flex; flex-direction: column; gap: var(--space-0); overflow-x: auto; }
.precs-consumo-calor-linha{ display: grid; grid-template-columns: 56px repeat(24, minmax(10px, 1fr)); gap: var(--space-0); align-items: center; }
.precs-consumo-calor-rot, .precs-consumo-calor-h{ font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); white-space: nowrap; }
.precs-consumo-calor-h{ text-align: left; }
.precs-consumo-calor-cel{ display: block; aspect-ratio: 1.6; border-radius: var(--space-0); border: 1px solid var(--border-color); background: transparent; outline: 1px solid transparent; outline-offset: -1px; transition: filter var(--dur-2) var(--ease-1), outline-color var(--dur-2) var(--ease-1); }
.precs-consumo-calor-cel:hover{ filter: brightness(1.3); outline-color: var(--precs-gold-hi, var(--precs-gold-title)); }   /* (1.1.148) era scale(1.25): o overflow-x: auto ganhava barra e a grade encolhia e crescia no hover */
.precs-consumo-calor-cel.q1{ background: color-mix(in srgb, var(--precs-gold) 18%, transparent); }
.precs-consumo-calor-cel.q2{ background: color-mix(in srgb, var(--precs-gold) 38%, transparent); }
.precs-consumo-calor-cel.q3{ background: color-mix(in srgb, var(--precs-gold) 58%, transparent); }
.precs-consumo-calor-cel.q4{ background: color-mix(in srgb, var(--precs-gold) 80%, transparent); }
.precs-consumo-calor-cel.q5{ background: var(--precs-gold-hi, var(--precs-gold-title)); }
.precs-consumo-calor-esc{ display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin-top: var(--space-2); font-family: var(--font-rotulo); font-size: var(--fs-3); color: var(--text-muted); }
.precs-consumo-calor-esc .precs-consumo-calor-cel{ width: var(--space-4); aspect-ratio: 1; }
.precs-consumo-saldo{ width: 100%; height: auto; display: block; }
.precs-consumo-saldo-linha{ fill: none; stroke: var(--precs-gold-title); stroke-width: 2; }
.precs-consumo-saldo-ponta{ fill: var(--precs-gold-hi, var(--precs-gold-title)); }
.precs-consumo-saldo-grade{ stroke: var(--border-color); stroke-width: 1; }
.precs-consumo-saldo-txt{ fill: var(--text-muted); font-family: var(--font-rotulo); }   /* (1.1.148) o tamanho vai por atributo do SVG: na viewBox de 960 o token dava 9px de tela */
.precs-consumo-origens tr.resto td{ color: var(--text-muted); }
.precs-consumo-origens .precs-consumo-trilho{ width: 100%; min-width: 80px; }
.precs-consumo-caso{ cursor: pointer; }
.precs-consumo-caso:hover td, .precs-consumo-caso.on td{ background: color-mix(in srgb, var(--precs-gold) 8%, transparent); }
.precs-consumo-selos-mini{ display: inline-flex; gap: var(--space-0); }
.precs-consumo-selos-mini i{ display: inline-block; width: 7px; height: 12px; border-radius: 2px; background: var(--bg-tertiary); }
.precs-consumo-selos-mini i.ok{ background: var(--accent-green); }
.precs-consumo-selos-mini i.falha{ background: var(--accent-red); }
.precs-consumo-selos-mini i.inc{ background: var(--text-muted); opacity: .45; }
.precs-consumo-selos-lista{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); font-family: var(--font-rotulo); font-size: var(--fs-6); color: var(--text-secondary); }
.precs-consumo-selos-lista li{ display: flex; align-items: center; gap: var(--space-2); }
.precs-consumo-selos-lista li i{ width: var(--space-3); height: var(--space-3); border-radius: var(--radius-pill); background: var(--text-muted); opacity: .5; flex: 0 0 auto; }
.precs-consumo-selos-lista li.ok i{ background: var(--accent-green); opacity: 1; }
.precs-consumo-selos-lista li.falha i{ background: var(--accent-red); opacity: 1; }
.precs-consumo-selos-lista li span{ margin-left: auto; color: var(--text-muted); font-size: var(--fs-4); }
.precs-consumo-ficha{ display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--precs-gold); border-radius: var(--radius-card); background: var(--bg-primary); }
.precs-consumo-notas{ margin: 0; padding-left: var(--space-5); font-family: var(--font-corpo); font-size: var(--fs-6); color: var(--text-secondary); }
/* o movimento: a cascata de entrada, as barras que sobem, a linha que se traca, o ponto do estado */
.precs-consumo-corpo.entra > *{ animation: precsConsumoEntra .5s var(--ease-2) both; }
.precs-consumo-corpo.entra > :nth-child(2){ animation-delay: 55ms; }
.precs-consumo-corpo.entra > :nth-child(3){ animation-delay: 110ms; }
.precs-consumo-corpo.entra > :nth-child(4){ animation-delay: 165ms; }
.precs-consumo-corpo.entra > :nth-child(5){ animation-delay: 220ms; }
.precs-consumo-corpo.entra > :nth-child(6){ animation-delay: 275ms; }
.precs-consumo-corpo.entra > :nth-child(7){ animation-delay: 330ms; }
.precs-consumo-corpo.entra > :nth-child(n+8){ animation-delay: 385ms; }
.precs-consumo-corpo.entra .precs-consumo-col-barra{ animation: precsConsumoSobe .7s var(--ease-2) both; animation-delay: calc(240ms + var(--i, 0) * 18ms); }
.precs-consumo-corpo.entra .precs-consumo-trilho-atrib{ animation: precsConsumoAlarga .8s var(--ease-2) both; animation-delay: 240ms; }
.precs-consumo-corpo.entra .precs-consumo-saldo-linha{ stroke-dasharray: 1; stroke-dashoffset: 1; animation: precsConsumoTraca 1.3s var(--ease-2) forwards; animation-delay: 240ms; }
.precs-consumo-corpo.entra .precs-consumo-saldo-ponta{ animation: precsConsumoAparece .4s var(--ease-2) both; animation-delay: 1.4s; }
.precs-consumo-corpo.entra .precs-consumo-calor-linha{ animation: precsConsumoEntra .45s var(--ease-2) both; animation-delay: calc(240ms + var(--i, 0) * 22ms); }
.precs-consumo-corpo.entra .precs-consumo-tile{ animation: precsConsumoEntra .5s var(--ease-2) both; animation-delay: calc(120ms + var(--i, 0) * 60ms); }
.precs-consumo-corpo.entra .precs-consumo-grupo{ animation-delay: calc(180ms + var(--i, 0) * 50ms); }
@keyframes precsConsumoEntra{ from{ opacity: 0; transform: translateY(var(--space-3)); } to{ opacity: 1; transform: none; } }
@keyframes precsConsumoSobe{ from{ transform: scaleY(0); } to{ transform: scaleY(1); } }
@keyframes precsConsumoAlarga{ from{ transform: scaleX(0); } to{ transform: scaleX(1); } }
@keyframes precsConsumoTraca{ to{ stroke-dashoffset: 0; } }
@keyframes precsConsumoAparece{ from{ opacity: 0; transform: scale(.4); } to{ opacity: 1; transform: none; } }
@keyframes precsConsumoPulsa{ 0%, 100%{ opacity: 1; transform: scale(1); } 50%{ opacity: .45; transform: scale(.7); } }
@media (prefers-reduced-motion: reduce){
  .precs-consumo-corpo.entra > *, .precs-consumo-corpo.entra .precs-consumo-col-barra, .precs-consumo-corpo.entra .precs-consumo-trilho-atrib, .precs-consumo-corpo.entra .precs-consumo-saldo-linha,
  .precs-consumo-corpo.entra .precs-consumo-saldo-ponta, .precs-consumo-corpo.entra .precs-consumo-calor-linha, .precs-consumo-corpo.entra .precs-consumo-tile, .precs-consumo-estado i{ animation: none; }
  .precs-consumo-corpo.entra .precs-consumo-saldo-linha{ stroke-dashoffset: 0; }
  .precs-consumo-anel-arco, .precs-consumo-tile, .precs-consumo-kit{ transition: none; }
}
/* o hero empilha quando a coluna aperta (container query, nao media de largura) */
@container (max-width: 820px){
  .precs-consumo-hero{ grid-template-columns: 1fr; justify-items: start; }
  .precs-consumo-hero-anel{ width: 100%; }
  .precs-consumo-hero-kpis{ width: 100%; }
}
@container (max-width: 480px){
  .precs-consumo-hero-kpis{ grid-template-columns: 1fr; }
  .precs-consumo-hero-num b{ font-size: var(--fs-11); }
}
/* celular */
html[data-aparelho]:not([data-tv]) .precs-consumo-card{ padding: var(--space-4); }
html[data-aparelho]:not([data-tv]) .precs-consumo-hero{ padding: var(--space-4); gap: var(--space-4); }
html[data-aparelho]:not([data-tv]) .precs-consumo-tabela th:nth-child(2), html[data-aparelho]:not([data-tv]) .precs-consumo-tabela td:nth-child(2){ display: none; }
html[data-aparelho]:not([data-tv]) .precs-consumo-barras.horas .precs-consumo-col:not(:nth-child(6n+1)) .precs-consumo-col-rot{ visibility: hidden; }
html[data-aparelho]:not([data-tv]) .precs-consumo-casos th:nth-child(5), html[data-aparelho]:not([data-tv]) .precs-consumo-casos td:nth-child(5),
html[data-aparelho]:not([data-tv]) .precs-consumo-casos th:nth-child(3), html[data-aparelho]:not([data-tv]) .precs-consumo-casos td:nth-child(3){ display: none; }
html[data-aparelho]:not([data-tv]) .precs-consumo-calor-linha{ grid-template-columns: 44px repeat(24, minmax(6px, 1fr)); }
html[data-aparelho]:not([data-tv]) .precs-consumo-kit{ flex-basis: 100%; }

/* (1.1.144) O TECLADO NO LOGIN DO RAMAL (celular): o body trava na janela visível, o header fica, o formulário rola por
   dentro e o que é decorativo (marca, cabeçalho do painel) sai enquanto o teclado está aberto. */
html[data-aparelho]:not([data-tv])[data-teclado] body{ height: var(--precs-vv-h, 100dvh); min-height: 0; overflow: hidden; }
html[data-aparelho]:not([data-tv])[data-teclado] #login-section.active{ max-height: calc(var(--precs-vv-h, 100dvh) - var(--precs-header-h, 64px)); overflow-y: auto; }
html[data-aparelho]:not([data-tv])[data-teclado] #login-section .precs-login-brand,
html[data-aparelho]:not([data-tv])[data-teclado] #login-section .panel-header{ display: none; }
html[data-aparelho]:not([data-tv])[data-teclado] #login-section .panel-body{ padding-top: var(--space-3); }

/* (1.1.147) OS AVISOS DE MENSAGEM. Duas pilhas fixas: a da comunicacao interna no canto inferior esquerdo, a do
   credor no direito. A camada e a mesma dos paineis laterais (--precs-camada-drawer): abaixo de todo modal, e o
   card de um canal so existe com o painel daquele canal FECHADO, entao nunca disputa lugar com ele. O container
   nao recebe clique (pointer-events: none), so os cards. No celular a pilha do credor vai para o alto, abaixo do
   header, para as duas nao se cobrirem. A cor do canal e um token por card: azul da paleta (comunicacao interna,
   o mesmo do cartao do hub) e o verde de estado para o credor. */
.precs-avisos{ position: fixed; bottom: var(--space-4); z-index: var(--precs-camada-drawer); display: flex; flex-direction: column; gap: var(--space-2);
  width: min(360px, calc(100vw - var(--space-8))); pointer-events: none; }
.precs-avisos-esq{ left: var(--space-4); }
.precs-avisos-dir{ right: var(--space-4); }
.precs-avisos:empty{ display: none; }
.precs-aviso{ --precs-aviso-cor: var(--precs-paleta-1); --precs-aviso-ms: 14000ms; pointer-events: auto; position: relative; overflow: hidden;
  display: flex; flex-direction: column; background: var(--bg-secondary); border: 1px solid var(--border-color); border-left: 4px solid var(--precs-aviso-cor);
  border-radius: var(--radius-card); box-shadow: var(--shadow-lg); animation: precsAvisoEntra .38s var(--ease-2) both; }
.precs-aviso-wa{ --precs-aviso-cor: var(--accent-green); }
.precs-aviso.saindo{ animation: precsAvisoSai .24s var(--ease-3) forwards; pointer-events: none; }
.precs-aviso.precs-aviso-pisca{ animation: precsAvisoPisca .5s var(--ease-2); }
.precs-aviso-topo{ display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-2) 0 var(--space-3);
  font-family: var(--font-rotulo); font-size: var(--fs-1); font-weight: 700; letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--precs-aviso-cor); }
.precs-aviso-topo > svg{ flex: 0 0 auto; }
.precs-aviso-topo > span:first-of-type{ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.precs-aviso-hora{ margin-left: auto; flex: 0 0 auto; color: var(--text-muted); font-family: var(--font-num); font-weight: 600; letter-spacing: 0; text-transform: none; }
.precs-aviso-x{ flex: 0 0 auto; width: var(--space-6); height: var(--space-6); display: inline-flex; align-items: center; justify-content: center; border: 0;
  border-radius: var(--radius-pill); background: transparent; color: var(--text-muted); cursor: pointer; font-family: var(--font-acao); font-size: var(--fs-8); line-height: 1; }
.precs-aviso-x:hover{ background: var(--bg-tertiary); color: var(--text-primary); }
.precs-aviso-corpo{ display: flex; align-items: center; gap: var(--space-3); width: 100%; padding: var(--space-2) var(--space-3) var(--space-3); border: 0;
  background: transparent; color: inherit; text-align: left; cursor: pointer; font: inherit; }
.precs-aviso-corpo:hover{ background: color-mix(in srgb, var(--precs-aviso-cor) 9%, transparent); }
.precs-aviso-corpo:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: -2px; }
.precs-aviso-foto, .precs-aviso .precs-wa-av{ width: 44px; height: 44px; border-radius: var(--radius-pill); object-fit: cover; flex: 0 0 auto; font-size: var(--fs-8); }
.precs-aviso-texto{ min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: var(--space-0); }
.precs-aviso-nome{ font-family: var(--font-corpo); font-size: var(--fs-6); font-weight: 600; color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.precs-aviso-previa{ font-family: var(--font-corpo); font-size: var(--fs-4); color: var(--text-secondary); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
.precs-aviso-n{ flex: 0 0 auto; min-width: var(--space-6); height: var(--space-6); padding: 0 var(--space-2); display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill); background: var(--precs-aviso-cor); color: var(--precs-wa-tinta-ouro); font-family: var(--font-num); font-size: var(--fs-3); font-weight: 700; }
.precs-aviso-seta{ flex: 0 0 auto; color: var(--text-muted); }
.precs-aviso-tempo{ height: 3px; background: var(--precs-aviso-cor); opacity: .55; transform-origin: left center; animation: precsAvisoEsvazia var(--precs-aviso-ms) linear forwards; }
.precs-aviso:hover .precs-aviso-tempo{ animation-play-state: paused; }
@keyframes precsAvisoEntra{ from{ opacity: 0; transform: translateY(var(--space-4)) scale(.98); } to{ opacity: 1; transform: none; } }
@keyframes precsAvisoSai{ to{ opacity: 0; transform: translateY(var(--space-2)) scale(.98); } }
@keyframes precsAvisoPisca{ 0%{ transform: none; } 35%{ transform: scale(1.03); } 100%{ transform: none; } }
@keyframes precsAvisoEsvazia{ from{ transform: scaleX(1); } to{ transform: scaleX(0); } }
html[data-aparelho]:not([data-tv]) .precs-avisos{ width: calc(100vw - var(--space-8)); }
html[data-aparelho]:not([data-tv]) .precs-avisos-dir{ bottom: auto; top: calc(var(--precs-header-h, 64px) + var(--space-2)); }
html[data-tv] .precs-avisos{ display: none; }
@media (prefers-reduced-motion: reduce){
  .precs-aviso, .precs-aviso.saindo, .precs-aviso.precs-aviso-pisca{ animation: none; }
  .precs-aviso-tempo{ animation: none; }
}
/* (1.1.147) a linha de cada canal no grupo "Som dos avisos de mensagem" das Preferencias */
.precs-prefs-avisos-linha{ display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3); padding: var(--space-2) 0; }
.precs-prefs-avisos-linha > span{ flex: 1 1 140px; font-family: var(--font-corpo); font-size: var(--fs-5); color: var(--text-primary); }
.precs-prefs-ouvir{ font-family: var(--font-acao); font-size: var(--fs-2); font-weight: 600; padding: var(--space-1) var(--space-3); border: 1px solid var(--border-color);
  border-radius: var(--radius-pill); background: var(--bg-secondary); color: var(--precs-gold-title); cursor: pointer; }
.precs-prefs-ouvir:hover{ border-color: var(--precs-gold); }

/* (1.1.148) A TROCA SUAVE do Consumo (janela, ciclo, origem, barras/calor): cross-fade das secoes, barras que sobem e
   linha que se traca, sem a cascata da entrada. E a ficha do caso no visual do Pipedrive: cabecalho do negocio, barra
   do funil, detalhes em dl, linha do tempo. */
.precs-consumo-corpo.troca > *{ animation: precsConsumoTroca .45s var(--ease-2) both; }
.precs-consumo-corpo.troca .precs-consumo-col-barra{ animation: precsConsumoSobe .55s var(--ease-2) both; animation-delay: calc(var(--i, 0) * 8ms); }
.precs-consumo-corpo.troca .precs-consumo-trilho-atrib{ animation: precsConsumoAlarga .6s var(--ease-2) both; }
.precs-consumo-corpo.troca .precs-consumo-saldo-linha{ stroke-dasharray: 1; stroke-dashoffset: 1; animation: precsConsumoTraca .9s var(--ease-2) forwards; }
.precs-consumo-corpo.troca .precs-consumo-calor-linha{ animation: precsConsumoTroca .4s var(--ease-2) both; animation-delay: calc(var(--i, 0) * 12ms); }
@keyframes precsConsumoTroca{ from{ opacity: .25; } to{ opacity: 1; } }
.precs-consumo-campo .precs-cal-btn{ text-transform: none; letter-spacing: 0; font-weight: 600; }
.precs-consumo-neg-topo{ display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3) var(--space-4); }
.precs-consumo-neg-av{ flex: 0 0 auto; width: 52px; height: 52px; border-radius: var(--radius-pill); display: inline-flex; align-items: center; justify-content: center;
  background: var(--precs-gold-light); color: var(--precs-gold-title); font-family: var(--font-titulo); font-size: var(--fs-9); font-weight: 700; }
.precs-consumo-neg-tit{ flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.precs-consumo-neg-tit b{ font-family: var(--font-titulo); font-size: calc(var(--fs-11) * 1.05); font-weight: 700; color: var(--text-primary); line-height: 1; }
.precs-consumo-neg-sub{ font-family: var(--font-corpo); font-size: var(--fs-6); color: var(--text-secondary); display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.precs-consumo-neg-status{ display: inline-flex; align-items: center; gap: var(--space-2); font-family: var(--font-rotulo); font-size: var(--fs-2); font-weight: 700; letter-spacing: var(--ls-caps); text-transform: uppercase;
  padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); background: var(--bg-tertiary); color: var(--text-secondary); }
.precs-consumo-neg-status i{ width: var(--space-2); height: var(--space-2); border-radius: var(--radius-pill); background: currentColor; }
.precs-consumo-neg-status.aberto{ color: var(--precs-paleta-1); }
.precs-consumo-neg-status.ganho{ color: var(--accent-green); }
.precs-consumo-neg-status.perdido{ color: var(--accent-red); }
.precs-consumo-ficha .precs-pipe-btn{ margin-top: 0; }
.precs-consumo-funil{ list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--space-1); counter-reset: etapa; }
.precs-consumo-funil li{ flex: 1 1 120px; min-width: 0; padding: var(--space-2) var(--space-4); background: var(--bg-tertiary); color: var(--text-muted); font-family: var(--font-rotulo); font-size: var(--fs-5); font-weight: 600;
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%, 12px 50%); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.precs-consumo-funil li:first-child{ clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 50%, calc(100% - 12px) 100%, 0 100%); }
.precs-consumo-funil li.feita{ background: var(--precs-gold-light); color: var(--precs-gold-title); }
.precs-consumo-funil li.atual{ background: var(--precs-gold-forma, var(--precs-gold)); color: var(--precs-wa-tinta-ouro); }
.precs-consumo-dl{ margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-1) var(--space-4); }
.precs-consumo-dl > div{ display: flex; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border-color); min-width: 0; }
.precs-consumo-dl dt{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-muted); flex: 0 1 45%; }
.precs-consumo-dl dd{ margin: 0; font-family: var(--font-corpo); font-size: var(--fs-6); color: var(--text-primary); text-align: right; overflow-wrap: anywhere; }
.precs-consumo-tempo{ list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0; }
.precs-consumo-tempo li{ display: grid; grid-template-columns: 88px var(--space-3) minmax(0, 1fr); gap: var(--space-3); align-items: start; padding: var(--space-2) 0; position: relative; }
.precs-consumo-tempo li::before{ content: ""; position: absolute; left: calc(88px + var(--space-3) + 5px); top: 0; bottom: 0; width: 1px; background: var(--border-color); }
.precs-consumo-tempo li i{ position: relative; width: var(--space-3); height: var(--space-3); margin-top: var(--space-1); border-radius: var(--radius-pill); background: var(--precs-gold); }
.precs-consumo-tempo li.marco i{ background: var(--precs-paleta-1); }
.precs-consumo-tempo-q{ font-family: var(--font-num); font-size: var(--fs-5); color: var(--text-muted); margin-top: var(--space-0); }
.precs-consumo-tempo-txt{ display: flex; flex-direction: column; gap: var(--space-0); min-width: 0; }
.precs-consumo-tempo-txt b{ font-family: var(--font-corpo); font-size: var(--fs-6); font-weight: 600; color: var(--text-primary); }
.precs-consumo-tempo-txt span{ font-family: var(--font-rotulo); font-size: var(--fs-5); color: var(--text-muted); }
.precs-consumo-pipe-mini{ display: inline-flex; vertical-align: middle; margin-left: var(--space-1); opacity: .7; transition: opacity var(--dur-2) var(--ease-1); }
.precs-consumo-pipe-mini:hover{ opacity: 1; }
@media (prefers-reduced-motion: reduce){
  .precs-consumo-corpo.troca > *, .precs-consumo-corpo.troca .precs-consumo-col-barra, .precs-consumo-corpo.troca .precs-consumo-trilho-atrib, .precs-consumo-corpo.troca .precs-consumo-saldo-linha, .precs-consumo-corpo.troca .precs-consumo-calor-linha{ animation: none; }
  .precs-consumo-corpo.troca .precs-consumo-saldo-linha{ stroke-dashoffset: 0; }
}

/* (1.1.153) POLIMENTO DO CONSUMO: as abas com marcador e levantada no hover, o Atualizar que gira, o ritmo dos
   ultimos minutos no hero, a seta do kit que anda, o titulo da secao na cor dela. */
.precs-consumo-aba:hover{ transform: translateY(-1px); }
.precs-consumo-aba.on{ position: relative; }
.precs-consumo-aba.on::after{ content: ""; position: absolute; left: var(--space-4); right: var(--space-4); bottom: -1px; height: 2px; border-radius: var(--radius-pill); background: var(--precs-gold-hi, var(--precs-gold-title)); animation: precsConsumoAlarga .35s var(--ease-2) both; }
#precs-consumo-atualizar{ display: inline-flex; align-items: center; gap: var(--space-2); }
#precs-consumo-atualizar svg{ transition: transform var(--dur-3) var(--ease-2); }
#precs-consumo-atualizar:hover svg{ transform: rotate(90deg); }
#precs-consumo-atualizar.girando svg{ animation: precsConsumoGira .9s linear infinite; }
@keyframes precsConsumoGira{ to{ transform: rotate(360deg); } }
.precs-consumo-ritmo{ display: flex; align-items: flex-end; gap: var(--space-3); margin-top: var(--space-1); }
.precs-consumo-ritmo-barras{ display: flex; align-items: flex-end; gap: var(--space-0); height: var(--space-7); flex: 0 1 220px; }
.precs-consumo-ritmo-barras i{ flex: 1 1 0; min-width: 2px; border-radius: 1px; background: color-mix(in srgb, var(--precs-gold) 70%, var(--bg-tertiary)); transform-origin: bottom center; transition: background var(--dur-2) var(--ease-1); }
.precs-consumo-ritmo-barras i:last-child{ background: var(--precs-gold-hi, var(--precs-gold-title)); }
.precs-consumo-ritmo-barras i:hover{ background: var(--precs-gold-hi, var(--precs-gold-title)); }
.precs-consumo-corpo.entra .precs-consumo-ritmo-barras i, .precs-consumo-corpo.troca .precs-consumo-ritmo-barras i{ animation: precsConsumoSobe .5s var(--ease-2) both; animation-delay: calc(280ms + var(--i, 0) * 10ms); }
.precs-consumo-ritmo-rot{ font-family: var(--font-rotulo); font-size: var(--fs-4); color: var(--text-muted); white-space: nowrap; }
.precs-consumo-kit-ico svg{ transition: transform var(--dur-3) var(--ease-2); }
.precs-consumo-kit:hover .precs-consumo-kit-ico svg{ transform: translateY(3px); }
.precs-consumo-card-tit{ transition: color var(--dur-2) var(--ease-1); }
.precs-consumo-card:hover .precs-consumo-card-tit{ color: var(--precs-sec-cor, var(--precs-gold-title)); }
.precs-consumo-hero-kpis .precs-consumo-tile{ animation-delay: calc(120ms + var(--i, 0) * 60ms); }
@media (prefers-reduced-motion: reduce){
  .precs-consumo-aba.on::after, #precs-consumo-atualizar.girando svg, .precs-consumo-corpo.entra .precs-consumo-ritmo-barras i, .precs-consumo-corpo.troca .precs-consumo-ritmo-barras i{ animation: none; }
  .precs-consumo-aba:hover, .precs-consumo-kit:hover .precs-consumo-kit-ico svg{ transform: none; }
}

/* ========================================================================== */
/* (30/09/2026) A TELA PESSOAS, REPAGINADA                                    */
/* ========================================================================== */
/* Pedido do Pedro: a Meta e o WhatsApp como abas do Discador, o verde do Consumo
   Pipedrive mais escuro, Pessoas atribuível, marcar a linha inteira para atribuir
   em massa, nada de "tique" ao filtrar ou ao tocar numa carta, e a tela inteira
   mais viva. Tudo por token; o modal segue popover, sem z-index. */
html{ --precs-pipe-marca: #0B6B3A; }

/* A tela presa no topo: `margin: auto` num contêiner flex centralizava na VERTICAL, e com poucas linhas (um filtro)
   o título e os filtros desciam até o meio da página. */
#pessoas-section{ margin: 0 auto; }
/* O voltar: pílula com a seta que anda para trás */
.precs-pessoas-topo .precs-pessoas-voltar{ display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-4) var(--space-2) var(--space-3);
  border-radius: var(--radius-pill); border: 1px solid var(--border-color); background: var(--bg-secondary); color: var(--text-secondary);
  font-family: var(--font-acao); font-weight: 600; font-size: var(--fs-5); cursor: pointer;
  transition: border-color var(--dur-2) var(--ease-1), background var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1); }
.precs-pessoas-topo .precs-pessoas-voltar svg{ transition: transform var(--dur-3) var(--ease-2); }
.precs-pessoas-topo .precs-pessoas-voltar:hover{ border-color: var(--precs-gold); background: var(--precs-gold-light); color: var(--precs-gold-title); }
.precs-pessoas-topo .precs-pessoas-voltar:hover svg{ transform: translateX(-3px); }
.precs-pessoas-topo .precs-pessoas-voltar:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 2px; }
/* A linha editada troca o excluir pelo Salvar no MESMO lugar: os dois empilhados deixavam a linha mais alta e a lista
   inteira descia atrás do modal. */
.precs-pessoas-linha.suja .precs-pessoas-btn.excluir{ display: none; }
.precs-pessoas-linha .precs-pessoas-btn.salvar:not([hidden]){ animation: precsPessoasVolta var(--dur-2) var(--ease-2) both; }
/* Quem sai do filtro some antes de fechar o espaço */
.precs-pessoas-lista .precs-pessoas-linha.saindo{ animation: precsPessoasSai var(--dur-2) var(--ease-1) both; pointer-events: none; }
@keyframes precsPessoasSai{ from{ opacity: 1; transform: none; } to{ opacity: 0; transform: scale(.985); } }
/* O topo: o combo de pessoas no lugar da busca, e a contagem ao lado */
.precs-pessoas-combo{ flex: 0 1 360px; min-width: 0; display: flex; justify-content: flex-end; }
.precs-pessoas-combo .precs-opcombo{ width: 100%; }
.precs-pessoas-combo .precs-opcombo-btn{ width: 100%; max-width: none; }
.precs-pessoas-conta{ font-family: var(--font-num); font-size: var(--fs-4); color: var(--text-muted); white-space: nowrap; }

/* Os filtros: ligam e desligam no próprio chip, com a contagem de cada setor */
.precs-pessoas-filtros .precs-chat-filtro{ display: inline-flex; align-items: center; gap: var(--space-1);
  transition: background var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1), transform var(--dur-2) var(--ease-2); }
.precs-pessoas-filtros .precs-chat-filtro:hover{ transform: translateY(-1px); }
.precs-pessoas-filtros .precs-chat-filtro:active{ transform: scale(.96); }
.precs-pessoas-filtro-n{ font-family: var(--font-num); font-weight: 600; font-size: var(--fs-2); padding: 0 var(--space-1);
  border-radius: var(--radius-pill); background: color-mix(in srgb, currentColor 14%, transparent); }

/* A lista: a cascata só na primeira montagem; o filtro esconde sem refazer, e quem volta entra com um fade curto */
.precs-pessoas-lista .precs-pessoas-linha{ animation: none;
  transition: border-color var(--dur-2) var(--ease-1), background var(--dur-2) var(--ease-1), transform var(--dur-2) var(--ease-2), box-shadow var(--dur-2) var(--ease-1); }
.precs-pessoas-lista.entrando .precs-pessoas-linha{ animation: precsPessoasLinhaEntra var(--dur-3) var(--ease-2) both; animation-delay: calc(var(--i, 0) * 22ms); }
.precs-pessoas-lista .precs-pessoas-linha.volta{ animation: precsPessoasVolta var(--dur-2) var(--ease-2) both; }
.precs-pessoas-lista .precs-pessoas-linha.filtrada{ display: none; }
@keyframes precsPessoasLinhaEntra{ from{ opacity: 0; transform: translateY(6px); } to{ opacity: 1; transform: none; } }
@keyframes precsPessoasVolta{ from{ opacity: 0; transform: scale(.985); } to{ opacity: 1; transform: none; } }
.precs-pessoas-lista .precs-pessoas-linha:hover{ box-shadow: var(--shadow); }

/* Marcar a linha inteira: o visto aparece sobre a foto, e a linha ganha o ouro */
.precs-pessoas-linha.marcavel{ cursor: pointer; }
.precs-pessoas-linha.marcavel .precs-pessoas-inp, .precs-pessoas-linha.marcavel .precs-pessoas-perm{ cursor: auto; }
.precs-pessoas-lista .precs-pessoas-linha.sel{
  border-color: var(--precs-gold);
  background: linear-gradient(90deg, color-mix(in srgb, var(--precs-gold) 14%, transparent), transparent 60%), var(--bg-secondary);
}
.precs-pessoas-foto-sel{ position: relative; display: inline-flex; flex: 0 0 auto; }
.precs-pessoas-sel-marca{
  position: absolute; right: -4px; bottom: -4px; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; background: var(--precs-gold); color: var(--bg-primary);
  outline: 2px solid var(--bg-secondary); opacity: 0; transform: scale(.4);
  transition: opacity var(--dur-2) var(--ease-1), transform var(--dur-3) var(--ease-2);
}
.precs-pessoas-sel-marca svg{ width: 12px; height: 12px; }
.precs-pessoas-linha.sel .precs-pessoas-sel-marca{ opacity: 1; transform: scale(1); }
.precs-pessoas-linha.sel .precs-pessoas-foto-sel .precs-pessoas-foto{ outline: 2px solid var(--precs-gold); outline-offset: 1px; }

/* A linha de quem ainda não entrou: o e-mail cabe na coluna, sem invadir a Área */
.precs-pessoas-linha.nova .precs-pessoas-email{ min-width: 0; width: 100%; box-sizing: border-box; }
.precs-pessoas-linha.nova .precs-pessoas-nome{ flex: 1 1 auto; }

/* "Visto por último" */
.precs-pessoas-selos{ display: flex; flex-wrap: wrap; gap: var(--space-1); margin-top: var(--space-0); }
.precs-pessoas-visto{ display: inline-flex; align-items: center; gap: var(--space-1); font-family: var(--font-rotulo); font-size: var(--fs-2);
  padding: 0 var(--space-2); border-radius: var(--radius-pill); border: 1px solid var(--border-color); color: var(--text-muted); white-space: nowrap; }
.precs-pessoas-visto.agora{ color: var(--accent-green-text); border-color: color-mix(in srgb, var(--accent-green) 55%, transparent); background: color-mix(in srgb, var(--accent-green) 10%, transparent); }
.precs-pessoas-visto.agora::before{ content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-green); animation: precsPessoasPulso 1.6s var(--ease-1) infinite; }
.precs-pessoas-visto.recente{ color: var(--text-secondary); }
.precs-pessoas-visto.nunca{ border-style: dashed; }
@keyframes precsPessoasPulso{ 0%, 100%{ opacity: 1; } 50%{ opacity: .35; } }

/* As pastilhas do resumo, cada uma na cor da sua tela */
.precs-pessoas-chip{ transition: background var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1); }
.precs-pessoas-chip.on[data-f="supwa"]{ border-color: var(--precs-wa-marca); background: color-mix(in srgb, var(--precs-wa-marca) 12%, transparent); color: color-mix(in srgb, var(--precs-wa-marca) 70%, var(--text-primary)); }
.precs-pessoas-chip.on[data-f="supwa"]::before{ background: var(--precs-wa-marca); }
.precs-pessoas-chip.on[data-f="meta"]{ border-color: var(--precs-meta-marca); background: color-mix(in srgb, var(--precs-meta-marca) 14%, transparent); color: color-mix(in srgb, var(--precs-meta-marca) 72%, var(--text-primary)); }
.precs-pessoas-chip.on[data-f="meta"]::before{ background: var(--precs-meta-marca); }
.precs-pessoas-chip.on[data-f="estrategias"]{ border-color: var(--precs-est-marca); background: color-mix(in srgb, var(--precs-est-marca) 14%, transparent); color: color-mix(in srgb, var(--precs-est-marca) 72%, var(--text-primary)); }
.precs-pessoas-chip.on[data-f="estrategias"]::before{ background: var(--precs-est-marca); }
.precs-pessoas-chip.on[data-f="chat"]{ border-color: var(--precs-paleta-1); background: color-mix(in srgb, var(--precs-paleta-1) 14%, transparent); color: var(--precs-paleta-1); }
.precs-pessoas-chip.on[data-f="chat"]::before{ background: var(--precs-paleta-1); }
.precs-pessoas-chip.on[data-f="consumo"]{ border-color: var(--precs-pipe-marca); background: color-mix(in srgb, var(--precs-pipe-marca) 18%, transparent); color: color-mix(in srgb, var(--precs-pipe-marca) 60%, var(--text-primary)); }
.precs-pessoas-chip.on[data-f="consumo"]::before{ background: var(--precs-pipe-marca); }
.precs-pessoas-chip.on[data-f="pessoas"]{ border-color: var(--precs-paleta-4); background: color-mix(in srgb, var(--precs-paleta-4) 14%, transparent); color: var(--precs-paleta-4); }
.precs-pessoas-chip.on[data-f="pessoas"]::before{ background: var(--precs-paleta-4); }
.precs-pessoas-chip.vazio{ border-style: dashed; color: var(--text-muted); }

/* O modal: tamanho estável (o rodapé existe sempre), cascata só ao abrir, e cada tela na sua cor */
.precs-pessoas-perm-modal{ width: min(660px, 94vw); }
.precs-pessoas-perm-modal.abrindo .precs-pessoas-cartas > *{ animation: precsPessoasLinhaEntra var(--dur-3) var(--ease-2) both; }
.precs-pessoas-perm-modal.abrindo .precs-pessoas-cartas > *:nth-child(2){ animation-delay: 40ms; }
.precs-pessoas-perm-modal.abrindo .precs-pessoas-cartas > *:nth-child(3){ animation-delay: 80ms; }
.precs-pessoas-carta{ transition: border-color var(--dur-2) var(--ease-1), background var(--dur-2) var(--ease-1), transform var(--dur-2) var(--ease-2); }
.precs-pessoas-carta-ico{ transition: background var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1), transform var(--dur-3) var(--ease-2); }
.precs-pessoas-carta.on .precs-pessoas-carta-ico{ transform: scale(1.06); }
.precs-pessoas-carta-marca{ transition: background var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1), transform var(--dur-3) var(--ease-2); }
.precs-pessoas-carta.on .precs-pessoas-carta-marca{ transform: scale(1.05); }
.precs-pessoas-carta[data-f="consumo"]{ --precs-carta-cor: var(--precs-pipe-marca); --precs-carta-tinta: color-mix(in srgb, var(--precs-pipe-marca) 55%, var(--text-primary)); }
.precs-pessoas-perm-quem .precs-pessoas-papel{ margin-left: auto; }
.precs-pessoas-so-ver{ color: var(--accent-orange); }
/* O X do modal: gira e acende devagar, em vez do corte seco */
.precs-pessoas-perm-modal .precs-chat-contato-x{
  transition: transform var(--dur-3) var(--ease-2), background var(--dur-2) var(--ease-1), color var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1);
}
.precs-pessoas-perm-modal .precs-chat-contato-x:hover{ transform: rotate(90deg); background: var(--bg-tertiary); color: var(--text-primary); }
.precs-pessoas-perm-modal .precs-chat-contato-x:active{ transform: rotate(90deg) scale(.9); }
/* O rodapé e o Salvar: sempre no lugar, apagado até haver o que salvar */
.precs-pessoas-perm-pe{ display: flex; justify-content: flex-end; padding-top: var(--space-2); border-top: 1px solid var(--border-color); }
.precs-pessoas-perm-modal .precs-pessoas-salvar{
  display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-5);
  border-radius: var(--radius-pill); border: 1px solid var(--border-color); background: var(--bg-tertiary); color: var(--text-muted);
  font-family: var(--font-acao); font-weight: 700; font-size: var(--fs-5); cursor: default;
  transition: background var(--dur-3) var(--ease-1), color var(--dur-2) var(--ease-1), border-color var(--dur-2) var(--ease-1), transform var(--dur-2) var(--ease-2), filter var(--dur-2) var(--ease-1);
}
.precs-pessoas-salvar-ico{ display: inline-flex; width: 16px; height: 16px; opacity: .5; transition: opacity var(--dur-2) var(--ease-1), transform var(--dur-3) var(--ease-2); }
.precs-pessoas-salvar-ico svg{ width: 100%; height: 100%; }
.precs-pessoas-perm-modal .precs-pessoas-salvar.primario{
  cursor: pointer; color: var(--bg-primary); border-color: transparent;
  background: linear-gradient(135deg, var(--precs-gold), color-mix(in srgb, var(--precs-gold) 70%, var(--precs-gold-title)));
  box-shadow: var(--shadow);
}
.precs-pessoas-perm-modal .precs-pessoas-salvar.primario .precs-pessoas-salvar-ico{ opacity: 1; transform: scale(1.1); }
.precs-pessoas-perm-modal .precs-pessoas-salvar.primario:hover{ transform: translateY(-1px); filter: brightness(1.08); box-shadow: var(--shadow-lg); }
.precs-pessoas-perm-modal .precs-pessoas-salvar.primario:active{ transform: scale(.97); }
.precs-pessoas-perm-modal .precs-pessoas-salvar:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 2px; }

/* O grupo do Discador: a carta dele em cima e as abas penduradas nela */
.precs-pessoas-grupo{ grid-template-columns: minmax(0, 1fr); gap: 0; }
.precs-pessoas-subabas{
  position: relative; display: flex; flex-direction: column; gap: var(--space-2);
  margin-left: var(--space-6); padding: var(--space-3) 0 0 var(--space-5); border-left: 2px solid var(--border-color);
}
.precs-pessoas-subabas-rot{ font-family: var(--font-rotulo); font-size: var(--fs-2); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); }
.precs-pessoas-subcarta{
  --mb: var(--precs-meta-marca);
  display: flex; align-items: center; gap: var(--space-3); width: 100%; text-align: left; cursor: pointer;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-inner); border: 1px solid var(--border-color);
  background: transparent; color: var(--text-primary); font-family: var(--font-corpo);
  transition: border-color var(--dur-3) var(--ease-1), background var(--dur-3) var(--ease-1), transform var(--dur-2) var(--ease-2);
}
.precs-pessoas-subcarta[data-f="supwa"]{ --mb: var(--precs-wa-marca); }
.precs-pessoas-subcarta[data-f="estrategias"]{ --mb: var(--precs-est-marca); }
.precs-pessoas-subcarta:hover:not(:disabled){ border-color: color-mix(in srgb, var(--mb) 55%, var(--border-color)); transform: translateX(2px); }
.precs-pessoas-subcarta:focus-visible{ outline: 2px solid var(--mb); outline-offset: 2px; }
.precs-pessoas-subcarta:disabled{ cursor: default; opacity: .6; }
.precs-pessoas-subcarta-ico{
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  background: color-mix(in srgb, var(--mb) 16%, transparent); color: color-mix(in srgb, var(--mb) 75%, var(--text-primary));
  transition: background var(--dur-3) var(--ease-1), color var(--dur-2) var(--ease-1);
}
.precs-pessoas-subcarta-ico svg{ width: 18px; height: 18px; }
.precs-pessoas-subcarta .precs-pessoas-carta-txt{ flex: 1 1 auto; }
/* O interruptor: pílula com a bolinha que corre */
.precs-pessoas-chave{
  position: relative; flex: 0 0 auto; width: 40px; height: 22px; border-radius: var(--radius-pill);
  background: var(--bg-tertiary); border: 1px solid var(--border-color);
  transition: background var(--dur-3) var(--ease-1), border-color var(--dur-3) var(--ease-1);
}
.precs-pessoas-chave i{
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--text-muted);
  transition: transform var(--dur-3) var(--ease-2), background var(--dur-3) var(--ease-1);
}
.precs-pessoas-subcarta.on, .precs-pessoas-subcarta.ligar{ border-color: var(--mb); background: color-mix(in srgb, var(--mb) 10%, transparent); }
.precs-pessoas-subcarta.on .precs-pessoas-subcarta-ico, .precs-pessoas-subcarta.ligar .precs-pessoas-subcarta-ico{ background: var(--mb); color: white; }
.precs-pessoas-subcarta.on .precs-pessoas-chave, .precs-pessoas-subcarta.ligar .precs-pessoas-chave{ background: var(--mb); border-color: var(--mb); }
.precs-pessoas-subcarta.on .precs-pessoas-chave i, .precs-pessoas-subcarta.ligar .precs-pessoas-chave i{ transform: translateX(18px); background: white; }
.precs-pessoas-subcarta.tirar{ border-color: var(--accent-red); background: color-mix(in srgb, var(--accent-red) 8%, transparent); }
.precs-pessoas-subcarta.tirar .precs-pessoas-chave{ border-color: var(--accent-red); }
.precs-pessoas-subcarta.tirar .precs-pessoas-chave i{ background: var(--accent-red); }

/* As cartas do modo em massa: ligar (a cor da tela), tirar (vermelho), não mexer (neutra) */
.precs-pessoas-carta.massa.ligar{ border-color: var(--precs-carta-cor); background: color-mix(in srgb, var(--precs-carta-cor) 12%, transparent); }
.precs-pessoas-carta.massa.ligar .precs-pessoas-carta-ico{ background: color-mix(in srgb, var(--precs-carta-cor) 22%, transparent); color: var(--precs-carta-tinta); }
.precs-pessoas-carta.massa.ligar .precs-pessoas-carta-marca{ background: var(--precs-carta-cor); border-color: var(--precs-carta-cor); color: var(--bg-primary); }
.precs-pessoas-carta.massa.tirar{ border-color: var(--accent-red); background: color-mix(in srgb, var(--accent-red) 8%, transparent); }
.precs-pessoas-carta.massa.tirar .precs-pessoas-carta-marca{ display: inline-flex; align-items: center; justify-content: center; background: var(--accent-red); border-color: var(--accent-red); color: white; font-weight: 700; }
.precs-pessoas-carta.massa.tirar .precs-pessoas-carta-txt b{ text-decoration: line-through; text-decoration-color: var(--accent-red); }

/* As fotos empilhadas (barra e cabeçalho do modal em massa) */
.precs-pessoas-massa-fotos{ display: inline-flex; align-items: center; flex: 0 0 auto; }
.precs-pessoas-pilha{ display: inline-flex; margin-left: -10px; border-radius: 50%; outline: 2px solid var(--bg-secondary);
  animation: precsPessoasPilha var(--dur-3) var(--ease-2) both; animation-delay: calc(var(--i, 0) * 40ms); }
.precs-pessoas-pilha:first-child{ margin-left: 0; }
.precs-pessoas-pilha .precs-pessoas-foto{ width: 34px; height: 34px; }
.precs-pessoas-pilha.mais{ align-items: center; justify-content: center; width: 34px; height: 34px; background: var(--bg-tertiary);
  color: var(--text-secondary); font-family: var(--font-num); font-size: var(--fs-3); }
@keyframes precsPessoasPilha{ from{ opacity: 0; transform: translateX(-8px) scale(.9); } to{ opacity: 1; transform: none; } }
.precs-pessoas-massa-quem .precs-pessoas-pilha .precs-pessoas-foto{ width: 40px; height: 40px; }

/* A barra da atribuição em massa: sobe do rodapé quando alguém é marcado */
.precs-pessoas-massa{
  position: sticky; bottom: var(--space-4); display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-4); padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border-radius: var(--radius-pill); border: 1px solid var(--precs-gold); background: var(--bg-tertiary); box-shadow: var(--shadow-lg);
  animation: precsPessoasSobe var(--dur-3) var(--ease-2) both;
}
.precs-pessoas-massa[hidden]{ display: none; }
@keyframes precsPessoasSobe{ from{ opacity: 0; transform: translateY(16px); } to{ opacity: 1; transform: none; } }
.precs-pessoas-massa-txt{ flex: 1 1 auto; font-family: var(--font-titulo); font-weight: 700; font-size: var(--fs-5); color: var(--text-primary); }
.precs-pessoas-massa-link{ border: none; background: none; cursor: pointer; padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm);
  font-family: var(--font-acao); font-weight: 600; font-size: var(--fs-4); color: var(--precs-gold-title); transition: background var(--dur-2) var(--ease-1); }
.precs-pessoas-massa-link:hover{ background: var(--precs-gold-light); }
.precs-pessoas-massa-btn{
  border: none; cursor: pointer; padding: var(--space-2) var(--space-5); border-radius: var(--radius-pill);
  font-family: var(--font-acao); font-weight: 700; font-size: var(--fs-5); color: var(--bg-primary); background: var(--precs-gold);
  transition: transform var(--dur-2) var(--ease-2), filter var(--dur-2) var(--ease-1);
}
.precs-pessoas-massa-btn:hover{ transform: translateY(-1px); filter: brightness(1.08); }
.precs-pessoas-massa-btn:focus-visible, .precs-pessoas-massa-link:focus-visible{ outline: 2px solid var(--precs-gold); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce){
  .precs-pessoas-lista.entrando .precs-pessoas-linha, .precs-pessoas-lista .precs-pessoas-linha.volta, .precs-pessoas-lista .precs-pessoas-linha.saindo, .precs-pessoas-perm-modal.abrindo .precs-pessoas-cartas > *,
  .precs-pessoas-pilha, .precs-pessoas-massa, .precs-pessoas-visto.agora::before{ animation: none; }
  .precs-pessoas-lista .precs-pessoas-linha:hover, .precs-pessoas-subcarta:hover:not(:disabled), .precs-pessoas-massa-btn:hover,
  .precs-pessoas-perm-modal .precs-chat-contato-x:hover, .precs-pessoas-perm-modal .precs-pessoas-salvar.primario:hover{ transform: none; }
  .precs-pessoas-chave i, .precs-pessoas-sel-marca{ transition: none; }
}
