@charset "UTF-8";
/* ============================================================================
 *  PRECS — estilo-componentes.css (componentes, modais e graficos)
 * ----------------------------------------------------------------------------
 *  Cards, qualificacoes, modais, tela de ensaio, graficos e o card do negocio.
 *
 *  (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.
 * ========================================================================== */
    /* PRECS — esconde o log de eventos do comercial */
    .precs-hidden { display: none !important; }

    /* PRECS — Gráfico compacto "Seu dia" no card de campanha (estado ocioso).
       Entra/sai com fade + slide; some quando cai uma chamada. */
    /* Painel do ocioso (estilo 3C): gráfico à ESQUERDA + histórico (tabela por
       extenso) à direita. O painel controla visibilidade/fade. */
    /* Gráfico "Seu dia" na COLUNA ESQUERDA (ao lado da campanha); histórico em
       LARGURA TOTAL abaixo. Ambos com fade; somem na chamada. */
    .precs-ocioso-grafico, .precs-ocioso-historico{
      display:none; box-sizing:border-box;
      opacity:0; transform:translateY(10px);
      transition:opacity var(--dur-3) ease, transform var(--dur-3) ease;
    }
    .precs-ocioso-grafico.mostrar, .precs-ocioso-historico.mostrar{ opacity:1; transform:translateY(0); }
    .precs-ocioso-grafico{ width:100%; }                        /* ocupa a coluna esquerda */
    /* Ao entrar em chamada, o gráfico SAI do fluxo enquanto desvanece (posição
       absoluta), assim o card de mailing sobe para o topo da coluna SEM ser
       empurrado pelo gráfico ainda visível. Evita o "pulo" da transição. */
    .precs-ocioso-grafico.saindo{ position:absolute; top:0; left:0; right:0; z-index:1; pointer-events:none; }
    .precs-ocioso-historico{ max-width:1120px; margin:var(--space-4) auto 0; }  /* largura total, centrado, abaixo */
    /* Tabela de últimas ligações (colunas como no 3C) */
    .hist-tabela{ background:var(--bg-primary); border:1px solid var(--border-color); border-radius:var(--radius-card); overflow:hidden; margin-top:var(--space-2); box-shadow:var(--shadow); }
    /* PRECS (1.1.4) — a coluna do IDENTIFICADOR ganhou PISO de 6,5rem e o PROTOCOLO cedeu
       espaço (era .8fr e 1.7fr). O identificador virou botão do Pipe, então a célula agora
       carrega ícone + número ("P #104778", ~95px) em vez de texto solto, e a coluna não
       tinha largura mínima nenhuma. Medido na largura real da tabela (1086px CSS): com o
       template antigo a coluna dava 134px e o botão caberia; o piso é seguro para as
       larguras em que ela encolhe (zoom compacto, janela estreita), onde o que seria
       cortado é um id de NEGÓCIO — e id cortado é pior que id ausente, porque "#1" parece
       um id válido e leva a procurar a lead errada.
       A folga sai do protocolo porque ele já é exibido com reticências de propósito
       (ninguém lê 21 dígitos numa tabela); com o novo template ele fica com 242px. */
    .hist-th, .hist-tr{ display:grid; grid-template-columns:1.1fr minmax(6.5rem, .9fr) 1.4fr 1.5fr .9fr; gap:var(--space-3); padding:var(--space-3) var(--space-4); align-items:center; }
    .hist-th{ font-size:.66rem; text-transform:uppercase; letter-spacing: var(--ls-caps); color:var(--text-muted); font-weight:700; border-bottom:1px solid var(--border-color); position:sticky; top:0; z-index:1; background:color-mix(in srgb, var(--bg-secondary) 70%, var(--bg-primary)); backdrop-filter:blur(2px); }
    .hist-tbody{ max-height:320px; overflow-y:auto; }
    .hist-tr{ border-top:1px solid var(--border-color); font-size:.9rem; transition:background-color .14s ease, box-shadow .14s ease; }
    .hist-tbody .hist-tr:first-child{ border-top:none; }
    .hist-tbody .hist-tr:nth-child(even){ background:color-mix(in srgb, var(--text-primary) 3%, transparent); }
    .hist-tr:hover{ background:color-mix(in srgb, var(--precs-gold,#B49552) 10%, transparent); box-shadow:inset 3px 0 0 var(--precs-gold,#B49552); }
    .hist-c-num{ font-family:'JetBrains Mono',monospace; font-weight:600; color:var(--text-primary); }
    .hist-c-mono{ font-family:'JetBrains Mono',monospace; font-size:.76rem; color:var(--text-muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    /* PRECS (1.1.4) — IDENTIFICADOR COMO BOTÃO DO PIPEDRIVE.
       O identificador do mailing É o id do negócio, então o número já era o caminho para a
       lead; faltava ser clicável. Mesmo verde e mesmo "P" branco do badge do menu
       (.precs-pipe-link), em escala de linha de tabela. O hover repete o vocabulário de lá
       (sobe 1px, clareia, sombra verde) para os dois lugares serem lidos como o mesmo
       botão em dois tamanhos.
       `width: fit-content` porque a célula é uma faixa do grid: sem isso o verde esticaria
       na largura da coluna e viraria uma tarja. */
    .hist-c-ident{ min-width:0; overflow:hidden; }
    /* ======================================================================
       (1.1.79) A CAIXA CANÔNICA DO SELO DE NEGÓCIO.

       RELATO DO PEDRO, 14 e 15/09/2026: "os botões do integração Pipe tudo de tamanhos
       diferentes, não tem um padrão". Medido: NOVE aparências do mesmo selo pelo painel, com
       font-size de .58rem a .78rem, três raios diferentes, três famílias de fonte e altura
       ditada pelo conteúdo em todas.

       A regra agora é uma só, e as variantes de contexto herdam dela em vez de redefinirem:

        · ALTURA FIXA (18px) e não altura de conteúdo, senão um id de 4 dígitos e um de 7 saem
          com caixas diferentes na mesma coluna;
        · `var(--font-num)` com `tabular-nums`, porque o que ele mostra é número;
        · `var(--fs-3)` em todo selo de ID, que é o degrau da rampa mais perto da média dos
          cinco valores que existiam;
        · `--radius-pill`, que é a forma que o painel já usa para chip (ver `.hist-pill`).

       FICAM DE FORA, e a fronteira é deliberada: `.precs-wa-neg-selo` (fundo tingido, dentro da
       linha da conversa do WhatsApp — é outra linguagem, não outra medida do mesmo selo),
       `.precs-pipe-selo` (é o logo de 20px no cabeçalho da lead, sem texto) e `.hist-pipe-p`
       (âncora de compatibilidade de um desenho que não existe mais). */
    .hist-pipe{
      display:inline-flex; align-items:center; justify-content:center;
      gap:var(--space-1); width:fit-content; max-width:100%; height:18px;
      font-family:var(--font-num); font-size:var(--fs-3); font-weight:600;
      font-variant-numeric:tabular-nums;
      padding:0 var(--space-2); border-radius:var(--radius-pill);
      text-decoration:none; color:#fff;
      background:linear-gradient(90deg,var(--pipe-verde,#017737),var(--pipe-verde-2,#0B8A4A));
      /* sem ellipsis aqui de propósito: id de negócio cortado ("#1" em vez de "#104778")
         parece um id válido e leva a procurar a lead errada. Se um dia faltar largura, é
         melhor o botão transbordar e alguém ver do que sumir um dígito em silêncio. A
         coluna tem piso de largura (ver .hist-th/.hist-tr) para isso não acontecer. */
      white-space:nowrap;
      transition:transform .14s ease, box-shadow .18s ease, filter .18s ease;
    }
    .hist-pipe:hover{ transform:translateY(-1px); filter:brightness(1.08); box-shadow:0 3px 10px rgba(40,167,69,.35); }
    .hist-pipe:active{ transform:translateY(0); }
    /* (1.1.38) `.hist-pipe-p` era a caixinha branca com a letra P; hoje o selo é o logo em
       SVG (precsPipeLogoHTML) e não precisa de moldura própria. A regra fica como âncora de
       compatibilidade caso algum caminho antigo ainda emita o span. */
    .hist-pipe-p{
      display:inline-flex; align-items:center; justify-content:center; flex:0 0 auto;
      width:14px; height:14px; border-radius:4px;
      background:#fff; color:var(--pipe-verde,#017737); font-size:.58rem; font-weight:700; line-height:1;
    }
    /* Dentro do chip verde o logo perde o próprio fundo: quadrado verde sobre gradiente verde
       vira uma mancha. Fica só o `p`, em branco, que é o que se lê. */
    .hist-pipe .precs-pipe-logo rect,
    .precs-pipe-btn .precs-pipe-logo rect,
    .precs-ficha-pipe .precs-pipe-logo rect{ fill:rgba(255,255,255,.16); }
    @media (prefers-reduced-motion: reduce){ .hist-pipe{ transition:none; } }
    /* (1.1.30) O NEGÓCIO QUE VEIO DA NOTA, e não do mailing, marcado sem virar outro botão.
       Ele veio do comentário que o PAINEL gravou na qualificação, e não do mailing da 3C — duas
       fontes com confiabilidade diferente para a mesma informação. Marcar é obrigação: se um dia
       o operador qualificar a manual com a lead errada aberta, é esta que erra, e o supervisor
       tem que saber de onde o número saiu antes de cobrar alguém.
       O sinal é o CONTORNO tracejado, e não outra cor: cor nova aqui competiria com a paleta de
       qualificação da mesma linha, e o verde do botão é o que ensina "isto abre o Pipedrive". A
       diferença fica no detalhe que quem procura encontra, e o resto do texto está no tooltip. */
    .hist-pipe-nota{
      background:linear-gradient(90deg,#15613d,#1e8437);
      box-shadow:inset 0 0 0 1px rgba(255,255,255,.28);
      border:1px dashed rgba(255,255,255,.42);
      padding:calc(var(--space-0) - 1px) calc(var(--space-2) - 1px);
    }
    .hist-c-qual{ display:inline-flex; align-items:center; overflow:hidden; }
    .hist-c-vazio{ color:var(--text-muted); }
    /* pílula de qualificação: usa --qc (cor da qualificação) na borda + tinta */
    .hist-pill{ display:inline-flex; align-items:center; gap:var(--space-2); max-width:100%;
      font-size:.74rem; font-weight:600; line-height:1.3; padding:var(--space-0) var(--space-2);
      border-radius:var(--radius-pill); color:var(--text-primary);
      border:1px solid color-mix(in srgb, var(--qc,#B49552) 55%, transparent);
      background:color-mix(in srgb, var(--qc,#B49552) 15%, transparent); }
    .hist-pill .dot{ width:8px; height:8px; border-radius:50%; flex:0 0 auto; background:var(--qc,#B49552); }
    .hist-pill > span:last-child{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    /* "Não qualificado": pílula neutra (cinza tracejado) — o operador não deu desfecho */
    .hist-pill-nq{ color:var(--text-muted); border:1px dashed color-mix(in srgb, var(--text-muted) 55%, transparent);
      background:color-mix(in srgb, var(--text-muted) 10%, transparent); }
    .hist-pill-nq .dot{ background:var(--text-muted); }
    .hist-c-dh{ color:var(--text-muted); font-size:.82rem; white-space:nowrap; }
    /* cabeçalho do histórico: título + contador + sublabel "últimos 7 dias" */
    .hist-badge{ display:inline-flex; align-items:center; justify-content:center; min-width:22px; height:19px; padding:0 var(--space-2); margin-left:var(--space-2);
      /* 700 e não 800 (1.1.2): nenhuma das cinco famílias baixa o 800, e medindo no
         DOM as larguras de 700 e 800 são idênticas — este badge sempre foi 700. */
      font-size:.72rem; font-weight:700; border-radius:var(--radius-pill);
      color:#131315 !important;                        /* escuro fixo, !important vence a regra .og-head span (dourado) */
      /* (1.1.6) OURO DA MARCA FIXO, e não var(--precs-gold). O token é a cor de TEXTO
         dourada do tema, e nos temas claros ele é um bronze ESCURO: com o rótulo #131315 por
         cima dava 3,54:1 no claro antigo, 3,21:1 no claro novo e 2,64:1 no brilho suave — o
         número dentro da pílula ficava ilegível, e foi exatamente isso que apareceu num print
         de produção. Usar o bronze como FUNDO inverte o papel dele. Com #B49552 dá 6,50:1, e
         a pílula fica igual nos três temas, que é o certo para um selo preenchido.
         Mesma correção já aplicada nos botões do cartão de resumo. */
      background:#B49552; box-shadow:0 1px 3px rgba(0,0,0,.25); }
    /* aviso de lista truncada: o badge conta TUDO, a tabela mostra as N mais recentes */
    .hist-rodape{ margin-top:var(--space-2); padding-top:var(--space-2);
      border-top:1px solid var(--border-color); font-size:.66rem; color:var(--text-muted);
      font-family:'Montserrat','Poppins',sans-serif; }
    .hist-sub{ margin-left:var(--space-2); font-size:.62rem; font-weight:600; letter-spacing:.4px; color:var(--text-muted) !important; text-transform:none; }
    .og-inner{
      background:var(--bg-primary); border:1px solid var(--border-color);
      border-radius: var(--radius-inner); padding:var(--space-3) var(--space-4);
    }
    .og-head{
      font-size:.72rem; text-transform:uppercase; letter-spacing: var(--ls-caps);
      color:var(--text-secondary); font-weight:700; margin-bottom:var(--space-3);
    }
    .og-head span{ color:var(--precs-gold,#B49552); }
    /* indicador sutil de "atualizando" no cabeçalho do Seu dia / histórico:
       estrela dourada da marca PRECS (mesma do loader), não um anel genérico. */
    .og-spin{ display:inline-block; width:14px; height:14px; margin-left:var(--space-2); vertical-align:-2px;
      background:center/contain no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-10 -10 20 20'%3E%3Cpath fill='%23B49552' d='M0 -9 C1.4 -2.6 2.6 -1.4 9 0 C2.6 1.4 1.4 2.6 0 9 C-1.4 2.6 -2.6 1.4 -9 0 C-2.6 -1.4 -1.4 -2.6 0 -9 Z'/%3E%3C/svg%3E");
      animation:precsStar 1.2s ease-in-out infinite; }
    @media (prefers-reduced-motion: reduce){ .og-spin{ animation:none; } }
    /* ===================== MODO SUPERVISÃO (gestor) ===================== */
    /* A tela de supervisão é um PAINEL DE PAREDE: fica aberta num monitor grande o dia
       inteiro, e limitar a 1200/1320px deixava faixas vazias dos dois lados enquanto a
       coluna de campanha era cortada e a tabela rolava por dentro. Aqui ela usa a largura
       disponível, com um teto alto só para não esticar a linha do agente até virar
       ilegível em ultrawide.
       O teto é em PIXELS, não em vw, e isso importa: o `main` roda com `zoom: 0.85` no
       modo normal, e unidade de viewport não é afetada pelo zoom do pai — um `97vw` aqui
       virava 1.319px visuais numa tela de 1.600, que é justamente a borda vazia dos dois
       lados. Em px o teto é medido no mesmo espaço em que o layout é escrito, e o zoom
       cuida do resto. */
    /* (1.1.96) O RESPIRO LATERAL É DAQUI, e ele faltava. Relato do Pedro, com captura: "acho
       que tá tudo muito colado nas bordas". Estava mesmo — a única folga dos lados vinha do
       `padding: var(--space-8) var(--space-4)` do `<main>`, ou seja, 16px de autor, e o
       `<main>` é generoso EM CIMA (32px) e apertado dos lados de propósito: o comentário dele
       diz "menos folga lateral: cards encostam mais nas bordas", e para a tela do operador —
       três colunas que disputam largura — isso é o certo.
       A supervisão é outra coisa: painéis com moldura, encostados na borda da janela sem nada
       entre a linha do painel e o fim da tela. Os 24px entram AQUI e não no `<main>`, senão
       roubariam largura das três colunas do operador para resolver um problema que é só desta
       tela. Some ao teto de 2100px: em monitor largo quem manda é o teto, e o respiro só
       aparece quando a janela é menor que ele — que é exatamente quando ele faz falta. */
    .precs-sup-wrap{ max-width:2100px; margin:0 auto; width:100%; padding-top:var(--space-4);
      padding-left:var(--space-6); padding-right:var(--space-6); }
    /* (1.1.17) `flex-wrap` porque as abas passaram a morar nesta linha: em tela estreita elas
       descem para baixo do título em vez de comprimir o nome do supervisor. */
    .precs-sup-head{ display:flex; align-items:center; justify-content:space-between;
      flex-wrap:wrap; gap:var(--space-3) var(--space-4); margin-bottom:var(--space-4); }
    /* A faixa das abas perde a margem de baixo: ela agora é irmã do título, e a margem do
       `.precs-sup-head` responde pelo respiro até os cards de contagem. */
    .precs-sup-head > .precs-sup-abas{ margin-bottom:0; flex:0 0 auto; }
    .precs-sup-titulo{ font-family:'Sora','Poppins',sans-serif; font-size:1.5rem; color:var(--text-primary); }
    /* (1.1.22) Rótulo que muda com a tela aberta (o cadastro de rede discordou do cache de
       perfil) cruza num fade curto em vez de estalar — ver a troca() em precsSupAplicarEscopo. */
    @keyframes precsRotuloTroca{ from{ opacity:.15; } to{ opacity:1; } }
    .precs-rotulo-troca{ animation: precsRotuloTroca .2s ease; }
    @media (prefers-reduced-motion: reduce){ .precs-rotulo-troca{ animation:none; } }
    /* (1.1.61) A LEGENDA DA PAGINA, e nao a sub-linha do operador.
       Esta classe se chamava `.precs-sup-sub` e o nome era usado por DUAS coisas sem relacao:
       a legenda do cabecalho (index.html, com o rotulo do escopo e o relogio) e a sub-linha de
       ramal+faixa de cada operador na tabela. As quatro regras espalhadas somavam nas duas, e
       cada metade acabou dependendo do que a outra declarava: a legenda ganhava o `display:flex`
       escrito para a sub-linha, e a sub-linha ganhava daqui o corpo e a cor da legenda.
       Por isso a separacao repete as declaracoes em vez de reparti-las: o objetivo e que nada se
       mova hoje, e que as duas passem a poder divergir amanha sem se arrastarem. */
    .precs-sup-legenda{ font-size:.82rem; color:var(--text-muted); margin-top:var(--space-0);
      display:flex; align-items:center; gap:var(--space-2); min-width:0; }
    .precs-sup-cards{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:var(--space-3); margin-bottom:var(--space-5); }
    /* O card virou <button> (filtro por estado). Precisa desfazer o estilo padrão de
       botão — fonte, alinhamento e largura — para continuar parecendo o card que era. */
    .precs-sup-card{ display:block; width:100%; text-align:left; cursor:pointer;
      font-family:inherit; appearance:none;
      background:var(--bg-secondary); border:1px solid var(--border-color); border-left:3px solid var(--c,#9aa3b2); border-radius:var(--radius-card); padding:var(--space-3) var(--space-4); box-shadow:var(--shadow);
      transition:transform .14s ease, border-color .14s ease, box-shadow .14s ease; }
    .precs-sup-card:hover{ transform:translateY(-2px); border-color:var(--c,#9aa3b2); }
    .precs-sup-card:focus-visible{ outline:2px solid var(--precs-gold,#B49552); outline-offset:2px; }
    /* Filtro ativo: a cor do próprio estado assume o card, para a resposta visual do
       clique ser a mesma cor do ponto que a supervisora clicou. */
    .precs-sup-card.ativo{ border-color:var(--c,#9aa3b2); border-left-width:3px;
      box-shadow:0 0 0 2px color-mix(in srgb, var(--c,#9aa3b2) 45%, transparent), var(--shadow); }
    .precs-sup-card.ativo .precs-sup-lbl{ color:var(--c,#9aa3b2); }
    @media (prefers-reduced-motion: reduce){
      .precs-sup-card{ transition:none; }
      .precs-sup-card:hover{ transform:none; }
    }
    .precs-sup-num{ font-size:1.6rem; font-weight:700; color:var(--text-primary); font-family:'JetBrains Mono',monospace; line-height:1; }
    .precs-sup-lbl{ font-size:.7rem; text-transform:uppercase; letter-spacing: var(--ls-caps); color:var(--text-muted); margin-top:var(--space-1); }

    /* ===== Barra de filtros (busca, campanha, ordem, contagem) ===== */
    .precs-sup-filtros{ display:flex; align-items:center; flex-wrap:wrap; gap:var(--space-2);
      margin-bottom:var(--space-4); }
    .precs-sup-busca{ display:inline-flex; align-items:center; gap:var(--space-2); min-width:0;
      flex:1 1 220px; max-width:340px; padding:var(--space-1) var(--space-2); border-radius: var(--radius-pill);
      background:var(--bg-secondary); border:1px solid var(--border-color);
      color:var(--text-muted); }
    /* (1.1.46) A BUSCA DA SUPERVISÃO SINALIZAVA FOCO COM 1px, e ela fica aberta o turno
       inteiro. O input zera o próprio outline (regra abaixo) e a compensação era só esta
       troca de `border-color` — 1px numa cor que, nos temas claros, não chega aos 3:1 que a
       WCAG 1.4.11 pede do indicador de foco. O sinal existia, e era fino demais para valer
       como um.
       O anel de 2px é o padrão que o projeto escreveu para si (ver o bloco do :focus-visible),
       e a cor sai do `--focus-ring-cor`, que é medido por família de luz. A borda continua
       mudando junto: ela é o que marca a caixa quando o anel está fora dela. */
    .precs-sup-busca:focus-within{ border-color:var(--focus-ring-cor);
      outline: var(--focus-ring-largura) solid var(--focus-ring-cor);
      outline-offset: var(--focus-ring-folga); }
    .precs-sup-busca input{ flex:1 1 auto; min-width:0; border:none; background:transparent;
      font-family:'Poppins',sans-serif; font-size:.82rem; color:var(--text-primary); }
    .precs-sup-busca input:focus{ outline:none; }
    .precs-sup-filtros select{ font-family:'Poppins',sans-serif; font-size:.8rem;
      padding:var(--space-2) var(--space-2); border-radius: var(--radius-pill); color:var(--text-primary);
      background:var(--bg-secondary); border:1px solid var(--border-color); cursor:pointer;
      max-width:16rem; }
    .precs-sup-filtros select:focus-visible{ outline:2px solid var(--precs-gold,#B49552); outline-offset:1px; }
    .precs-sup-contagem{ margin-left:auto; font-size:.75rem; color:var(--text-muted);
      font-family:'JetBrains Mono',monospace; white-space:nowrap; }
    .precs-sup-limpar{ cursor:pointer; font-family:'Manrope','Poppins',sans-serif;
      font-size:.74rem; font-weight:600; padding:var(--space-1) var(--space-3); border-radius: var(--radius-pill);
      color:var(--precs-gold,#B49552); background:transparent;
      border:1px solid var(--border-color); }
    .precs-sup-limpar:hover{ border-color:var(--precs-gold,#B49552); }
    .precs-sup-limpar:focus-visible{ outline:2px solid var(--precs-gold,#B49552); outline-offset:1px; }
    /* ====================================================================
       (1.1.17) DUAS FAIXAS, no lugar de duas colunas.
       A tabela era 2.1fr contra 1fr da coluna da direita, e o pedido de 21/08 foi direto: "a
       disposição dos cards hoje é ruim, o Ao vivo e o Ligações por campanha não estarem um do lado
       do outro". Agora a tabela ocupa a largura inteira em cima e os três painéis descem para uma
       faixa de três colunas embaixo dela (ver `.precs-sup-lado`).
       O que isso resolve: as sete trilhas da linha param de disputar 2/3 da tela (a campanha era
       cortada em "Campanha Au…" justamente por isso), e os três painéis passam a ser comparáveis
       de relance em vez de empilhados numa coluna magra.
       ==================================================================== */
    .precs-sup-grid{ display:grid; grid-template-columns:1fr; gap:var(--space-4); align-items:start; }
    /* (1.1.16) UMA COLUNA, PARA A TELA DE ESCUTA (contas shadow). Com "Em atendimento agora"
       e "Ligações por campanha" fora, a coluna da direita fica só com o feed: sem esta classe
       ela continuaria roubando 1fr da largura para um bloco só, e a tabela — que é a tela
       inteira para quem só escuta — ficaria em 2.1/3.1 do espaço. Vira uma coluna, o feed desce
       para baixo da tabela e as sete trilhas da linha dividem a largura toda.
       Quem aplica é precsSupAplicarEscopo (app.js), no render, porque o perfil chega por rede. */
    /* (1.1.17) A classe da tela de Escuta continua, agora como reafirmação: a grade já é de uma
       coluna para todos. Ela segue sendo aplicada por `precsSupAplicarEscopo` e testada, porque
       é ela que garante o comportamento se a grade do gestor voltar a ter duas colunas um dia. */
    .precs-sup-grid.precs-sup-grid-solo{ grid-template-columns:1fr; }
    @media (max-width:960px){ .precs-sup-cards{ grid-template-columns:repeat(2,1fr); } .precs-sup-grid{ grid-template-columns:1fr; } }
    .precs-sup-panel{ border-radius:var(--radius-card); }
    /* ====================================================================
       (1.1.17 · 2ª volta) SEM SCROLL INTERNO NA TABELA, e agora por decisão de quem usa.
       A 1ª volta pôs teto de 58vh e rolagem própria, com o argumento de manter os três painéis
       de baixo sempre visíveis. O Pedro reprovou na tela: "podemos tirar o scroll da tabela
       que eu não gosto". É a MESMA conclusão da versão anterior a esta (o teto de 62vh que
       existia e foi removido), e duas rejeições do mesmo padrão em telas diferentes são
       resposta: nesta tabela, quem rola é a página, uma barra só.
       O que compensa: as abas subiram para a linha do título (uma faixa a menos antes da
       tabela) e os três painéis de baixo têm teto próprio, então o caminho até eles ficou
       mais curto mesmo sem a tabela rolar.
       ==================================================================== */
    .precs-sup-tabela{ overflow:visible; }
    /* 6 colunas. "Lig." e "Conv." voltaram porque agora TÊM fonte: o diagnóstico da
       Fase 0 achou agents/status/metrics/total, que é o endpoint do painel da própria
       3C. Com a fonte de reserva (agents/status puro) elas mostram "—", nunca zero.
       A campanha ganhou espaço da coluna de status: "Campanha Automática 01" era cortada
       em "Campanha Au…", e o status mais longo ("Falando · 00:55") cabe em menos. */
    /* (1.1.15 · 8ª volta) SÃO SETE COLUNAS: entrou AÇÕES no fim. As duas ações da linha
       (escutar e deslogar) estavam penduradas na sub-linha do ramal em 11px, ou não existiam.
       Numa coluna própria elas alinham entre as linhas, que é o que deixa a tabela varrível. */
    /* A TRILHA DE AÇÕES É EM PIXELS, e não `auto`. Cada linha é um grid próprio, então uma
       trilha `auto` mede o conteúdo DAQUELA linha: a do agente Offline (que não tem botão)
       media zero e empurrava a coluna de Tempo para a direita, saindo de fila com as vizinhas.
       É a mesma pegadinha que a lista de campanhas pagou com `min-width:15ch` nos selos.

       (1.1.15 · 9ª volta) 206px, e não 178: o botão de escutar troca de rótulo quando a escuta
       começa ("Escutar" → "Sair da linha") e cresce ~30px, então a linha do operador escutado
       transbordava para dentro da coluna TEMPO — relatado em 20/08 com print. A trilha é
       dimensionada pelo rótulo MAIOR, que é o estado excepcional; folga na trilha custa pixels
       parados, e transbordo custa a leitura da coluna vizinha. */
    .precs-sup-linha{ display:grid;
      grid-template-columns:2.1fr 1.5fr 1fr .45fr .45fr 1.15fr 206px;
      gap:var(--space-2); align-items:center; padding:var(--space-2) var(--space-4);
      border-top:1px solid var(--border-color); font-size:.85rem;
      /* (1.1.22 · 2ª volta) A borda transparente vai na BASE (cabeçalho incluído) para as
         colunas continuarem alinhadas quando as linhas de agente ganharem o filete colorido. */
      border-left:3px solid transparent; }
    /* (1.1.45) A LINHA DO ESQUELETO, enquanto o painel de agentes não voltou da 3C.
       Ela não herda as sete colunas da grade de propósito: o esqueleto promete a SILHUETA
       (linhas de altura certa, na cadência certa), e não um espelho célula por célula — um
       esqueleto com sete colunas vazias mediria mais atenção que a tabela real. A altura
       casa com a linha de verdade para a lista não pular quando os dados chegam, que é o
       mesmo cuidado do `min-height` da lista de conversas do WhatsApp. */
    .precs-sup-linha-skel{ display:flex; gap:var(--space-4); align-items:center; }
    /* (1.1.22 · 2ª volta) O FILETE DO ESTADO em cada linha (a gramática da ficha e do card
       pausado: cor como acento, nunca como superfície). Com a linha reconciliada por chave, o
       filete LAVA de cor na troca de estado. O SOPRO verde do Falando foi testado e RETIRADO
       no mesmo dia ("não gostei muito", 25/08/2026): o filete sozinho já responde, e fundo é
       superfície. E o hover guia o olho pelas sete colunas sem matar a seleção. */
    .precs-sup-linha[data-ag]{ border-left-color:var(--ag-cor, transparent);
      transition:border-color .45s ease, background .45s ease; }
    .precs-sup-linha[data-ag]:hover{
      background:color-mix(in srgb, var(--text-primary) 5%, transparent); }
    /* (1.1.22 · 2ª volta) ORDENADO POR STATUS, a lista vira seções: a primeira linha de cada
       bloco ganha um respiro extra, e Falando/TPA/Manual leem como grupos. A classe vem do
       render e só existe nessa ordenação. */
    .precs-sup-linha.grupo-inicio{ margin-top:10px; }
    @media (prefers-reduced-motion: reduce){
      .precs-sup-linha[data-ag]{ transition:none; } }
    /* (1.1.22) O QUE FICA À VISTA ENQUANTO A PÁGINA ROLA. Preparo para os 30 operadores do fim
       do ano, respeitando a decisão travada em teste: a tabela NÃO rola por dentro (o teto
       interno foi reprovado na tela DUAS vezes nesta versão) — quem rola é a página, uma
       barra só. Então quem gruda é o resto: os cards de estado grudam no topo da janela e o
       cabeçalho de ordenação gruda logo abaixo deles. O deslocamento do cabeçalho vem do
       pintor (`--sup-cards-h`), porque a fileira de cards quebra em duas linhas em tela
       estreita e um valor cravado deixaria o cabeçalho por baixo (ou com um vão). */
    .precs-sup-cards{ position:sticky; top:0; z-index:8; background:var(--bg-primary);
      padding-top:var(--space-2); margin-top:calc(var(--space-2) * -1); }
    /* O sticky do cabeçalho existia desde sempre e nunca funcionou: `.panel` tem
       overflow:hidden (é o que apara a faixa de estado no card do operador), e ancestral com
       overflow escondido vira o contêiner de rolagem do sticky — que aqui não rola. O painel
       da tabela não tem faixa para aparar, então libera o overflow e o sticky passa a valer
       contra a rolagem da página. */
    .precs-sup-panel{ overflow:visible; }
    .precs-sup-th{ top:var(--sup-cards-h, 0px); }
    /* (1.1.22) MODO DENSO, ligado pelo pintor acima de 18 operadores online (`data-denso`,
       mesma mecânica do data-n da parede): avatar menor e menos respiro derrubam a linha de
       ~50px para ~36px, e trinta linhas passam a caber quase inteiras numa tela 1080. */
    #sup-agentes[data-denso] .precs-sup-linha{ padding-top:3px; padding-bottom:3px;
      font-size:.8rem; }
    #sup-agentes[data-denso] .precs-sup-av{ width:22px; height:22px; font-size:.54rem; }
    #sup-agentes[data-denso] .precs-sup-agente-txt{ line-height:1.1; }
    #sup-agentes[data-denso] .precs-sup-sub{ margin-top:0; }
    /* (1.1.61) A REGRA DA FAIXA NO DENSO SAIU, por ter ficado EXATAMENTE redundante. Ela era o
       unico lugar do projeto que declarava 66x11, e foi dela que o tamanho padrao da leva veio:
       o denso e o modo apertado da tabela, entao faixa legivel ali e legivel em qualquer lugar.
       Agora que o degrau `normal` do componente declara 66x11 para a tabela inteira, o denso
       herda o mesmo valor, e repetir aqui so criaria um segundo lugar para mudar o numero. */
    /* (1.1.22) A LINHA-RESUMO DOS OFFLINE: uma linha discreta no pé da lista, no vocabulário
       dos rótulos de caixa-alta do painel. É botão de verdade (teclado funciona de graça). */
    .precs-sup-off-resumo{ display:block; width:100%; text-align:center;
      padding:var(--space-2) var(--space-4); border:none;
      border-top:1px solid var(--border-color); background:transparent;
      color:var(--text-muted); font-family:'Manrope','Poppins',sans-serif;
      font-size:.68rem; font-weight:700; letter-spacing:var(--ls-caps);
      text-transform:uppercase; cursor:pointer; }
    .precs-sup-off-resumo:hover{ color:var(--precs-gold, #B49552); }
    .precs-sup-off-resumo:focus-visible{ outline:2px solid var(--precs-gold,#B49552);
      outline-offset:-2px; }
    .precs-sup-acoes{ display:inline-flex; align-items:center; gap:var(--space-2);
      justify-content:flex-end; flex:0 0 auto; }
    .precs-sup-th-acoes{ text-align:right; }
    /* CONVERSÕES COM PESO. Era o número mais apagado da linha, do lado de "ligações", que está em
       destaque — e para closer é o contrário: ligação é esforço, conversão é resultado. Quem já
       converteu hoje ganha o dourado da casa; quem está em zero fica no tom secundário, sem
       vermelho nenhum: zero às 9h da manhã não é problema, e pintar de alerta o que é só cedo
       ensina a ignorar a cor. */
    .precs-sup-conv{ font-family:'JetBrains Mono',monospace; text-align:right;
      font-weight:700; font-size:.92rem; color:var(--text-secondary); }
    /* (1.1.22 · 2ª volta) A pastilha dourada na conversão foi testada e RETIRADA no mesmo dia
       ("acho melhor só colorir o texto", 25/08/2026): o dourado no número já distingue do zero
       apagado, e a pastilha deslocava o alinhamento da coluna. */
    .precs-sup-conv.tem{ color:var(--precs-gold-forma, var(--precs-gold, #B49552)); }

    /* A FATIA DO QUADRO em cada card de estado. Fina e na cor do próprio estado: ela responde
       "que parte do quadro está assim" sem obrigar a ler e comparar seis números. */
    .precs-sup-card-fatia{ height:3px; margin-top:6px; border-radius:var(--radius-pill);
      background:var(--border-color); overflow:hidden; }
    .precs-sup-card-fatia i{ display:block; height:100%; border-radius:var(--radius-pill);
      background:var(--c, var(--text-muted));
      transition:width var(--dur-3, .3s) var(--ease-1); }
    @media (prefers-reduced-motion: reduce){ .precs-sup-card-fatia i{ transition:none; } }
    /* ZERO FICA APAGADO. "0 offline" é uma boa notícia, e não pode ter o mesmo peso de "5
       falando" — mas continua na faixa: card que some e volta faria a linha inteira dançar a
       cada leitura. */
    .precs-sup-card.vazio{ opacity:.5; }
    .precs-sup-card.vazio .precs-sup-card-fatia{ opacity:0; }
    /* (1.1.22) Zero→um acende com transição: o card é atualizado em lugar (o pintor mais polido
       da tela), então opacity tem de onde partir — só faltava declarar. A lista REPETE a
       transition da base do card (transform/border/sombra do hover): regra posterior de mesma
       especificidade substitui a inteira, não soma. */
    .precs-sup-card{ transition:transform .14s ease, border-color .14s ease,
      box-shadow .14s ease, opacity .4s ease; }
    .precs-sup-card .precs-sup-card-fatia{ transition:opacity .4s ease; }
    @media (prefers-reduced-motion: reduce){
      .precs-sup-card, .precs-sup-card .precs-sup-card-fatia{ transition:none; } }

    /* O feed vazio explica o que vai aparecer ali, em vez de só dizer que não há nada. */
    .precs-sup-feed-vazio{ display:flex; flex-direction:column; gap:var(--space-2);
      padding:var(--space-4); }
    .precs-sup-feed-vazio b{ font-size:.86rem; color:var(--text-primary); }
    .precs-sup-feed-vazio span{ font-size:.75rem; color:var(--text-muted); line-height:1.5; }
    /* O TEMPO QUE PASSOU DO CORTE. A cor entra no relógio, e não na linha: a linha é da pessoa, e
       o que está fora do esperado é o tempo dela naquele estado. O pulso é lento de propósito —
       numa tela que fica aberta o dia inteiro, piscar rápido vira ruído que se aprende a ignorar. */
    /* (1.1.22 · correção) O VALE DO PULSO SUBIU DE .55 PARA .8: com nove closers em manual o
       dia inteiro, a coluna fica cheia de tempos estourados, e no fundo do vale o laranja a 55%
       ficava ilegível ("difícil de enxergar", 25/08/2026). O movimento continua sendo o aviso;
       a leitura não pode ser o preço dele. */
    @keyframes precsSupDurPassou{
      0%, 100%{ opacity:1; }
      50%{ opacity:.8; }
    }
    .precs-sup-dur.passou{
      color:var(--accent-orange); font-weight:700;
      animation:precsSupDurPassou 2.6s ease-in-out infinite;
    }
    /* (1.1.67) AS CORES DOS DOIS GRAUS NÃO MORAM AQUI, e sim junto da cor base, no bloco da
       coluna de status em 60-campanhas-e-tv.css. O motivo é de cascata e foi medido: a cor base
       daquele bloco é `.precs-sup-status .precs-sup-dur`, que tem a MESMA especificidade de
       `.precs-sup-dur.passou` e vem DEPOIS no pacote — então ela vencia o laranja em silêncio.
       O peso e a animação continuam aqui, porque esses não competem com ninguém. */
    @media (prefers-reduced-motion: reduce){
      .precs-sup-dur.passou{ animation:none; }
    }

    /* Tempo total + barra de distribuição por estado. É a informação que a supervisora
       não tem em lugar nenhum hoje: para ONDE o tempo do operador foi. */
    .precs-sup-tempo{ display:flex; flex-direction:column; gap:var(--space-1); min-width:0; }
    .precs-sup-tt{ font-family:'JetBrains Mono',monospace; font-size:.74rem; color:var(--text-secondary); }
    .precs-sup-barra{ display:flex; height:6px; border-radius:3px; overflow:hidden;
      background:var(--bg-primary); box-shadow:inset 0 0 0 1px var(--border-color); }
    .precs-sup-barra i{ display:block; height:100%;
      /* (1.1.22) Preparatório da tabela reconciliada (Onda 6 do plano): enquanto a linha é
         reescrita por innerHTML esta transition nunca dispara (nó novo não interpola), e no
         dia em que a linha sobreviver, a barra passa a crescer macio de graça. */
      transition:width .6s var(--ease-1); }
    @media (prefers-reduced-motion: reduce){ .precs-sup-barra i{ transition:none; } }
    @media (max-width:1200px){
      /* Em tela estreita a barra some antes das colunas numéricas: ela é a informação
         mais rica, mas também a que menos sofre por ficar num tooltip. */
      /* (1.1.15 · 8ª volta) Ações continua na tela: seis trilhas para os seis filhos visíveis
         (Tempo é escondido logo abaixo). Escutar e deslogar são o motivo de a tela existir
         para o supervisor — esconder por largura seria mandar ele abrir a 3C. */
      .precs-sup-linha{ grid-template-columns:2fr 1.2fr 1.1fr .45fr .45fr 206px; }
      .precs-sup-tempo{ display:none; }
      /* > *:nth-child e não span:nth-child — o cabeçalho de "Tempo" virou <button>
         (coluna ordenável), e o seletor antigo deixaria de escondê-lo. */
      .precs-sup-th > *:nth-child(6){ display:none; }
    }
    /* Agente: foto + (nome / ramal) + emblema da faixa, resolvidos pelo ramal que o
       roster fornece em `extension`. É o diferencial em relação ao painel da 3C. */
    .precs-sup-agente{ display:flex; align-items:center; gap:var(--space-2); min-width:0; }
    .precs-sup-av{ display:inline-flex; align-items:center; justify-content:center;
      width:30px; height:30px; flex:0 0 auto; border-radius:50%; overflow:hidden;
      background:var(--bg-tertiary); font-size:.68rem; font-weight:700;
      color:var(--precs-gold,#B49552);
      box-shadow:0 0 0 1px var(--border-color); }
    .precs-sup-av img{ width:100%; height:100%; object-fit:cover; display:block; }
    /* (1.1.22) O ANEL DE ESTADO NO AVATAR DA TABELA, no vocabulário da TV: `--ag-cor` vem da
       raiz da linha (escrita pelo render) e, com a linha reconciliada por chave, o anel LAVA
       de cor na troca de estado — box-shadow interpola. Escopado à linha com data-ag: o mesmo
       avatar aparece em outros cards onde o anel não tem cor de estado para mostrar. */
    .precs-sup-linha[data-ag] .precs-sup-av{
      box-shadow:0 0 0 1px var(--bg-secondary), 0 0 0 2.5px var(--ag-cor, var(--border-color));
      transition:box-shadow .45s ease; }
    /* (1.1.22) Linha que entra (operador logou, filtro abriu) usa a curva canônica; o estado
       vazio/erro entra pelo fade do padrão dos vazios. */
    .precs-sup-linha.entra{ animation: precsLeadIn .32s var(--ease-2); }
    .precs-sup-tab-vazio{ animation: precsEmptyIn .28s var(--ease-2) both; }
    @media (prefers-reduced-motion: reduce){
      .precs-sup-linha[data-ag] .precs-sup-av{ transition:none; }
      .precs-sup-linha.entra, .precs-sup-tab-vazio{ animation:none; }
    }
    .precs-sup-agente-txt{ display:flex; flex-direction:column; min-width:0; }
    #sup-agentes .precs-sup-agente-txt{ line-height:1.2; }
    /* Ramal e faixa na MESMA linha, embaixo do nome. Com a faixa ao LADO do nome, a
       primeira coluna truncava tudo em "Ana Caroli…" — o nome é a informação principal
       e não pode ser a que encolhe. */
    /* (1.1.61) O COMPONENTE DA ESTRUTURA; O CONTEXTO DA AS METRICAS.
       Esta classe agora e emitida por `precsSupOpHTML` em varias superficies, e por isso ela
       ficou so com o que e verdade em TODAS: a caixa flex. As tres declaracoes que sairam
       tinham historias diferentes e as duas primeiras eram CODIGO MORTO, provado:
         · `font-size:.82rem` e `color` vieram da legenda da pagina, que dividia esta classe
           ate o passo 0 desta leva. Nenhum dos dois fazia trabalho: TODO filho da sub-linha
           declara os seus proprios (`.precs-sup-ramal` .66rem, `.precs-sup-escutado` .6rem, e
           a faixa e um SVG com medida no atributo). Levar corpo de letra inerte para outras
           cinco superficies seria propagar o acidente em vez de encerra-lo.
         · `margin-top` FAZ trabalho, mas so aqui: e o que separa a sub-linha do nome na tabela
           de Operadores, cujo wrapper nao tem `gap`. Na aba de WhatsApp o wrapper tem
           `gap:1px` proprio, e somar os dois empurraria a linha. Desceu para o escopo de
           `#sup-agentes`, junto do `line-height`, que tem exatamente o mesmo caso e onde o
           modo denso ja escopava assim. */
    .precs-sup-sub{ display:flex; align-items:center; gap:var(--space-2); min-width:0; }
    #sup-agentes .precs-sup-sub{ margin-top:var(--space-0); }
    /* LARGURA FIXA NO RAMAL, e é o que alinha as faixas.
       A faixa não tem trilha própria no grid: ela mora dentro desta célula, empurrada pelo
       texto do ramal. Sem largura fixa, o `x` da faixa era "onde o ramal acabou", então
       ramal de 4 dígitos (1052), de 6 (605487) e o traço de quem não tem ramal davam três
       posições diferentes, e a coluna inteira ficava serrilhada de cima a baixo.
       6ch cobre o maior ramal em uso; `tabular-nums` garante que todo dígito ocupe o mesmo
       avanço mesmo se a JetBrains Mono não carregar e a fallback não for monoespaçada.
       NÃO criar uma sétima trilha no grid da linha para a faixa: a largura sairia das
       colunas de número, que é onde a supervisão olha. */
    .precs-sup-ramal{ font-family:'JetBrains Mono',monospace; font-size:.66rem; color:var(--text-muted);
      flex:0 0 auto; min-width:6ch; font-variant-numeric:tabular-nums; }
    .precs-sup-fx{ display:inline-flex; flex:0 0 auto; opacity:.9; }
    /* Sem faixa cadastrada, precsSupFaixa devolve string vazia e o <span> continua no DOM:
       como item flex vazio ele ainda consome o `gap` do contêiner, e a linha ficava com um
       vão inexplicável. */
    .precs-sup-fx:empty{ display:none; }
    /* O `display:block` vale sempre. Os 40px sao a RESERVA para uma faixa emitida fora do
       componente de identidade: quem passa por `precsSupOpHTML` cai no degrau (66x11 em
       `normal` e `grande`, nenhuma em `compacto`), e este valor nunca e lido. Ele fica porque
       apagar largura de um SVG sem regra o devolve ao nativo de 96px, que era exatamente o
       defeito D1 desta leva. */
    .precs-sup-fx svg{ display:block; width:40px; height:auto; }
    /* ========================================================================
       (1.1.61) OS TRES DEGRAUS DO COMPONENTE DE IDENTIDADE (ver precsSupOpHTML).
       ------------------------------------------------------------------------
       SO SELETOR DE DESCENDENTE, e isto e restricao e nao estilo. `teste-vista-bolso.js` e
       `teste-aparelho.js` injetam a linha do agente a mao, sem avatar e sem o wrapper
       `.precs-sup-agente-txt`, e medem altura e trilhas de grid em pixels. Uma regra com `>`
       contando com a arvore completa quebraria os dois.

       O QUE CADA DEGRAU DECLARA E SO O QUE DIFERE DA BASE: `.precs-sup-av` ja nasce 30px, e
       por isso `compacto` e `normal` nao dizem nada sobre avatar. Repetir o valor aqui criaria
       um segundo lugar para mudar o mesmo numero.

       A FAIXA VAI A 66x11 NOS DOIS DEGRAUS QUE A TEM, e este e o unico numero de faixa do
       projeto depois desta leva. Ele vem do modo denso (logo acima), que e o modo apertado. No
       compacto ela nao existe: o componente nem emite o no, e a regra abaixo e cinto e
       suspensorio para quem passar `extras.subFim` com faixa dentro.
       ======================================================================== */
    .precs-sup-op-normal .precs-sup-fx svg,
    .precs-sup-op-grande .precs-sup-fx svg{ width:66px; height:11px; }
    .precs-sup-op-compacto .precs-sup-fx{ display:none; }
    .precs-sup-op-grande .precs-sup-av{ width:40px; height:40px; }

    /* O ANEL DO OPERADOR EM FOCO. Contorno INTERNO e FECHADO, e nao filete a esquerda nem
       `outline`, porque os dois ja tem dono: o filete e do estado (`--ag-cor`) e o `outline` e
       do `:focus-visible`, com piso de 3:1 travado pelo teste-foco-anel.js. Forma fechada e o
       que distingue foco de estado e de selecao para quem nao separa as cores, e sobrevive ao
       tema de Contraste. `--precs-gold-title` e o unico dos ouros ainda sem trabalho de estado
       nesta tela, e vai SEM fallback hex: ele e declarado no :root do 00-base.css, entao o navegador
       nunca leria o literal e ele so engordaria o contador `fallback-hex`. `inset` tambem e o
       que mantem o contador `anel-cru` parado: ele
       casa `box-shadow:` seguido direto de `0 0 0`. */
    .precs-sup-op[data-emfoco]{ box-shadow:inset 0 0 0 2px var(--precs-gold-title);
      border-radius:var(--radius-inner); }

    @media (max-width:1100px){ .precs-sup-fx{ display:none; } }
    .precs-sup-tabela .precs-sup-linha:first-child{ border-top:none; }
    /* (1.1.17) MONTSERRAT, como todo rótulo de coluna do projeto. `.hist-th` (a tabela de
       últimas ligações do operador) tem a mesma medida, o mesmo peso e o mesmo uppercase, e usa
       Montserrat pelo bloco de tipografia da marca. Este ficou em Poppins por omissão, e a
       diferença aparece quando as duas telas estão abertas lado a lado. */
    .precs-sup-th{ font-family:'Montserrat',sans-serif; font-size:.66rem; text-transform:uppercase; letter-spacing: var(--ls-caps); color:var(--text-muted); font-weight:700; position:sticky; top:0; background:var(--bg-secondary); z-index:1; }
    /* O nome virou <button> (abre o dia do operador): reset de aparência primeiro, e um
       sublinhado pontilhado para dizer que é clicável sem virar link azul. */
    .precs-sup-nome{ font-weight:600; color:var(--text-primary); overflow:hidden;
      text-overflow:ellipsis; white-space:nowrap; display:block; max-width:100%;
      padding:0; border:none; background:transparent; font-family:inherit;
      font-size:inherit; text-align:left; }
    /* (1.1.61) A AFORDANCIA DE CLIQUE SE QUALIFICA PELO ELEMENTO, e nao pela classe.
       O cursor de mao e o sublinhado pontilhado moravam em `.precs-sup-nome` solta, o que
       funcionava enquanto essa classe existia num lugar so, onde o nome E botao. O componente
       de identidade (`precsSupOpHTML`) leva a mesma classe para as tres tabelas de WhatsApp, e
       ali o nome NAO e clicavel: catorze nomes por aba ganhariam sublinhado dourado e cursor de
       mao prometendo um clique que nao existe. Prometer interacao que nao acontece e pior que
       nao ter estilo nenhum.
       Qualificar por `button` resolve na raiz e nao por excecao: quem e botao ganha a
       afordancia, quem e <b> nao ganha, e nao existe uma terceira lista para manter em
       sincronia. `:focus-visible` desce junto, porque <b> nao recebe foco de teclado. */
    button.precs-sup-nome{ cursor:pointer;
      border-bottom:1px dotted color-mix(in srgb, var(--precs-gold,#B49552) 55%, transparent); }
    button.precs-sup-nome:hover{ color:var(--precs-gold,#B49552); }
    button.precs-sup-nome:focus-visible{ outline:2px solid var(--precs-gold,#B49552); outline-offset:2px; }
    /* (1.1.22 · 2ª volta) A CAMPANHA EM SEGUNDO PLANO: é o texto mais repetitivo da tabela
       ("Campanha Automatica - ID 01" em nove linhas) e disputava atenção com status e números.
       Tom apagado e um ponto menor; o balão continua devolvendo o nome inteiro. */
    .precs-sup-camp{ color:var(--text-muted); font-size:.8rem;
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-sup-status{ display:inline-flex; align-items:center; gap:var(--space-2); color:var(--text-secondary); white-space:nowrap; }
    .precs-sup-status .dot, .precs-sup-feed-item .dot,
    .precs-sup-atend-sub .dot{ width:8px; height:8px; border-radius:50%; flex:0 0 8px; display:inline-block; }
    /* OFFLINE sem depender de cor: a linha esmaece e o ponto fica vazado. Ocioso e
       Offline eram dois cinzas quase idênticos, e a supervisora lia operador ativo como
       ausente — os tokens foram separados, e isto é a segunda camada, que funciona
       inclusive para quem não distingue cinza de cinza. */
    .precs-sup-linha.off{ opacity:.55; }
    .precs-sup-linha.off .dot{ background:transparent !important;
      box-shadow:inset 0 0 0 1.5px var(--st-offline, #6b7280); }
    .precs-sup-linha.off:hover{ opacity:.8; }
    .precs-sup-lig{ font-family:'JetBrains Mono',monospace; text-align:right; color:var(--text-primary); }

    /* Posição no ranking de ligações do dia. Discreta por padrão; dourada no pódio. */
    .precs-sup-pos{ flex:0 0 1.35rem; text-align:right; font-family:'JetBrains Mono',monospace;
      font-size:.72rem; color:var(--text-muted); }
    .precs-sup-pos.topo{ color:var(--precs-gold,#B49552); font-weight:700; }
    @media (max-width:1100px){ .precs-sup-pos{ display:none; } }

    /* Cabeçalho ordenável. É <button>, então o reset de aparência vem antes do estilo. */
    .precs-sup-ord{ display:inline-flex; align-items:center; gap:var(--space-1); padding:0;
      border:none; background:transparent; cursor:pointer; text-align:left;
      font:inherit; text-transform:inherit; letter-spacing:inherit; font-weight:inherit;
      color:var(--text-muted); }
    .precs-sup-ord:hover{ color:var(--text-secondary); }
    .precs-sup-ord.ativo{ color:var(--precs-gold,#B49552); }
    .precs-sup-ord:focus-visible{ outline:2px solid var(--precs-gold,#B49552); outline-offset:2px; }
    /* (1.1.9) Coluna sem dado no lote: o cabeçalho fica inerte e o `title` diz o motivo.
       `cursor:default` e não `not-allowed`: não é proibição, é ausência de número. */
    .precs-sup-ord:disabled{ cursor:default; opacity:.45; }
    .precs-sup-ord:disabled:hover{ color:var(--text-muted); }
    .precs-sup-seta{ font-size:.7em; line-height:1; }
    /* "Lig." e "Tempo" são colunas numéricas alinhadas à direita: o cabeçalho acompanha,
       senão o rótulo fica sobre a casa das centenas em vez de sobre o número. */
    .precs-sup-th > *:nth-child(4), .precs-sup-th > *:nth-child(5){ justify-content:flex-end; text-align:right; }

    /* ===== Ligações por campanha ===== */
    /* PRECS (1.1.1) — o nome da campanha aparece INTEIRO.
       A coluna era minmax(6rem,11rem) com ellipsis, e "Campanha Automática - ID 02"
       não cabe em 11rem: as três campanhas viravam "Campanha Automática - …", ou seja,
       a tabela mostrava três linhas visualmente idênticas e o número da campanha —
       a única coisa que as distingue — era justamente o que sumia.
       max-content deixa a coluna pedir a largura do maior nome; o ellipsis fica como
       rede para um nome absurdo, mas agora só age depois de 22rem. */
    .precs-sup-cbar{ display:grid; grid-template-columns:minmax(6rem,max-content) 1fr 2.6rem 5rem;
      gap:var(--space-2); align-items:center; padding:var(--space-1) 0; font-size:.8rem; }
    .precs-sup-cbar-nome{ color:var(--text-secondary); overflow:hidden;
      text-overflow:ellipsis; white-space:nowrap; max-width:22rem; }
    .precs-sup-cbar-trilha{ height:8px; border-radius:4px; overflow:hidden;
      background:var(--bg-primary); box-shadow:inset 0 0 0 1px var(--border-color); }
    .precs-sup-cbar-fill{ display:block; height:100%; border-radius:4px;
      /* FORMA, não texto: usa o ouro da marca em todos os temas. Com --precs-gold esta barra
         saía oliva escuro nos três temas claros, porque aquele token carrega a restrição de
         contraste do TEXTO — e aqui não há letra nenhuma em cima. */
      background:linear-gradient(90deg, var(--precs-gold-forma,#B49552), var(--precs-gold-title,#D3B26B));
      transition:width var(--dur-3) ease; }
    .precs-sup-cbar-num{ font-family:'JetBrains Mono',monospace; text-align:right;
      color:var(--text-primary); font-weight:600; }
    .precs-sup-cbar-ag{ font-size:.7rem; color:var(--text-muted); white-space:nowrap; }
    /* Ligações de quem já saiu: ficam no rodapé, não numa barra. A campanha em que
       ligaram não é informada, e virar a maior barra da tela com o rótulo "Sem campanha"
       era dar destaque justamente ao número que não diz nada. */
    .precs-sup-cbar-nota{ margin-top:var(--space-2); padding-top:var(--space-2); font-size:.7rem;
      color:var(--text-muted); border-top:1px solid var(--border-color); line-height:1.4; }
    @media (prefers-reduced-motion: reduce){ .precs-sup-cbar-fill{ transition:none; } }
    @media (max-width:760px){
      .precs-sup-cbar{ grid-template-columns:minmax(5rem,1fr) 1fr 2.6rem; }
      .precs-sup-cbar-ag{ display:none; }
    }

    /* ===== Em atendimento agora (Fase 3) ===== */
    /* ====================================================================
       (1.1.17) A COLUNA DA DIREITA VIROU FAIXA HORIZONTAL.
       `grid-auto-flow:column` com trilhas de `minmax(0,1fr)` é o que faz os três painéis dividirem
       a largura igualmente E funciona nas duas telas sem regra extra: painel escondido tem
       `display:none`, logo não é item da grade e não reserva coluna. Na tela de Escuta (contas
       shadow), onde só o feed sobra, ele ocupa a largura inteira sozinho — com `1fr 1fr 1fr` fixo
       ele ficaria com um terço e dois buracos.
       ==================================================================== */
    .precs-sup-lado{ display:grid; grid-auto-flow:column; grid-auto-columns:minmax(0,1fr);
      gap:var(--space-4); min-width:0; align-items:start; }
    /* Teto de altura nos três, para nenhum esticar a faixa inteira. O feed já tinha o seu (300px);
       os outros dois cresciam sem limite — "Em atendimento agora" com oito ligações ativas era o
       caso real. Em px e não em vh de propósito: px dentro de elemento com `zoom` acompanha a
       densidade, que é o que se quer aqui (mais linhas visíveis no compacto). */
    #sup-atend, #sup-campanhas{ max-height:300px; overflow-y:auto; overscroll-behavior:contain; }
    /* ====================================================================
       (1.1.17) ORDEM E VISIBILIDADE DOS PAINÉIS (ver o bloco em app.js).
       `display:none !important` e não `hidden`: as funções de pintura escrevem `painel.hidden` por
       conta própria a cada ciclo, conforme o painel TEM ou NÃO conteúdo. Com a escolha do
       supervisor no mesmo atributo, a próxima pintura desfaria o gesto dele. É a mesma razão (e o
       mesmo `!important`) do `.precs-card-oculto` do motor de cards do operador.
       ==================================================================== */
    .precs-sup-painel-oculto{ display:none !important; }
    .precs-sup-painel-acoes{ display:inline-flex; align-items:center; gap:2px; margin-left:auto; }
    .precs-sup-painel-alca, .precs-sup-painel-x{
      background:transparent; border:none; padding:0 var(--space-1); line-height:1;
      color:var(--text-muted); cursor:pointer; border-radius:var(--radius-sm);
      font-family:inherit; font-size:.7rem;
      transition:color var(--dur-1) ease, background var(--dur-1) ease; }
    .precs-sup-painel-alca{ cursor:grab; }
    .precs-sup-painel-alca:active{ cursor:grabbing; }
    .precs-sup-painel-alca:hover, .precs-sup-painel-x:hover{
      color:var(--precs-gold,#B49552); background:var(--bg-tertiary); }
    .precs-sup-painel-x:focus-visible, .precs-sup-painel-alca:focus-visible{
      outline:2px solid var(--precs-gold,#B49552); outline-offset:1px; }
    /* O cabeçalho precisa ser flex para o `margin-left:auto` das ações empurrar elas para a direita.
       `.panel-header` do projeto é bloco, então a mudança fica escopada aos painéis da supervisão. */
    .precs-sup-panel > .panel-header{ display:flex; align-items:center; gap:var(--space-2); }
    .precs-sup-painel-fantasma{ opacity:.35; }
    .precs-sup-painel-escolhido{ border-color:color-mix(in srgb, var(--precs-gold,#B49552) 55%, var(--border-color)); }
    /* A faixa de restaurar: discreta, porque ela só existe para desfazer. */
    .precs-sup-restaurar{ display:flex; align-items:center; justify-content:space-between;
      gap:var(--space-3); padding:var(--space-2) var(--space-3); margin-top:var(--space-2);
      border:1px dashed var(--border-color); border-radius:var(--radius-inner);
      font-size:.75rem; color:var(--text-muted); }
    .precs-sup-restaurar[hidden]{ display:none; }
    .precs-sup-restaurar button{ font-family:'Manrope','Poppins',sans-serif; font-size:.72rem;
      font-weight:600; padding:var(--space-1) var(--space-3); border-radius:var(--radius-pill);
      color:var(--precs-gold,#B49552); background:transparent;
      border:1px solid var(--border-color); cursor:pointer; }
    .precs-sup-restaurar button:hover{ border-color:var(--precs-gold,#B49552); }
    @media (prefers-reduced-motion: reduce){
      .precs-sup-painel-alca, .precs-sup-painel-x{ transition:none; }
    }
    @media (max-width:1100px){
      .precs-sup-lado{ grid-auto-flow:row; grid-auto-columns:auto; }
    }
    .precs-sup-selo{ display:inline-block; min-width:1.2rem; padding:0 var(--space-1); margin-left:var(--space-2);
      border-radius: var(--radius-pill); text-align:center; font-family:'JetBrains Mono',monospace;
      font-size:.68rem; font-weight:700; color:var(--bg-primary);
      background:var(--precs-gold,#B49552); }
    .precs-sup-selo:empty{ display:none; }
    .precs-sup-atend{ padding:var(--space-2) 0; border-top:1px solid var(--border-color); }
    #sup-atend .precs-sup-atend:first-child{ border-top:none; padding-top:0; }
    .precs-sup-atend-cab{ display:flex; align-items:center; gap:var(--space-2); min-width:0; }
    .precs-sup-atend-txt{ display:flex; flex-direction:column; min-width:0; line-height:1.25; }
    .precs-sup-atend-op{ font-weight:600; color:var(--text-primary); font-size:.85rem;
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-sup-atend-sub{ display:inline-flex; align-items:center; gap:var(--space-1);
      font-size:.72rem; color:var(--text-muted); }
    /* (1.1.9) Card que ficou porque a supervisão deixou o detalhe aberto: a ligação já
       acabou. Esmaece o cabeçalho e nomeia o fato, para ninguém ler o credor ali achando
       que a conversa está em curso. A borda dourada do `.aberto` continua marcando qual
       card está expandido. */
    .precs-sup-atend.encerrado .precs-sup-atend-cab{ opacity:.72; }
    .precs-sup-atend-fim{ color:var(--text-secondary); font-weight:600; }
    /* (1.1.9) Qualificação que subiu para a 3C, no topo do detalhe. Fica ACIMA do bloco do
       negócio de propósito: é a pergunta que a supervisão faz primeiro quando abre o card
       de uma ligação encerrada. */
    .precs-sup-atend-qual{ display:flex; align-items:center; gap:var(--space-2);
      font-size:.74rem; margin-bottom:var(--space-2); }
    .precs-sup-atend-qual .dot{ width:8px; height:8px; border-radius:50%; flex:0 0 8px; display:inline-block; }
    .precs-sup-atend-qual-rot{ color:var(--text-muted); text-transform:uppercase; letter-spacing: var(--ls-caps); font-size:.66rem; }
    .precs-sup-atend-qual-nome{ font-weight:600; }
    /* Credor e número: o dado sensível da tela. Fica num bloco proprio, para ficar claro
       na leitura do código onde ele aparece — e para sair inteiro se a regra mudar. */
    .precs-sup-atend-lead{ display:flex; align-items:baseline; justify-content:space-between;
      gap:var(--space-2); margin:var(--space-2) 0 0 2.15rem; min-width:0; }
    .precs-sup-atend-cred{ font-size:.8rem; color:var(--text-secondary); min-width:0;
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-sup-atend-tel{ font-family:'JetBrains Mono',monospace; font-size:.74rem;
      color:var(--precs-gold,#B49552); white-space:nowrap; }
    /* Identificador do negócio, campanha e origem do dado. "ao vivo" (chegou pelo evento
       agora) e "do histórico" (veio da consulta do dia) merecem confiança diferente, e a
       supervisora precisa saber qual está lendo. */
    .precs-sup-atend-meta2{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2);
      margin:var(--space-1) 0 0 2.15rem; font-size:.68rem; color:var(--text-muted); }
    .precs-sup-atend-id{ font-family:'JetBrains Mono',monospace; color:var(--precs-gold,#B49552); }
    .precs-sup-atend-camp{ min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-sup-atend-vivo, .precs-sup-atend-hist{ padding:.05rem var(--space-1); border-radius: var(--radius-pill);
      font-size:.62rem; text-transform:uppercase; letter-spacing: var(--ls-caps); white-space:nowrap; }
    .precs-sup-atend-vivo{ color:var(--st-call, #22c55e);
      box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--st-call, #22c55e) 45%, transparent); }
    .precs-sup-atend-hist{ box-shadow:inset 0 0 0 1px var(--border-color); }
    /* (1.1.15) O CSS da fila de conciliação saiu com o painel dela. A detecção continua, e o
       aviso virou uma linha do "Ao vivo", que já tem estilo próprio. */

    /* ===== (1.1.15) ESCUTAS AO VIVO NA EMPRESA =====
       Uma linha por escuta em curso: quem ouve, quem é ouvido, desde quando. A nossa vem com o
       ponto pulsando (a mesma animação do "ao vivo" do resto do painel) e um pouco mais de tinta.
       Densa de propósito: é uma lista de leitura corrida, como a fila de agentes ao lado. */
    .precs-sup-esc-item{ display:flex; align-items:center; gap:var(--space-2);
      padding:var(--space-2) var(--space-3); border-top:1px solid var(--border-color);
      font-size:.78rem; color:var(--text-secondary);
      /* (1.1.22) A dúvida agora chega pelo TIQUE (nó vivo), então o esmaecer e o fundo dourado
         da escuta própria podem transicionar em vez de estalar. */
      transition:opacity .5s ease, background .4s ease; }
    @media (prefers-reduced-motion: reduce){ .precs-sup-esc-item{ transition:none; } }
    .precs-sup-esc-item:first-child{ border-top:none; }
    .precs-sup-esc-item.minha{ background:color-mix(in srgb, var(--precs-gold,#B49552) 7%, transparent); }
    .precs-sup-esc-dot{ width:8px; height:8px; border-radius:50%; flex:0 0 auto;
      background:var(--accent-red,#ef4444); }
    .precs-sup-esc-quem{ font-weight:600; color:var(--text-primary); }
    .precs-sup-esc-item.minha .precs-sup-esc-quem{ color:var(--precs-gold,#B49552); }
    .precs-sup-esc-seta{ color:var(--text-muted); }
    .precs-sup-esc-alvo{ font-weight:600; color:var(--text-primary); min-width:0;
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    /* O que o evento da 3C não informou fica em itálico e cinza: é ausência de dado, e não um
       nome estranho. */
    .precs-sup-esc-nao{ font-style:italic; font-weight:400; color:var(--text-muted); cursor:help; }
    /* Linha que pode ser resíduo: esmaece e diz por quê. Não é erro, é confiança menor. */
    .precs-sup-esc-item.duvida{ opacity:.62; }
    .precs-sup-esc-duvida{ flex:0 0 auto; padding:0 var(--space-1); border-radius:var(--radius-pill);
      font-size:.58rem; font-weight:700; text-transform:uppercase; letter-spacing:var(--ls-caps);
      color:var(--text-muted); cursor:help; border:1px solid var(--border-color); }
    /* (1.1.22) O selo existe SEMPRE no HTML (estrutura estática) e é a classe da linha, mantida
       pelo tique, que o revela — sem isto a linha que cruzava os dez minutos ficava sem o aviso
       até a próxima repintura, porque a assinatura do pintor não envelhece. */
    .precs-sup-esc-item:not(.duvida) .precs-sup-esc-duvida{ display:none; }
    .precs-sup-esc-t{ margin-left:auto; flex:0 0 auto; font-family:'JetBrains Mono',monospace;
      font-size:.74rem; color:var(--text-muted); }
    .precs-sup-esc-nota{ padding:var(--space-2) var(--space-3); border-top:1px solid var(--border-color);
      font-size:.68rem; line-height:1.45; color:var(--text-muted); }
    /* O selo na linha do agente: "alguém já está acompanhando esta pessoa". Vermelho discreto,
       porque é a mesma cor do "no ar" do resto da tela. */
    .precs-sup-escutado{ display:inline-flex; align-items:center; gap:4px; flex:0 0 auto;
      padding:0 var(--space-1); border-radius:var(--radius-pill); cursor:help;
      font-size:.6rem; font-weight:700; text-transform:uppercase; letter-spacing:var(--ls-caps);
      color:var(--accent-red,#ef4444);
      border:1px solid color-mix(in srgb, var(--accent-red,#ef4444) 45%, transparent); }
    .precs-sup-escutado .precs-sup-esc-dot{ width:6px; height:6px; }

    /* ============ (1.1.15) ESPELHO DO DISCADOR, em tela cheia ============
       A primeira versão foi um painel na coluna da direita e foi reprovada: naquela largura os
       campos do mailing viram pilha, o negócio desce para fora da vista, e nada lembra a tela do
       operador — além de empurrar "Em atendimento agora" para baixo da dobra.
       Agora são as MESMAS TRÊS COLUNAS do discador, na mesma ordem, em tela cheia. A barra da
       escuta (z-index 10040) fica visível por cima deste overlay (9998), de propósito: o áudio é
       o assunto, e o botão de sair da linha não pode ficar atrás de nada. */
    .precs-espelho-overlay{
      display:none; position:fixed; inset:0; z-index:9998;
      /* (1.1.17) O PRETO LITERAL FICA, e a revisão de cores literais deste arquivo passou por
         aqui e decidiu manter. Véu de modal existe para ESCURECER o que está atrás, e escurecer
         é escurecer nos três temas — trocar por `color-mix` sobre `--bg-primary` poria um véu
         BRANCO sobre uma tela branca no PRECS Claro, e aí o espelho deixaria de ler como uma
         janela sobre outra coisa. Mesma régua dos verdes do Pipedrive mais abaixo: literal que
         não é cor de tema não vira token. */
      background:rgba(0,0,0,.6); backdrop-filter:blur(2px);
      align-items:center; justify-content:center; overflow:hidden;
      /* (1.1.17) O PÉ RESERVA A BARRA DA ESCUTA. O espelho só abre durante uma escuta, e a
         barra (z-index 10040) fica por cima deste overlay de propósito — o áudio é o assunto e
         o botão de sair da linha não pode ficar atrás de nada. Sem esta reserva, crescer a
         altura do modal o levaria para DEBAIXO da barra. Com ela, o modal centraliza no espaço
         que sobra e pode usar quase toda a tela.

         (1.1.49) E A RESERVA VIROU MEDIDA, porque 7rem era um palpite que a barra podia estourar
         em silêncio. Em celular ela passou a ter duas faixas (60-campanhas-e-tv.css), e duas
         faixas podem passar dos 112px — quando passam, a barra cobre o rodapé do modal e ninguém
         avisa. Agora quem escreve `--precs-spy-reserva` é a própria barra, com a altura que ela
         realmente ocupou, em `precsSpyPintar`. O 7rem fica como fallback: é o valor certo para o
         caso de uma faixa, e é o que vale antes da primeira medição. */
      padding:2vh 2vw var(--precs-spy-reserva, 7rem);
    }
    .precs-espelho-overlay.open{ display:flex; }
    .precs-espelho-overlay.closing{ animation:precsOverlayOut var(--dur-2) ease forwards; }
    .precs-espelho-overlay.closing .precs-espelho-modal{ animation:precsModalOut var(--dur-2) var(--ease-3) forwards; }
    @media (prefers-reduced-motion: reduce){
      .precs-espelho-overlay.closing, .precs-espelho-overlay.closing .precs-espelho-modal{ animation:none; }
    }
    /* (1.1.15 · 5ª volta) MENOR. Com 1560px e 94vh o espelho cobria a supervisão inteira e virou
       "tela cheia" de verdade — e o pedido era espelhar a tela dele, não substituir a nossa. Em
       1360 x 88vh ele continua com as três colunas do discador e deixa a moldura da supervisão
       visível em volta, que é o que diz "isto é uma janela sobre outra coisa". */
    .precs-espelho-modal{
      /* (1.1.15 . 8a volta) O MODAL RODA COM ZOOM (ver o bloco no index.html), e vw/vh nao sao
         afetados por zoom: eles medem a viewport inteira. Sem a divisao por --precs-escala, um
         `94vw` aqui renderizaria 94vw * 0,85 = 80vw, e o `88vh` cobriria 75vh — o espelho
         encolheria junto com a fonte, que e o oposto do que o zoom deveria fazer aqui (dar MAIS
         pixels de layout para o mesmo espaco fisico). Mesmo cuidado do mailing do operador. */
      /* (1.1.17) 1500px, pedido do Pedro depois de testar na mão. O ganho é na coluna do meio,
         que leva campanha, cronômetros e negócio; as laterais são listas e já estavam boas. O
         `94vw` continua sendo o freio em tela pequena. */
      width:min(calc(1500px / var(--precs-escala, 1)), calc(94vw / var(--precs-escala, 1)));
      max-height:calc(88vh / var(--precs-escala, 1)); display:flex; flex-direction:column;
      background:var(--bg-primary); border:1px solid color-mix(in srgb, var(--precs-gold,#B49552) 35%, var(--border-color));
      border-radius:var(--radius-card); box-shadow:var(--shadow-lg); animation:pmEntra var(--dur-3) ease;
    }
    .precs-espelho-head{
      display:flex; align-items:center; justify-content:space-between; flex:0 0 auto; gap:var(--space-3);
      padding:var(--space-3) var(--space-4); border-bottom:1px solid var(--border-color);
      font-weight:700; font-size:.95rem; color:var(--text-primary);
    }
    .precs-espelho-tit{ display:inline-flex; align-items:center; gap:var(--space-2); }
    .precs-espelho-tit #precs-espelho-quem{ color:var(--precs-gold,#B49552); }
    .precs-espelho-cab-dir{ display:inline-flex; align-items:center; gap:var(--space-3); }
    /* O aviso do cabeçalho é a legenda do painel inteiro, e fica em minúsculas e discreto: ele
       precisa ser lido uma vez, não a cada olhada. */
    .precs-espelho-aviso{ font-size:.7rem; font-weight:400; color:var(--text-muted); }
    /* AS TRÊS COLUNAS, nas proporções do discador: a do meio é a mais larga porque leva campanha
       e negócio; as laterais levam ficha e anotações, que são listas. Rola por dentro, nunca a
       página — a página atrás é a tabela de agentes, e ela não pode se mover. */
    /* (1.1.15 · 6ª volta) O PISO DE ALTURA. Sem ele o modal tinha a altura do conteúdo, e em
       ocioso — quando não há mailing, negócio nem anotação — ele virava uma tarja larga e baixa
       ("muito magrinho", 19/08). Pior que a aparência: o modal MUDAVA DE TAMANHO a cada troca de
       estado do operador, e durante uma escuta isso é a tela pulando na cara de quem está
       tentando acompanhar. Com o piso, o espelho tem a mesma estatura em ocioso, em chamada e em
       TPA, e o que muda é só o conteúdo — como na tela dele. */
    /* ====================================================================
       (1.1.17) ALTURA FIXA, E CADA COLUNA ROLA POR DENTRO.
       O piso da 6ª volta resolveu metade do problema (o modal "magrinho" em ocioso) e deixou a
       outra: entre o piso e o teto de 88vh a altura continuava sendo a do CONTEÚDO. Então a
       chegada das anotações do Pipedrive, que são o último bloco a carregar, esticava o quadro
       inteiro — e quando o `dealId` trocava e as colunas voltavam para "Carregando…", ele
       encolhia de novo. Relato de 21/08: "o modal expande depois diminui por causa das
       anotações, e isso é ruim".
       Agora o quadro tem altura FIXA e o conteúdo rola dentro de cada coluna, que é o que a tela
       do operador faz com a coluna de anotações. O modal para de se mexer: o que muda é só o que
       está escrito nele.
       `align-items:stretch` (o padrão do grid, mas explicitado porque estava `start`) é o que dá
       a altura inteira da linha para as três colunas terem onde rolar. E `min-height:0` na coluna
       é o que faz o `overflow` valer dentro de um flex container — sem ele o conteúdo empurra a
       coluna e a barra de rolagem nunca aparece.
       ==================================================================== */
    .precs-espelho-corpo{
      display:grid; grid-template-columns:1fr 1.15fr 1fr; gap:var(--space-3);
      padding:var(--space-4); overflow:hidden; align-items:stretch;
      /* (1.1.17 · 2ª volta) MAIS ALTO. Os 640px/74vh da 1ª volta deixavam uns 250px de tela
         sobrando embaixo (print de 16h07), e o teto em px vencia o de vh em qualquer notëbook:
         com 950px de viewport, 74vh dá 703 e o 640 cortava antes. Agora o vh manda na faixa
         útil e o px é só o freio de monitor grande. A conta que fecha: 78vh + cabeçalho
         (~49px) + a reserva de 7rem da barra da escuta cabe em 100vh. */
      height:min(calc(900px / var(--precs-escala, 1)), calc(78vh / var(--precs-escala, 1)));
    }
    /* ====================================================================
       (1.1.17) UM BLOCO POR DENSIDADE, pelo mesmo motivo do `.precs-topo-linha` do operador
       (estilo.css, "POR QUE HÁ UM BLOCO POR MODO"): o modal roda com `zoom`, e media query mede a
       VIEWPORT, que o zoom não afeta. Com os limites crus, o espelho em COMPACTO perdia uma coluna
       antes da hora: numa tela de 1100px o layout dele recebe 1100/0,72 = 1528px — espaço de sobra
       para as três colunas — e a query de 1200 disparava do mesmo jeito, empilhando duas.
       Media query não aceita var(), então a conta vai nos próprios limites:
       limite_real = limite_efetivo × escala.
         duas colunas = 1200 efetivos -> 864 (0,72) | 1020 (0,85) | 1200 (1)
         uma  coluna  =  820 efetivos -> 590 (0,72) |  697 (0,85) |  820 (1)

       (1.1.44) OS SEIS LIMITES VIRARAM DOIS, pela mesma troca feita no painel do operador:
       container query mede a caixa REAL, que já está no espaço escalado, então a conta
       `limite × escala` deixa de existir. Aqui ela colapsa ainda melhor, e vale ver por quê: a
       largura do modal é `min(1500px, 94vw) / escala`, ou seja ela JÁ divide pela escala. Levando
       os três pares de limites antigos para largura de modal, os três caem no MESMO número:
         duas colunas: 0,94×864/0,72 = 0,94×1020/0,85 = 0,94×1200/1 = 1128px de modal
         uma  coluna : 0,94×590/0,72 = 0,94×697/0,85 = 0,94×820/1  =  771px de modal
       Não é coincidência: era sempre a mesma medida, escrita seis vezes em unidades diferentes.
       O contêiner é o MODAL e não o corpo, porque um elemento não consulta o próprio tamanho.
       ==================================================================== */
    .precs-espelho-modal{ container-type: inline-size; container-name: espelho; }
    @container espelho (max-width: 1128px){ .precs-espelho-corpo{ grid-template-columns:1fr 1fr; } }
    @container espelho (max-width:  771px){ .precs-espelho-corpo{ grid-template-columns:1fr; } }
    /* (1.1.15 · 3ª volta) O TINT DE ESTADO no modal, que era o que mais faltava para a tela
       parecer a do operador. Lá a cor do estado lava a borda da tela (#precs-tint) e é como ele
       sabe de longe em que estado está; aqui ela entra na moldura e num brilho interno, com a
       MESMA cor (PRECS_ESTADO_CORES). A intensidade acompanha o tema pela mesma variável que o
       tint do operador usa, para o claro não ficar imperceptível nem o escuro estourar. */
    .precs-espelho-modal{
      border-color:color-mix(in srgb, var(--esp-tint,#9aa3b2) 55%, var(--border-color));
      box-shadow:var(--shadow-lg),
                 inset 0 0 0 1px color-mix(in srgb, var(--esp-tint,#9aa3b2) 18%, transparent),
                 inset 0 0 46px -12px color-mix(in srgb, var(--esp-tint,#9aa3b2) 42%, transparent);
      transition:border-color var(--dur-3, .3s) ease, box-shadow var(--dur-3, .3s) ease;
    }
    @media (prefers-reduced-motion: reduce){ .precs-espelho-modal{ transition:none; } }
    .precs-esp-col{ display:flex; flex-direction:column; gap:var(--space-3); min-width:0;
      min-height:0; overflow-y:auto; overscroll-behavior:contain; }
    /* (1.1.17) O esqueleto do espelho: reserva o espaço do que está vindo do Pipedrive para a
       coluna não pular quando a resposta chega. As barras são as mesmas do card de atendimento
       (`.precs-skel-bar`), só o espaçamento é daqui. */
    .precs-esp-skel{ padding:var(--space-1) 0; }
    /* Os cards do espelho SÃO `.panel`, o mesmo do painel do operador: fonte, sombra, raio e
       cabeçalho com ícone vêm de lá. O que fica aqui é só o que é específico do espelho. */
    .precs-esp-col > .panel{ margin:0; }
    /* (1.1.17) OS FILHOS DA COLUNA NÃO ENCOLHEM, e sem esta linha a coluna que rola não rolava.
       A coluna é um flex container de altura fixa, e todo item de flex nasce com `flex-shrink:1`:
       em vez de estourar a altura e acionar o `overflow`, os cards ENCOLHIAM para caber, e o
       conteúdo de dentro deles era recortado sem barra de rolagem nenhuma — a lista de 14
       anotações aparecia cortada no pé da coluna e não havia como alcançar o resto. O print de
       conferência mostrou; a medição de `scrollHeight` não, porque com os cards encolhidos o
       conteúdo da coluna "cabia" (721 de 721). */
    .precs-esp-col > *{ flex:0 0 auto; }
    /* ====================================================================
       (1.1.17) O CARD QUE CRESCE E ROLA POR DENTRO, em vez de a coluna inteira rolar.
       Pedido do Pedro, com o caso na tela: um mailing de dez campos empurrava PROTOCOLO e
       DURAÇÃO para fora da vista, e para ler a duração era preciso rolar a coluna toda —
       incluindo o telefone e o cabeçalho, que não precisavam sair de lugar.
       Agora o card de dados (e as listas de qualificação e de anotações) ABSORVE a altura que
       sobra e rola dentro de si; o que está antes e depois dele na coluna fica parado.
       `min-height:0` em cada elo é obrigatório: sem ele um filho de flex não encolhe abaixo do
       conteúdo e a barra de rolagem nunca aparece.
       ==================================================================== */
    .precs-esp-col > .precs-esp-cresce{ flex:1 1 auto; min-height:0;
      display:flex; flex-direction:column; }
    .precs-esp-col > .precs-esp-cresce > .panel-body{ min-height:0; display:flex;
      flex-direction:column; overflow:hidden; }
    /* (1.1.49) NÃO PONHA `flex:0 0 auto` NO CABEÇALHO DAQUI. Eu pus, e era inerte: `.panel-header`
       é item de um flex em COLUNA com `min-height:auto` e `overflow:visible`, e nessa combinação o
       tamanho mínimo automático já o impede de encolher abaixo do próprio conteúdo. Medido com
       sonda em 390x844: 54,3px de altura para 53px de conteúdo, sem a regra fazer diferença.
       O que fez o título parecer cortado no print de 02/09/2026 é a altura da FILEIRA, não a do
       cabeçalho — o corpo do espelho virava três linhas de grid dentro de uma caixa de altura
       fixa com `overflow:hidden`. Quem resolve isso é o bloco de aparelho mais abaixo, dando
       altura de conteúdo e rolagem própria. */
    .precs-esp-mailing, .precs-esp-quals, .precs-esp-notas{ overflow-y:auto; min-height:0;
      overscroll-behavior:contain; }
    .precs-esp-col > .panel > .panel-body{ padding:var(--space-3) var(--space-4); }
    /* A faixa de estado no topo do card da campanha, como no dele. */
    .precs-esp-camp-card{ position:relative; overflow:hidden; }
    /* (1.1.15 · 9ª volta) A FAIXA E O RÓTULO LEEM A COR DO MODAL, e por isso a troca de estado
       ANIMA em vez de cortar. O valor inline morria junto com o nó a cada `innerHTML`; a variável
       mora no modal, que sobrevive, e a transição acontece nela. Mesma duração da faixa dele
       (.precs-state-bar declara `transition: background .4s` no estilo.css). */
    .precs-esp-camp-card .precs-state-bar{ position:absolute; top:0; left:0; right:0; height:3px;
      background:var(--esp-cor-estado, var(--st-idle)); opacity:1;
      transition:background-color var(--dur-3, .3s) ease; }
    .precs-esp-estado-txt{ color:var(--esp-cor-estado, var(--st-idle));
      transition:color var(--dur-3, .3s) ease; }
    /* O FADE DA TROCA DE ESTADO. Curto e só em opacidade: o conteúdo das três colunas muda de
       verdade (em TPA entra a qualificação, em ocioso sai o mailing), e sem isso a substituição
       acontece dentro de um quadro — o "duro" que o relato de 20/08 descreveu. Não mexe em
       `transform` de propósito: a coluna do meio tem a rosca e os cronômetros, e deslocar tudo
       isso a cada TPA cansa mais do que informa. */
    .precs-esp-mudou > .precs-esp-col{ animation:precsEspMudou .38s var(--ease-1) 1; }
    @keyframes precsEspMudou{ from{ opacity:.35; } to{ opacity:1; } }
    @media (prefers-reduced-motion: reduce){
      .precs-esp-camp-card .precs-state-bar, .precs-esp-estado-txt{ transition:none; }
      .precs-esp-mudou > .precs-esp-col{ animation:none; }
    }
    /* (1.1.15 · 8ª volta) `.precs-esp-agora` SAIU. Ela era a terceira linha do card de tempo, com o
       acumulado do dia embaixo do cronômetro — e o card do operador tem duas linhas, rótulo e
       cronômetro. "Só tira espaço dos números que realmente importam" (19/08), e o card dele é a
       prova: linha que o original não tem é o espelho deixando de espelhar. O número foi para o
       balão do card, onde responde a pergunta de quem for perguntar em vez de competir por atenção
       a cada olhada. */
    /* A entrada dos cards, igual à do discador (`precsLeadIn`, a mesma que o card de mailing dele
       usa ao cair a ligação). Só na TROCA de ligação: o espelho repinta a cada mudança de estado,
       e animar em toda repintura viraria tremor. Quem decide é precsSupPintarEspelho. */
    /* (1.1.15 · 7ª volta) OS TEMPOS VOLTAM PARA UMA LINHA SÓ, agora com a fonte reduzida — que é
       o pedido de 19/08: "podemos diminuir um pouco a fonte para poder caber no mesmo formato que
       é o discador normal, os 4 cards de ocioso, manual, em chamada e TPA todos um do lado do
       outro".

       AS DUAS VOLTAS ANTERIORES E O QUE FALTAVA. A 5ª pôs os quatro numa linha e o rótulo
       "EM CHAMADA" vazou por cima da borda; a 6ª fugiu para 2×2, o que resolveu o vazamento e
       trocou a leitura de relance por um bloco quadrado que a tela dele não tem. Nenhuma das duas
       mexeu na CAUSA: o card do discador é HORIZONTAL (bolinha à esquerda, texto à direita), e
       numa coluna de ~380px isso deixa ~62px de texto útil por card. Nada cabe em 62px.

       ENTÃO O CARD VIRA VERTICAL AQUI, e só aqui: a bolinha sai da linha do texto e vai para o
       canto, o que devolve a largura inteira do card para o rótulo, o cronômetro e a linha do dia.
       Com isso os quatro (cinco, quando há intervalo) cabem numa linha e nada quebra. É a mesma
       hierarquia da tela dele — bolinha, rótulo, número — reempilhada para o espaço que existe.

       `display:flex` em vez de grid: o quinto card do intervalo aparece e desaparece conforme o
       operador entra em pausa, e `flex:1 1 0` divide a linha entre quantos existirem sem precisar
       de uma regra por contagem. */
    .precs-esp-camp-card .precs-tempos-grid{ display:flex; gap:var(--space-1); }
    .precs-esp-camp-card .precs-tempo-card{
      flex:1 1 0; min-width:0; display:block; position:relative;
      padding:var(--space-2) var(--space-3);
    }
    /* A bolinha sai do fluxo do texto e vai para a direita, na ALTURA DO CRONÔMETRO — e não no
       canto de cima, que foi a primeira tentativa. No canto de cima ela reserva 11px na linha do
       rótulo, que é justamente a linha apertada; na altura do cronômetro ela divide espaço com
       "00:51", que ocupa menos da metade da largura. Ninguém disputa espaço com ninguém. */
    .precs-esp-camp-card .precs-tempo-dot{
      position:absolute; right:6px; top:50%; transform:translateY(-50%);
    }
    .precs-esp-camp-card .precs-tempo-info{ min-width:0; }
    /* (1.1.15 · 8ª volta) A FONTE VOLTOU A SER A DELE, e este é o ponto: a 7ª volta reduziu
       rótulo e cronômetro (0,54rem e 0,82rem) para caber, e o que faltava era o ZOOM — o espelho
       renderizava 18% maior que a tela do operador porque o overlay é filho de <body> e o painel
       dele vive dentro do `main`, que roda com zoom 0,85 (ver o bloco no index.html). Com o zoom
       no lugar, cada card tem 110px de layout em vez de 81, e a tipografia DELE cabe.
       Duas escalas de fonte para a mesma tela era exatamente o que ia divergir no primeiro
       ajuste; agora só o EMPILHAMENTO é diferente, e ele é diferente por causa da largura da
       coluna, não por gosto. O que fica é o cinto: cortar com "…" em vez de vazar. */
    .precs-esp-camp-card .precs-tempo-label{ overflow:hidden; text-overflow:ellipsis; }
    .precs-esp-camp-card .precs-tempo-valor{
      white-space:nowrap; padding-right:14px;   /* o canto da bolinha */
    }
    /* O termômetro do espelho é mais fino e com rótulo menor: ele está numa coluna que tem um
       terço da largura da tela do operador, e a fatia de 8% ali tem ~35px.
       O seletor é COMPOSTO (`.precs-esp-camp-card .precs-esp-thermo`) porque `.precs-thermo` mora
       mil linhas abaixo neste mesmo arquivo: com uma classe só de cada lado o empate de
       especificidade é decidido pela ordem, e a altura de 24px dele venceria. */
    .precs-esp-camp-card .precs-esp-thermo{ height:18px; margin-bottom:var(--space-2); }
    /* Em telas estreitas o modal já vira uma coluna, e aí os cards têm largura sobrando: voltam
       para duas linhas de dois, que é o que o grid do discador faz no mesmo aperto. */
    @media (max-width:820px){
      .precs-esp-camp-card .precs-tempos-grid{ flex-wrap:wrap; }
      .precs-esp-camp-card .precs-tempo-card{ flex:1 1 46%; }
    }
    .precs-esp-entra{ animation:precsLeadIn .32s var(--ease-2); }
    @media (prefers-reduced-motion: reduce){ .precs-esp-entra{ animation:none; } }
    .precs-esp-card{
      background:var(--bg-secondary); border:1px solid var(--border-color);
      border-radius:var(--radius-card); padding:var(--space-3) var(--space-4); min-width:0;
    }
    /* (1.1.17) Montserrat: é título de card, e todo título de card do painel (`.panel-header`)
       usa Montserrat. */
    .precs-esp-card-tit{
      display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-2);
      font-family:'Montserrat',sans-serif;
      font-size:.7rem; text-transform:uppercase; letter-spacing:var(--ls-caps);
      font-weight:700; color:var(--precs-gold,#B49552);
    }
    /* O número da ligação em tamanho de manchete, igual ao do discador: é o primeiro dado que o
       operador vê e o que a supervisão usa para confirmar que está ouvindo a ligação certa. */
    .precs-esp-num{ font-family:'JetBrains Mono',monospace; font-size:1.3rem; font-weight:700;
      color:var(--text-primary); line-height:1.2; word-break:break-all; }
    .precs-esp-num-vazio{ font-family:'Poppins',sans-serif; font-size:.9rem; font-weight:400;
      color:var(--text-muted); }
    .precs-esp-situacao{ margin-top:2px; font-size:.78rem; color:var(--text-secondary); }
    /* (1.1.38) Também era dourado, pelo mesmo engano do botão do WhatsApp. Aqui a moldura
       fica (é um chip discreto dentro de um card cheio), mas a cor passa a ser a do destino. */
    .precs-esp-negid{ display:inline-flex; align-items:center; gap:var(--space-1);
      margin-top:var(--space-2); padding:2px var(--space-2); border-radius:var(--radius-pill);
      font-size:.72rem; font-weight:600; text-decoration:none; color:var(--pipe-verde-2,#0B8A4A);
      border:1px solid color-mix(in srgb, var(--pipe-verde-2,#0B8A4A) 45%, var(--border-color)); }
    .precs-esp-negid .dot{ width:6px; height:6px; border-radius:50%; background:currentColor; }
    .precs-esp-negid:hover{ border-color:var(--pipe-verde-2,#0B8A4A);
      background:color-mix(in srgb, var(--pipe-verde-2,#0B8A4A) 10%, transparent); }
    /* O mailing rola por dentro: precatório passa de vinte campos e sem teto a coluna 1 ficaria
       três vezes mais alta que as outras duas. */
    .precs-esp-mailing{ display:flex; flex-direction:column; gap:var(--space-1);
      /* (1.1.17) O teto interno saiu: quem rola agora é a COLUNA (ver .precs-espelho-corpo).
         Dois níveis de rolagem no mesmo lugar era barra dentro de barra, e o de dentro nunca
         era encontrado. */
      min-height:0; }
    .precs-esp-mailing .detail-card{ margin:0; }
    .precs-esp-nota{ font-size:.75rem; line-height:1.5; color:var(--text-muted); }
    /* (1.1.21) A RESERVA SE APRESENTA COMO RESERVA (ver precsEspelhoColunaLigacao): quando a
       ligação do espelho veio do histórico, este aviso fica no topo da coluna e precisa ler
       como ressalva, não como legenda — cor de alerta e a faixinha à esquerda fazem isso sem
       gritar por cima do resto do card. */
    .precs-esp-reserva{
      margin-top:var(--space-2); padding:6px var(--space-2);
      border-left:3px solid var(--st-manual, #f59e0b);
      background:color-mix(in srgb, var(--st-manual, #f59e0b) 10%, transparent);
      border-radius:0 var(--radius-sm, 6px) var(--radius-sm, 6px) 0;
      color:var(--text-secondary, var(--text-muted));
    }
    /* PROTOCOLO e DURAÇÃO no pé da primeira coluna, como no discador. */
    .precs-esp-rodape{ display:grid; grid-template-columns:1.4fr 1fr; gap:var(--space-3); }
    .precs-esp-mini{ background:var(--bg-secondary); border:1px solid var(--border-color);
      border-radius:var(--radius-card); padding:var(--space-2) var(--space-3); min-width:0; }
    /* (1.1.17) Montserrat, como `.detail-label` do operador, que é o mesmo papel: rótulo de campo. */
    .precs-esp-mini-rot{ font-family:'Montserrat',sans-serif; font-size:.62rem;
      text-transform:uppercase; letter-spacing:var(--ls-caps);
      color:var(--text-muted); }
    .precs-esp-mini-val{ font-family:'JetBrains Mono',monospace; font-size:.78rem;
      color:var(--text-primary); word-break:break-all; }
    .precs-esp-mini-val.fraco{ color:var(--text-muted); cursor:help; }
    .precs-esp-mini-val.forte{ font-size:1.05rem; font-weight:700; }
    .precs-esp-camp{ font-size:1.05rem; font-weight:700; color:var(--text-primary); line-height:1.25; }
    .precs-esp-camp-est{ margin-top:var(--space-2); }
    /* (1.1.15 · 7ª volta) AQUI MORAVAM `.precs-esp-sessao`, `.precs-esp-tempos` e
       `.precs-esp-tempo*` — a PRIMEIRA versão dos tempos do espelho, quatro chips próprios num
       grid de quatro colunas. Ela foi substituída na 2ª volta, quando o bloco passou a usar o
       markup do discador (`.precs-tempos` / `.precs-tempo-card`), e o markup saiu do app.js sem
       que estas regras saíssem daqui.

       CSS órfão não é só peso morto: `.precs-esp-tempos` continuava valendo `display:grid` com
       quatro colunas, e quando a 7ª volta reusou esse MESMO nome de classe no wrapper do bloco
       novo, o título, o termômetro e a grade viraram três colunas lado a lado — título quebrado
       em quatro linhas, termômetro de 2px de largura e o card do TPA cortado fora do card da
       campanha. Meia hora para achar, num arquivo que ninguém tinha tocado. */
    /* O card do negócio na mesma leitura do Pipedrive, que é a que o operador tem na tela dele:
       id e situação em cima à esquerda, proprietário em cima à direita, título, a fita do funil e
       o valor. */
    .precs-esp-neg-topo{ display:flex; align-items:flex-start; justify-content:space-between;
      gap:var(--space-2); margin-bottom:var(--space-2); }
    .precs-esp-neg-id{ display:inline-flex; align-items:center; gap:var(--space-1);
      font-family:'JetBrains Mono',monospace; font-size:.72rem; font-weight:600;
      color:var(--text-secondary); }
    .precs-esp-neg-p{ display:inline-flex; align-items:center; justify-content:center;
      width:14px; height:14px; border-radius:3px; font-size:.58rem; font-weight:700;
      color:#fff; background:linear-gradient(90deg,#1a7a4c,#28a745); }
    .precs-esp-neg-selo{ margin-left:var(--space-1); padding:0 var(--space-1);
      border-radius:var(--radius-pill); font-family:'Manrope','Poppins',sans-serif;
      font-size:.58rem; letter-spacing:var(--ls-caps);
      /* (1.1.22) Aberto→ganho/perdido transiciona quando o nó sobreviver à repintura; quando o
         corpo reescrever junto, perde-se a transição daquele ciclo, sem prejuízo. */
      transition:color var(--dur-2) ease, background var(--dur-2) ease,
        border-color var(--dur-2) ease; }
    .precs-esp-neg-selo.aberto{ color:#28a745;
      border:1px solid color-mix(in srgb, #28a745 45%, transparent); }
    .precs-esp-neg-selo.ganho{ color:#fff; background:#1a7a4c; }
    .precs-esp-neg-selo.perdido{ color:var(--accent-red);
      border:1px solid color-mix(in srgb, var(--accent-red) 45%, transparent); }
    .precs-esp-neg-dono{ display:inline-flex; align-items:center; gap:var(--space-2); min-width:0; }
    .precs-esp-neg-av{ display:inline-flex; align-items:center; justify-content:center;
      width:26px; height:26px; border-radius:50%; flex:0 0 auto;
      font-size:.66rem; font-weight:700; color:var(--bg-primary);
      background:var(--precs-gold,#B49552); }
    .precs-esp-neg-dono-txt{ display:flex; flex-direction:column; min-width:0; }
    .precs-esp-neg-dono-txt b{ font-size:.72rem; color:var(--text-primary); line-height:1.2;
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-esp-neg-dono-txt i{ font-style:normal; font-size:.6rem; text-transform:uppercase;
      letter-spacing:var(--ls-caps); color:var(--text-muted); }
    .precs-esp-neg-tit{ font-size:.9rem; font-weight:700; color:var(--text-primary); line-height:1.3;
      font-family:'JetBrains Mono',monospace; }
    .precs-esp-neg .precs-fita{ margin-top:var(--space-2); }
    .precs-esp-neg-meta{ display:flex; flex-wrap:wrap; gap:var(--space-2); margin-top:var(--space-2);
      font-size:.72rem; color:var(--text-muted); }
    .precs-esp-neg-valor{ font-family:'JetBrains Mono',monospace; color:var(--precs-gold,#B49552); }
    /* ===== (1.1.38) A MARCA DO PIPEDRIVE EM UM LUGAR SÓ =====
       A 1.1.15 unificou o COMPORTAMENTO ("um padrão para todos"), mas a cor ficou espalhada:
       o histórico usava `linear-gradient(90deg,#1a7a4c,#28a745)`, a ficha `#28A745`, o espelho
       o DOURADO da PRECS, e o WhatsApp um "P" em Poppins dentro de um quadradinho. Cinco
       aparências para a mesma ação, de novo, e foi o que o Pedro viu em 28/08/2026.
       Agora a cor é token e o desenho é o logo de verdade (precsPipeLogoHTML, no app.js).
       O verde é o da marca, e ele NÃO responde a tema: logo de terceiro tem cor própria, e
       recolori-lo por tema seria descaracterizar a marca — é o mesmo critério que mantém o
       ouro da PRECS fixo nos temas dos outros. */
    html{ --pipe-verde: #017737; --pipe-verde-2: #0B8A4A; }
    .precs-pipe-logo{ flex:0 0 auto; display:block; border-radius:4px; }

    /* ===== (1.1.15) O BOTÃO PADRÃO DE "ABRIR O NEGÓCIO NO PIPEDRIVE" =====
       Eram três aparências para a mesma ação (selo verde no histórico, botão dourado no card de
       atendimento, outro no espelho). Verde é a cor do Pipedrive e é o que a equipe já reconhece
       como "isto me leva para lá"; o dourado é a cor da PRECS e estava dizendo a coisa errada.
       Texto branco sobre o mesmo gradiente do selo do histórico, que já passa contraste. */
    /* (1.1.79) ELE É O ÚNICO SELO COM FRASE ("Abrir #123 no Pipedrive"), então a fonte continua
       sendo a de ação e não a de número. O que ele passa a dividir com os outros é a ALTURA e o
       degrau de tamanho: 24px e `--fs-4`, um degrau acima dos selos de id, que é a diferença
       honesta entre um botão e uma etiqueta. */
    .precs-pipe-btn{ display:inline-flex; align-items:center; justify-content:center;
      gap:var(--space-1); height:24px;
      margin-top:var(--space-2); padding:0 var(--space-3);
      border-radius:var(--radius-pill); font-family:var(--font-acao);
      font-size:var(--fs-4); font-weight:600; text-decoration:none; color:#fff;
      background:linear-gradient(90deg,var(--pipe-verde,#017737),var(--pipe-verde-2,#0B8A4A));
      border:1px solid transparent;
      transition:filter var(--dur-1, .15s) var(--ease-1); }
    .precs-pipe-btn:hover{ filter:brightness(1.12); }
    .precs-pipe-btn:focus-visible{ outline:2px solid var(--precs-gold,#B49552); outline-offset:2px; }
    @media (prefers-reduced-motion: reduce){ .precs-pipe-btn{ transition:none; } }
    /* Em ocioso o espelho mostra o que a tela dele mostra: o dia e a última lead, em vez de três
       cards dizendo que não há nada. */
    .precs-esp-espera{ font-size:1.05rem; font-weight:700; color:var(--text-primary); line-height:1.25; }
    /* "O dia dele" na mesma leitura do card "SEU DIA · HOJE" da tela dele: quatro números com a
       cor semântica de cada métrica. */
    .precs-esp-dia{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--space-2);
      margin-bottom:var(--space-2); }
    .precs-esp-dia-num{ padding:var(--space-2); border-radius:var(--radius-inner);
      background:var(--bg-primary); border:1px solid var(--border-color); text-align:center;
      border-top:2px solid var(--pm-cor,var(--border-color)); }
    .precs-esp-dia-num b{ display:block; font-family:'JetBrains Mono',monospace; font-size:1.25rem;
      color:var(--pm-cor,var(--text-primary)); line-height:1.1; }
    .precs-esp-dia-num i{ font-style:normal; font-size:.62rem; text-transform:uppercase;
      letter-spacing:var(--ls-caps); color:var(--text-muted); }
    .precs-esp-ult{ display:flex; flex-direction:column; gap:2px; }
    .precs-esp-ult b{ font-size:.82rem; color:var(--text-primary); line-height:1.3; }
    .precs-esp-ult span{ font-size:.72rem; color:var(--text-secondary);
      font-family:'JetBrains Mono',monospace; }
    .precs-esp-ult-qual{ display:inline-flex; align-items:center; gap:var(--space-1);
      font-family:'Poppins',sans-serif !important; font-size:.72rem; }
    .precs-esp-ult-qual .dot{ width:7px; height:7px; border-radius:50%; flex:0 0 auto; }
    .precs-esp-hist{ display:flex; flex-direction:column; gap:4px;
      min-height:0; }
    .precs-esp-hist-item{ display:grid;
      grid-template-columns:auto auto auto minmax(0,1fr); align-items:center; gap:var(--space-2);
      padding:var(--space-1) var(--space-2); border-radius:var(--radius-inner);
      background:var(--bg-primary); border:1px solid var(--border-color); }
    /* (1.1.79) O espelho herda a caixa canônica do selo: ele tinha .62rem e padding próprio,
       que era uma das nove medidas do mesmo botão. */
    /* (1.1.15 · 6ª volta) A linha do tempo do operador, no espelho em ocioso. Mesma pele das
       linhas do histórico acima — ela mora no mesmo card e brigar de estilo com a vizinha faria a
       coluna parecer duas telas coladas. */
    .precs-esp-linha-tempo{ display:flex; flex-direction:column; gap:4px;
      min-height:0; }
    .precs-esp-lt-item{ display:grid; grid-template-columns:auto auto minmax(0,1fr);
      align-items:center; gap:var(--space-2);
      padding:var(--space-1) var(--space-2); border-radius:var(--radius-inner);
      background:var(--bg-primary); border:1px solid var(--border-color); }
    .precs-esp-lt-h{ font-family:'JetBrains Mono',monospace; font-size:.66rem;
      color:var(--text-muted); }
    .precs-esp-lt-txt{ font-size:.74rem; color:var(--text-secondary);
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-esp-hist-semid{ font-size:.62rem; color:var(--text-muted); }
    /* Protocolo ausente e outros valores que a tela não tem: cinza, e nunca escondido. */
    .precs-esp-fraco{ color:var(--text-muted) !important; cursor:help; }
    .precs-esp-dur{ font-size:1.05rem; font-weight:700; }
    /* O card do que não é espelhável fica tracejado: "existe na tela dele, e não aqui". */
    .precs-esp-nao-card{ border-style:dashed !important; }
    /* O selo verde do Pipedrive no cabeçalho das anotações, igual ao dele. */
    .precs-esp-p-ico{ display:inline-flex; align-items:center; justify-content:center;
      width:16px; height:16px; border-radius:4px; font-size:.62rem; font-weight:700;
      color:#fff; background:linear-gradient(90deg,#1a7a4c,#28a745); }
    /* A lista de qualificações usa o markup dele, e aqui é LEITURA: sem cursor de clique e sem
       hover, para ninguém tentar qualificar pela tela da supervisão. */
    .precs-esp-qual-slot .qualification-item{ cursor:default; }
    .precs-esp-qual-slot .qualification-item:hover{ transform:none; }
    .precs-esp-hist-num{ font-family:'JetBrains Mono',monospace; font-size:.74rem;
      color:var(--text-primary); flex:0 0 auto; }
    .precs-esp-hist-h{ font-family:'JetBrains Mono',monospace; font-size:.66rem;
      color:var(--text-muted); flex:0 0 auto; }
    .precs-esp-hist-q{ display:inline-flex; align-items:center; gap:var(--space-1);
      font-size:.7rem; color:var(--text-secondary); min-width:0;
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-esp-hist-q .dot{ width:7px; height:7px; border-radius:50%; flex:0 0 auto; }
    /* O QUE NÃO É ESPELHÁVEL. Em dourado suave, e não em vermelho: é informação sobre a
       FERRAMENTA, não sobre o operador, e não pode ser lida como alerta de que algo está errado
       com ele. O card inteiro fica tracejado para dizer "existe na tela dele, e não aqui". */
    .precs-esp-card-nao{ border-style:dashed; }
    .precs-esp-nao{ padding:var(--space-2) var(--space-3); border-radius:var(--radius-inner);
      font-size:.73rem; line-height:1.5; color:var(--text-secondary);
      background:color-mix(in srgb, var(--precs-gold,#B49552) 8%, transparent);
      border:1px solid color-mix(in srgb, var(--precs-gold,#B49552) 22%, var(--border-color)); }
    .precs-esp-qual-ok{ display:flex; align-items:center; gap:var(--space-2);
      font-size:.78rem; color:var(--text-secondary); margin-bottom:var(--space-2); }
    .precs-esp-qual-ok .dot{ width:8px; height:8px; border-radius:50%; flex:0 0 auto; }
    .precs-esp-quals{ display:flex; flex-direction:column; gap:4px; margin-top:var(--space-2);
      min-height:0; }
    /* A lista de qualificações é REFERÊNCIA de leitura, então ela nasce apagada: nada aqui pode
       parecer selecionado, porque a seleção dele não trafega. Só a que JÁ SUBIU ganha destaque. */
    .precs-esp-qual{ display:flex; align-items:center; gap:var(--space-2);
      padding:var(--space-1) var(--space-2); border-radius:var(--radius-inner);
      font-size:.74rem; color:var(--text-muted); border-left:3px solid transparent; opacity:.75; }
    .precs-esp-qual .dot{ width:7px; height:7px; border-radius:50%; flex:0 0 auto; }
    .precs-esp-qual.marcada{ opacity:1; color:var(--text-primary); font-weight:600;
      background:var(--bg-primary); border-left-color:var(--precs-gold,#B49552); }
    .precs-esp-card-notas{ min-width:0; }
    .precs-esp-notas{ display:flex; flex-direction:column; gap:var(--space-2);
      /* (1.1.17) Este era o pior dos cinco: 60vh SEM dividir pela escala, contra um piso de
         54vh no corpo — a lista de anotações sozinha bastava para estourar o quadro, que é
         exatamente o "expande e diminui" relatado. Quem rola agora é a coluna. */
      min-height:0; }
    .precs-esp-nota-item{ padding:var(--space-2) var(--space-3); border-radius:var(--radius-inner);
      background:var(--bg-primary); border:1px solid var(--border-color); }
    .precs-esp-nota-cab{ display:flex; flex-wrap:wrap; align-items:center; gap:var(--space-2);
      margin-bottom:2px; font-size:.66rem; color:var(--text-muted); }
    .precs-esp-nota-quando{ font-family:'JetBrains Mono',monospace; }
    .precs-esp-nota-autor{ color:var(--text-secondary); }
    .precs-esp-nota-qual{ padding:0 var(--space-1); border-radius:var(--radius-pill);
      font-weight:600; color:var(--c,#9aa3b2);
      border:1px solid color-mix(in srgb, var(--c,#9aa3b2) 45%, transparent); }
    .precs-esp-nota-txt{ font-size:.76rem; line-height:1.5; color:var(--text-secondary);
      overflow-wrap:anywhere; }
    .precs-sup-atend-btn{ margin:var(--space-2) 0 0 2.15rem; cursor:pointer;
      font-family:'Manrope','Poppins',sans-serif; font-size:.72rem; font-weight:600;
      padding:var(--space-1) var(--space-2); border-radius: var(--radius-pill); color:var(--precs-gold,#B49552);
      background:transparent; border:1px solid var(--border-color); }
    .precs-sup-atend-btn:hover{ border-color:var(--precs-gold,#B49552); }
    .precs-sup-atend-btn:focus-visible{ outline:2px solid var(--precs-gold,#B49552); outline-offset:1px; }
    .precs-sup-atend-semdeal{ margin:var(--space-1) 0 0 2.15rem; font-size:.72rem; color:var(--text-muted); }
    .precs-sup-atend-det{ margin:var(--space-2) 0 0 2.15rem; padding:var(--space-2) var(--space-3);
      border-radius:var(--radius-inner); background:var(--bg-primary);
      border:1px solid var(--border-color); }
    .precs-sup-atend-neg{ display:flex; flex-wrap:wrap; align-items:baseline; gap:var(--space-2);
      padding-bottom:var(--space-2); margin-bottom:var(--space-2); border-bottom:1px solid var(--border-color); }
    .precs-sup-atend-tit{ font-weight:600; font-size:.8rem; color:var(--text-primary); }
    .precs-sup-atend-meta{ font-size:.7rem; color:var(--text-muted);
      font-family:'JetBrains Mono',monospace; }
    /* PRECS (1.1.1) — "Abrir no Pipe" era um link de 0,7rem sem área de clique, perdido
       na ponta direita de uma linha densa. É a ação PRINCIPAL do detalhe: é para isso
       que a supervisora abre o painel. Virou botão de verdade — contorno, respiro e
       alvo de clique — e ganhou o ícone de link externo, que já é a convenção do resto
       do painel para "abre em outra aba".
       (1.1.15) E VIROU O PADRÃO `.precs-pipe-btn`, verde do Pipedrive, junto com o do espelho:
       a regra do dourado é "cor da PRECS", e este botão leva para FORA. O que sobra aqui é só
       o posicionamento na linha densa do card de atendimento. */
    .precs-sup-atend-det .precs-pipe-btn{ margin-left:auto; flex:none; white-space:nowrap; }
    .precs-sup-atend-nota{ display:flex; flex-wrap:wrap; align-items:baseline; gap:var(--space-1);
      padding:var(--space-1) 0; border-top:1px solid var(--border-color); font-size:.76rem; }
    .precs-sup-atend-det .precs-sup-atend-nota:first-of-type{ border-top:none; }
    .precs-sup-atend-nota-txt{ flex:1 1 100%; color:var(--text-secondary); line-height:1.45;
      white-space:pre-wrap; overflow-wrap:anywhere; }
    .precs-sup-atend-carimbos{ margin-top:var(--space-2); font-size:.7rem; color:var(--text-muted); }

    /* Diagnóstico de campos (Fase 0) — temporário, sai com o DIAG_REMOTO. */
    .precs-sup-campos:empty{ display:none; }
    .precs-sup-campos{ margin-top:var(--space-4); padding:var(--space-3) var(--space-4); border-radius:var(--radius-card);
      background:var(--bg-secondary); border:1px dashed var(--border-color); }
    .precs-sup-campos-cab{ display:flex; align-items:center; justify-content:space-between;
      gap:var(--space-2); font-size:.72rem; text-transform:uppercase; letter-spacing: var(--ls-caps);
      font-weight:700; color:var(--text-muted); margin-bottom:var(--space-2); }
    /* (1.1.15) O botão "copiar" deste cabeçalho usava `.precs-cad-btn`, que era do editor de
       cadastro de operadores. O editor foi apagado, e um botão que empresta o estilo de outra
       tela morre quando ela sai: agora ele tem a própria regra, com a mesma aparência. */
    .precs-sup-campos-btn{ cursor:pointer; font-family:'Manrope','Poppins',sans-serif; font-size:.72rem;
      font-weight:600; padding:var(--space-1) var(--space-1); border-radius: var(--radius-sm);
      color:var(--precs-gold,#B49552); background:transparent; border:1px solid var(--border-color); }
    .precs-sup-campos-btn:hover{ border-color:var(--precs-gold,#B49552); }
    .precs-sup-campos-txt{ margin:0; font-family:'JetBrains Mono',monospace; font-size:.7rem;
      line-height:1.6; color:var(--text-secondary); white-space:pre-wrap;
      overflow-wrap:anywhere; max-height:16em; overflow-y:auto; }
    /* O feed guarda 40 eventos e chegam vários por segundo: com 62vh ele esticava a
       coluna e empurrava "Ligações por campanha" para o fim da página. 300px mostram os
       últimos ~8, que é o que "ao vivo" quer dizer; o resto rola dentro dele. */
    .precs-sup-feed{ max-height:300px; overflow-y:auto; padding:var(--space-1) 0; }
    .precs-sup-feed-item{ display:flex; align-items:center; gap:var(--space-2); padding:var(--space-2) var(--space-4); border-top:1px solid var(--border-color); font-size:.82rem; }
    /* (1.1.22) O item novo entra pela curva canônica do projeto. Só quem NASCE anima (o feed
       reconcilia por chave, então item existente nunca passa por aqui) e só quando o feed já
       tinha conteúdo — a primeira leva não é notícia, é boot. */
    .precs-sup-feed-item.entra{ animation: precsLeadIn .32s var(--ease-2); }
    @media (prefers-reduced-motion: reduce){ .precs-sup-feed-item.entra{ animation:none; } }
    .precs-sup-feed .precs-sup-feed-item:first-child{ border-top:none; }
    /* (1.1.9) O item mais recente pulsa, reusando a animação do "ao vivo" do operador
       (precsAoVivoDot, definida mais abaixo neste arquivo). Só o primeiro: a lista tem 40
       linhas e animar todas viraria ruído. */
    .precs-sup-feed-item.novo .dot{ animation: precsAoVivoDot 1.3s ease-in-out infinite; }
    /* (1.1.46) O ÚLTIMO FURO DA VARREDURA DE MOVIMENTO. Esta era a única das 33 animações
       `infinite` do projeto sem guarda — e das piores para ficar sem, porque é `infinite` num
       painel que fica aberto o turno inteiro. O irmão logo acima (`.entra`) tem a dele na linha
       seguinte, e a mesma keyframe está guardada nos outros dois consumidores (`.precs-aovivo
       .dot` e `.precs-wa-grav-dot`); nenhuma das duas alcançava este seletor. */
    @media (prefers-reduced-motion: reduce){ .precs-sup-feed-item.novo .dot{ animation:none; } }
    /* (1.1.15 · 7ª volta) A LINHA COM RESSALVA se anuncia. Hoje é só a do logout: a 3C não informa
       quem encerrou a sessão, e "Fulano saiu" sem essa ressalva lê como decisão dele. O sublinhado
       pontilhado é a convenção que o resto do painel já usa para "tem mais a ler aqui", e o
       `cursor:help` é o que faz alguém parar o mouse para descobrir. */
    .precs-sup-feed-item.com-dica{ cursor:help; }
    .precs-sup-feed-item.com-dica .precs-sup-feed-txt{
      text-decoration:underline dotted;
      text-decoration-color:color-mix(in srgb, var(--text-muted) 70%, transparent);
      text-underline-offset:3px;
    }
    @media (prefers-reduced-motion: reduce){
      .precs-sup-feed-item.novo .dot{ animation:none; }
    }
    /* ======================================================================
       (1.1.68) O ICONE DE DESFECHO DO AO VIVO.

       Ele ocupa o lugar do ponto na linha, entao herda a mesma regra de flex: largura fixa, sem
       encolher e sem crescer. `flex:0 0 auto` e nao `0 0 8px` porque o SVG tem 13px -- o ponto
       cabia em 8 e o glifo precisa de mais para ainda ser reconhecivel.

       NENHUMA COR NOVA: `--st-call` e o verde de "em chamada", `--st-manual` o laranja de "alguem
       precisa olhar", `--st-mtpa` o roxo da maquina atendendo e `--accent-red` a falha. Sao as
       cores que a tela ja usa com esses significados, e por isso o icone nao precisa ser
       aprendido.

       E A COR AQUI E DO DESFECHO, NAO DO AGENTE, que e a diferenca que fez o bloco existir: o
       ponto do feed pinta o ESTADO de quem gerou o evento, e numa ligacao abandonada nao ha agente
       nenhum. O cinza de ocioso diria a coisa errada sobre a unica linha do feed que e alarme. */
    .precs-sup-feed-ico{ flex:0 0 auto; display:inline-block; }
    .precs-sup-feed-ico[data-desf="conectada"]{ color:var(--st-call); }
    /* O laranja de "alguém precisa olhar" é o certo aqui: abandono é credor que atendeu e não
       encontrou operador livre. A linha só chega até este seletor depois do filtro do AMD — ver
       PRECS_SUP_AMD_JANELA em app.js, onde 29 de 29 eventos medidos eram caixa postal. */
    .precs-sup-feed-ico[data-desf="abandonada"]{ color:var(--st-manual); }
    .precs-sup-feed-ico[data-desf="caixa"]{ color:var(--st-mtpa); }
    .precs-sup-feed-ico[data-desf="falha"]{ color:var(--accent-red); }
    /* O PULSO DA LINHA MAIS NOVA SEGUE VALENDO. Ele estava preso a `.dot`, e o icone teria tirado
       do feed a unica marca de "isto acabou de acontecer" justo nas linhas de ligacao. Com a
       guarda de movimento reduzido na linha seguinte, como manda o irmao logo acima. */
    .precs-sup-feed-item.novo .precs-sup-feed-ico{ animation: precsAoVivoDot 1.3s ease-in-out infinite; }
    @media (prefers-reduced-motion: reduce){
      .precs-sup-feed-item.novo .precs-sup-feed-ico{ animation:none; }
    }
    .precs-sup-feed-txt{ flex:1; color:var(--text-secondary); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-sup-feed-t{ font-size:.7rem; color:var(--text-muted); font-family:'JetBrains Mono',monospace; }
    .og-stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:var(--space-2); margin-bottom:var(--space-4); }
    .og-stat{ text-align:center; }
    .og-stat b{ display:block; font-size:1.15rem; font-weight:700; color:var(--text-primary); line-height:1.1; }
    .og-stat span{ font-size:.62rem; text-transform:uppercase; letter-spacing: var(--ls-caps); color:var(--text-muted); }
    .og-bars{ display:flex; align-items:flex-end; gap:var(--space-2); }
    .og-day{ flex:1; display:flex; flex-direction:column; align-items:center; gap:var(--space-1); }
    .og-day-val{ font-size:.72rem; color:var(--text-secondary); font-weight:600; min-height:.85em; }
    .og-track{ width:100%; height:52px; display:flex; align-items:flex-end; }
    .og-bar{
      width:100%; border-radius:4px 4px 0 0; background:var(--m-ligacoes,#E8A33D);
      height:0; min-height:2px; position:relative; overflow:hidden;
      transition:height .5s var(--ease-1);
    }
    .og-bar i{
      position:absolute; left:0; right:0; bottom:0; display:block;
      background:var(--m-atendidas,#22C55E); height:0;
      transition:height .5s var(--ease-1);
    }
    .og-day small{ font-size:.7rem; color:var(--text-muted); }
    .og-day{ cursor:pointer; }
    .og-day.sel .og-bar{ outline:2px solid var(--precs-gold,#B49552); outline-offset:1px; }
    .og-voltar{
      float:right; background:none; border:none; color:var(--precs-gold,#B49552);
      font-size:.7rem; font-weight:700; cursor:pointer; padding:0;
    }
    /* Donut de qualificações (Meu Desempenho + gráfico ocioso) — SVG puro */
    .pm-donut-wrap{ display:flex; align-items:center; gap:var(--space-4); margin-top:var(--space-2); }
    .pm-donut{ width:92px; height:92px; flex:0 0 auto; }
    .pm-donut-num{ font-size:20px; font-weight:700; fill:var(--text-primary); }
    .pm-donut-lbl{ font-size:8px; fill:var(--text-muted); text-transform:uppercase; letter-spacing: var(--ls-caps); }
    .pm-leg-wrap{ flex:1; display:flex; flex-direction:column; gap:var(--space-1); min-width:0; }
    .pm-leg{ display:flex; align-items:center; gap:var(--space-2); font-size:.84rem; }
    /* (1.1.6) Anel interno pelo mesmo motivo do anel de base do donut: o ponto de "Mudo" e
       "Caixa Postal" é #1f2937 e desaparecia no card escuro, então a legenda tinha uma
       linha com nome e contagem e nenhuma cor visível ao lado. O recurso é o que a
       .precs-etiqueta já usa neste arquivo: contorno por inset shadow, que não ocupa caixa
       e por isso não desloca nada na fila. */
    .pm-leg-dot{ width:9px; height:9px; border-radius:50%; flex:0 0 auto;
      box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text-primary) 25%, transparent); }
    .pm-leg-nome{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--text-secondary); }
    .pm-leg-qtd{ color:var(--text-muted); font-weight:600; white-space:nowrap; }
    /* Interação do donut: fatia cresce no hover/foco, legenda acende/apaga */
    .pm-donut-seg{ transition:stroke-width .18s ease, opacity .18s ease; cursor:pointer; }
    .pm-donut-wrap .pm-leg{ cursor:pointer; border-radius:var(--radius-sm); padding:var(--space-0) var(--space-1); transition:background var(--dur-1) ease, opacity var(--dur-1) ease; }
    .pm-leg.pm-leg-hover{ background:color-mix(in srgb, var(--precs-gold,#B49552) 16%, transparent); }
    .pm-leg.pm-leg-off{ opacity:.4; }
    /* ======================================================================
       (1.1.72) A QUALIFICAÇÃO ESCOLHIDA GANHA O ANEL DA COR DELA.

       Pedido do Pedro em 14/09/2026: "quando selecionamos as qualificações no discador em TPA
       fica a corzinha em volta, bem bonito; a gente podia fazer com que na supervisão ao
       selecionar uma qualificação para filtrar ficasse a mesma borda".

       É LITERALMENTE A MESMA RECEITA de `.qualification-item.selected` (00-base.css): borda na
       cor, fundo com 12% dela e o anel por `box-shadow`. Reusar o desenho, e não só a ideia, é o
       que faz o supervisor reconhecer na hora um estado que ele já conhece da tela do operador.

       A COR VEM DO PRÓPRIO ITEM (`--qual-cor`, escrito no render), então o anel é da cor da
       qualificação escolhida. O fallback em `--accent-blue` cobre o balde "Não qualificada", que
       é cinza e não tem cor de qualificação própria.

       SELEÇÃO NÃO É HOVER, e as classes são separadas por isso: com as duas na mesma, passar o
       mouse acenderia a moldura de "escolhido" numa qualificação que ninguém escolheu.

       SEM O `box-shadow` DO ORIGINAL, e a diferença é de contexto e não de gosto: lá o anel duplica
       a borda porque o item tem 44px de altura e precisa se destacar de longe; aqui a legenda tem
       uma linha, e a borda mais o fundo já resolvem. Evita também somar uma linha ao contador
       `anel-cru` da catraca, que existe justamente porque essas sombras não têm token ainda.

       A BORDA TRANSPARENTE NASCE COM O ITEM, e não aparece só na seleção: sem ela o item ganharia
       1px de cada lado ao ser escolhido, e a coluna inteira andaria a cada clique.

       E ELA VEM ANTES DA REGRA DE SELEÇÃO, o que não é arrumação: `.pm-donut-wrap .pm-leg` e
       `.pm-leg.pm-leg-sel` têm a MESMA especificidade (0,2,0), então quem estiver por último
       vence. Com a transparente embaixo, o `border-color` da escolhida era apagado e a medida do
       teste voltava `rgba(0,0,0,0)` nas duas. É a mesma cicatriz das três cores do tempo do
       status, duas levas atrás. */
    .pm-donut-wrap .pm-leg{ border:1px solid transparent; }
    .pm-leg.pm-leg-sel{
      border-color: var(--qual-cor, var(--accent-blue));
      background: color-mix(in srgb, var(--qual-cor, var(--accent-blue)) 12%, transparent);
      font-weight: 600;
    }
    .pm-leg.pm-leg-sel .pm-leg-nome{ color:var(--text-primary); }
    .pm-donut-num{ transition:opacity var(--dur-1) ease; }
    /* fade suave ao trocar de dia (donut e gráfico ocioso reanimam) */
    .pm-donut-wrap{ animation:pmFade var(--dur-3) ease; }
    .og-inner{ animation:pmFade var(--dur-3) ease; }
    /* Botão Desligar: só aparece com .hangup-on (sem reservar espaço — o antigo
       reserve deixava um vão grande). A altura estável do card vem do min-height
       do corpo (abaixo), que acomoda tanto o estado ocioso quanto o em-chamada. */
    #hangup-wrap{ display:none; }
    #hangup-wrap.hangup-on{ display:block; }
    /* Altura mínima do corpo da campanha: dá um piso confortável ao ocioso e ao
       em-chamada. No TPA o botão Desligar some e o card fica compacto — como a
       seção está ancorada no topo, o topo do card não se mexe (só encolhe para
       baixo), então não sobra o vão gigante que existia com espaço reservado. */
    #precs-card-campanha .panel-body{ min-height: 15rem; }

    /* ======================================================================
       (1.1.139) A SUPERVISÃO NO CELULAR: o que ainda vazava para o lado.
       A vista de bolso da supervisão já existe no 60-campanhas-e-tv.css (cards de contagem em faixa que rola,
       linha da tabela em áreas, filtros em coluna). O relato de 25/09/2026 mostrava a PÁGINA inteira rolando de
       lado mesmo assim, e a causa é a grade: um item de grid nasce com `min-width:auto`, então o painel cresce
       até a largura do conteúdo mais largo (a barra de ações das campanhas, um cabeçalho de painel com selo e
       botões numa linha só) e arrasta a página junto. Aqui: os itens da grade e os painéis travados na largura
       da tela, as barras que quebram linha, e um cinto de segurança no contêiner.
       ====================================================================== */
    html[data-aparelho]:not([data-tv]) .precs-sup-wrap{ max-width: 100%; overflow-x: hidden; }
    html[data-aparelho]:not([data-tv]) .precs-sup-grid > *{ min-width: 0; max-width: 100%; }
    html[data-aparelho]:not([data-tv]) .precs-sup-panel{ max-width: 100%; }
    html[data-aparelho]:not([data-tv]) .precs-sup-panel .panel-header{ flex-wrap: wrap; gap: var(--space-2); }
    html[data-aparelho]:not([data-tv]) .precs-camp-acoes{ flex-wrap: wrap; row-gap: var(--space-2); max-width: 100%; }
    html[data-aparelho]:not([data-tv]) .precs-campt-filtro .precs-campt-secoes{ flex-wrap: wrap; }
    /* O CARTÃO DO AGENTE num celular ESTREITO (360px): a linha de baixo (lig, conv, tempo e os dois botões) somava
       319px numa caixa de 304px, e a página rolava de lado exatamente esses 15px. A saída que mantém as TRÊS
       faixas (quatro davam 152px por cartão) é medir o próprio painel (container query, não media query) e, abaixo
       de 330px, encolher o vão das colunas e deixar os botões só com o ícone: o `aria-label` e o balão seguem
       dizendo "Escutar" e "Deslogar". */
    html[data-aparelho]:not([data-tv]) #sup-agentes{ container-type: inline-size; }
    /* `#sup-agentes` nos seletores por ESPECIFICIDADE: este arquivo carrega antes do 60-campanhas-e-tv.css, e a vista
       de bolso de lá tem as mesmas classes (nth-child(7) button); em empate quem vem depois vence. O id desempata. */
    @container (max-width: 330px){
      html[data-aparelho]:not([data-tv]) #sup-agentes .precs-sup-linha{ column-gap: var(--space-1); }
      html[data-aparelho]:not([data-tv]) #sup-agentes .precs-sup-linha > *:nth-child(7){ gap: var(--space-0); }
      html[data-aparelho]:not([data-tv]) #sup-agentes .precs-sup-linha > *:nth-child(7) .precs-sup-rot{ display: none; }
      html[data-aparelho]:not([data-tv]) #sup-agentes .precs-sup-linha > *:nth-child(7) button,
      html[data-aparelho]:not([data-tv]) #sup-agentes .precs-sup-linha > *:nth-child(7) .btn{ padding-left: var(--space-1); padding-right: var(--space-1); }
    }

    /* (1.1.142) OS PAINÉIS DO LADO NO CELULAR ("alguns cards como o ao vivo, ligações por campanha quebram no
       celular", Pedro, 25/09/2026). A coluna lateral era `grid-auto-columns: auto` abaixo de 1100px, e uma linha
       sem quebra dentro de "Em atendimento agora" (o motivo da ligação) puxava o painel para 450px numa tela de
       393: a página inteira andava de lado e as barras e o "Ao vivo" saíam da borda. Coluna de largura mínima
       zero, e o que era `nowrap` passa a quebrar: no celular a linha inteira vale mais que a linha única. */
    html[data-aparelho]:not([data-tv]) .precs-sup-lado{ grid-auto-flow: row; grid-template-columns: minmax(0, 1fr); grid-auto-columns: minmax(0, 1fr); }
    html[data-aparelho]:not([data-tv]) .precs-sup-lado > *{ min-width: 0; max-width: 100%; }
    html[data-aparelho]:not([data-tv]) .precs-sup-atend, html[data-aparelho]:not([data-tv]) .precs-sup-atend *{ white-space: normal; overflow-wrap: anywhere; }
    html[data-aparelho]:not([data-tv]) .precs-sup-atend-cab{ flex-wrap: wrap; }
    html[data-aparelho]:not([data-tv]) .precs-sup-feed-item{ align-items: flex-start; }
    html[data-aparelho]:not([data-tv]) .precs-sup-feed-txt{ white-space: normal; overflow-wrap: anywhere; }
    html[data-aparelho]:not([data-tv]) .precs-sup-feed-t{ white-space: nowrap; }
    html[data-aparelho]:not([data-tv]) .precs-sup-cbar{ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 2.6rem; }
    html[data-aparelho]:not([data-tv]) .precs-sup-cbar > *{ min-width: 0; }
    html[data-aparelho]:not([data-tv]) .precs-sup-cbar-ag{ display: none; }
    html[data-aparelho]:not([data-tv]) .precs-sup-cbar-nota{ white-space: normal; }
