    /* ===== Tela de Ensaio (editar layout) ===== */
    .precs-ensaio-overlay {
      display: none;
      position: fixed;
      inset: 0;
      z-index: 1000;
      background: var(--bg-primary, #0f0f0f);
      flex-direction: column;
    }
    .precs-ensaio-overlay.open { display: flex; animation: precsOverlayIn var(--dur-2) ease; }
    .precs-ensaio-overlay.closing { animation: precsOverlayOut var(--dur-2) ease forwards; }
    @keyframes precsOverlayIn { from { opacity: 0; } to { opacity: 1; } }
    @media (prefers-reduced-motion: reduce) {
      .precs-ensaio-overlay.open, .precs-ensaio-overlay.closing { animation: none; }
    }
    .precs-ensaio-topbar {
      flex: 0 0 auto;
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: var(--space-4);
      padding: var(--space-4) var(--space-6);
      border-bottom: 1px solid var(--border-color);
      background: var(--bg-secondary);
    }
    .precs-ensaio-titulo { display: flex; flex-direction: column; gap: var(--space-0); }
    .precs-ensaio-titulo-linha {
      display: inline-flex;
      align-items: center;
      gap: var(--space-2);
      font-weight: 700;
      font-size: 1.05rem;
    }
    .precs-ensaio-titulo-linha svg { color: var(--accent-color, #B49552); flex-shrink: 0; }
    .precs-ensaio-sub { font-size: 0.8rem; color: var(--text-secondary); }
    .precs-ensaio-acoes { display: flex; gap: var(--space-2); flex-shrink: 0; }
    .precs-ensaio-acoes .btn {
      padding: var(--space-2) var(--space-4);
      font-size: 0.88rem;
      line-height: 1.2;
      white-space: nowrap;
      width: auto;
      min-width: 0;
    }
    /* Topbar responsiva: em telas estreitas empilha título e ações, e os
       botões dividem a largura igualmente sem estourar. */
    @media (max-width: 820px) {
      .precs-ensaio-topbar {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-3);
      }
      .precs-ensaio-acoes { width: 100%; }
      .precs-ensaio-acoes .btn { flex: 1; padding: var(--space-2) var(--space-2); font-size: 0.82rem; }
    }
    /* (1.1.44) O ENSAIO PASSOU A RODAR COM O ZOOM DO PAINEL, e isto é a MESMA correção que o
       espelho da supervisão já tinha recebido, pelo mesmo motivo escrito lá: "não era escolha
       de tamanho, era o zoom faltando".

       O Ensaio não é um esquema: ele monta os cards de VERDADE, com as classes de verdade
       (`.precs-col-card`, `.call-details`, `.detail-card`) e dados fictícios. Sem o zoom, a
       mesma regra de CSS renderizava ~18% maior aqui do que na tela de campanha no modo normal,
       e ~39% maior no compacto — ou seja, o operador arrumava os cards numa proporção que ele
       nunca veria trabalhando, e o que "cabia" no Ensaio podia não caber de fato.

       O ARRASTE SOBREVIVE porque ele é o nativo do HTML5 (`draggable`, `dragstart`, `dragover`),
       e quem faz o teste de acerto é o navegador. O que `zoom` costuma quebrar é ancoragem de
       `position: fixed` e conta de coordenada entre espaços diferentes; aqui a comparação é
       entre `clientY` e `getBoundingClientRect()`, que vivem no MESMO espaço e continuam
       coerentes. Não há nenhum `fixed` dentro do palco. */
    html[data-fonte="compacto"]    .precs-ensaio-palco { zoom: 0.72; }
    html[data-fonte="normal"]      .precs-ensaio-palco { zoom: 0.85; }
    html[data-fonte="confortavel"] .precs-ensaio-palco { zoom: 1; }
    .precs-ensaio-palco {
      flex: 1 1 auto;
      overflow: auto;
      padding: var(--space-8) var(--space-6);
      /* O palco vira o contêiner do Ensaio pelo mesmo motivo do painel: com o zoom acima, um
         limite cru de media query volta a estar errado em duas das três densidades. E o número
         passa a ser o MESMO do painel (1180), que é a propriedade que um preview fiel deve ter:
         o Ensaio empilha exatamente onde a tela de campanha empilha. */
      container-type: inline-size;
      container-name: ensaio;
    }
    /* Grade do ensaio: 3 colunas flex independentes (não estoura a tela) */
    .precs-ensaio-grid {
      max-width: 1700px;
      margin: 0 auto;
      display: flex;
      align-items: flex-start;
      justify-content: center;
      gap: var(--space-6);
    }
    .precs-ensaio-col {
      flex: 1 1 0;
      min-width: 0;
      display: flex;
      flex-direction: column;
      gap: var(--space-2);
    }
    /* Coluna do meio um pouco mais larga (cabe campanha/pipe confortável) */
    .precs-ensaio-col[data-col="2"] { flex: 1.3 1 0; }

    .precs-ensaio-card {
      position: relative;
      width: 100%;
      outline: 2px dashed var(--accent-color, #B49552);
      outline-offset: 3px;
      cursor: grab;
      transition: opacity var(--dur-1), transform .1s;
    }
    .precs-ensaio-card.precs-dragging { opacity: 0.4; cursor: grabbing; }

    /* (1.1.7) Card que NÃO pode ser escondido. A marca vai na etiqueta porque é ela que o
       operador olha antes de arrastar, e é texto e não ícone para seguir a decisão do
       projeto de não usar emoji na interface. O card segue arrastável: o que a marca
       comunica é "muda de lugar, não desaparece". */
    .precs-ensaio-card.precs-card-fixo > .precs-card-grip::after {
      content: ' · fixo';
      opacity: .75;
      font-weight: 600;
    }

    /* ---- PRECS (1.1.7) — INTERRUPTOR DE VISIBILIDADE POR CARD ---- */
    /* Fica no canto oposto à etiqueta, dentro do próprio card. É um botão de verdade
       (foco, Enter, leitor de tela), e não um alvo de arraste: recuperar um card não pode
       depender de mira. `pointer-events` explícito porque a etiqueta vizinha desliga o
       dela para não roubar o arraste, e o botão precisa do contrário. */
    .precs-card-visi {
      position: absolute;
      top: 0.5rem; right: 0.85rem;
      z-index: 6;
      pointer-events: auto;
      display: inline-flex; align-items: center; gap: var(--space-1);
      padding: var(--space-0) var(--space-3);
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-pill);
      font-family: 'Manrope','Poppins',sans-serif;
      font-size: 0.72rem; font-weight: 700; letter-spacing: .3px;
      color: var(--text-secondary);
      cursor: pointer;
      transition: border-color .12s, color .12s, background .12s;
    }
    .precs-card-visi:hover { border-color: var(--accent-color, #B49552); color: var(--text-primary); }
    .precs-card-visi:focus-visible { outline: 2px solid var(--accent-color, #B49552); outline-offset: 2px; }

    /* O card ESCONDIDO continua no lugar dele, esmaecido e encolhido até a altura da
       etiqueta. Ver o card apagado ONDE ELE ESTAVA é o que ensina o que "escondido"
       significa, e é o que garante que o operador saiba onde ele volta a aparecer.
       Sem `display:none` de propósito: o dia em que este card sumir da tela de ensaio é o
       dia em que alguém volta a perdê-lo. */
    .precs-ensaio-card.precs-oculto {
      max-height: 2.6rem;
      overflow: hidden;
      opacity: .45;
      filter: grayscale(1);
      outline-style: dotted;
      cursor: default;
    }
    .precs-ensaio-card.precs-oculto > .precs-card-grip::after {
      content: ' · escondido';
      opacity: .85;
      font-weight: 600;
    }
    /* O botão não pode herdar o esmaecimento: é ele que desfaz o estado, então tem que
       continuar legível e clicável enquanto tudo em volta está apagado. */
    .precs-ensaio-card.precs-oculto > .precs-card-visi {
      opacity: 1;
      filter: none;
      border-color: var(--accent-color, #B49552);
      color: var(--accent-color, #B49552);
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-ensaio-card, .precs-card-visi { transition: none; }
    }
    /* No ensaio o mailing aparece inteiro (sem teto de altura) */
    .precs-ensaio-card[data-card-key="mailing"] {
      max-height: none !important;
      overflow: visible !important;
    }

    /* Slots (espaços pontilhados): invisíveis até começar a arrastar */
    .precs-slot {
      height: 0;
      min-height: 0;
      border: 2px dashed transparent;
      border-radius: var(--radius-inner);
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;
      transition: height .12s ease, min-height .12s ease, border-color .12s, background .12s;
    }
    .precs-ensaio-grid.precs-arrastando .precs-slot {
      height: 54px;
      min-height: 54px;
      border-color: var(--text-muted, #888);
    }
    .precs-slot-dica {
      font-size: 0.78rem;
      color: var(--text-muted, #888);
      opacity: 0;
      transition: opacity .12s;
      pointer-events: none;
    }
    .precs-ensaio-grid.precs-arrastando .precs-slot .precs-slot-dica { opacity: 0.7; }
    .precs-slot.precs-slot-ativo {
      border-color: var(--accent-color, #B49552);
      border-style: solid;
      background: rgba(180,149,82,0.12);
    }
    .precs-slot.precs-slot-ativo .precs-slot-dica { color: var(--accent-color, #B49552); opacity: 1; }

    /* O card escondido do PAINEL REAL. !important é NECESSÁRIO, não preguiça: o app.js
       escreve style.display nesses mesmos cards durante o ciclo da ligação (mailing ao
       conectar, qualificação no TPA, negócio ao vincular), e sem o !important o card
       ocultado voltaria a aparecer no próximo evento de chamada.
       (1.1.7) Só vale para o painel REAL. No ensaio o escondido usa .precs-oculto, que
       ESMAECE em vez de sumir: lá o operador precisa continuar vendo o card para poder
       trazê-lo de volta. */
    .precs-card-oculto { display: none !important; }

    /* Rodapé do ensaio: o resumo do que está escondido, em texto. Serve de conferência
       final antes de salvar, para ninguém sair da tela sem saber o que tirou. */
    .precs-ensaio-rodape {
      margin: var(--space-5) auto 0;
      max-width: 1700px;
      padding-top: var(--space-3);
      border-top: 1px solid var(--border-color);
      font-family: 'Manrope','Poppins',sans-serif;
      font-size: .8rem;
      color: var(--text-secondary);
    }
    .precs-ensaio-rodape b { color: var(--text-primary); }
    /* (1.1.10) Número de telefone do mock do Ensaio. Substitui o último `style="font-size"`
       inline que restava no index.html — o outro já tinha sido removido antes, e este ficou
       sozinho justamente porque estava dentro do mock, que ninguém revisa. */
    .precs-ensaio-tel { font-size: 1.25rem; }

    /* Espaço no topo do card de ensaio para a etiqueta (grip) caber dentro,
       sem ser cortada pela borda. */
    .precs-ensaio-card { padding-top: var(--space-6); }
    .precs-card-grip {
      position: absolute;
      top: 0.5rem; left: 0.85rem;
      /* (1.1.42) Aqui o ouro era USADO COMO SUPERFÍCIE mas vinha do token de TEXTO
         (`--accent-color` segue `--precs-gold`). Nos temas claros esse token é o bronze
         escuro, feito para ser letra; no Zebrado claro ele vale `#101010`. Com o rótulo
         `#1a1a1a` cravado por cima, a pílula saía PRETA COM TEXTO PRETO.
         O par certo para fundo é `--precs-gold-forma` + `--precs-wa-tinta-ouro`: os dois são
         declarados juntos por todos os nove temas, e o `teste-temas.js` cobra isso. */
      background: var(--precs-gold-forma, #B49552);
      color: var(--precs-wa-tinta-ouro, #131315);
      font-size: 0.72rem; font-weight: 700;
      padding: var(--space-0) var(--space-3);
      border-radius: var(--radius-pill);
      letter-spacing: 0.4px;
      z-index: 5;
      pointer-events: none;
      white-space: nowrap;
      box-shadow: var(--shadow);
    }

    .precs-prefs-label {
      font-size: 0.8rem;
      font-weight: 600;
      color: var(--text-secondary);
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      margin-bottom: var(--space-2);
    }
    .precs-prefs-hint {
      font-size: 0.78rem;
      color: var(--text-muted);
      margin-top: var(--space-2);
      line-height: 1.4;
    }
    /* Botões segmentados (escolha única) */
    .precs-seg {
      display: flex;
      gap: var(--space-2);
      background: var(--bg-primary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-inner);
      padding: var(--space-1);
    }
    /* (1.1.16) `display:flex` de autor VENCE o `[hidden]{display:none}` do navegador, que é regra
       de UA. Sem esta linha, `el.hidden = true` num `.precs-seg` não esconde nada: foi o que o
       print de conferência da tela de Escuta mostrou, com a faixa de abas na tela e o `hidden`
       valendo `true` no DOM. Mesma armadilha do `.precs-card-oculto`, que precisou de
       `!important` porque o JS escreve `display` nos mesmos cards. */
    .precs-seg[hidden] { display: none; }
    /* (1.1.39) E A MESMA ARMADILHA PEGOU O BOTÃO, uma linha depois.
       Ao dar `display: inline-flex` ao botão (para o ícone e o rótulo alinharem), a regra de
       autor passou a vencer o `[hidden]{display:none}` de UA — e a aba "Campanhas", que o
       perfil de shadow esconde por `btn.hidden = true` (ver `precsSupAplicarPerfil`), voltou a
       aparecer para quem não pode vê-la. Quem pegou foi o `teste-supervisao-tabela.js`, medindo
       `getComputedStyle(...).display` do botão. É exatamente o caso que o comentário logo acima
       descreve para o contêiner; declarar o par junto é o que impede a terceira ocorrência. */
    .precs-seg button[hidden] { display: none; }
    .precs-seg button {
      flex: 1;
      display: inline-flex; align-items: center; justify-content: center; gap: 6px;
      padding: var(--space-2) var(--space-2);
      border: none;
      background: transparent;
      color: var(--text-secondary);
      font-family: inherit;
      font-size: 0.85rem;
      font-weight: 500;
      /* (1.1.39) Era `7px` cravado, o único número mágico do componente — o trilho usa
         `--radius-inner` (8px) e a pastilha ficava 1px fora do encaixe. */
      border-radius: calc(var(--radius-inner) - 1px);
      cursor: pointer;
      transition: background var(--dur-2), color var(--dur-2), box-shadow var(--dur-2);
      white-space: nowrap;
    }
    /* (1.1.39) O hover só mudava a COR DO TEXTO, o que num trilho escuro é quase nada. Entra a
       lavagem de fundo, copiada do único segmentado que já tinha hover decente: a aba do
       WhatsApp na supervisão (`.precs-sup-aba-wa:hover`, mais abaixo neste arquivo). */
    .precs-seg button:hover { color: var(--text-primary);
      background: color-mix(in srgb, var(--text-primary) 6%, transparent); }
    /* ======================================================================
       (1.1.39) O SELECIONADO GANHOU O OURO EM TODOS OS GRUPOS.

       O ouro com anel existia numa regra só, escrita à mão para o botão PRECS do grupo de
       TEMA. Todo o resto do modal — Tamanho do painel, Fundo da conversa, Anotação durante a
       ligação, Log de eventos — ficava com a pastilha cinza genérica. Daí o estranhamento do
       Pedro em 28/08/2026: "ao selecionar por exemplo o PRECS do TEMA é muito mais bonito
       selecionado que o PRECS do fundo da conversa, sendo que os dois são PRECS". Era o MESMO
       nome, o MESMO glyph (U+2726 nos dois), e um tratamento visual em cada.

       Não era duplicação de CSS: era subespecificação. Existia um `.active` genérico e um
       override manual. A correção é promover o override a regra do componente — e com ele
       valem também as abas da supervisão e os filtros de período, que usam o mesmo `.precs-seg`.

       `--precs-gold-forma` no lugar do `#B49552` cravado: aquele literal ignorava o tema
       Contraste, onde o ouro é #E8C46A, e no tema claro deixava o anel numa cor que não é a
       do tema nem a da marca. O anel é FORMA, não texto — é exatamente o caso para o qual
       esse token foi criado. A cor da LETRA continua saindo de `--precs-gold-title`, que é
       tokenizado por tema e responde pelo contraste.

       ESCOPADO AO MODAL, e isso é deliberado. `.precs-seg` também veste as abas da supervisão
       (onde a aba do WhatsApp é verde de propósito) e os filtros de período. O relato é sobre
       Preferências, e pintar de ouro a faixa de abas de outra tela seria decidir por conta
       própria uma mudança que ninguém pediu. Quando essa decisão for tomada, é só subir o
       seletor. */
    .precs-seg button.active {
      background: var(--bg-secondary);
      color: var(--text-primary);
      box-shadow: var(--shadow);
    }
    /* (1.1.43) O ANEL DOURADO GANHOU UM CONTORNO DE TINTA POR DENTRO, e a letra deixou de ser
       o único carregador do estado.
       Medido: `.precs-seg` tem fundo `--bg-primary`, a pastilha ativa `--bg-secondary` e o hover
       uma lavagem de 6% de `--text-primary`. No Zebrado isso dá trilho #0A0A0A, ativo #141414 e
       hover ~#1B1B1B — o botão SOB O MOUSE ficava mais claro que o selecionado. E a letra do
       ativo sai de `--precs-gold-title`, que naquele tema É `--text-primary`: a mesma cor que o
       hover já dava. Vale também no PRECS e no Contraste, mais fraco.
       O contorno de tinta a 62% resolve sem tocar em `font-weight` — o teste-preferencias mede a
       largura do trilho em pixel, e mudar o peso mudaria a largura de "Contraste". */
    .precs-prefs-body .precs-seg button.active {
      color: var(--precs-gold-title, var(--precs-gold, #B49552));
      box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text-primary) 62%, transparent),
        0 0 0 1px color-mix(in srgb, var(--precs-gold-forma, #B49552) 45%, transparent),
        var(--shadow);
    }
    /* E a lavagem do hover cai para 4% DENTRO do modal, que é o outro lado da mesma medida.
       Escopado para não mexer nas abas da supervisão, que usam o mesmo `.precs-seg` e não têm
       este relato. */
    .precs-prefs-body .precs-seg button:hover:not(.active) {
      background: color-mix(in srgb, var(--text-primary) 4%, transparent);
    }
    .precs-seg button.active:hover { background: var(--bg-secondary); }
    /* (1.1.39) O ÍCONE DO SEGMENTO, com uma convenção só.
       Antes cada grupo resolvia por conta: o tema usava caracteres literais colados ao texto
       (uma delas emoji colorido de sistema), o fundo da conversa usava entidades numéricas com
       massas ópticas que não conversam (★ sólido grande ao lado de □ vazado pequeno), o
       tamanho tinha o wrapper `.precs-seg-aa`, e anotação e log não tinham nada. Ícone que
       herda `color` é o que faz o glyph acender junto com o rótulo quando o botão está ativo —
       era metade do charme do grupo de TEMA, e agora vale para todos. */
    .precs-seg-ico{ flex: 0 0 auto; display: inline-flex; align-items: center;
      justify-content: center; width: 1.05em; height: 1.05em; line-height: 1; }
    .precs-seg-ico svg{ display: block; width: 100%; height: 100%; }

    /* ======================================================================
       (1.1.41) A GALERIA DE PAPÉIS, E POR QUE ELA NÃO É UM `.precs-seg`.

       O trilho segmentado tem ~378px úteis dentro do modal (420px de largura menos os 20px
       de padding de cada lado do corpo), `flex:1` por botão e `white-space:nowrap`. Com três
       rótulos ele já vinha no limite: "Constelação" sozinho come quase um terço. O quarto
       papel não cabia, e a intenção declarada é chegar a seis ou oito.

       Grade de duas colunas resolve o espaço E resolve uma coisa que o trilho nunca deu: o
       ícone de traço dizia qual era o DESENHO, mas não dizia nada sobre a cor de fundo, a
       força da textura ou como aquilo fica atrás de um balão. A miniatura mostra o papel de
       verdade, com os mesmos quatro tokens (ver o bloco dos papéis, mais acima).

       Papel novo daqui em diante é uma linha em `PRECS_PAPEIS`, um bloco de tokens e um card.
       Nada de recontar largura. */
    /* ======================================================================
       (1.1.41 · 2ª volta) O BOTÃO DE MAIS TEMAS E A GALERIA.

       A primeira volta pôs os temas liberados por ramal como discos de 26px ao lado do trilho.
       Coube, e mesmo assim não era o certo: o disco é uma moeda de duas cores, sem onde pôr
       nome, nota ou ícone, e a partir do quarto vira mostruário de bolinhas. Agora um botão
       abre uma GALERIA própria, que é onde tema novo cabe sem discussão de espaço.

       O botão só aparece para quem tem algo além dos três da casa: sem desbloqueio nenhum, o
       modal de Preferências fica idêntico ao de antes.

       (1.1.43) E ELE DEIXOU DE SER UM BOTÃO SOLTO: virou a QUARTA PASTILHA do trilho. Saíram
       daqui o `.precs-tema-linha` (a linha flex que embrulhava trilho e botão) e todo o estilo
       próprio do botão — borda de pílula, hover, aceso e foco. Nada disso precisa existir mais:
       como `.precs-seg button`, a pastilha herda o componente inteiro, inclusive o aceso com
       contorno de tinta que a 1.1.43 acabou de calibrar para não depender de matiz.
       Some com isso a classe de defeito que a 1.1.42 teve de medir em pixel — dois controles
       disputando a mesma linha, um empurrando o outro. Não há mais o que sobrepor.
       O que sobra é o disco, e só o espaçamento dele. Ele leva gap e recuo menores que as três
       pastilhas de rótulo: o disco de 14px pesa menos que o ícone de 1,05em, e os pixels
       economizados aqui são os que fazem os quatro rótulos caberem.
       O seletor precisa do `button`: `.precs-seg button` é (0,1,1) e declara `gap` e `padding`,
       então uma classe sozinha (0,1,0) perde e a regra não faz nada. Foi o que aconteceu na
       primeira escrita desta linha, e o sintoma foi o trilho não ganhar um pixel. */
    .precs-seg button.precs-seg-mais{ gap: 5px; padding-left: 6px; padding-right: 6px; }
    /* (1.1.43) E O TRILHO DE TEMA PODE QUEBRAR EM DUAS LINHAS. Só ele, e por medida: com quatro
       pastilhas ele precisa de 368px dos 378px que o modal oferece, e essa folga de 10px vale
       para ESTA fonte e ESTE modal. Sem o `flex-wrap`, apertar significa `scrollWidth` maior que
       o `clientWidth`, ou seja "Contraste" saindo pela direita — foi o defeito de 31/08/2026,
       que agora não tem mais como acontecer por fora e passaria a acontecer por dentro.
       Com o wrap, apertar significa a quarta pastilha descer uma linha, que é feio e legível em
       vez de bonito e cortado. O `flex: 1` de basis zero não impede o wrap: o mínimo automático
       do item de flex é o min-content, então a linha estoura e quebra em vez de encolher o
       rótulo. O teste cobra que na largura padrão ela continue em UMA linha. */
    #precs-seg-tema{ flex-wrap: wrap; }
    /* A moeda partida na diagonal: chapadas dizem "as cores deste tema"; um degradê inventaria
       tons que a paleta não tem.
       (1.1.43) SÃO TRÊS FAIXAS E NÃO DUAS. Com duas, o Bordô mostrava vinho-quase-preto e ouro,
       e o vinho do tema não aparecia em lugar nenhum do controle. A faixa do meio é `d4`, a cor
       de assinatura — a mesma que a pílula da maquete usa.

       (1.1.43) Desceu de 18px para 14px: dentro da pastilha ele divide a largura com o rótulo e
       com os outros três segmentos, e 18px empurrava a conta do trilho para o limite. 14px é a
       altura da linha do rótulo, então ele assenta sem esticar a pastilha. */
    .precs-tema-mais-disco{
      flex: 0 0 auto; width: 14px; height: 14px; border-radius: 50%;
      border: 1px solid color-mix(in srgb, var(--text-primary) 22%, transparent);
      background: linear-gradient(135deg, var(--d1, var(--bg-tertiary)) 0 40%,
        var(--d4, var(--text-muted)) 40% 68%,
        var(--d2, var(--text-muted)) 68% 100%);
    }

    /* ---- A galeria, e a lista de atalhos ---- */
    /* As duas abrem POR CIMA do modal de Preferências, então precisam de um z-index acima
       dele. O resto (véu, animação de entrada, corpo que rola) vem de `.precs-prefs-overlay`,
       que as duas vestem: dois overlays com aparências diferentes seriam dois modais, e estes
       são o mesmo modal um passo adiante.

       (1.1.54) A LISTA DE ATALHOS ENTROU NESTA REGRA, e a ausência dela era um defeito que a
       operação via. RELATO DO PEDRO, 03/09/2026: "abre a modal de preferências, depois a de
       ver os atalhos, e a de atalhos fica atrás da de preferências; tenho que fechar
       preferências pra ver os atalhos".
       ------------------------------------------------------------------------------
       A causa: `#precs-atalhos-overlay` vestia `.precs-prefs-overlay` e NÃO sobrescrevia o
       z-index, então ficava nos mesmos `2000` do modal que o abriu. Empate de z-index é
       resolvido por ORDEM DE DOM, e o overlay de Preferências vem depois no `index.html`
       (linha 495 contra 474) — então ele vencia, sempre, e a lista abria por baixo.
       Medido antes do conserto: os dois em `z-index: 2000`, e `elementFromPoint` no centro da
       tela devolvia `#precs-layout-reset-btn`, que é um botão de Preferências.
       A galeria de temas nasceu com a linha certa e por isso nunca teve o problema; a lista de
       atalhos veio depois, vestiu a mesma classe e ninguém lembrou desta. É a terceira vez que
       z-index sem escala cobra o mesmo preço neste projeto — as outras duas estão em
       `20-operador.css:786` (o balão atrás do botão que o abriu) e `20-operador.css:639` (a
       confirmação atrás da ficha ao vivo, 18/08/2026).

       AS DUAS COMPARTILHAM O VALOR de propósito, e isso não recria o empate de cima: elas são
       ALTERNATIVAS e não uma pilha. As duas só abrem de dentro de Preferências, e com uma
       delas aberta o botão que abriria a outra está atrás do próprio véu; a tecla `?` também
       não alcança, porque o handler dela desiste quando há modal no topo (`index.html:3043`).
       Quem garante que isso continua verdade é o `teste-camadas.js`, que abre os pares que
       convivem e pergunta ao navegador quem está na frente. */
    .precs-temas-overlay,
    .precs-atalhos-overlay{ z-index: 10050; }
    .precs-temas-modal{ max-width: 520px; }
    /* (1.1.43) DUAS COLUNAS FIXAS, e é a mesma grade do `.precs-papel-grade` logo abaixo.
       Com `minmax(148px, 1fr)` em 480px úteis davam TRÊS colunas de 154px, e sete cartões
       fechavam 3+3+1 com um órfão na última linha. Em duas colunas o cartão vai a 236px, que é
       a largura que faz a renda de 48px e a malha de 16px LEREM — em 154px a textura virava
       ruído. E com os dois grupos por luz os quatro escuros fecham 2x2 exato.
       O modal cresce em altura e rola pelo `overflow-y` do corpo, sob o teto de 84vh: é o
       comportamento que o `.precs-prefs-modal` já foi desenhado para ter. */
    .precs-temas-grade{
      display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--space-2); margin-bottom: var(--space-4);
    }
    /* O título de grupo é filho de LINHA CHEIA da mesma grade, e não um segundo contêiner: o
       seletor `#precs-temas-grade .precs-tema-card` continua valendo para os testes que contam
       e medem cartão. */
    .precs-temas-secao{
      grid-column: 1 / -1; margin-top: var(--space-1);
      font-size: .7rem; font-weight: 600; text-transform: uppercase;
      letter-spacing: var(--ls-caps); color: var(--text-muted);
    }
    .precs-temas-secao:first-child{ margin-top: 0; }
    .precs-tema-card{
      display: flex; flex-direction: column; gap: 5px;
      padding: 5px 5px 8px;
      border: 1px solid var(--border-color); border-radius: var(--radius-inner);
      background: var(--bg-tertiary); color: var(--text-secondary);
      font-family: inherit; text-align: left; cursor: pointer;
      transition: border-color var(--dur-2), color var(--dur-2),
        box-shadow var(--dur-2), transform var(--dur-1);
    }
    /* (1.1.43) O HOVER PERDEU A BORDA DOURADA, e é aqui que morre "o Zebrado não parece que tá
       com tema selecionado" (Pedro, 01/09/2026).
       O estado ativo era codificado em MATIZ: nome em `--precs-gold-title`, borda e anel em
       `--precs-gold-forma`. Nos dois Zebrado esses tokens SÃO o branco (#FFFFFF) ou o preto
       (#101010) do próprio tema, então `color-mix(forma 45%, --border-color)` do hover dava
       #8D8D8D e `color-mix(forma 60%, transparent)` do ativo dava #8F8F8F — dois pixels de
       diferença entre "o mouse está em cima" e "este é o meu tema".
       Agora são DOIS CANAIS e nenhum deles é cor: o hover fala por SUPERFÍCIE (lavagem mais o
       1px de elevação que já existia) e o ativo fala por CONTORNO. */
    .precs-tema-card:hover{ color: var(--text-primary); transform: translateY(-1px);
      background: color-mix(in srgb, var(--text-primary) 7%, var(--bg-tertiary)); }
    /* O ATIVO: 2px de tinta e um halo de marca.
       `inset 0 0 0 1px` somado à borda dá contorno de 2px SEM crescer a pegada do cartão, então
       trocar de tema não reflui a grade. O par `--text-primary` contra `--bg-tertiary` é, por
       construção de cada paleta, o de maior contraste do tema — 15,3:1 no Zebrado escuro, 18,1:1
       no claro — e nenhuma dessas contas consulta matiz.
       O halo de ouro fica FORA, a 28%, e não sustenta informação nenhuma: no Zebrado ele é branco
       e se dissolve contra a borda, e isso é indiferente, porque quem carrega o estado é a tinta.
       O nome também sai do ouro: no claro ele era `--precs-gold-title` a 4,94:1, no limite. */
    .precs-tema-card.active{
      color: var(--text-primary);
      border-color: var(--text-primary);
      box-shadow: inset 0 0 0 1px var(--text-primary),
        0 0 0 3px color-mix(in srgb, var(--precs-gold-forma, #B49552) 28%, transparent),
        var(--shadow);
    }
    .precs-tema-card:focus-visible{ outline: var(--focus-ring-largura) solid var(--focus-ring-cor);
      outline-offset: 2px; }
    .precs-tema-card-nome{
      display: flex; align-items: center; gap: 5px; padding: 0 3px;
      font-size: .8rem; font-weight: 600; line-height: 1.2;
    }
    /* O ✓ ocupa lugar sempre (visibilidade e não display), senão o nome dança 15px para o lado
       a cada troca de tema.
       (1.1.43) E ELE VIROU CHIP PREENCHIDO, por INVERSÃO DE LUMINÂNCIA: disco em
       `--text-primary` com o traço em `--bg-tertiary`. Antes era um traço de 12px na MESMA cor
       do nome — num tema onde o nome não muda de cor, isso equivale a não existir. */
    .precs-tema-card-ok{
      flex: 0 0 auto; width: 15px; height: 15px; border-radius: 50%;
      display: inline-flex; align-items: center; justify-content: center;
      visibility: hidden; background: transparent;
    }
    .precs-tema-card-ok svg{ display: block; width: 9px; height: 9px; }
    .precs-tema-card.active .precs-tema-card-ok{
      visibility: visible; background: var(--text-primary); color: var(--bg-tertiary);
    }
    /* "EM USO" POR ESCRITO, e é o terceiro canal — o único que sobrevive a monocromia, a baixa
       visão e a não conhecer o ícone, tudo ao mesmo tempo.
       `aria-hidden` no markup porque o `aria-pressed` do botão já diz isso ao leitor de tela, e
       ouvir "Bordô em uso, pressionado" é redundância que atrapalha. */
    .precs-tema-card-uso{
      margin-left: auto; padding: 1px 6px; border-radius: var(--radius-pill, 999px);
      background: var(--text-primary); color: var(--bg-tertiary);
      font-size: .6rem; font-weight: 700; text-transform: uppercase;
      letter-spacing: var(--ls-caps); line-height: 1.55; display: none;
    }
    .precs-tema-card.active .precs-tema-card-uso{ display: block; }
    .precs-tema-card-nota{ padding: 0 3px; font-size: .68rem; line-height: 1.35;
      color: var(--text-muted); }

    /* A MAQUETE. Ela é esquemática de propósito — ver o comentário de `precsPintarGaleriaTemas`
       para o motivo de não ser uma prévia fiel. O que ela promete é o que entrega: o fundo do
       tema, a superfície dos cards e a cor de acento, nas proporções em que aparecem na tela. */
    .precs-tema-maquete{
      position: relative; display: block; height: 62px; overflow: hidden;
      border-radius: calc(var(--radius-inner) - 2px);
      border: 1px solid color-mix(in srgb, var(--text-primary) 10%, transparent);
      background: var(--d1);
      --precs-tema-mini-fator: .40;
      isolation: isolate;
    }
    /* (1.1.43) A TEXTURA DO TEMA, lida do MESMO bloco que pinta o `<body>` (ver os blocos de
       canvas, onde cada um ganhou o seletor `.precs-tema-maquete[data-tema=…]`). Era a maior
       parte de "o seletor ficou ruim de cores": sem ela, quatro cartões escuros e três claros
       diferiam só por 2% de luminância e por um ponto de acento.
       DUAS CALIBRAGENS, e as duas têm precedente no `.precs-papel-mini`:
       • O LADRILHO ENCOLHE (fator .40). A renda repete a cada 120px e a maquete tem 62px de
         altura: em tamanho real ela mostraria o trecho reto de um arco e nada mais. Vira 48px,
         o losango vira 26px, a malha vira 16px.
       • A FORÇA É SOMADA POR EMPILHAMENTO, e é aqui que difere do papel. O papel é máscara
         monocromática, então bastava multiplicar `opacity`. A textura de canvas traz a COR e a
         opacidade assadas no SVG (`stroke='%23B49552' opacity='.075'`), e é justamente a cor
         que a maquete precisa mostrar — ouro no PRECS e no Bordô escuro, vinho no Bordô claro,
         branco no Zebrado, preto no Zebrado claro. Três camadas idênticas compõem o alfa por
         1-(1-a)³: .055 vira .156, .075 vira .209, .11 vira .295. A ordem relativa entre os
         temas continua verdadeira, que é a mesma régua do `* 2.6` do papel.
       O Contraste declara `none`, e `none, none, none` é válido: a maquete dele fica LISA, o que
       é a identidade dele e não a ausência de tratamento. */
    .precs-tema-maquete::before{
      content: ''; position: absolute; inset: 0; pointer-events: none;
      background-image: var(--precs-canvas-textura, none), var(--precs-canvas-textura, none),
                        var(--precs-canvas-textura, none);
      background-size: calc(var(--precs-canvas-escala, 64px) * var(--precs-tema-mini-fator))
                       calc(var(--precs-canvas-escala, 64px) * var(--precs-tema-mini-fator));
      background-repeat: repeat;
    }
    /* O pseudo-elemento pinta ANTES dos `<i>` posicionados, então a barra e as linhas ficam por
       cima sem precisar de z-index. */
    .precs-tema-maquete i{ position: absolute; display: block; border-radius: 3px; }
    .precs-tema-maq-barra{ left: 0; right: 0; top: 0; height: 15px; border-radius: 0;
      background: var(--d3);
      /* O FIO é o que separa `d1` de `d3` quando as duas diferem 2% de luminância, que é o caso
         de cinco dos sete temas. Espelha o divisor da cabeça do card de verdade, e vai a 55%
         pelo mesmo motivo já escrito nas texturas do claro: fio de meio pixel perde a maior
         parte da tinta para o antialiasing antes de a opacidade valer. */
      border-bottom: 1px solid color-mix(in srgb, var(--d4) 55%, transparent); }
    .precs-tema-maq-linha{ background: var(--d2); opacity: .85; height: 6px; }
    .precs-tema-maq-linha.um{ left: 10px; top: 26px; width: 44%; }
    .precs-tema-maq-linha.dois{ left: 10px; top: 37px; width: 28%; opacity: .45; }
    .precs-tema-maq-ponto{ right: 9px; top: 4px; width: 7px; height: 7px; border-radius: 50%;
      background: var(--d2); }
    /* (1.1.43) A PÍLULA DE ASSINATURA, na cor que DÁ NOME ao tema. É o elemento que faz o Bordô
       anunciar o vinho: o cartão dele mostrava ouro como acento (`d2` = #D3B26B, o MESMO do
       PRECS) e nada de vinho, então o tema vinho não se anunciava no controle que serve
       justamente para escolhê-lo. Superfície cheia, porque `d4` precisa de área para ler. */
    .precs-tema-maq-botao{ right: 10px; bottom: 8px; width: 34px; height: 11px;
      border-radius: var(--radius-pill, 999px); background: var(--d4); }
    @media (prefers-reduced-motion: reduce){
      .precs-tema-card{ transition: none; }
      .precs-tema-card:hover{ transform: none; }
    }
    .precs-papel-grade{
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: var(--space-2);
    }
    .precs-papel-card{
      display: flex; flex-direction: column; gap: 6px;
      padding: 5px 5px 7px;
      border: 1px solid var(--border-color);
      border-radius: var(--radius-inner);
      background: var(--bg-tertiary);
      color: var(--text-secondary);
      font-family: inherit; font-size: .78rem; font-weight: 500;
      cursor: pointer;
      transition: border-color var(--dur-2), color var(--dur-2),
        box-shadow var(--dur-2), transform var(--dur-1);
    }
    /* Mesma armadilha do `.precs-seg button[hidden]` logo acima: `display:flex` de autor vence
       o `[hidden]{display:none}` de UA, e um card escondido por JS continuaria na tela. */
    .precs-papel-card[hidden]{ display: none; }
    .precs-papel-card:hover{
      color: var(--text-primary);
      border-color: color-mix(in srgb, var(--precs-gold-forma, #B49552) 45%, var(--border-color));
      transform: translateY(-1px);
    }
    /* O selecionado usa o MESMO vocabulário do `.precs-seg button.active` do modal: letra em
       `--precs-gold-title` (tokenizado por tema, responde pelo contraste) e anel em
       `--precs-gold-forma` (ouro como forma, que é o que 4,5:1 não cobra). */
    .precs-papel-card.active{
      color: var(--precs-gold-title, var(--precs-gold, #B49552));
      border-color: color-mix(in srgb, var(--precs-gold-forma, #B49552) 60%, transparent);
      box-shadow: 0 0 0 1px color-mix(in srgb, var(--precs-gold-forma, #B49552) 50%, transparent),
        var(--shadow);
    }
    .precs-papel-card:focus-visible{
      outline: var(--focus-ring-largura) solid var(--focus-ring-cor); outline-offset: 2px;
    }
    .precs-papel-rot{
      display: flex; align-items: center; gap: 5px;
      padding: 0 2px; line-height: 1.2;
    }
    /* A marca do escolhido é um ✓ que só existe no card ativo. Ele ocupa lugar SEMPRE (o
       `visibility` no lugar do `display`), senão o rótulo dança 14px para o lado a cada
       troca de papel. */
    .precs-papel-ok{
      flex: 0 0 auto; width: 12px; height: 12px; visibility: hidden;
    }
    .precs-papel-ok svg{ display: block; width: 100%; height: 100%; }
    .precs-papel-card.active .precs-papel-ok{ visibility: visible; }

    /* A MINIATURA. Mesma máquina do `.precs-wa-chat`: fundo no elemento, textura num
       `::before` mascarado que herda `currentColor`. Duas diferenças, as duas deliberadas:

       • O LADRILHO ENCOLHE (`--precs-papel-mini-fator`). O papel PRECS repete a cada 92px e o
         Constelação a cada 200px; numa janela de 58px de altura, o Constelação em tamanho
         real mostraria pedaço de uma estrela e mais nada. O fator é token para um papel de
         ladrilho muito grande poder afinar o próprio sem tocar na máquina.
       • A FORÇA É AMPLIFICADA. As forças reais vão de .05 a .08, calibradas para não competir
         com o texto do balão numa tela inteira. Repetidas num retângulo de 58px elas dão um
         retângulo chapado, e a galeria existe justamente para a pessoa VER a diferença. O
         multiplicador é o mesmo para todos, então a ordem relativa entre os papéis (o
         Constelação é o mais forte, o Timbrado o mais fraco) continua verdadeira. */
    .precs-papel-mini{
      --precs-papel-mini-fator: .42;
      position: relative; isolation: isolate; overflow: hidden;
      height: 58px;
      border-radius: calc(var(--radius-inner) - 2px);
      border: 1px solid color-mix(in srgb, var(--text-primary) 9%, transparent);
      background: var(--precs-wa-papel-fundo, var(--bg-primary));
    }
    .precs-papel-mini::before{
      content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
      color: var(--text-primary);
      opacity: calc(var(--precs-wa-papel-forca, .05) * 2.6);
      background: currentColor;
      -webkit-mask-image: var(--precs-wa-textura); mask-image: var(--precs-wa-textura);
      -webkit-mask-size:
        calc(var(--precs-wa-papel-escala, 78px) * var(--precs-papel-mini-fator))
        calc(var(--precs-wa-papel-escala, 78px) * var(--precs-papel-mini-fator));
      mask-size:
        calc(var(--precs-wa-papel-escala, 78px) * var(--precs-papel-mini-fator))
        calc(var(--precs-wa-papel-escala, 78px) * var(--precs-papel-mini-fator));
      -webkit-mask-repeat: repeat; mask-repeat: repeat;
    }
    /* Dois balõezinhos mudos por cima do papel: sem eles a miniatura é um retângulo texturizado
       e não se lê como CONVERSA. São formas puras, sem texto, e ficam fora do leitor de tela
       (o card já se anuncia pelo rótulo). */
    .precs-papel-bolha{
      position: absolute; height: 9px; border-radius: 5px;
      box-shadow: var(--precs-wa-balao-sombra, 0 1px 2px rgba(0,0,0,.18));
    }
    .precs-papel-bolha.e{ left: 8px; top: 13px; width: 46%;
      background: var(--precs-wa-balao-credor, var(--bg-tertiary)); }
    .precs-papel-bolha.d{ right: 8px; top: 30px; width: 38%;
      background: var(--precs-wa-balao-proprio, var(--bg-tertiary)); }
    @media (prefers-reduced-motion: reduce){
      .precs-papel-card{ transition: none; }
      .precs-papel-card:hover{ transform: none; }
    }

    /* PRECS — cronômetros de estado da sessão */
    .precs-tempos {
      margin-top: var(--space-4);
      padding-top: var(--space-5);
      border-top: 1px solid var(--border-color);
    }
    .precs-tempos-titulo {
      font-size: 0.78rem;
      font-weight: 600;
      color: var(--text-secondary);
      margin-bottom: var(--space-3);
      letter-spacing: 0.02em;
      display: flex;
      align-items: center;
      gap: var(--space-2);
    }
    /* PRECS — tempo TOTAL da sessão (soma dos 4 baldes), alinhado à direita do
       título. Dá a visão do tempo total sem tirar os tempos por estado. */
    /* (1.1.6) botão do resumo printável, no título dos Tempos da sessão */
    .precs-tempos-share {
      display: inline-flex; align-items: center; justify-content: center;
      width: 22px; height: 22px; margin-left: var(--space-2); flex: 0 0 auto;
      border-radius: var(--radius-sm); cursor: pointer;
      color: var(--precs-gold); background: transparent;
      border: 1px solid color-mix(in srgb, var(--precs-gold) 32%, transparent);
      transition: background-color var(--dur-1) ease, border-color var(--dur-1) ease, transform .12s ease;
    }
    .precs-tempos-share:hover {
      background: color-mix(in srgb, var(--precs-gold) 14%, transparent);
      border-color: color-mix(in srgb, var(--precs-gold) 58%, transparent);
      transform: translateY(-1px);
    }
    .precs-tempos-share:active { transform: translateY(0); }
    .precs-tempos-share svg { display: block; }
    /* (1.1.10) A expansão de área de clique por pseudo-elemento foi retirada daqui também.
       O histórico completo do porquê está no comentário de .precs-tel-btn, no estilo.css —
       em resumo: colidiu com o sistema de tooltip, o comentário malformado engoliu o
       `position: relative`, e sem ele o pseudo-elemento virou overlay invisível do tamanho da
       coluna. Três regressões por um ganho que ninguém pediu. */
    @media (prefers-reduced-motion: reduce) { .precs-tempos-share { transition: none; } }
    .precs-tempos-total {
      margin-left: auto;
      display: inline-flex;
      align-items: baseline;
      gap: var(--space-1);
      padding: var(--space-0) var(--space-2);
      border-radius: var(--radius-pill);
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
    }
    .precs-tempos-total-lbl {
      font-size: 0.6rem;
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      color: var(--text-muted);
      font-weight: 700;
    }
    .precs-tempos-total-val {
      font-size: 0.86rem;
      font-weight: 700;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
      font-family: var(--font-num);
    }
    .precs-tempos-grid {
      display: grid;
      /* 5 colunas desde 1.1.0 (entrou o card de Intervalo). Não é repeat(5,1fr)
         cravado: com minmax o grid quebra em duas linhas por conta própria quando a
         coluna do painel encolhe, em vez de espremer cinco cards ilegíveis. */
      grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
      gap: var(--space-2);
    }
    .precs-tempo-card {
      display: flex;
      align-items: center;
      gap: var(--space-2);
      padding: var(--space-2) var(--space-3);
      border-radius: var(--radius-inner);
      /* (1.1.54) `--bg-tertiary` E NÃO `--bg-primary`, e isto é o token cumprindo o próprio nome.
         O `--bg-tertiary` é declarado no :root com o comentário "fundo de chip e trilho"
         (00-base.css:49); estes quatro cronômetros SÃO chips, e o termômetro logo acima deles já
         usava o token certo. Pintar chip com a cor da PÁGINA passou despercebido enquanto página
         e card eram quase a mesma cor em todos os temas — e ficou visível no dia em que os
         claros temáticos separaram os dois: os quatro cronômetros de estado apareciam com a cor
         cheia do tema, bem onde o operador precisa ler OCIOSO / MANUAL / EM CHAMADA / TPA.
         Nos temas escuros a troca inverte o relevo do chip (era mais escuro que o card, passa a
         ser mais claro) e essa é a leitura certa: chip dentro de card se destaca do card, e a
         referência é o card que o contém, não a página que está atrás dele. */
      background: var(--bg-tertiary);
      border: 1px solid var(--border-color);
      /* (1.1.22) `background` entrou na lista: o card ATIVO tem fundo tintado, e a passagem de
         bastão (ocioso → em chamada → TPA, toggled pelo tique no espelho e na tela dele) trocava
         borda e sombra macio com o fundo saltando no meio. */
      transition: border-color var(--dur-2), box-shadow var(--dur-2), transform var(--dur-1),
        background var(--dur-2);
      /* âncora do anel de "assumiu o cronômetro" (::after mais abaixo) */
      position: relative;
    }
    .precs-tempo-card.precs-tempo-ativo {
      border-color: var(--tempo-cor, #f59e0b);
      /* PRECS — preenchimento tintado no estado ativo (mesmo padrão de
         .qualification-item.selected). Sem isto, a borda fina de 1px "sumia"
         nos temas escuros (Escuro/Precs/Contraste) e o card ativo ficava igual
         aos inativos. O color-mix mistura a cor do estado com o fundo do tema,
         então funciona nos 3 temas sem cor fixa. */
      background: color-mix(in srgb, var(--tempo-cor, #f59e0b) 14%, var(--bg-primary));
      box-shadow: 0 0 0 1px var(--tempo-cor, #f59e0b),
                  0 6px 16px -4px color-mix(in srgb, var(--tempo-cor, #f59e0b) 55%, transparent),
                  var(--shadow);
      transform: translateY(-1px);
    }
    /* PRECS (1.1.2) — PASSAGEM DO BASTÃO, em anel que se expande e some.
       O card ativo já era bem diferente do inativo (fundo tintado, anel, glow,
       rótulo colorido, bolinha pulsando), mas não havia sinal do INSTANTE em que o
       cronômetro trocava de card: os quatro ficavam parados e, de um segundo para o
       outro, outro estava aceso.

       A PRIMEIRA VERSÃO ANIMAVA O PRÓPRIO CARD (scale + brightness) e dava um "pulo
       quebrado". Três causas somadas, todas evitadas aqui:
         1. o card declara `transition: transform var(--dur-1)`, e a animação mexia em
            transform também — transição e animação disputando a mesma propriedade
            brigam no início e no instante em que a animação devolve o controle;
         2. escalar um elemento COM TEXTO sob o zoom de 0,85 do main cai em fração de
            pixel, e o texto re-rasteriza no meio do movimento;
         3. `filter: brightness()` repinta o card inteiro, sombra e glow junto.

       Um pseudo-elemento não tem texto, não entra no layout e não é alvo daquela
       transição, então anima só com opacity e transform — que o compositor resolve
       sem repintar nada. O efeito também ficou mais legível: em vez de o card se
       mexer, sai um anel de dentro dele.

       Dispara uma vez só, quando a classe entra, porque precsAtualizarTempos usa
       classList.toggle com force e reaplicar a mesma classe não reinicia animação em
       CSS. O tique de 1s não repinta isto. */
    .precs-tempo-card.precs-tempo-ativo::after {
      content: "";
      position: absolute;
      inset: -1px;                                     /* cobre o anel de 1px do box-shadow */
      border-radius: calc(var(--radius-inner) + 1px);
      border: 2px solid var(--tempo-cor, #f59e0b);
      opacity: 0;
      pointer-events: none;
      animation: precsTempoAssume .55s var(--ease-1) 1;
    }
    @keyframes precsTempoAssume {
      0%   { opacity: .9; transform: scale(1); }
      100% { opacity: 0;  transform: scale(1.13); }
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-tempo-card.precs-tempo-ativo::after { animation: none; }
    }
    /* rótulo e valor assumem a cor do estado quando ativo: reforça a leitura
       (qual cronômetro está correndo) sem depender só da borda. */
    .precs-tempo-card.precs-tempo-ativo .precs-tempo-label {
      color: color-mix(in srgb, var(--tempo-cor, #f59e0b) 78%, var(--text-primary));
    }
    /* Não há mais disputa com a passagem de bastão: aquela animação mora no ::after
       e esta no próprio card, então o alarme de 4 minutos pisca normalmente mesmo
       enquanto o card está ativo. (Na primeira versão as duas viviam no card e a
       ordem deste bloco decidia quem rodava.) */
    .precs-tempo-card.precs-tempo-alerta {
      border-color: #ef4444;
      box-shadow: 0 0 0 1px #ef4444, var(--shadow);
      animation: precs-alerta-pulse 1.4s ease-in-out infinite;
    }
    .precs-tempo-card.precs-tempo-alerta .precs-tempo-valor { color: #ef4444; }
    @keyframes precs-alerta-pulse {
      0%, 100% { box-shadow: 0 0 0 1px #ef4444, var(--shadow); }
      50%      { box-shadow: 0 0 0 3px rgba(239,68,68,.45), var(--shadow); }
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-tempo-card.precs-tempo-alerta { animation: none; }
    }
    /* PRECS — bolinha de estado em SVG (não CSS). Um círculo com border-radius:50%
       ficava OVAL por causa do zoom do container (mesmo motivo dos radios de
       qualificação, que já eram SVG). O SVG escala limpo e fica 100% redondo.
       A cor vem de --tempo-cor, unificada com a borda do card em todos os temas. */
    .precs-tempo-dot {
      width: 11px; height: 11px;
      flex: 0 0 auto; align-self: center; display: block;
      overflow: visible;
    }
    .precs-tempo-dot circle { fill: var(--tempo-cor, #9aa3b2); transform-origin: center; }
    .precs-tempo-card.precs-tempo-ativo .precs-tempo-dot circle {
      filter: drop-shadow(0 0 3px var(--tempo-cor, #f59e0b));
      animation: precsTempoDotPulse 1.6s ease-in-out infinite;
    }
    /* PRECS — renomeado de precsDotPulse para precsTempoDotPulse. Existiam DOIS
       @keyframes com o nome precsDotPulse: este (scale/opacity, da bolinha do
       cronômetro) e o da linha 421 (anel verde que expande, do badge "Conectado").
       Nome repetido em CSS não soma, o último vence: o badge "Conectado" executava o
       scale em vez do anel verde, e o efeito para o qual ele foi escrito nunca
       aparecia. Com nomes distintos, cada um volta a fazer o que devia. */
    @keyframes precsTempoDotPulse {
      0%, 100% { transform: scale(1); opacity: 1; }
      50%      { transform: scale(.82); opacity: .72; }
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-tempo-card.precs-tempo-ativo .precs-tempo-dot circle { animation: none; }
    }
    .precs-tempo-info { min-width: 0; }
    .precs-tempo-label {
      font-size: 0.68rem;
      color: var(--text-muted);
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      white-space: nowrap;
    }
    .precs-tempo-valor {
      font-size: 0.98rem;
      font-weight: 700;
      color: var(--text-primary);
      font-variant-numeric: tabular-nums;
    }
    @media (max-width: 600px) {
      .precs-tempos-grid { grid-template-columns: repeat(2, 1fr); }
    }

    /* PRECS (1.1.5) — TOPO DO MENU: SUBTRAÍDO, COM O FOCO DO DIA PROMOVIDO.
       O histórico deste bloco, porque ele já foi refeito três vezes e as tentativas
       revertidas precisam continuar visíveis:
         • até 1.0.33 era tudo empilhado e centralizado — foto, saudação, faixa, frase e os
           três chips — somando ~200px antes do conteúdo. Em notebook de 1366x768, que é o
           que tem em call center, a lista de campanhas começava perto da metade da tela.
         • 1.0.34 testou o hero HORIZONTAL (foto à esquerda, chips à direita) e foi
           REVERTIDO: ganhava espaço e perdia no visual, a foto no canto não ficou boa. O
           comentário de então registrou a saída recomendada: mover os chips para o header.
         • 1.1.5 (agora) faz isso, e vai além: tira a FOTO do hero em vez de reposicioná-la,
           porque o header já mostra foto + nome + empresa. O problema nunca foi onde pôr a
           foto, era ter duas identidades na mesma tela.
       Resultado: o topo cai de ~200px para ~110px (medido: 174 -> 82 no tamanho normal, e
       o card "Meu desempenho" ganhou 107px de altura) sem espremer nada, porque o que saiu
       era repetição, não informação. E o único item que ninguém via — o foco do dia — passa
       a ser o elemento com mais presença do bloco.

       O EIXO CENTRAL FICA. Cheguei a alinhar o bloco à esquerda e medi o resultado: com os
       três cards na tela, a borda esquerda do topo ficava 248px à direita da borda do
       primeiro card, porque a grade é centralizada e dimensionada pelo CONTEÚDO — nenhum
       max-width fixo acompanha isso, e o desencontro lê como erro de layout. Centralizado,
       não existe borda esquerda para desencontrar: é um título centralizado sobre uma fila
       centralizada, que é a composição que o Pedro manteve quando reverteu o hero
       horizontal na 1.0.34. O que estava errado ali era a foto, o nome dourado, os chips e
       o foco minúsculo, não o eixo. */
    .precs-welcome {
      width: 100%;
      margin: 0 auto var(--space-4);
      display: flex;
      flex-direction: column;
      align-items: center;      /* cada filho centraliza e tem a largura do conteúdo */
      gap: var(--space-3);
      padding: var(--space-1) var(--space-1) 0;
      text-align: left;
    }
    /* foto, saudação, divisória e cronômetro da sessão na MESMA linha: nenhum deles ganha
       uma faixa própria de altura. flex-wrap para telas estreitas. */
    .precs-welcome-linha {
      display: flex; align-items: center; justify-content: center;
      gap: var(--space-4); flex-wrap: wrap;
    }
    /* PRECS (1.1.5) — A FOTO VOLTOU, DENTRO DA LINHA. Ela saiu do topo por repetir a
       identidade do header, e voltou por um motivo diferente do que a tirou: sem ela o
       bloco fica só tipografia e perde o rosto do operador, que é o que faz o menu ser
       "dele". A diferença é onde ela mora agora.
       ANTES (até 1.1.4): 72px empilhada ACIMA da saudação, custando ~80px de altura que
       saíam do card "Meu desempenho".
       AGORA: 44px À ESQUERDA da saudação, DENTRO da linha que já existia. O elemento mais
       alto da linha era o chip de Sessão (~40px), então a foto custa ~4px, não 80.
       Isto NÃO é o hero horizontal revertido na 1.0.34: lá a foto ia para a BORDA ESQUERDA
       de um hero de largura total, longe do texto ("a foto jogada no canto não ficou boa").
       Aqui ela fica encostada no nome, e o grupo inteiro continua centralizado no eixo.
       44px sob o zoom 0,85 dá ~37px reais — a mesma ordem do avatar do header, que é lido
       sem problema. As fotos do roster são de corpo parcial, não closes de rosto, então
       abaixo disso o rosto deixa de ser reconhecível (foi o que motivou o 66px→96px→72px
       da 1.0.34); aqui a leitura de perto é a mesma do header. */
    .precs-welcome-foto { display: flex; align-items: center; }
    .precs-welcome-foto:empty { display: none; }
    /* PRECS (1.1.56) — A FOTO DO HERO CRESCE DE 36px PARA 52px, e o que destravou isso foi uma
       MEDIÇÃO, não uma mudança de gosto.
       A regra que segurava o tamanho está escrita duas vezes neste arquivo (o chip achatado da
       1.1.5 e o cronômetro da 1.1.54) e diz a mesma coisa: "cada pixel que a linha da saudação
       ganha sai do `#precs-meudia-card`". Isso continua sendo verdade — e deixou de ser um
       problema. Medido no card ao lado: ele termina com cerca de 320px de BRANCO, porque as
       barras dos 7 dias têm altura fixa e o `.pm-fill` engole toda a sobra. Os 15px que esta
       linha ganha saem de lá, ou seja: de um espaço que hoje não mostra nada.
       ESCOPADO AO HERO de propósito. O `.precs-avatar` de 36px é o mesmo elemento do header, e
       lá o tamanho está certo — ele divide 62px de altura com nome, razão social e ramal. */
    .precs-welcome-foto .precs-avatar { width: 52px; height: 52px; }
    .precs-welcome-foto .precs-avatar-ini { font-size: var(--fs-10); }
    .precs-avatar-hero {
      width: 44px; height: 44px;
      box-shadow: 0 0 0 2px var(--precs-gold, #B49552), 0 3px 10px rgba(0,0,0,.35);
    }
    .precs-avatar-hero.precs-avatar-ini { font-size: 1.05rem; }
    /* divisória entre a IDENTIDADE (foto + nome + faixa) e a MÉTRICA (cronômetro): são
       duas naturezas de informação na mesma linha, e sem o traço o chip lê como parte do
       nome. Fica entre os dois, não entre a foto e o nome — foto e nome são a mesma coisa. */
    .precs-welcome-div {
      width: 1px; height: 26px; flex: none;
      background: color-mix(in srgb, var(--text-primary) 18%, transparent);
    }
    /* PRECS — anel do avatar na COR DA FAIXA. O 2º anel usa a cor do texto do
       tema em baixa opacidade: contorno que adapta ao tema, garantindo que a
       faixa BRANCA (tema claro) e a PRETA (tema escuro/precs) não sumam. */
    .precs-avatar.precs-tem-anel-faixa {
      box-shadow:
        0 0 0 3px var(--precs-faixa-cor, var(--precs-gold, #B49552)),
        0 0 0 4px color-mix(in srgb, var(--text-primary) 22%, transparent),
        0 4px 16px rgba(0,0,0,.4);
    }
    /* PRECS — faixinha de BJJ (SVG). Usada pela tela do SUPERVISOR (precsSupFaixa); o
       .precs-faixa-wrap era do hero e saiu com ele em 1.1.5. */
    .precs-faixinha { display: inline-flex; filter: drop-shadow(0 1px 2px rgba(0,0,0,.35)); }
    .precs-faixinha svg { display: block; }
    .precs-welcome-greet {
      /* 1,75rem → 1,5rem em 1.1.5: sem a foto de 72px acima, a saudação não precisa mais
         daquele porte para não parecer legenda da imagem. */
      font-size: var(--fs-11);
      font-weight: 700;
      color: var(--text-primary);
      letter-spacing: 0.2px;
      line-height: 1.15;
    }
    /* PRECS (1.1.5) — AQUI FICAVA `.precs-greet-nome { color: var(--precs-gold) }`, o nome
       do operador em dourado. Removida a pedido do Pedro. O peso 700 já separa o nome do
       "Bom dia,", e o acento de cor do bloco passa a ser só o sublinhado da FAIXA logo
       abaixo — que é cor com significado, não decoração.
       O <span class="precs-greet-nome"> continua sendo emitido pelo app.js de propósito: é
       o gancho para envolver só o nome se um dia ele voltar a ter tratamento próprio. */
    .precs-greet-inner { display: inline-block; }
    /* PRECS — FAIXA como sublinhado fino embaixo da saudação, na cor da faixa.
       Sem texto por extenso (o nome da faixa fica no tooltip).
       (1.0.34) Duas tentativas foram revertidas a pedido do Pedro, e ficam registradas
       para não serem repetidas: (a) trocar por uma barra de BJJ em SVG, que solta no hero
       lê como BARRA DE PROGRESSO e não como faixa; (b) reforçar o contorno para 1px a 55%,
       que resolvia a leitura da preta e da branca mas deixou o sublinhado pesado.
       Voltou ao 0,5px a 26% original, discreto. Consequência assumida: nas faixas PRETA e
       BRANCA o sublinhado é bem sutil, e o nome da faixa continua disponível no tooltip. */
    .precs-greet-faixa::after {
      content: "";
      display: block;
      height: 3px;
      width: 100%;
      margin: 5px auto 0;
      border-radius: var(--radius-pill);
      background: var(--precs-faixa-cor, var(--precs-gold, #B49552));
      box-shadow: 0 0 0 .5px color-mix(in srgb, var(--text-primary) 26%, transparent);
    }
    /* PRECS (1.1.5) — FOCO DO DIA PROMOVIDO A CITAÇÃO.
       Era um `.precs-welcome-sub` de 0,85rem em --text-secondary, com o rótulo de 0,62rem
       colado à esquerda da frase, tudo numa linha embaixo do nome. Funcionava como legenda
       e era lido como legenda: o time não sabia que existia.
       Agora é um bloco com filete dourado à esquerda (o mesmo idioma de realce que o hover
       das listas do painel usa), rótulo ACIMA e frase em --text-primary a 1,05rem. Três
       mudanças pequenas que, juntas, tiram o item da periferia: contorno próprio, hierarquia
       vertical e cor de texto principal.
       O grid existe para o lápis de editar ficar ancorado à direita, no topo, sem depender
       de `vertical-align` — e para a frase poder quebrar em duas linhas sem empurrar o
       botão. As áreas são nomeadas porque a ordem no DOM (rótulo, frase, botão) não é a
       ordem visual (botão na coluna 2, ocupando as duas linhas). */
    .precs-foco-bloco {
      display: grid;
      /* `auto auto` + justify-content:start, e NÃO `1fr auto`: com 1fr a coluna do texto
         esticava até os 44rem e o lápis ficava largado no vazio à direita, longe da frase
         que ele edita. Assim as duas colunas encostam no conteúdo e o botão segue o fim do
         texto; o max-width abaixo é que faz a frase quebrar em duas linhas quando é longa. */
      grid-template-columns: minmax(0, auto) auto;
      grid-template-areas: "rotulo editar" "frase editar";
      justify-content: start;
      align-items: start;
      gap: var(--space-0) var(--space-2);
      max-width: 44rem;
      padding-left: var(--space-4);
      border-left: 3px solid var(--precs-gold, #B49552);
    }
    .precs-foco-label {
      grid-area: rotulo;
      font-size: var(--fs-2); font-weight: 700;
      text-transform: uppercase; letter-spacing: var(--ls-caps);
      color: var(--precs-gold, #B49552);
    }
    .precs-foco-frase {
      grid-area: frase;
      font-size: var(--fs-9); line-height: 1.35;
      color: var(--text-primary); font-style: italic;
    }
    /* PRECS (1.1.57) — O CONVITE NAO E UMA FRASE, entao nao se veste como uma.
       Quando o operador ainda nao escreveu nada, o bloco deixou de cair numa das 23 frases da
       casa e passou a oferecer o espaco. O texto do convite perde o italico (que aqui marca
       CITACAO, e um convite nao e citacao de ninguem) e baixa para a cor secundaria, para nao
       competir com a frase de verdade que vai ocupar aquele lugar amanha. */
    .precs-foco-frase.precs-foco-convite {
      font-style: normal;
      color: var(--text-secondary);
      font-size: var(--fs-6);
    }
    /* botão discreto p/ o operador gerenciar as próprias frases de foco */
    .precs-foco-edit {
      grid-area: editar; align-self: center;
      display: inline-flex; align-items: center; justify-content: center;
      width: 22px; height: 22px;
      border: 1px solid transparent; border-radius: var(--radius-sm);
      background: transparent; color: var(--text-muted); cursor: pointer;
      opacity: .55; transition: opacity var(--dur-1), color var(--dur-1), background-color var(--dur-1), border-color var(--dur-1);
    }
    .precs-foco-edit:hover { opacity: 1; color: var(--precs-gold, var(--accent-3cplus)); background: var(--precs-gold-light, rgba(180,149,82,.16)); }
    .precs-foco-edit:focus-visible {
      outline: none; opacity: 1;
      box-shadow: 0 0 0 3px var(--precs-gold-light, rgba(180,149,82,.35));
      border-color: var(--precs-gold, var(--accent-3cplus));
    }

    /* ===== PRECS — modal "Minhas frases de foco" (cadastro local do operador) */
    .precs-frases-overlay {
      display: none; position: fixed; inset: 0; z-index: 10000;
      background: rgba(0,0,0,.55); backdrop-filter: blur(2px);
      align-items: center; justify-content: center; padding: 5vh 5vw;
    }
    .precs-frases-overlay.open { display: flex; }
    .precs-frases-overlay.closing { animation: precsOverlayOut .18s ease forwards; }
    .precs-frases-overlay.closing .precs-frases-modal { animation: precsModalOut .18s var(--ease-3) forwards; }
    .precs-frases-modal {
      width: min(520px, 94vw); max-height: 86vh; display: flex; flex-direction: column;
      background: var(--bg-secondary); border: 1px solid var(--border-color);
      border-radius: var(--radius-card);
      box-shadow: var(--shadow-lg);
      padding: var(--space-6) var(--space-6) var(--space-5); animation: pmEntra .22s ease;
    }
    .precs-frases-head { display: flex; align-items: flex-start; gap: var(--space-3); }
    .precs-frases-tit {
      font-weight: 700; font-size: var(--fs-8); color: var(--text-primary);
      font-family: var(--font-corpo);
    }
    .precs-frases-sub { font-size: var(--fs-4); color: var(--text-secondary); margin-top: var(--space-1); line-height: 1.4; }
    .precs-frases-x {
      margin-left: auto; flex: none; width: 32px; height: 32px; display: inline-flex;
      align-items: center; justify-content: center; border-radius: var(--radius-sm);
      background: transparent; border: 1px solid transparent; color: var(--text-muted); cursor: pointer;
      transition: color var(--dur-1), background-color var(--dur-1);
    }
    .precs-frases-x:hover { color: var(--text-primary); background: var(--bg-tertiary); }
    .precs-frases-add { display: flex; gap: var(--space-2); margin-top: var(--space-4); }
    .precs-frases-add .precs-field { flex: 1; }
    .precs-frases-lista { margin-top: var(--space-4); overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-2); }
    .precs-frases-item {
      display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-3);
      background: var(--bg-primary); border: 1px solid var(--border-color);
      border-radius: var(--radius-inner);
      animation: precsHomeIn .26s var(--ease-2) both;
    }
    .precs-frases-txt { flex: 1; font-size: var(--fs-5); color: var(--text-primary); line-height: 1.4; }
    .precs-frases-del {
      flex: none; width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
      border-radius: var(--radius-sm); background: transparent; border: 1px solid transparent;
      color: var(--text-muted); cursor: pointer; transition: color var(--dur-1), background-color var(--dur-1), border-color var(--dur-1);
    }
    .precs-frases-del:hover { color: var(--accent-red, #EF4444); background: color-mix(in srgb, var(--accent-red, #EF4444) 12%, transparent); }
    .precs-frases-vazio { font-size: var(--fs-5); color: var(--text-secondary); line-height: 1.5; padding: var(--space-1) var(--space-0); }
    @media (prefers-reduced-motion: reduce){
      .precs-frases-modal, .precs-frases-item { animation: none; }
      .precs-frases-overlay.closing, .precs-frases-overlay.closing .precs-frases-modal { animation: none; }
    }
    /* (O .precs-welcome-right, que enfileirava os três chips, saiu em 1.1.5 junto com dois
       deles: sobrou o de Sessão, e ele mora na .precs-welcome-linha, ao lado da saudação.) */
    .precs-stat {
      display: flex;
      align-items: center;
      gap: var(--space-2);
      background:
        linear-gradient(135deg,
          color-mix(in srgb, var(--precs-gold, #B49552) 16%, var(--bg-secondary)),
          var(--bg-secondary) 62%);
      border: 1px solid color-mix(in srgb, var(--precs-gold, #B49552) 30%, var(--border-color));
      border-radius: var(--radius-card);
      padding: var(--space-2) var(--space-3);
      min-width: 96px;
      box-shadow: inset 0 1px 0 color-mix(in srgb, var(--precs-gold,#B49552) 12%, transparent), var(--shadow);
      transition: border-color var(--dur-2), transform var(--dur-1), box-shadow var(--dur-2);
    }
    /* PRECS (1.1.5) — CHIP ACHATADO. Sobrou um chip só no topo, e ele agora divide a linha
       com a saudação: no tamanho antigo (~52px de altura) ele puxava a linha inteira para
       a altura dele e o ganho de espaço da repaginada ia embora. Ícone menor e padding
       menor deixam a linha na altura do texto da saudação.
       (Aqui viviam as regras de HIERARQUIA entre os três chips, da 1.1.2: ramal e relógio
       perdiam o fundo dourado para não competir com o de Sessão, que é o único que muda.
       Saíram junto com os dois chips — a hierarquia virou desnecessária quando o que não
       mudava deixou de estar na tela.) */
    /* PRECS (1.1.56) — O CHIP ACOMPANHA A FOTO. Ele foi achatado em 1.1.5 e ganhou corpo sem
       ganhar altura em 1.1.54, as duas vezes pela mesma restrição: ele era o elemento MAIS ALTO
       da linha, então era ele quem definia o quanto a linha custava ao card ao lado.
       Agora quem é mais alto é a FOTO (52px contra os 40,6px do chip), e a restrição mudou de
       dono: enquanto o chip couber dentro da altura da foto, crescer não custa NADA — nem à
       linha, nem ao card. É por isso que o alvo aqui é 52px e não "o maior possível".
       Deixá-lo no tamanho antigo ao lado de uma foto de 52px é que seria a decisão errada: o
       único dado da tela que muda sozinho pareceria um detalhe ao lado de um retrato. */
    .precs-stat-slim {
      padding: var(--space-1) var(--space-4);
      min-width: 0;
    }
    .precs-stat-slim .precs-stat-icon { width: 32px; height: 32px; border-radius: var(--radius-inner); }
    /* (1.1.54) O CRONÔMETRO GANHOU CORPO SEM GANHAR ALTURA, e a segunda metade é a regra.
       RELATO DO PEDRO, 03/09/2026: o tempo de sessão está "pequeno demais para o que vale".
       Ele é o único dado da tela que MUDA sozinho e o único jeito de o operador saber há quanto
       tempo está logado — e estava no mesmo 1rem de um rótulo qualquer.
       A ALTURA É RESTRIÇÃO DURA, não gosto. Medido: o chip tem 34,81px e a
       `.precs-welcome-linha` inteira tem 34,81px — ou seja, o chip É o elemento mais alto da
       linha, e todo pixel que ele ganha sai do `#precs-meudia-card` por meio do
       `precsAjustarAlturaMenu`. Foi exatamente por isso que ele foi achatado na 1.1.5, e a
       decisão continua valendo: o que muda aqui é a REPARTIÇÃO da altura, não o total.
       A conta: o número sobe de 1rem para 1,15rem (+2,3px de caixa), o rótulo desce de 0,6rem
       para 0,56rem e o respiro entre os dois vai a zero (−2px).
       O 0,56 saiu de MEDIR, não de calcular: com 0,58 o chip fechou em 35,13px, 0,32 a mais,
       e 0,32px de sobra viraria 0,32px a menos de gráfico no card ao lado. O critério de pronto
       aqui é o `getBoundingClientRect().height` do chip, não o olho.
       Só o `-slim` — que existe num lugar só, o chip de Sessão do menu (`index.html:1245`).
       O `.precs-stat` cheio não é usado por ninguém hoje, e mexer nele seria mexer no que
       vier a usá-lo depois. */
    /* (1.1.57, segunda volta) O NÚMERO VOLTA PARA 18px. Ele tinha ido a 24px para acompanhar
       a foto de 52px, e o resultado foi desproporcional pelo motivo certo: 24px é EXATAMENTE o
       tamanho da saudação ("Boa tarde, Kevin"), então o cronômetro passou a disputar a âncora
       do bloco em vez de apoiá-la. Quem manda no hero é o nome; o tempo de sessão é o dado que
       muda, não o título.
       A CAIXA do chip fica grande — o padding e o ícone de 32px continuam —, então ele segue
       proporcional à foto. O que desce é só a voz do número. */
    .precs-stat-slim .precs-stat-value { font-size: var(--fs-10); }
    .precs-stat-slim .precs-stat-label { font-size: var(--fs-2); margin-bottom: 0; }
    /* PREMIUM — realce dourado + leve subida + brilho sutil no hover */
    .precs-stat:hover {
      border-color: color-mix(in srgb, var(--precs-gold, #B49552) 60%, var(--border-color));
      transform: translateY(-1px);
      box-shadow: inset 0 1px 0 color-mix(in srgb, var(--precs-gold,#B49552) 16%, transparent),
                  0 4px 16px color-mix(in srgb, var(--precs-gold,#B49552) 22%, transparent);
    }
    .precs-stat-icon {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 32px; height: 32px;
      border-radius: var(--radius-inner);
      flex-shrink: 0;
      color: var(--precs-gold, #B49552);
      background: color-mix(in srgb, var(--precs-gold, #B49552) 16%, transparent);
      box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--precs-gold, #B49552) 26%, transparent);
    }
    .precs-stat-info { display: flex; flex-direction: column; line-height: 1.12; text-align: left; }
    .precs-stat-label {
      font-size: 0.6rem;
      text-transform: uppercase;
      letter-spacing: var(--ls-caps);
      font-weight: 700;
      color: var(--precs-gold-title, var(--precs-gold, #D3B26B));
      margin-bottom: var(--space-0);
    }
    .precs-stat-value {
      font-size: 1rem;
      font-weight: 700;
      letter-spacing: .3px;
      color: var(--text-primary);
      font-family: var(--font-num);
      white-space: nowrap;        /* nunca quebra o valor em duas linhas */
    }
    /* Sessão "pulsa": anel dourado que respira no badge, sinalizando que corre. */
    .precs-stat[data-stat="sessao"] .precs-stat-icon { animation: precs-stat-pulse 2.4s ease-in-out infinite; }
    @keyframes precs-stat-pulse {
      0%,100%{ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--precs-gold,#B49552) 26%, transparent),
                            0 0 0 0 color-mix(in srgb, var(--precs-gold,#B49552) 45%, transparent); }
      50%{ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--precs-gold,#B49552) 26%, transparent),
                       0 0 0 6px color-mix(in srgb, var(--precs-gold,#B49552) 0%, transparent); }
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-stat[data-stat="sessao"] .precs-stat-icon { animation: none; }
    }
    /* PRECS (1.1.5) — ENTRADA DO TOPO. O hero nunca teve animação de entrada: os 3 cards
       de baixo surgiam em cascata e o topo aparecia seco, o que fazia o bloco parecer
       parte da moldura em vez de conteúdo. Reusa o precsHomeIn dos cards, com o mesmo
       escalonamento curto, então o topo entra ANTES deles e o olho desce naturalmente.
       `backwards` e NÃO `both`: com `both` o valor animado fica dono de opacity/transform
       depois de terminar e sequestra hover e realces — a lição está registrada no bloco
       de animação dos cards do menu. */
    .precs-welcome-linha,
    .precs-foco-bloco { animation: precsHomeIn .34s var(--ease-2) backwards; }
    .precs-welcome-linha { animation-delay: .02s; }
    .precs-foco-bloco   { animation-delay: .09s; }

    @media (max-width: 640px) {
      .precs-welcome-linha { justify-content: center; text-align: center; }
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-welcome-linha, .precs-foco-bloco { animation: none; }
    }

    /* PRECS — Brand loader (letras "Precs" acendendo + estrela girando) */
    .precs-brand-loader {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: var(--space-4);
      padding: var(--space-6) 0;
    }
    .precs-brand-loader svg { overflow: visible; }
    .precs-bl-letter,
    .precs-bl-star {
      animation: precsBlGlow 1.6s ease-in-out infinite;
      transform-box: fill-box;
      transform-origin: center;
    }
    .precs-bl-l1 { animation-delay: 0s;    }
    .precs-bl-l2 { animation-delay: 0.16s; }
    .precs-bl-l3 { animation-delay: 0.32s; }
    .precs-bl-l4 { animation-delay: 0.48s; }
    .precs-bl-l5 { animation-delay: 0.64s; }
    .precs-bl-star {
      animation: precsBlGlow 1.6s ease-in-out infinite,
                 precsBlSpin 3.2s linear infinite;
      animation-delay: 0.8s, 0s;
    }
    .precs-bl-caption {
      font-size: 0.85rem;
      color: var(--text-secondary);
    }
    /* variante compacta: usada no gráfico e no histórico do ocioso ao atualizar */
    .precs-brand-loader.precs-bl-sm { padding: var(--space-4) 0; gap: var(--space-2); }
    .precs-brand-loader.precs-bl-sm .precs-bl-caption { font-size: .74rem; }
    @keyframes precsBlGlow {
      0%, 100% { opacity: 0.18; }
      50%      { opacity: 1; }
    }
    @keyframes precsBlSpin {
      from { transform: rotate(0deg); }
      to   { transform: rotate(360deg); }
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-bl-letter, .precs-bl-star { animation: none; opacity: 1; }
    }
    .precs-btn-star {
      animation: precsBlSpin 1.1s linear infinite;
      transform-origin: center;
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-btn-star { animation: none; }
    }

    /* PRECS — Skeleton de carregamento das campanhas (no lugar do spinner) */
    .precs-skel-list {
      display: flex;
      flex-direction: column;
      gap: var(--space-3);
      text-align: left;
    }
    .precs-skel-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: var(--space-4) var(--space-5);
      background: var(--bg-primary);
      border: 2px solid var(--border-color);
      border-radius: var(--radius-inner);
    }
    .precs-skel-lines { flex: 1; }
    .precs-skel-arrow {
      width: 14px; height: 14px; border-radius: 4px;
      margin-left: var(--space-4);
    }
    .precs-skel-bar { height: 12px; border-radius: var(--radius-sm); }
    .precs-skel-bar-lg { width: 55%; margin-bottom: var(--space-2); }
    .precs-skel-bar-sm { width: 30%; height: 10px; }
    /* superfície "shimmer" que percorre os blocos */
    .precs-skel-bar, .precs-skel-arrow {
      background: linear-gradient(
        90deg,
        var(--border-color) 0%,
        var(--bg-tertiary) 20%,
        var(--border-color) 40%,
        var(--border-color) 100%
      );
      background-size: 200% 100%;
      animation: precsShimmer 1.4s ease-in-out infinite;
    }
    @keyframes precsShimmer {
      0%   { background-position: 200% 0; }
      100% { background-position: -200% 0; }
    }
    @media (prefers-reduced-motion: reduce) {
      .precs-skel-bar, .precs-skel-arrow { animation: none; }
    }

    /* PRECS — foco nítido e CONSISTENTE em todo campo editável do painel
       (login, busca de negócio, discagem manual e anotação): mesmo anel na cor
       do tema. Antes cada campo tinha um foco diferente. */
    .form-group input:focus-visible,
    .dialer-input:focus-visible,
    #phone-input-campaign:focus-visible,
    #manual-deal-input:focus-visible,
    .precs-mvinc-input:focus-visible,
    .precs-nota-input:focus-visible {
      outline: none;
      border-color: var(--accent-blue);
      box-shadow: 0 0 0 3px var(--accent-blue-light);
    }

    /* PRECS — o input do modo manual usa a classe "input" solta (não está
       dentro de um .form-group), então o seletor descendente não pega a cor.
       Forçamos por ID para o número ficar legível nos dois temas. */
    #phone-input-campaign {
      color: var(--text-primary);
      border: 1px solid var(--border-color);
      border-radius: var(--radius-inner);
      font-variant-numeric: tabular-nums;
      letter-spacing: var(--ls-caps);
      font-size: 1.05rem;
      transition: border-color var(--dur-2), box-shadow var(--dur-2);
    }
    #phone-input-campaign::placeholder {
      color: var(--text-muted);
    }
    .campaign-item:focus-visible,
    .qualification-item:focus-visible {
      outline: none;
      border-color: var(--accent-blue);
      box-shadow: 0 0 0 3px var(--accent-blue-light);
    }

    /* PRECS — microanimação quando o card da lead entra/troca */
    /* PRECS — editor de anotação do operador (TPA): card do Pipe vira nota */
    .precs-nota-card{ background:var(--lead-surface); border:1px solid var(--lead-border);
      border-radius:var(--radius-card); padding:var(--space-4) var(--space-4); box-shadow:var(--shadow); }
    .precs-nota-head{ display:flex; align-items:flex-start; gap:var(--space-2); margin-bottom:var(--space-3);
      color:var(--precs-gold,#B49552); }
    .precs-nota-ico{ flex:none; display:inline-flex; margin-top:var(--space-0); }
    .precs-nota-tit{ font-size:.95rem; font-weight:700; color:var(--lead-title); line-height:1.2;
      font-family:'Poppins','Manrope',sans-serif; }
    .precs-nota-sub{ font-size:.8rem; color:var(--lead-muted); margin-top:var(--space-0);
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .precs-nota-bar{ display:flex; gap:var(--space-2); margin-bottom:var(--space-2); }
    .precs-nota-b{ width:32px; height:30px; border-radius:var(--radius-inner); cursor:pointer; font-size:.9rem;
      border:1px solid var(--lead-border-2,var(--border-color));
      background:var(--lead-surface-2,var(--bg-secondary)); color:var(--lead-text,var(--text-primary));
      transition:background var(--dur-1), border-color var(--dur-1), color var(--dur-1), transform .1s; }
    .precs-nota-b:hover{ border-color:var(--precs-gold,#B49552); color:var(--precs-gold,#B49552); }
    .precs-nota-b:active{ transform:translateY(1px); }
    .precs-nota-input{ min-height:120px; max-height:260px; overflow-y:auto;
      border:1px solid var(--lead-border-2,var(--border-color)); border-radius: var(--radius-inner);
      padding:var(--space-3) var(--space-3); background:var(--lead-surface-2,var(--bg-primary));
      color:var(--lead-text,var(--text-primary)); font-size:.9rem; line-height:1.45; outline:none;
      transition:border-color var(--dur-1), box-shadow var(--dur-1); }
    .precs-nota-input:focus{ border-color:var(--precs-gold,#B49552);
      box-shadow:0 0 0 3px var(--precs-gold-light, rgba(180,149,82,.16)); }
    /* (1.1.10) CINTO E SUSPENSÓRIO CONTRA FORMATAÇÃO DE FORA.
       O caminho principal é o onpaste (precsNotaColar), que insere texto puro. Esta regra é a
       rede: qualquer nó que entre no campo com estilo próprio — colagem por um caminho que eu
       não previ, arrastar texto, aba com app.js antigo em cache — renderiza herdando a cor e o
       fundo do campo em vez de trazer os do Pipedrive (que era fundo cinza e fonte branca,
       ilegível sobre o card claro).
       `!important` aqui é o uso legítimo dele: o que se está sobrepondo é `style=` inline vindo
       de fora, e só !important vence inline. O escopo é o interior deste campo, e os três
       botões B/I/U continuam funcionando porque negrito, itálico e sublinhado NÃO são cor —
       font-weight, font-style e text-decoration ficam de fora da lista de propósito. */
    .precs-nota-input * {
      background: transparent !important;
      color: inherit !important;
      font-family: inherit !important;
      font-size: inherit !important;
      line-height: inherit !important;
    }
    .precs-nota-input:empty:before{ content:attr(data-ph); color:var(--lead-muted); pointer-events:none; }
    .precs-nota-hint{ font-size:.74rem; color:var(--lead-muted); margin-top:var(--space-2); line-height:1.35; }

    /* PRECS (1.1.5) — MODO COMPACTO: a anotação DURANTE A LIGAÇÃO.
       O campo passou a existir já na chamada, para o operador escrever enquanto conversa em
       vez de tentar lembrar de tudo no TPA. O problema era altura: no tamanho cheio ele mede
       227px, e a coluna central em chamada já termina em 626px. Medido nas três telas da
       operação: 1920x1080 sobra 215px, 1600x900 sobra 35px, e 1366x768 — o notebook que tem
       em call center — FALTA 97px, ou seja, a página passaria a rolar durante a ligação,
       que é justamente o que o painel evita (é por isso que o mailing rola por dentro).
       Então na chamada ele nasce compacto e CRESCE conforme o operador digita (o
       contenteditable sobe do min-height até o max-height de 260px, e só então rola por
       dentro). No TPA volta ao tamanho cheio, que é quando a anotação é obrigatória em
       várias qualificações e o operador precisa reler o que escreveu.
       As três economias, em ordem de tamanho: a barra B/I/U sobe para a MESMA LINHA do
       título (economiza os 38px dela), o subtítulo com o nome do negócio sai (é repetição
       do card que está logo acima) e a linha de ajuda sai (ela explica o que acontece no
       ENVIO, que é assunto do TPA). O campo em si cai de 120px para 56px. */
    .precs-nota-compacta{
      display:grid;
      grid-template-columns:1fr auto;
      grid-template-areas:"head bar" "input input";
      align-items:center;
      gap:var(--space-2);
      padding:var(--space-3);
    }
    .precs-nota-compacta .precs-nota-head{ grid-area:head; margin-bottom:0; }
    .precs-nota-compacta .precs-nota-bar{ grid-area:bar; margin-bottom:0; }
    .precs-nota-compacta .precs-nota-input{ grid-area:input; min-height:56px; }
    .precs-nota-compacta .precs-nota-sub,
    .precs-nota-compacta .precs-nota-hint{ display:none; }
    /* (1.1.7) Card de anotação SEM NEGÓCIO VINCULADO. Ele existe para explicar uma
       AUSÊNCIA, então é visivelmente inerte: sem barra de formatação e sem campo, com o
       aviso ocupando o lugar do editor. O que ele não pode ser é invisível, porque foi o
       painel vazio que fez o operador ler "o card sumiu" em vez de "não há onde gravar". */
    /* (1.1.7) SELO DE VÍNCULO no cabeçalho do mailing. Ver precsRenderSeloVinculo.
       O TEXTO usa tokens já cobertos por teste-contraste.js; a cor de estado fica só no
       ponto, que é decoração e não carrega informação sozinho (o texto ao lado diz tudo).
       Assim o selo não abre uma frente nova de contraste nos três temas. */
    .precs-selo-vinc{
      display:inline-flex; align-items:center; gap:var(--space-1);
      margin-top:var(--space-1);
      padding:2px var(--space-2);
      border:1px solid var(--border-color);
      border-radius:var(--radius-pill);
      font-family:var(--font-acao);
      font-size:.7rem; font-weight:700; letter-spacing:.02em;
      color:var(--text-secondary); white-space:nowrap;
    }
    .precs-selo-dot{ width:7px; height:7px; border-radius:50%; background:var(--text-muted); flex-shrink:0; }
    .precs-selo-vinc-ok .precs-selo-dot{ background:var(--st-call,#22c55e); }
    .precs-selo-vinc-ok{ color:var(--text-primary); }
    .precs-selo-vinc-aguarda .precs-selo-dot{ background:var(--st-manual,#f59e0b); }
    .precs-selo-vinc-sem{ border-style:dashed; }

    /* (1.1.7) TELA DE ENCERRAMENTO DA ABA DO PIPEDRIVE. Ver precsEncerrarAba no app.js.
       É uma SOBREPOSIÇÃO e não uma troca do documento: o timer de boot e o window.onerror
       continuam vivos, e destruir o documento por baixo deles gerava exceção que virava
       chamada ao Lambda a partir de uma aba morrendo.
       Cores da marca, e não os cinzas genéricos que estavam aqui antes. */
    #precs-aba-encerrada{
      position:fixed; inset:0; z-index:99999;
      display:flex; align-items:center; justify-content:center;
      background:#131315; padding:var(--space-6);
    }
    .precs-aba-fim-caixa{ max-width:460px; text-align:center; }
    .precs-aba-fim-selo{
      display:inline-block; margin-bottom:var(--space-4);
      padding:2px var(--space-3); border:1px solid #B49552; border-radius:var(--radius-pill);
      font-family:var(--font-acao); font-size:.68rem; font-weight:700;
      letter-spacing: var(--ls-caps); text-transform:uppercase; color:#B49552;
    }
    .precs-aba-fim-tit{
      font-family:'Sora','Poppins',sans-serif; font-size:1.25rem; font-weight:600;
      color:#D3B26B; margin-bottom:var(--space-3);
    }
    .precs-aba-fim-txt{
      font-family:'Poppins',sans-serif; font-size:.88rem; line-height:1.55; color:#F3F3F3;
    }
    .precs-aba-fim-acao{
      margin-top:var(--space-5); padding:var(--space-3);
      border:1px dashed #B49552; border-radius:var(--radius-inner);
      font-family:'Poppins',sans-serif; font-size:.85rem; color:#F3F3F3;
    }
    .precs-aba-fim-acao b{ color:#FFC95B; }
    .precs-aba-fim-pisca{ animation:precsAbaPisca .5s ease 2; }
    @keyframes precsAbaPisca{ 50%{ background:rgba(255,201,91,.18); } }
    .precs-aba-fim-btn{
      margin-top:var(--space-4); padding:var(--space-2) var(--space-5);
      background:transparent; border:1px solid #C1C6CE; border-radius:var(--radius-pill);
      font-family:var(--font-acao); font-size:.82rem; font-weight:600;
      color:#C1C6CE; cursor:pointer;
    }
    .precs-aba-fim-btn:hover{ border-color:#B49552; color:#F3F3F3; }
    .precs-aba-fim-pe{
      margin-top:var(--space-5); font-family:'Poppins',sans-serif;
      font-size:.75rem; line-height:1.45; color:#C1C6CE;
    }
    @media (prefers-reduced-motion: reduce){ .precs-aba-fim-pisca{ animation:none; } }

    .precs-nota-dispensa{ opacity:.9; }
    .precs-nota-aviso{
      font-size:.8rem; line-height:1.45; color:var(--lead-muted);
      margin-top:var(--space-3);
      padding:var(--space-3);
      border:1px dashed var(--lead-border);
      border-radius:var(--radius-inner);
    }
    .precs-nota-aviso b{ color:var(--lead-title); }

    /* PRECS — HISTÓRICO DE ANOTAÇÕES (bloco dentro do card do negócio).
       Família no PLURAL (.precs-notas-*) de propósito: a família no singular
       (.precs-nota-*, acima) é o card de ESCRITA da anotação no TPA. Nomes
       distintos evitam a colisão silenciosa em que a segunda declaração vence a
       primeira, que é o defeito que já pegamos em .precs-avatar.

       O bloco é deliberadamente DISCRETO: dentro da ligação o que manda é o nome,
       o valor e o telefone. O histórico é apoio, então entra com separador sutil,
       rótulo pequeno e altura limitada, sem competir com a grade de campos. */
    /* IDENTIDADE PIPEDRIVE — faixa verde e selo "P", COMPARTILHADOS entre o card do
       negócio e o card de anotações. Os dois mostram conteúdo que vem do Pipedrive e
       precisam se anunciar igual; antes a faixa e o selo existiam só como style
       inline dentro de precsRenderLeadCard, então repetir no card de anotações
       criaria uma segunda implementação do mesmo elemento visual — o começo do
       problema que a auditoria aponta em 6.3. O verde é cor de MARCA do Pipedrive e
       fica igual nos 3 temas, de propósito. */
    .precs-pipe-faixa{ background:linear-gradient(90deg,#1a7a4c,#28a745); height:6px; }
    /* (1.1.38) O selo virou moldura do LOGO: o fundo verde e a letra saíram daqui porque o
       SVG já traz os dois. Ver precsPipeLogoHTML no app.js. */
    .precs-pipe-selo{ display:inline-flex; align-items:center; justify-content:center;
      flex:0 0 auto; }
    /* O badge do menu ("Últimos leads trabalhados") tinha o estilo INLINE, com o verde
       antigo cravado. Agora usa o token, como todos os outros. */
    /* (1.1.79) A MESMA CAIXA DO SELO DE NEGÓCIO (ver a canônica em 10-supervisao.css). */
    .precs-pipe-link{ display:inline-flex; align-items:center; justify-content:center;
      gap:var(--space-1); flex-shrink:0; 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;
      margin-left:auto; color:#fff;
      background:linear-gradient(90deg,var(--pipe-verde,#017737),var(--pipe-verde-2,#0B8A4A));
      transition:filter var(--dur-1, .15s) ease; }
    /* PRECS (1.1.57, segunda volta) — O SELO DO PIPEDRIVE SUBIU PARA A LINHA DO TITULO no card
       de ultimos leads, e la ele perde duas coisas.
       O `margin-left:auto` primeiro: ele existe para empurrar o selo ate a borda direita da
       linha do telefone, e no grupo novo — que e dimensionado pelo proprio conteudo — nao ha
       espaco livre para consumir. Deixa-lo seria carregar uma intencao que nao vale mais ali.
       O NUMERO, POREM, FICA — e isto e uma volta atras com dono. Eu tinha tirado o "#93369" do
       selo por parecer eco do titulo ("Negocio #93369") a dois centimetros de distancia, e o
       `teste-notas-outbox.js` reprovou na assercao "identificador do negocio aparece no card".
       Ele estava certo e eu nao: o titulo so vira "Negocio #<id>" quando o negocio NAO TEM NOME.
       Quando tem — "PRECATORIO A", que e o caso comum na operacao — o numero existia unicamente
       no selo, e tira-lo fazia o identificador sumir da tela inteira. A repeticao que eu vi era
       o caso particular; o caso geral era perda de dado. */
    .precs-hist-item .precs-pipe-link{ margin-left: 0; }
    .precs-pipe-link:hover{ filter:brightness(1.12); }
    @media (prefers-reduced-motion: reduce){ .precs-pipe-link{ transition:none; } }
    .precs-pipe-rotulo{ font-size:.72rem; text-transform:uppercase; letter-spacing: var(--ls-caps);
      color:var(--lead-label); font-weight:600; min-width:0; }
    .precs-pipe-cab{ display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-3); flex-wrap:wrap; }

    /* ================= PRECS (1.1.8) — CARD DO NEGÓCIO REPAGINADO =================
       O card repetia o mailing (nome, tribunal, autos, orçamento, organização vêm todos da
       planilha, e a coluna da esquerda já mostra cada um com botão de copiar). Passou a
       responder o que só o Pipedrive sabe: em que ETAPA o negócio está, de QUEM ele é, se
       está aberto ou fechado, e qual a PRÓXIMA ATIVIDADE agendada. */
    .precs-neg-card{
      position:relative; isolation:isolate;
      background:var(--lead-surface); border:1px solid var(--lead-border);
      border-radius: var(--radius-card); overflow:hidden; box-shadow:var(--shadow);
    }
    /* COR POR TRIBUNAL, no PRÓPRIO CAMPO e não como etiqueta no cabeçalho.
       A pílula no topo virava mais uma etiqueta entre as etiquetas do Pipe, competindo com
       elas em vez de identificar o tribunal. Aqui a cor entra como brilho difuso atrás do
       texto, ONDE o dado está, e nenhuma cor de texto muda: o valor continua no token do
       tema, então nada disso entra na conta de contraste. */
    /* Vale para o campo do card do negócio E para o card do mailing: a cor acompanha o
       DADO, onde quer que ele esteja na tela. Sem o mailing aqui, a cor sumiria na maioria
       das ligações, porque o mailing de precatório quase sempre traz a coluna TRIBUNAL e o
       dedup tira o campo do card do negócio. */
    /* O brilho fica ATRÁS DO TEXTO, e não preenchendo o card. Preencher o card inteiro
       transformava a cor em um bloco grande, que é justamente a poluição visual que esta
       revisão existe para reduzir; atrás do valor ela vira o realce de uma palavra. */
    [data-trib-campo] .precs-trib-valor{
      position:relative; display:inline-block; isolation:isolate;
    }
    [data-trib-campo] .precs-trib-valor::before{
      content:''; position:absolute; inset:-5px -12px; z-index:-1; pointer-events:none;
      background:radial-gradient(ellipse at center, rgba(var(--trib), var(--trib-a,.62)), transparent 72%);
      filter:blur(9px);
    }
    /* Alpha por tema: o mesmo valor que é sutil sobre o #131315 vira mancha sobre branco. */
    html[data-luz="claro"] [data-trib-campo] .precs-trib-valor::before{ --trib-a:.42; }
    /* O tema Contraste existe para REMOVER decoração. Aqui ele remove. */
    html[data-theme="contraste"] [data-trib-campo] .precs-trib-valor::before{ display:none; }

    /* ---- Topo do card: identificação à esquerda, PROPRIETÁRIO à direita ----
       É onde o Pipedrive coloca o dono do negócio, e saber de quem é a lead é decisão de
       abordagem: o operador já olha para aquele canto. */
    .precs-neg-topo{
      display:flex; align-items:flex-start; justify-content:space-between;
      gap:var(--space-3); margin-bottom:var(--space-3);
    }
    .precs-neg-topo .precs-pipe-cab{ margin-bottom:0; }
    .precs-neg-dono{ display:flex; align-items:center; gap:var(--space-2); flex-shrink:0; }
    .precs-neg-avatar{
      width:38px; height:38px; flex-shrink:0; border-radius:50%;
      display:inline-flex; align-items:center; justify-content:center;
      /* (1.1.42) Mesmo defeito do `.precs-card-grip`: ouro de TEXTO usado como fundo, com
         tinta preta cravada. No Zebrado claro o avatar do negócio virava um círculo preto com
         a inicial preta dentro. */
      background:var(--precs-gold-forma,#B49552); color:var(--precs-wa-tinta-ouro,#131315);
      font-family:var(--font-acao); font-size:.8rem; font-weight:700;
      background-size:cover; background-position:center;
    }
    /* Com foto o círculo não pode manter o dourado por baixo (borda de cor aparecendo). */
    .precs-neg-avatar-foto{ background-color:transparent; }
    .precs-neg-dono-txt{ display:flex; flex-direction:column; line-height:1.25; min-width:0; }
    .precs-neg-dono-nome{
      font-size:.92rem; font-weight:700; color:var(--lead-text);
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:180px;
    }
    .precs-neg-dono-rot{
      font-size:.68rem; font-weight:600; letter-spacing: var(--ls-caps); text-transform:uppercase;
      color:var(--lead-label);
    }
    /* Status do negócio. `won` e `lost` são ALERTA: o operador está ligando para um
       negócio já fechado, e até a 1.1.8 não havia nada na tela dizendo isso. */
    .precs-neg-status{
      display:inline-flex; align-items:center;
      font-size:.66rem; font-weight:700; letter-spacing: var(--ls-caps); text-transform:uppercase;
      padding:.1rem .5rem; border-radius:var(--radius-pill); line-height:1.4;
      color:var(--st-cor); border:1px solid var(--st-cor);
    }
    /* CHIP DO TRIBUNAL, ao lado do status. Ele saiu da grade porque é IDENTIFICAÇÃO e não
       campo de consulta: ali é lido de relance, e o card ganhou uma linha inteira de volta.
       Sem fundo nem borda próprios — quem marca é o brilho da cor atrás do texto, o mesmo
       tratamento que o campo tinha, agora num espaço menor. */
    .precs-neg-tribchip{
      display:inline-flex; align-items:center; gap:var(--space-1);
      font-size:.68rem; font-weight:700; letter-spacing:.3px;
      color:var(--lead-text); line-height:1.4;
    }
    .precs-neg-tribchip svg{ width:12px; height:12px; color:var(--lead-label); flex-shrink:0; }
    /* O brilho precisa ser MAIS FORTE aqui do que era no campo da grade: o chip tem quatro
       letras, e o mesmo alpha que marcava um card de 150px de largura vira imperceptível
       nesse espaço. Blur menor pelo mesmo motivo, para a cor ficar concentrada atrás do
       texto em vez de se diluir. */
    .precs-neg-tribchip .precs-trib-valor::before{
      inset:-4px -9px; filter:blur(7px); --trib-a:.92;
    }
    html[data-luz="claro"] .precs-neg-tribchip .precs-trib-valor::before{ --trib-a:.55; }

    /* ---- FITA DE ETAPAS, no desenho do Pipedrive ----
       Lá o funil inteiro aparece numa fita horizontal: a etapa atual preenchida em verde
       com "N dias", as anteriores marcadas e as seguintes esmaecidas. Reproduzir a MESMA
       leitura é o que faz o operador não precisar trocar de aba para saber em que pé está
       o negócio. Rola no eixo X quando o funil é longo (o de Prospecção tem 8 etapas). */
    /* O VERDE É O DO PIPEDRIVE, e não o --st-call do painel.
       O --st-call significa "chamada em curso" no discador inteiro (faixa de estado,
       cronômetro, tempos da sessão). Usá-lo aqui fazia a etapa do negócio parecer um
       indicador de chamada, misturando dois vocabulários de cor na mesma tela. Este verde
       é o da fita de etapas do Pipedrive, e só aparece aqui. */
    /* O verde do Pipe é #26A65B. Com o texto BRANCO que ele usa, esse par dá 3,14:1 —
       abaixo de AA, e aqui é texto de 0,68rem sob zoom 0,85 (uns 9px reais) que o operador
       lê com o cliente na linha. Escurecer 20% chega a #1E8549, que com branco dá 4,66:1 e
       continua sendo lido como o mesmo verde. É o tom mais PRÓXIMO do dele que passa: os
       valores entre um e outro foram medidos, e #1F884B (18%) ainda ficava em 4,49:1.
       Texto branco nos dois temas, como no Pipedrive claro e escuro. */
    :root{ --pipe-verde:#1E8549; --pipe-verde-fraco:rgba(30,133,73,.20); }
    .precs-fita{
      display:flex; gap:3px; margin-bottom:var(--space-2);
      overflow-x:auto; scrollbar-width:thin; padding-bottom:2px;
    }
    /* FORMATO DE SETA (chevron), como a fita do Pipe: bico à direita e encaixe à
       esquerda. O clip-path substitui borda e raio, por isso os passos não têm mais
       cantos arredondados nem borda — a silhueta é a borda. */
    .precs-fita-passo{
      flex:1 1 0; min-width:86px;
      padding:.34rem .7rem .34rem 1.1rem;
      background:var(--lead-surface-2); color:var(--lead-muted);
      font-size:.68rem; font-weight:600; line-height:1.35;
      white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
      clip-path:polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%, 9px 50%);
    }
    /* O primeiro não tem encaixe à esquerda e o último não tem bico à direita, senão a
       fita pareceria cortada nas pontas. */
    .precs-fita-passo:first-child{
      padding-left:.7rem;
      clip-path:polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%);
    }
    .precs-fita-passo:last-child{
      clip-path:polygon(0 0, 100% 0, 100% 100%, 0 100%, 9px 50%);
    }
    .precs-fita-passo:first-child:last-child{ clip-path:none; border-radius:var(--radius-inner); }
    /* Etapas já vencidas: preenchidas, mas sem competir com a atual. */
    .precs-fita-feita{ background:var(--pipe-verde-fraco); color:var(--lead-text); }
    /* A ATUAL é a única em verde cheio, como no Pipe. `flex-basis:auto` e não `0`: ela
       carrega "N dias · nome da etapa" e precisa do espaço do próprio conteúdo, senão o
       nome trunca em "Não aceitou Prop…" — que corta justamente a parte que diferencia
       uma etapa da outra. As demais cedem a largura. */
    /* Texto BRANCO, como no Pipedrive nos dois temas. O verde já foi calibrado para esse
       par passar AA (ver o comentário em --pipe-verde).
       SEM negrito: em 0,68rem sob zoom, o bold engrossa as letras a ponto de fechar os
       contornos e piorar a leitura, que é o oposto do que ele deveria fazer. O destaque já
       vem do fundo verde. */
    .precs-fita-atual{
      flex:0 1 auto; max-width:60%;
      background:var(--pipe-verde); color:#fff;
    }
    /* ====================================================================== */
    /* (1.1.10) A FITA VOLTOU, COM JANELA DE TRÊS ETAPAS                      */
    /* ---------------------------------------------------------------------- */
    /*  O porquê está no comentário de fitaEtapas, no app.js. Aqui só o desenho.
        As PONTAS do bico agora saem de classe (.precs-fita-ini / .precs-fita-fim) em vez de
        :first-child/:last-child — o contador é irmão dos passos, então ele roubava o
        :last-child e o bico da direita saía deformado. As regras antigas por posição continuam
        acima, inofensivas: quando a fita tem só a janela, quem manda são estas.
        Sem `overflow-x`: com três passos sempre cabe, então a barra de rolagem horizontal que
        aparecia com o funil inteiro deixa de existir. */
    .precs-fita{ align-items:stretch; flex-wrap:nowrap; overflow-x:visible; }
    .precs-fita-ini{
      padding-left:.7rem;
      clip-path:polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%);
    }
    .precs-fita-fim{
      clip-path:polygon(0 0, 100% 0, 100% 100%, 0 100%, 9px 50%);
    }
    /* Janela de um passo só (funil de uma etapa, ou negócio na única etapa existente): sem
       bico nenhum, senão a peça fica com as duas pontas cortadas e lê como erro de render. */
    .precs-fita-ini.precs-fita-fim{ clip-path:none; border-radius:var(--radius-inner); }
    /* A atual pode ocupar o que precisar; as vizinhas cedem e truncam, porque o nome delas é
       contexto e o da atual é a informação. */
    .precs-fita .precs-fita-passo:not(.precs-fita-atual){
      flex:1 1 0; min-width:0;
      overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
    }
    .precs-fita-conta{
      margin-left:var(--space-2); flex:0 0 auto; align-self:center;
      font-family:var(--font-num); font-size:.66rem;
      color:var(--lead-muted); white-space:nowrap;
    }

    /* ====================================================================== */