/* =========================================================================
   PGFARMA — Design System
   Refinamento inspirado em SaaS modernos: muito respiro, bordas quase
   imperceptíveis, sombras suaves, tipografia com hierarquia clara.
   Marca: vermelho é ACENTO; fundos neutros/claros (ou escuros no dark).
   Tudo via variáveis CSS para permitir tema claro/escuro.
   ========================================================================= */

/* ---- Tokens: TEMA CLARO (padrão) ---------------------------------------- */
:root,
:root[data-tema="claro"] {
    --fundo: #ffffff;          /* página BRANCA, como a DRB */
    --superficie: #ffffff;
    --superficie-2: #f5f6f8;   /* tom sutil p/ cabeçalho de tabela, hovers */
    --superficie-3: #eceef2;
    --borda: #e6e8ec;          /* um pouco mais visível p/ molduras no branco */
    --borda-forte: #dde0e6;

    --texto: #1f2733;
    --texto-suave: #5f6875;   /* texto de apoio (escurecido p/ contraste AA ≥4.5:1) */
    --texto-rotulo: #6b7280;  /* rótulos de coluna/label (contraste AA ≥4.5:1) */
    --texto-inverso: #ffffff;

    /* Marca (nossa identidade — vermelho em gradiente) */
    --vinho: #9e1b1b;         /* menu ativo, títulos de destaque */
    --vermelho: #c62828;      /* ação: botões primários, links */
    --vermelho-hover: #a91f1f;
    --vermelho-suave: rgba(198, 40, 40, 0.08);
    --vermelho-suave-2: rgba(198, 40, 40, 0.13);

    /* Hyperlink = AZUL (padrão de link). O vermelho fica p/ marca/ações. */
    --link: #2563eb;         /* AA sobre fundo branco (≥4.5:1) */
    --link-hover: #1d4ed8;

    --sucesso: #1a9e52;
    --sucesso-bg: #e9f6ef;
    --neutro: #6b7686;
    --neutro-bg: #f0f2f5;
    --alerta: #c62828;
    --alerta-bg: #fdecec;
    /* Status do funil (segundo eixo) */
    --info: #2563eb;           /* em andamento */
    --info-bg: #e8f0fe;
    --aviso: #b45309;          /* em block (âmbar, bem visível) */
    --aviso-bg: #fdf0dc;
    --aviso-borda: #f0b429;
    --roxo: #7c3aed;           /* destaque secundário (ex.: tempo na semana) */
    --roxo-bg: #f1eafd;

    --sombra-sm: 0 1px 2px rgba(17, 24, 39, 0.03);
    --sombra: 0 1px 2px rgba(17, 24, 39, 0.03), 0 8px 20px rgba(17, 24, 39, 0.04);
    --anel-foco: 0 0 0 3px var(--vermelho-suave-2);

    --raio: 14px;
    --raio-sm: 9px;
    --raio-pill: 999px;
    --largura-menu: 258px;
    --largura-menu-recolhido: 76px;
    --largura-trilho: 64px;   /* trilho de presença (direita, fixo — cabe a pílula ~46px) */
}

/* ---- Tokens: TEMA ESCURO ------------------------------------------------ */
:root[data-tema="escuro"] {
    --fundo: #101318;
    --superficie: #171b22;
    --superficie-2: #1e232b;
    --superficie-3: #262c35;
    --borda: #242932;
    --borda-forte: #333a45;

    --texto: #e7eaf0;
    --texto-suave: #a7b0bd;
    --texto-rotulo: #8b95a4;   /* clareado p/ contraste AA sobre o fundo escuro */
    --texto-inverso: #ffffff;

    --vinho: #e26a6a;
    --vermelho: #e05656;
    --vermelho-hover: #ef6a6a;
    --vermelho-suave: rgba(224, 90, 90, 0.13);
    --vermelho-suave-2: rgba(224, 90, 90, 0.20);

    /* Hyperlink = AZUL clareado p/ contraste AA sobre o fundo escuro. */
    --link: #60a5fa;
    --link-hover: #93c5fd;

    --sucesso: #4ade80;
    --sucesso-bg: rgba(34, 197, 94, 0.13);
    --neutro: #9aa4b1;
    --neutro-bg: rgba(148, 163, 184, 0.12);
    --alerta: #f87171;
    --alerta-bg: rgba(248, 113, 113, 0.13);
    /* Status do funil (segundo eixo) */
    --info: #60a5fa;
    --info-bg: rgba(96, 165, 250, 0.15);
    --aviso: #fbbf24;
    --aviso-bg: rgba(251, 191, 36, 0.15);
    --aviso-borda: rgba(251, 191, 36, 0.55);
    --roxo: #a78bfa;
    --roxo-bg: rgba(167, 139, 250, 0.16);

    --sombra-sm: 0 1px 2px rgba(0, 0, 0, 0.25);
    --sombra: 0 2px 10px rgba(0, 0, 0, 0.32);
    --anel-foco: 0 0 0 3px var(--vermelho-suave-2);
}

/* ---- Base --------------------------------------------------------------- */
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
    margin: 0;
    font-family: "Segoe UI", system-ui, -apple-system, Roboto, Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 1.6;
    color: var(--texto);
    background: var(--fundo);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}
a { color: var(--link); text-decoration: none; }
a:hover { color: var(--link-hover); text-decoration: underline; }
h1, h2, h3 { color: var(--texto); margin: 0; font-weight: 700; }

[x-cloak] { display: none !important; }

/* ---- Acessibilidade: foco visível por teclado, movimento reduzido, toque -- */
/* Um anel de foco consistente para TODOS os controles (botões, links, cards,
   linhas clicáveis com tabindex, chips). Só aparece na navegação por teclado. */
:focus-visible { outline: 2px solid var(--vermelho); outline-offset: 2px; }
/* Inputs já têm anel próprio via box-shadow no :focus — não dobrar. */
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* Alvo de toque confortável em telas sensíveis ao toque. */
@media (pointer: coarse) {
    .btn-icone { width: 40px; height: 40px; }
}

/* Rótulo acessível a leitores de tela, mas invisível na tela (sr-only). */
.rotulo-oculto {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Erros gerais do formulário (de clean(), não ligados a um campo). */
.form-erro-geral {
    background: var(--alerta-bg); color: var(--alerta);
    border-radius: var(--raio-sm); padding: 10px 14px; margin-bottom: 16px;
    font-size: 13.5px; font-weight: 600;
}

/* Mensagens do sistema (Django messages) — cor por tipo, anunciadas por a11y. */
.mensagens { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.mensagem { display: flex; align-items: center; gap: 9px; font-size: 13.5px; font-weight: 600;
    padding: 11px 15px; border-radius: var(--raio-sm); }
.mensagem svg { flex: none; }
.mensagem-success { color: var(--sucesso); background: var(--sucesso-bg); }
.mensagem-error { color: var(--alerta); background: var(--alerta-bg); }
.mensagem-warning { color: var(--aviso); background: var(--aviso-bg); box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.mensagem-info, .mensagem-debug { color: var(--info); background: var(--info-bg); }

.icone, .icone-sm { fill: none; stroke: currentColor; stroke-linecap: round; stroke-linejoin: round; }
.icone { width: 19px; height: 19px; stroke-width: 1.7; flex: none; }
.icone-sm { width: 16px; height: 16px; stroke-width: 1.75; flex: none; }

/* =========================================================================
   LAYOUT: menu lateral + cabeçalho + conteúdo
   ========================================================================= */
/* 2 colunas: menu + área. O cabeçalho ocupa a área INTEIRA (vai até a borda direita);
   o trilho de presença NÃO é mais coluna do grid — flutua (position:fixed) ABAIXO do
   cabeçalho, sobre a faixa reservada à direita (padding-right do .conteudo). */
.app {
    display: grid;
    grid-template-columns: var(--largura-menu) 1fr;
    min-height: 100vh;
    transition: grid-template-columns 0.18s ease;
}
.app.menu-recolhido { grid-template-columns: var(--largura-menu-recolhido) 1fr; }

/* ---- Menu lateral ------------------------------------------------------- */
.menu {
    background: var(--superficie);
    border-right: 1px solid var(--borda);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
}

/* ---- Trilho de PRESENÇA (direita) — DUAS PÍLULAS suspensas, FLUTUANDO abaixo do header -- */
/* Não é coluna do grid: `position:fixed` à direita, começando LOGO ABAIXO do cabeçalho
   (top = altura do header). Fundo TRANSPARENTE → o `.bg-espaco` (fixed, z-index:-1) compõe a
   tela toda atrás das pílulas. O `.conteudo` reserva a faixa via padding-right. */
.trilho-presenca {
    background: transparent;
    position: fixed;
    top: 64px;                  /* = altura do .cabecalho (abaixo dele) */
    right: 0;
    bottom: 0;
    width: var(--largura-trilho);
    overflow-y: auto;
    overflow-x: hidden;
    z-index: 4;                 /* < .cabecalho(5) e MUITO < modal(50) */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 14px 0;
}
.trilho-pilula {
    border: 1px solid rgba(0,0,0,.07);
    border-radius: 34px;                       /* cápsula (pontas bem arredondadas) */
    box-shadow: 0 4px 16px rgba(0,0,0,.14);    /* efeito "suspenso" (leve, p/ pílula clara) */
    width: 46px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 9px;
    padding: 11px 6px 13px;
}
/* =========================================================================
   O BOTÃO FLUTUANTE DE FEEDBACK (achado 13 do dono) — *"botão suspenso no canto
   direito inferior de todo o sistema"*.

   ⚠️ A POSIÇÃO FOI MEDIDA, NÃO ESCOLHIDA. O canto inferior direito JÁ TEM MORADOR:
   o `.trilho-presenca` logo acima é `position: fixed; right: 0; bottom: 0; width:
   64px` e vale em TODA tela autenticada (mora no `base_app.html`, não por tela).
   Um botão em `right: 20px` cairia DENTRO da faixa dele. Por isso o afastamento sai
   da MESMA variável que dá a largura ao trilho — se ela mudar, os dois andam juntos.

   ⚠️ `z-index: 6` — acima do conteúdo e do trilho (4), ABAIXO dos popovers (30) e do
   modal (50). É isso, e só isso, que faz o overlay do modal cobri-lo: com o modal
   aberto ele não flutua por cima de nada, e não precisou de regra nova nem de estado
   de Alpine para isso — nada a driftar.

   ⚠️ A COR SAI DAQUI, da classe. Um `style="color: inherit"` inline venceria a classe
   e apagaria a cor do desenho (foi o erro do R49, em sete botões). */
.botao-feedback {
    position: fixed;
    right: calc(var(--largura-trilho) + 20px);
    bottom: 20px;
    z-index: 6;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    border: 1px solid var(--borda-forte);
    border-radius: 999px;
    background: var(--superficie);
    color: var(--texto);
    font: inherit;
    font-size: 13.5px;
    font-weight: 600;
    box-shadow: var(--sombra);
    cursor: pointer;
    transition: border-color .12s, color .12s, transform .12s;
}
.botao-feedback:hover { border-color: var(--vermelho); color: var(--vermelho); transform: translateY(-1px); }
.botao-feedback:focus-visible { outline: 2px solid var(--vermelho); outline-offset: 2px; }

/* CIMA "Trabalhando agora": VERDE translúcido (o .bg-espaco aparece por trás).
   BAIXO "Equipe": fundo claro (branco no tema claro; superfície no escuro). */
.trilho-pilula--timer  { background: rgba(52,168,83,.18); border-color: rgba(52,168,83,.32); }
.trilho-pilula--equipe { background: var(--superficie); }
.trilho-pilula-ic { width: 16px; height: 16px; flex: none; }
.trilho-pilula--timer  .trilho-pilula-ic { color: var(--sucesso); }
.trilho-pilula--equipe .trilho-pilula-ic { color: var(--texto-rotulo); }
.trilho-membro { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.trilho-avatar { position: relative; display: inline-flex; cursor: pointer; text-decoration: none; }
/* SÓ avatar (sem nome), 34px. Anel branco na pílula VERDE; cinza-claro na pílula CLARA
   (onde o branco sumiria). */
.trilho-avatar .avatar-comp {
    width: 34px; height: 34px; font-size: 13px;
    border: 2px solid #fff;
    box-sizing: border-box;
}
.trilho-pilula--equipe .trilho-avatar .avatar-comp { border-color: var(--borda); }
.trilho-bolinha {
    position: absolute;
    right: -1px;
    bottom: -1px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    border: 2px solid var(--superficie);   /* anel na cor da pílula clara (Equipe) */
    box-sizing: content-box;
}
.trilho-bolinha--verde   { background: var(--sucesso); }
.trilho-bolinha--amarelo { background: var(--aviso); }
.trilho-bolinha--offline { background: var(--texto-rotulo); }   /* cinza da presença offline */
/* Timer VERDE logo abaixo do avatar — texto puro (sem chip); tica no cliente. Combina com a
   pílula verde translúcida de cima. */
.trilho-timer {
    font-size: 10px;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.2px;
    color: var(--sucesso);
    font-weight: 600;
    white-space: nowrap;
}

.menu-topo {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 20px 22px;
    height: 66px;
}
.marca {
    display: inline-flex;
    align-items: center;
    line-height: 0;
    white-space: nowrap;
    color: var(--vermelho);              /* claro: vermelho da marca (o SVG usa currentColor) */
}
:root[data-tema="escuro"] .marca { color: #fff; }   /* escuro: mesma marca, em branco */
.marca-svg { display: block; width: auto; height: 26px; }
.marca-svg-icone { display: none; }                  /* menu ABERTO → logo completa */
.app.menu-recolhido .marca-svg-completo { display: none; }
.app.menu-recolhido .marca-svg-icone { display: block; height: 30px; }  /* RECOLHIDO → só o ícone */
/* recolhido + hover/foco (menu expande): volta a logo COMPLETA, como faz com os textos */
.app.menu-recolhido .menu:hover .marca-svg-completo,
.app.menu-recolhido .menu:focus-within .marca-svg-completo { display: block; }
.app.menu-recolhido .menu:hover .marca-svg-icone,
.app.menu-recolhido .menu:focus-within .marca-svg-icone { display: none; }
.app.menu-recolhido .menu-item span,
.app.menu-recolhido .menu-usuario-info { display: none; }
.app.menu-recolhido .menu-topo { justify-content: center; padding: 20px 0; }
/* Botão FIXAR (pin/alfinete): trava o menu aberto. Some no modo ícone; reaparece
   no hover (para permitir fixar a partir do estado recolhido). */
.menu-pin {
    margin-left: auto;
    background: none; border: none; cursor: pointer;
    color: var(--texto-rotulo);
    padding: 6px; border-radius: var(--raio-sm);
    display: inline-flex; align-items: center;
    transition: transform 0.18s ease, background 0.18s ease, color 0.18s ease;
}
.menu-pin:hover { background: var(--superficie-2); color: var(--texto); }
.menu-pin:focus-visible { outline: 2px solid var(--vermelho); outline-offset: 1px; }
.menu-pin.fixado { color: var(--vinho); transform: rotate(45deg); }
.app.menu-recolhido .menu-pin { display: none; }
.app.menu-recolhido .menu:hover .menu-pin,
.app.menu-recolhido .menu:focus-within .menu-pin { display: inline-flex; }

.menu-nav { flex: 1; overflow-y: auto; padding: 10px 14px; }
.menu-grupo { margin-bottom: 22px; }
/* O rótulo do grupo é um BOTÃO de accordion (expande/recolhe os itens). */
.menu-rotulo {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    width: 100%;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    font-size: 11px;
    /* NEGRITO: o menu PRINCIPAL manda na hierarquia. O subitem vem em peso normal
       (`.menu-item`, 400) — antes era o inverso na leitura (rótulo 600 miúdo contra
       item 550 em 14px, que pesava mais no olho). */
    font-weight: 700;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--texto-rotulo);
    padding: 4px 12px 8px;
    text-align: left;
    border-radius: var(--raio-sm);
}
.menu-rotulo:hover { color: var(--texto); }
.menu-rotulo:focus-visible { outline: 2px solid var(--vermelho); outline-offset: 1px; }
/* Com o ícone do grupo SEMPRE visível, o rótulo tem 3 filhos (ícone/texto/chevron);
   sem o `flex: 1` o `space-between` jogaria o texto para o MEIO do botão. Com ele o
   texto fica coladinho no ícone e só o chevron vai para a direita. */
.menu-rotulo > span { flex: 1; min-width: 0; }
.menu-chevron {
    width: 13px; height: 13px; flex: none;
    transition: transform 0.18s ease;
}
.menu-grupo.grupo-aberto > .menu-rotulo .menu-chevron { transform: rotate(90deg); }
/* ACCORDION (só quando EXPANDIDO: fixado OU hover/foco). Recolhido em ícones =
   TODOS os itens visíveis (sem accordion). accordion-pronto liga a regra só
   depois de o Alpine abrir o grupo da tela atual (evita flash). */
.app.accordion-pronto:not(.menu-recolhido) .menu-grupo:not(.grupo-aberto) .menu-grupo-itens,
.app.accordion-pronto.menu-recolhido .menu:hover .menu-grupo:not(.grupo-aberto) .menu-grupo-itens,
.app.accordion-pronto.menu-recolhido .menu:focus-within .menu-grupo:not(.grupo-aberto) .menu-grupo-itens {
    display: none;
}

/* ÍCONE DO GRUPO — visível SEMPRE (aberto, recolhido e recolhido+hover). Quem
   carrega o ícone é o MENU PRINCIPAL (o grupo); o subitem é só texto, indentado
   sob ele. Antes era o contrário (`display: none` aqui, ícone em cada item), o
   que deixava o grupo sem identidade visual no menu aberto.
   ⚠️ NÃO volte a escondê-lo no hover do recolhido: é ele que identifica o grupo. */
.menu-grupo-icone { display: inline-flex; width: 20px; height: 20px; flex: none; }
/* Os ITENS do grupo não têm mais ícone: a indentação do CONTÊINER é o que os
   mostra como FILHOS. 26px + os 12px de padding do item = 38px, exatamente onde
   começa o TEXTO do rótulo do grupo (12 de padding + 20 do ícone + 6 do gap). */
.menu-grupo-itens { padding-left: 26px; }
/* GRUPO ABERTO: a caixa envolve o grupo INTEIRO — o rótulo (o menu principal) E os
   subitens —, não só a lista de filhos. Bate o olho e se sabe ONDE SE ESTÁ, com o
   cabeçalho dentro do destaque. Discreto de propósito: `--superficie-2` é UM degrau
   acima do fundo do menu (`--superficie`) e o token já vale nos DOIS temas
   (claro #f5f6f8 / escuro #1e232b) — nada de cor fixa, o menu é escuro no escuro.
   NÃO compete com o `.menu-item.ativo`: aquele é VERMELHO (`--vermelho-suave` +
   texto `--vinho`), este é CINZA neutro — os dois se leem juntos. */
.menu-grupo.grupo-aberto {
    background: var(--superficie-2);
    border-radius: var(--raio-sm);
    padding: 6px 0;
}
/* O hover do item e o do rótulo TAMBÉM são `--superficie-2`: dentro da caixa pintada
   sumiriam (mesmo tom sobre mesmo tom). Sobem um degrau para o retorno sobreviver. */
.menu-grupo.grupo-aberto .menu-item:hover,
.menu-grupo.grupo-aberto > .menu-rotulo:hover {
    background: var(--superficie-3);
}
/* RECOLHIDO sem hover: a trilha é só de ícones — nada de caixa pintada em volta de
   um ícone solto. A caixa volta quando o menu expande (hover/foco), junto com o
   rótulo e os itens; aí ela envolve o grupo inteiro como no menu aberto. */
.app.menu-recolhido .menu-grupo.grupo-aberto { background: none; padding: 0; }
.app.menu-recolhido .menu:hover .menu-grupo.grupo-aberto,
.app.menu-recolhido .menu:focus-within .menu-grupo.grupo-aberto {
    background: var(--superficie-2);
    padding: 6px 0;
}

/* MENU RECOLHIDO (ícones): mostra SÓ o ícone de cada GRUPO (menu principal) —
   nada de submenus, sem scroll vertical. No hover/foco, volta ao menu completo
   (rótulos + itens do grupo aberto), agora COM o ícone do grupo. */
.app.menu-recolhido .menu-grupo { margin-bottom: 4px; }
.app.menu-recolhido .menu-rotulo { justify-content: center; padding: 10px 0; color: var(--texto-suave); }
.app.menu-recolhido .menu-rotulo > span,
.app.menu-recolhido .menu-chevron { display: none; }
.app.menu-recolhido .menu-grupo-itens { display: none; }
.app.menu-recolhido .menu-rotulo:hover { background: var(--superficie-2); color: var(--texto); }
/* Hover/foco: menu completo de novo. */
.app.menu-recolhido .menu:hover .menu-grupo,
.app.menu-recolhido .menu:focus-within .menu-grupo { margin-bottom: 22px; }
.app.menu-recolhido .menu:hover .menu-rotulo,
.app.menu-recolhido .menu:focus-within .menu-rotulo { justify-content: space-between; padding: 4px 12px 8px; color: var(--texto-rotulo); }
.app.menu-recolhido .menu:hover .menu-rotulo > span,
.app.menu-recolhido .menu:focus-within .menu-rotulo > span { display: inline; }
.app.menu-recolhido .menu:hover .menu-chevron,
.app.menu-recolhido .menu:focus-within .menu-chevron { display: block; }
.app.menu-recolhido .menu:hover .menu-grupo.grupo-aberto .menu-grupo-itens,
.app.menu-recolhido .menu:focus-within .menu-grupo.grupo-aberto .menu-grupo-itens { display: block; }
.menu-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 12px;
    margin: 3px 0;
    border-radius: var(--raio-sm);
    color: var(--texto-suave);
    /* Peso NORMAL: o subitem é filho — quem carrega o negrito é o `.menu-rotulo`
       (o menu principal). O item ATIVO recupera o destaque logo abaixo (600). */
    font-weight: 400;
    font-size: 14px;
    white-space: nowrap;
}
.menu-item:hover { background: var(--superficie-2); color: var(--texto); text-decoration: none; }
.menu-item.ativo { background: var(--vermelho-suave); color: var(--vinho); font-weight: 600; }
.menu-item.ativo .icone { color: var(--vinho); }
.app.menu-recolhido .menu-item { justify-content: center; padding: 9px 0; }

/* Rodapé do menu: usuário + sair */
.menu-rodape {
    border-top: 1px solid var(--borda);
    padding: 14px;
    display: flex;
    align-items: center;
    gap: 11px;
}
.avatar {
    width: 38px; height: 38px; border-radius: 50%;
    background: linear-gradient(135deg, var(--vermelho), var(--vinho));
    color: #fff; font-weight: 700; font-size: 15px;
    display: flex; align-items: center; justify-content: center;
    flex: none;
}
/* ---- Avatar de responsável — COMPONENTE reutilizável (templatetag avatar) ----
   Foto redonda OU iniciais sobre cor ESTÁVEL do nome OU tracejado "não atribuído".
   O MESMO componente em todas as telas (Ativação, SD, SAP, GP, Projetos, etc.). */
.avatar-comp {
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%; flex: none; overflow: hidden; vertical-align: middle;
    font-weight: 700; color: #fff; text-transform: uppercase; letter-spacing: .2px;
    line-height: 1; user-select: none;
    background: hsl(var(--avatar-hue, 220), 48%, 46%);
}
.avatar-comp img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-card { width: 30px; height: 30px; font-size: 12px; }
.avatar-lista { width: 24px; height: 24px; font-size: 10.5px; }
.avatar-grande { width: 64px; height: 64px; font-size: 24px; }
.avatar-vazio {
    background: none; color: var(--texto-suave);
    border: 1.5px dashed var(--borda-forte);
}
/* Avatar FANTASMA (sem responsável): círculo cinza VISÍVEL com ícone de pessoa —
   deixa claro "ninguém aqui" (antes o vazio era quase invisível). */
.avatar-fantasma { background: var(--superficie-2); color: var(--texto-suave);
    box-shadow: inset 0 0 0 1.5px var(--borda-forte); }
.avatar-fantasma svg { width: 62%; height: 62%; }
a.avatar-pegar { cursor: pointer; text-decoration: none; transition: border-color .15s ease, color .15s ease; }
a.avatar-pegar:hover { border-color: var(--vermelho); color: var(--vermelho); }
/* Avatar do PEGÊ (persona do SISTEMA — o que o sistema faz sozinho). Mora nesta
   família para encaixar no card sem destoar dos avatares vizinhos. Sem avatar
   configurado em Parâmetros, cai na ENGRENAGEM sobre a cor da marca: lê-se
   "automático" e NUNCA se confunde com o .avatar-fantasma ("sem responsável"),
   que é cinza com ícone de PESSOA. */
.avatar-pege-sem-foto { background: var(--info-bg); color: var(--info);
    box-shadow: inset 0 0 0 1.5px var(--info); }
.avatar-pege-sem-foto svg { width: 58%; height: 58%; }
.avatar-mais { background: var(--superficie-3); color: var(--texto-suave); font-size: 11px; }
.avatar-pilha { display: inline-flex; align-items: center; }
.avatar-pilha > .avatar-comp { margin-left: -9px; box-shadow: 0 0 0 2px var(--superficie); }
.avatar-pilha > .avatar-comp:first-child { margin-left: 0; }

.menu-usuario-info { flex: 1; min-width: 0; }
.menu-usuario-nome { font-weight: 600; font-size: 13.5px; color: var(--texto);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.menu-usuario-cargo { font-size: 12px; color: var(--texto-suave); }
.btn-sair {
    background: none; border: none; cursor: pointer; color: var(--texto-rotulo);
    padding: 8px; border-radius: var(--raio-sm); display: inline-flex;
}
.btn-sair:hover { background: var(--alerta-bg); color: var(--alerta); }
.app.menu-recolhido .menu-rodape { justify-content: center; }
.app.menu-recolhido .menu-rodape form,
.app.menu-recolhido .menu-usuario-info { display: none; }

/* ---- Bloco 4: HOVER-EXPAND do menu recolhido (OVERLAY, não empurra) ------
   Recolhido = padrão (só ícones). Ao passar o mouse (ou focar por teclado,
   :focus-within), o menu expande à largura cheia como OVERLAY: a COLUNA do grid
   continua estreita (76px), então o conteúdo NÃO é empurrado — o menu transborda
   por cima, com sombra. Largura explícita no recolhido para a transição animar de
   76px → cheia (o bloco global de prefers-reduced-motion zera a transição). */
.app.menu-recolhido .menu { width: var(--largura-menu-recolhido); transition: width 0.18s ease; }
.app.menu-recolhido .menu:hover,
.app.menu-recolhido .menu:focus-within {
    width: var(--largura-menu);
    z-index: 40;  /* acima do cabeçalho (5)/dropdowns (30); abaixo do modal (50) */
    box-shadow: 12px 0 34px -10px rgba(15, 23, 42, 0.28);
}
/* No hover/foco, os rótulos voltam (desfaz o "só ícones"). */
.app.menu-recolhido .menu:hover .marca .marca-resto,
.app.menu-recolhido .menu:focus-within .marca .marca-resto { display: inline; }
.app.menu-recolhido .menu:hover .menu-rotulo,
.app.menu-recolhido .menu:focus-within .menu-rotulo { display: flex; }
.app.menu-recolhido .menu:hover .menu-item span,
.app.menu-recolhido .menu:focus-within .menu-item span { display: inline; }
.app.menu-recolhido .menu:hover .menu-usuario-info,
.app.menu-recolhido .menu:focus-within .menu-usuario-info { display: block; }
.app.menu-recolhido .menu:hover .menu-rodape form,
.app.menu-recolhido .menu:focus-within .menu-rodape form { display: block; }
.app.menu-recolhido .menu:hover .menu-item,
.app.menu-recolhido .menu:focus-within .menu-item { justify-content: flex-start; padding: 9px 12px; }
.app.menu-recolhido .menu:hover .menu-topo,
.app.menu-recolhido .menu:focus-within .menu-topo { justify-content: flex-start; padding: 20px 22px; }
.app.menu-recolhido .menu:hover .menu-rodape,
.app.menu-recolhido .menu:focus-within .menu-rodape { justify-content: flex-start; }

/* ---- Área principal ----------------------------------------------------- */
.area { display: flex; flex-direction: column; min-width: 0; }

.cabecalho {
    height: 64px;
    background: var(--superficie);
    border-bottom: 1px solid var(--borda);
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 20px;
    position: sticky; top: 0; z-index: 5;
}
.btn-icone-cabecalho {
    background: none; border: none; cursor: pointer; color: var(--texto-suave);
    padding: 8px; border-radius: var(--raio-sm); display: inline-flex;
}
.btn-icone-cabecalho:hover { background: var(--superficie-2); color: var(--texto); }
/* Busca discreta, integrada e encostada à esquerda (não flutua no centro) */
.busca {
    flex: none;
    width: 260px;
    display: flex; align-items: center; gap: 8px;
    background: var(--superficie-2);
    border: 1px solid var(--borda);
    border-radius: var(--raio-sm);
    padding: 7px 12px;
    color: var(--texto-rotulo);
    transition: border 0.12s, box-shadow 0.12s;
}
.busca:focus-within { border-color: var(--borda-forte); box-shadow: var(--anel-foco); }
.busca input {
    border: none; background: none; outline: none; flex: 1;
    color: var(--texto); font-size: 13.5px;
}
.cabecalho-acoes { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.sino { position: relative; }
.sino .ponto {
    position: absolute; top: 7px; right: 7px; width: 7px; height: 7px;
    background: var(--vermelho); border-radius: 50%; border: 2px solid var(--superficie);
}

/* Conteúdo fluido: preenche 100% da largura DISPONÍVEL (entre o menu lateral e a
   borda da janela), com padding de respiro — sem max-width fixo nem
   centralização, para não sobrar faixa branca dos lados em telas largas. O
   kanban rola horizontal se as etapas não couberem. (Os modais são
   independentes: .modal-overlay é position:fixed, fora deste container.) */
/* padding-right maior reserva a faixa do trilho FLUTUANTE (position:fixed), p/ o conteúdo
   não passar por baixo das pílulas. O cabeçalho (irmão) NÃO tem este recuo → vai até a borda. */
.conteudo { padding: 32px 40px; padding-right: calc(var(--largura-trilho) + 40px); width: 100%; }
.pagina-cabecalho { margin-bottom: 24px; display: flex; align-items: flex-start;
    justify-content: space-between; gap: 16px; }
.pagina-cabecalho-texto { min-width: 0; }
.pagina-cabecalho h1 { font-size: 26px; font-weight: 700; letter-spacing: -0.4px; }
.pagina-cabecalho .subtitulo { color: var(--texto-suave); margin-top: 6px; font-size: 14px; }
.pagina-acao { flex: none; }
/* Lista no estilo DRB: tabela num QUADRO LEVE (borda fina, cantos arredondados,
   sombra sutil, cabeçalho levemente tingido). Não é "solta" de ponta a ponta. */
.lista {
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    background: var(--superficie);
    box-shadow: var(--sombra-sm);
    overflow: auto;
}

/* Estado-vazio PADRÃO das listas de detalhe (parcial componentes/_lista_detalhe).
   Substitui as ~7 variantes de `<p class="texto-suave" style="margin:...">` que
   divergiam de tela para tela. Margem zero: fica dentro do cartão/bloco. */
.lista-vazia { margin: 0; color: var(--texto-suave); font-size: 14px; line-height: 1.5; }

/* =========================================================================
   COMPONENTES
   ========================================================================= */

/* ---- Cartão ------------------------------------------------------------- */
.cartao {
    background: var(--superficie);
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    box-shadow: var(--sombra-sm);
    padding: 26px 28px;
}
.cartao + .cartao { margin-top: 20px; }
.cartao-cabecalho {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 20px;
}
.cartao-cabecalho h2 { font-size: 16px; font-weight: 600; }

/* ---- Cartões de indicador (grid) --------------------------------------- */
.indicadores {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 18px;
    margin-bottom: 26px;
}
.indicador {
    background: var(--superficie);
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    box-shadow: var(--sombra-sm);
    padding: 20px 22px;
    display: flex; align-items: center; gap: 16px;
    color: var(--texto);
    transition: box-shadow 0.15s, transform 0.15s;
}
.indicador:hover { box-shadow: var(--sombra); text-decoration: none; }
.indicador-icone {
    width: 46px; height: 46px; border-radius: var(--raio-sm);
    background: var(--vermelho-suave); color: var(--vermelho);
    display: flex; align-items: center; justify-content: center; flex: none;
}
.indicador-numero { font-size: 26px; font-weight: 700; line-height: 1; color: var(--texto); }
.indicador-rotulo { font-size: 13px; color: var(--texto-suave); margin-top: 5px; }

/* ---- Tabela ------------------------------------------------------------- */
.tabela-wrap { overflow-x: auto; margin: 0 -4px; }
.tabela { width: 100%; border-collapse: collapse; }
.tabela th {
    text-align: left; font-size: 13px; font-weight: 500;
    color: var(--texto-suave);
    padding: 13px 16px; border-bottom: 1px solid var(--borda);
}
.tabela td { padding: 17px 16px; border-bottom: 1px solid var(--borda); color: var(--texto); }
.lista .tabela thead th { background: var(--superficie-2); }
.celula-titulo { font-weight: 600; }
.celula-sub { font-size: 12.5px; color: var(--texto-suave); margin-top: 2px; }
.tabela tbody tr:last-child td, .tabela tr:last-child td { border-bottom: none; }
.tabela tbody tr { transition: background 0.12s; }
.tabela tbody tr:hover { background: var(--superficie-2); }
.tabela .col-acoes { text-align: right; white-space: nowrap; }

/* ---- MODO COMPACTO da tabela (R66 · BLOCO 7) ----------------------------
   ⚠️⚠️ É UM SLOT, NÃO UMA MUDANÇA DE `.tabela`. Medido: o que estica a lista de
   cobranças NÃO é o número de linhas (já paginava) — é a ALTURA de cada uma. Com
   `padding: 17px 16px` uma linha mede ~80px, e 32 linhas dão **2.563px de
   rolagem** num viewport de 720px (medido no navegador, na lista dentro do modal):
   só as 4 primeiras eram alcançáveis sem rolar.

   ⚠️ **`.tabela` É COMPARTILHADA POR 77 TELAS.** Baixar o padding dela deixaria
   todas mais apertadas — uma mudança que ninguém pediu, em telas que ninguém
   olhou. Por isso a régua entra por uma classe A MAIS: quem não a escreve sai
   BYTE A BYTE igual, e há teste afirmando exatamente isso.

   ⚠️ E o `th` desce junto: cabeçalho alto sobre linha baixa fica desproporcional —
   é o mesmo bloco visual. */
.tabela-compacta th { padding: 8px 16px; }
.tabela-compacta td { padding: 8px 16px; }

/* ---- Ícone de AÇÃO: FAMÍLIA ÚNICA (box quadrado com fundo) ---------------
   UM só "botão de ícone de ação" em todas as páginas: box quadrado ~28px,
   FUNDO FIXO neutro em repouso, ícone centralizado (modelado no antigo
   .tri-icone, o único com box fixo). Por ESTADO, o BOX recebe o fundo suave do
   conceito (as mesmas vars dos selos/chips) e o ícone a cor forte. As famílias
   antigas (.flag-btn/.flag-icone, .tri-icone, .int-balao) apontam para cá — não
   há mais ícone "fantasma" (fundo só no hover). NÃO se aplica ao avatar
   (.resp-comp/.avatar — CÍRCULO, sinaliza "pessoa") nem ao termômetro
   (.chip-termo — é um dado). */
.acoes-linha { display: inline-flex; gap: 4px; justify-content: flex-end; }
.btn-icone, .flag-btn, .flag-icone, .tri-icone, .int-balao {
    display: inline-flex; align-items: center; justify-content: center;
    flex: none; width: 28px; height: 28px; border-radius: 7px;
    border: none; padding: 0; line-height: 0; text-decoration: none;
    background: var(--superficie-2); color: var(--texto-rotulo);
    transition: outline-color 0.12s, background 0.12s, color 0.12s;
}
.btn-icone, .flag-btn, .tri-icone, .int-balao { cursor: pointer; }
.btn-icone:hover, .flag-btn:hover, .tri-icone:hover, .int-balao:hover,
.btn-icone:focus-visible, .flag-btn:focus-visible, .tri-icone:focus-visible, .int-balao:focus-visible {
    outline: 2px solid var(--borda-forte); outline-offset: 1px; text-decoration: none;
}
.btn-icone[disabled] { opacity: 0.4; cursor: not-allowed; }
.btn-icone[disabled]:hover { outline: none; }
/* R1 — badge com o Nº de tentativas FEITAS do chamado SAP aberto, ancorado no
   canto do ícone de telefone (só aparece quando > 0). O wrapper dá o contexto de
   posição sem mexer no .btn-icone (compartilhado por vários clusters). */
.tel-sap-wrap { position: relative; display: inline-flex; flex: none; }
.badge-tentativas {
    position: absolute; top: -5px; right: -5px;
    min-width: 15px; height: 15px; padding: 0 3px; box-sizing: border-box;
    border-radius: 999px; background: var(--texto); color: var(--superficie);
    font-size: 9px; font-weight: 700; line-height: 15px; text-align: center;
    box-shadow: 0 0 0 2px var(--superficie);  /* anel p/ descolar do ícone */
    pointer-events: none;
}
/* ESTADOS — o BOX recebe o fundo suave e o ícone a cor forte (paleta dos
   selos). Nomes canônicos .acao-* + os ALIASES das famílias antigas
   (flag-*/tri-*/perigo), para não reescrever todo template de uma vez.
   Definidos DEPOIS do box → vencem por ordem de origem. */
.acao-neutro,  .flag-neutro, .tri-cinza       { background: var(--superficie-2);   color: var(--texto-suave); }
.acao-aviso,   .flag-aviso,  .tri-amarelo     { background: var(--aviso-bg);       color: var(--aviso); }
.acao-alerta,  .flag-alerta, .btn-icone.perigo { background: var(--alerta-bg);      color: var(--alerta); }
.acao-sucesso, .flag-sucesso                  { background: var(--sucesso-bg);     color: var(--sucesso); }
.acao-critico, .flag-critico, .tri-vermelho   { background: var(--vermelho-suave); color: var(--vermelho); }
/* ⚠️ R48 — DUAS CORES NOVAS na MESMA família (nomes canônicos `.acao-*` com o
   alias `.flag-*`, como as cinco acima): `info` para o informativo LIGADO e
   `apagado` para o informativo DESLIGADO.
   O ícone de COLETA do card do SAP aparece SEMPRE, inclusive apagado — é a régua
   que os outros três informativos já seguem ("todos os cards com o MESMO conjunto
   de ícones"). Ícone que SOME conforme o estado faz a fileira dançar de card para
   card, e a pessoa passa a procurar pela POSIÇÃO e não acha.
   ⚠️ `--info` existe nos DOIS temas (#2563eb claro / #60a5fa escuro); o apagado usa
   `--texto-suave`, que é o token de apoio com contraste AA — e NÃO um cinza
   inventado, que seria token fantasma (reincidente nesta casa). */
.acao-info,    .flag-info                     { background: color-mix(in srgb, var(--info) 12%, transparent); color: var(--info); }
.acao-apagado, .icone-apagado                 { background: transparent; color: var(--texto-suave); opacity: .45; }

/* ---- Badges de status — finos e sutis ----------------------------------- */
.badge {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11.5px; font-weight: 600; padding: 4px 10px;
    border-radius: var(--raio-pill); line-height: 1.4;
}
.badge::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; }
.badge svg { width: 13px; height: 13px; }
.badge:has(svg)::before { content: none; }
.badge-sucesso { color: var(--sucesso); background: var(--sucesso-bg); }
.badge-neutro { color: var(--neutro); background: var(--neutro-bg); }
.badge-alerta { color: var(--alerta); background: var(--alerta-bg); }
/* P4/T5.7: `badge-aviso` era FANTASMA — o selo "Já coberto" da triagem saía SEM
   COR (herdava a do texto), e o selo "Paga" da lista de despesas caiu no mesmo
   furo. Os tokens `--aviso`/`--aviso-bg` já existiam nos DOIS temas (:44-45 e
   :95-96); faltava só a regra. */
.badge-aviso { color: var(--aviso); background: var(--aviso-bg); }

/* ---- Botões ------------------------------------------------------------- */
.btn {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 14px; font-weight: 600; padding: 9px 16px;
    border-radius: var(--raio-sm); border: 1px solid transparent;
    cursor: pointer; text-decoration: none;
    transition: background 0.12s, border 0.12s, box-shadow 0.12s;
    white-space: nowrap;
}
.btn:hover { text-decoration: none; }
.btn-primario { background: var(--vermelho); color: #fff; }
.btn-primario:hover { background: var(--vermelho-hover); color: #fff; }
.btn-secundario { background: var(--superficie); color: var(--texto); border-color: var(--borda-forte); }
.btn-secundario:hover { background: var(--superficie-2); }
.btn-perigo { background: none; color: var(--alerta); border-color: var(--alerta); }
.btn-perigo:hover { background: var(--alerta-bg); }
.btn-sucesso { background: var(--sucesso); color: #fff; }
.btn-sucesso:hover { filter: brightness(0.94); color: #fff; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-ghost { background: none; color: var(--texto-suave); border-color: transparent; }
.btn-ghost:hover { background: var(--superficie-2); color: var(--texto); }
/* Ghost com intenção destrutiva discreta (ex.: Excluir cadastro): neutro em
   repouso, revela o vermelho só no hover. */
.btn-ghost-perigo { background: none; color: var(--texto-suave); border-color: transparent; }
.btn-ghost-perigo:hover { background: var(--alerta-bg); color: var(--alerta); }

/* ---- Formulários -------------------------------------------------------- */
.form-campo { margin-bottom: 18px; }
.form-campo > label,
form p > label {
    display: block; font-weight: 600; font-size: 13px;
    color: var(--texto); margin-bottom: 7px;
}
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="url"], input[type="search"],
input[type="tel"],
select, textarea {
    width: 100%; padding: 10px 13px;
    background: var(--superficie);
    border: 1px solid var(--borda-forte);
    border-radius: var(--raio-sm);
    color: var(--texto); font-size: 14px; font-family: inherit;
    transition: border 0.12s, box-shadow 0.12s;
}
input:focus, select:focus, textarea:focus {
    outline: none; border-color: var(--vermelho); box-shadow: var(--anel-foco);
}
/* ⚠️ P12 — CAMPO TRAVADO TEM DE PARECER TRAVADO. A regra acima crava
   `background: var(--superficie)`, e isso SOBRESCREVE o cinza que o navegador dá
   de graça a um input `disabled`: medido no DEV, o campo do preço bloqueado saía
   com fundo BRANCO, idêntico a um editável (só as caixas de seleção, que não
   passam por esta regra, acinzentavam sozinhas). O usuário clica, digita, nada
   acontece, e abre chamado. Vale para TODO campo desabilitado do sistema, não só
   o do preço — é o mesmo defeito de `<button>` sem `color: inherit`: estilo da
   casa que apaga o padrão do navegador sem repor o equivalente. */
input:disabled, select:disabled, textarea:disabled {
    /* `--superficie-3` (e NÃO um `--fundo-suave` inventado): é o token que já
       existe nos DOIS temas — #eceef2 no claro, #262c35 no escuro. Token
       fantasma é reincidente aqui; o fallback silencioso do `var()` esconderia. */
    background: var(--superficie-3);
    color: var(--texto-suave);
    border-color: var(--borda);
    cursor: not-allowed;
}
textarea { min-height: 96px; resize: vertical; }
select { appearance: none; background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa3af' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 13px center; padding-right: 36px; }
.form-acoes { display: flex; align-items: center; gap: 10px; margin-top: 26px; }
.form-ajuda { font-size: 13px; color: var(--texto-suave); line-height: 1.6; margin: 0 0 22px; }
/* CV-4.9: ajuda que AVISA (estado-vazio que vai barrar a criação), e não só
   informa — na .form-ajuda normal (cinza-suave) o aviso passa despercebido.
   Âmbar (--aviso), não vermelho: é atenção, não erro — nada falhou ainda. */
.form-ajuda-alerta { color: var(--aviso); font-weight: 500; }
.form-erro { color: var(--alerta); font-size: 13px; margin-top: 5px; }
.checkbox-linha { display: flex; align-items: center; gap: 9px; }
.checkbox-linha input { width: auto; }
.checkbox-linha > label { margin: 0; }

/* ---- Upload moderno (F1.8) --------------------------------------------------
   Dropzone temática (clara/escura) que substitui o <input type=file> nativo. O
   input fica TRANSPARENTE por cima (clique/drag-drop/required nativos). ----- */
.pg-upload { position: relative; }
.pg-upload .pg-upload-input {
    position: absolute; inset: 0; width: 100%; height: 100%;
    margin: 0; padding: 0; opacity: 0; cursor: pointer; z-index: 1;
}
.pg-upload-alvo {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 18px 14px; text-align: center;
    background: var(--superficie); color: var(--texto-suave);
    border: 1.5px dashed var(--borda-forte); border-radius: var(--raio-sm);
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.pg-upload-alvo .icone-sm { width: 18px; height: 18px; }
.pg-upload:hover .pg-upload-alvo,
.pg-upload .pg-upload-input:focus-visible + .pg-upload-alvo {
    border-color: var(--link); background: var(--superficie-2); color: var(--texto);
}
.pg-upload.pg-upload-sobre .pg-upload-alvo {
    border-color: var(--link); border-style: solid;
    background: var(--superficie-2); color: var(--texto);
}
.pg-upload-preview {
    position: relative; display: flex; align-items: center; gap: 10px;
    padding: 8px 10px; background: var(--superficie);
    border: 1px solid var(--borda-forte); border-radius: var(--raio-sm);
}
.pg-upload-img {
    width: 46px; height: 46px; object-fit: cover; border-radius: 6px;
    border: 1px solid var(--borda-forte);
}
.pg-upload-nome {
    flex: 1; min-width: 0; font-size: 13px; color: var(--texto);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pg-upload-limpar {
    position: relative; z-index: 2; border: none; background: none;
    color: var(--texto-suave); cursor: pointer; font-size: 20px; line-height: 1;
    padding: 2px 8px; border-radius: 6px; transition: color 0.12s, background 0.12s;
}
.pg-upload-limpar:hover { color: var(--alerta); background: var(--alerta-bg); }

/* ---- Date-picker moderno (F1.9) ---------------------------------------------
   Calendário visual (dia + hora) que substitui o seletor nativo. O input nativo
   fica escondido (mantém name/value/required); um campo temático abre o popover. */
.pg-data { position: relative; }
.pg-data .pg-data-real {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    padding: 0; border: 0; opacity: 0; pointer-events: none;
}
.pg-data-campo {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 10px 13px; text-align: left; cursor: pointer;
    background: var(--superficie); color: var(--texto);
    border: 1px solid var(--borda-forte); border-radius: var(--raio-sm);
    font-size: 14px; font-family: inherit; transition: border 0.12s, box-shadow 0.12s;
}
.pg-data-campo:hover { border-color: var(--link); }
.pg-data-campo:focus-visible { outline: none; border-color: var(--vermelho); box-shadow: var(--anel-foco); }
.pg-data-campo .icone-sm { color: var(--texto-suave); flex: none; }
.pg-data-txt { flex: 1; }
.pg-data-campo.pg-data-vazio .pg-data-txt { color: var(--texto-suave); }

.pg-data-pop {
    position: absolute; z-index: 60; top: calc(100% + 6px); left: 0;
    width: 266px; padding: 12px;
    background: var(--superficie); border: 1px solid var(--borda-forte);
    border-radius: var(--raio); box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
}
.pg-cal-cab { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.pg-cal-mes { font-weight: 600; font-size: 14px; text-transform: capitalize; color: var(--texto); }
.pg-cal-nav { border: none; background: none; color: var(--texto-suave); cursor: pointer; padding: 4px; border-radius: 6px; display: inline-flex; }
.pg-cal-nav:hover { background: var(--superficie-2); color: var(--texto); }
.pg-cal-grade { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.pg-cal-ds { text-align: center; font-size: 11px; color: var(--texto-suave); padding: 4px 0; }
.pg-cal-dia {
    aspect-ratio: 1; border: none; background: none; cursor: pointer;
    color: var(--texto); border-radius: 7px; font-size: 13px; padding: 0;
}
.pg-cal-dia:hover { background: var(--superficie-2); }
.pg-cal-hoje { box-shadow: inset 0 0 0 1px var(--link); }
.pg-cal-sel, .pg-cal-sel:hover { background: var(--link); color: #fff; }
.pg-cal-hora {
    display: flex; align-items: center; gap: 6px;
    margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--borda-forte);
}
.pg-cal-hora .icone-sm { color: var(--texto-suave); flex: none; }
.pg-cal-hora select { width: auto; padding: 6px 24px 6px 8px; }
.pg-cal-acoes { display: flex; justify-content: space-between; margin-top: 10px; }
.pg-cal-acoes button {
    border: none; background: none; color: var(--link); cursor: pointer;
    font-size: 13px; padding: 4px 6px; border-radius: 6px;
}
.pg-cal-acoes button:hover { background: var(--superficie-2); }

/* Seção agrupada dentro de um formulário (ex.: bloco Financeiro do White Label) */
.form-secao { border-top: 1px solid var(--borda); margin-top: 20px; padding-top: 16px; }
.form-secao-titulo { font-size: 14px; font-weight: 700; margin-bottom: 4px; }
.form-secao-nota { font-size: 12.5px; color: var(--texto-suave); margin-bottom: 14px; }

/* Formset inline (linhas de contato do ERP): campos em grade + botão remover. */
.contato-erp-linha { display: flex; gap: 10px; align-items: flex-end; margin-bottom: 10px; }
.contato-erp-campos { flex: 1; display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px 10px; }
.contato-erp-linha .form-campo { margin: 0; }
@media (min-width: 720px) { .contato-erp-campos { grid-template-columns: repeat(4, 1fr); } }
/* Campo LARGO da linha (ex.: Observação): ocupa a linha inteira em vez de sobrar
   numa coluna estreita com um rasgo vazio ao lado. Classe EXPLÍCITA (e não
   `:last-child`/`:nth-child`) para não quebrar quando alguém reordenar ou
   acrescentar um campo ao formset. */
.contato-erp-campos .campo-largo { grid-column: 1 / -1; }
.contato-erp-campos .campo-largo textarea { width: 100%; min-height: 62px; resize: vertical; }

/* Interruptor (toggle) para campos booleanos, ex.: Ativo */
.campo-interruptor { display: flex; align-items: center; gap: 10px; }
.campo-interruptor > label { margin: 0; }
.campo-interruptor input[type="checkbox"] {
    appearance: none; -webkit-appearance: none; margin: 0; padding: 0; border: none;
    width: 42px; height: 24px; border-radius: 999px; flex: none;
    background: var(--borda-forte); position: relative; cursor: pointer;
    transition: background 0.15s;
}
.campo-interruptor input[type="checkbox"]::after {
    content: ""; position: absolute; top: 3px; left: 3px;
    width: 18px; height: 18px; border-radius: 50%; background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); transition: transform 0.15s;
}
.campo-interruptor input[type="checkbox"]:checked { background: var(--sucesso); }
.campo-interruptor input[type="checkbox"]:checked::after { transform: translateX(18px); }
.campo-interruptor input[type="checkbox"]:focus-visible { box-shadow: var(--anel-foco); outline: none; }

/* Lista de checkboxes (ex.: seleção de lojas na Integração) */
.lista-checkboxes { max-height: 220px; overflow-y: auto; border: 1px solid var(--borda-forte);
    border-radius: var(--raio-sm); padding: 8px 12px; background: var(--superficie); }
.lista-checkboxes label { display: flex; align-items: center; gap: 8px; font-weight: 400;
    font-size: 14px; padding: 4px 0; margin: 0; cursor: pointer; }
.lista-checkboxes input[type="checkbox"] { width: auto; }

/* Código monoespaçado (ex.: links copiáveis no detalhe do White Label) */
code { background: var(--superficie-2); padding: 2px 7px; border-radius: 6px;
    font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
    font-size: 12.5px; color: var(--texto); }

/* Formulário inline de "adicionar" (ex.: pré-requisitos da etapa) */
.form-adicionar { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; }
.form-adicionar label { display: block; font-weight: 600; font-size: 13px; margin-bottom: 6px; }

/* Feed de conversa do ticket (append-only) */
.feed { display: flex; flex-direction: column; gap: 14px; margin-bottom: 18px; }
.feed-item { display: flex; gap: 10px; align-items: flex-start; }
.feed-corpo { flex: 1; background: var(--superficie-2); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); padding: 8px 12px; }
.feed-meta { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 3px; }
.feed-autor { font-weight: 600; font-size: 13px; }
.feed-quando { font-size: 12px; color: var(--texto-suave); }
.feed-texto { font-size: 13.5px; color: var(--texto); white-space: normal; word-break: break-word; }
.form-feed textarea { width: 100%; }
/* R46 — O COMPOSITOR GANHOU UM RODAPÉ. `.form-adicionar` é de 7 templates e segue
   intocada; `.form-feed` é de UM só (o feed compartilhado), então a virada para coluna
   mora nela. Isso conserta as TRÊS telas que usam o componente de uma vez
   (Integração, Ticket, SAP) — e arrisca as três de uma vez, por isso há teste em duas
   delas + o contra-vácuo do SAP. */
.form-feed { flex-direction: column; align-items: stretch; gap: 8px; }
.feed-rodape { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 8px 10px; border: 1px solid var(--borda); border-radius: var(--raio-sm);
    background: var(--superficie-2);
    transition: background .15s ease, border-color .15s ease; }
/* A CONSEQUÊNCIA APARECE ONDE A AÇÃO ACONTECE: com "Cliente vê" ligado, a faixa do
   Enviar muda de cor. ⚠️ `--aviso`/`--aviso-bg` existem nos DOIS temas; um preenchido
   com `--texto-inverso` (branco nos dois) ficaria ilegível sobre o âmbar CLARO do
   tema escuro. Por isso tinta de fundo + borda, nunca texto branco sobre âmbar. */
.feed-rodape--cliente { background: var(--aviso-bg); border-color: var(--aviso); }
/* O INTERRUPTOR DE DOIS ESTADOS. É um `<label>` com o checkbox escondido — NÃO dois
   botões: o form declara `hx-disabled-elt="find button"`, que pega o PRIMEIRO
   `<button>` do form, e um botão a mais aqui faria o htmx desabilitar o elemento
   errado durante o envio. Há teste contando os botões do form por causa disso. */
.feed-visivel { display: inline-flex; align-items: center; cursor: pointer; overflow: hidden;
    border: 1px solid var(--borda); border-radius: 999px; background: var(--superficie);
    font-size: 12px; font-weight: 600; user-select: none; }
.feed-visivel-op { padding: 4px 10px; color: var(--texto-suave); white-space: nowrap; }
.feed-visivel-op:first-of-type { background: var(--superficie-3); color: var(--texto); }
.feed-visivel--on { border-color: var(--aviso); }
.feed-visivel--on .feed-visivel-op:first-of-type { background: none; color: var(--texto-suave); }
.feed-visivel--on .feed-visivel-op:last-of-type { background: var(--aviso-bg); color: var(--aviso); }
.erro-campo { color: var(--vermelho); font-size: 12.5px; margin-top: 4px; }

/* Alternar visão (Quadro/Lista) — controle segmentado. Vale para <button>
   (abas Alpine) E <a> (pílulas de período/escopo com HTMX ou querystring). */
.alternar-visao { display: inline-flex; background: var(--superficie-2); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); padding: 3px; gap: 3px; margin-bottom: 20px; flex-wrap: wrap; }
.alternar-visao button, .alternar-visao a { display: inline-flex; align-items: center; gap: 6px; border: none; background: none;
    cursor: pointer; padding: 6px 14px; border-radius: 6px; font-size: 13.5px; font-weight: 600; color: var(--texto-suave);
    text-decoration: none; }
.alternar-visao button.ativo, .alternar-visao a.ativo { background: var(--superficie); color: var(--vermelho); box-shadow: var(--sombra-sm); }

/* =========================================================================
   Configurações → Parâmetros: a casca com abas.
   Esta tela é PÁGINA (não modal): são 7 abas e formulários largos.
   ========================================================================= */
/* O container ÚNICO — as ABAS e o CARTÃO moram dentro dele, então têm a mesma
   largura e a mesma borda esquerda. Não é "100% da tela": formulário de 2000px
   é ilegível (a linha fica longa demais para o olho voltar). ~1040px é o alvo. */
.param-casca { max-width: 1040px; }
/* A faixa tem 7 rótulos e QUEBRA em duas linhas no estreito. `display: flex`
   (não inline-flex) faz a faixa acompanhar a largura do container em vez de
   encolher no conteúdo — sem isso a 2ª linha "pula" e desalinha do cartão. */
.param-abas { display: flex; width: 100%; row-gap: 3px; }

/* Campos curtos em 2 COLUNAS a partir de ~720px; 1 coluna no estreito.
   `align-items: start` para o campo com texto de ajuda longo não esticar o
   vizinho. Aba Marca (uploads) e aba API ficam em 1 coluna de propósito. */
.param-grade { display: grid; grid-template-columns: 1fr; gap: 0 20px; align-items: start; }
@media (min-width: 720px) {
    .param-grade { grid-template-columns: 1fr 1fr; }
    /* O que precisa da linha inteira (título de seção, aviso, ações). */
    .param-grade > .param-largura-total { grid-column: 1 / -1; }
}

/* =========================================================================
   Kanban do funil de ativação — colorido, cards ricos (estilo board moderno)
   Cada coluna recebe --cor-coluna inline (rotação de cores no template).
   ========================================================================= */
.kanban { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 10px; align-items: flex-start; }
.kanban-coluna {
    /* Colunas ENXUTAS (estilo Pipedrive/Linear): sem moldura grossa nem fundo —
       só uma FAIXA colorida fina no topo + cabeçalho + cards. Mais estreitas
       para caber ~5 etapas onde antes cabiam ~3; ainda crescem p/ preencher. */
    flex: 1 1 216px; min-width: 216px;
    background: transparent; border: none;
    border-top: 2.5px solid var(--cor-coluna); border-radius: 0;
    padding: 0 6px;
}
.kanban-coluna-neutra { border-top-style: dashed; }
.kanban-cabecalho { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 4px 12px; }
.kanban-titulo { display: inline-flex; align-items: center; gap: 8px; font-weight: 700; font-size: 13.5px; color: var(--texto); }
.kanban-ponto { width: 9px; height: 9px; border-radius: 50%; background: var(--cor-coluna); flex: none; }
.kanban-contagem {
    background: color-mix(in srgb, var(--cor-coluna) 16%, transparent);
    color: var(--cor-coluna); font-size: 12px; font-weight: 800;
    border-radius: 999px; padding: 1px 10px; min-width: 24px; text-align: center;
}
/* B3: soma de R$ por etapa no board do Lead (kanban e lista). */
.kanban-total, .painel-bloco-total { font-size: 11.5px; font-weight: 700;
    color: var(--sucesso); white-space: nowrap; }
.kanban-total { margin-left: auto; }  /* empurra total + contagem p/ a direita no kanban */
.kanban-cards { display: flex; flex-direction: column; gap: 9px; min-height: 40px; }

.kanban-card {
    display: block; position: relative; background: var(--superficie);
    border: 1px solid var(--borda); border-left: 3px solid var(--cor-coluna);
    border-radius: var(--raio-sm); padding: 10px 11px 9px;
    box-shadow: var(--sombra-sm); text-decoration: none; color: var(--texto);
    transition: box-shadow .15s ease, transform .12s ease;
}
.kanban-card:hover { box-shadow: var(--sombra); transform: translateY(-1px); text-decoration: none; }
.kanban-card-topo { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.kanban-card-titulo { font-weight: 700; font-size: 13px; line-height: 1.3; }
.kanban-card-sub { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--texto-suave); margin-top: 3px; }
.kanban-card-sub svg { width: 13px; height: 13px; flex: none; }
.kanban-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-top: 8px; }
/* V-F3: responsável (avatar) fixado no fim da fileira de ícones do card.
   B1: o `margin-left:auto` ficou INERTE desde que o irmão .kanban-card-selo-meio
   ganhou `flex:1` — ele consome a sobra ANTES de as margens auto resolverem, e é
   o crescimento dele que empurra o responsável p/ a direita. Mantido de
   propósito, como rede: se o selo sair desta fileira (ou vier condicional), o
   auto volta a valer e o avatar continua no fim. */
.kanban-chips-resp { margin-left: auto; display: inline-flex; align-items: center; }
.kanban-card-rodape { margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--borda); }
.kanban-resp { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--texto-suave); }
.kanban-vazio { font-size: 12.5px; color: var(--texto-rotulo); text-align: center; padding: 14px 0; margin: 0; }

/* Card RICO do Kanban — paridade de conteúdo com a linha da lista (Fase 2). */
.kanban-card-topo { align-items: center; }
/* Foto/logo compacta dentro de célula de TABELA (ex.: 1ª coluna de Clientes). */
.celula-identidade { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; }
.lista-foto img,
.lista-foto .painel-foto-vazia { width: 28px; height: 28px; border-radius: 6px; }
/* B1 — identidade LADO A LADO do board: cliente (esq.) + logo do ERP (dir.).
   Empilhadas a 22px ficavam pequenas demais; em linha cabem 30px e ficam
   legíveis. O ERP-vazio segue discreto (traço leve). */
/* TA-4: as fotos crescem de 30px para 40px para ACOMPANHAR a altura do bloco de
   texto (título + sub-linha ≈ 40-44px), em vez de flutuar pequenas no meio da
   linha. `align-items: flex-start` (era center) alinha o topo delas com o topo
   do título — as duas juntas cobrem da 1ª à 2ª linha.
   ⚠️ Por que TAMANHO FIXO e não `height:100%`+`aspect-ratio` (que auto-calibraria
   pela altura real): o card usa flex com `flex-wrap` e há dois `.kanban-card-topo`
   com alinhamentos diferentes — a cadeia de `stretch` quebraria de forma que só
   se vê renderizando. Fixo é previsível e não colapsa nem estoura.
   ⚠️ VALIDAÇÃO VISUAL PENDENTE (Davi): 40px é o palpite seguro; o ajuste fino do
   tamanho é no olho, e tem de ser conferido nos DOIS boards (Ativação e SD). */
.fotos-identidade { display: inline-flex; flex-direction: row; align-items: flex-start;
    gap: 4px; flex: none; }
.fotos-identidade .painel-foto { display: block; }
.fotos-identidade .painel-foto img,
.fotos-identidade .painel-foto-vazia { width: 40px; height: 40px; border-radius: 7px; }
.painel-foto-erp-vazia { opacity: .72; border-style: dashed; }
/* TS — célula do AnyDesk na lista (máscara + Revelar/Ocultar) e o popup de
   restrição injetado nela: compacto, não estoura a altura da linha. */
.celula-anydesk { display: inline-flex; align-items: center; gap: 6px; }
.celula-anydesk .aviso-status { max-width: 320px; padding: 8px 10px; font-size: 12px; }
.celula-anydesk .aviso-status .btn { padding: 4px 8px; font-size: 12px; }
.kanban-card-cliente { flex: 1; min-width: 0; font-weight: 600; font-size: 12.5px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Nome do cliente na Carteira como BOTÃO (abre o 360º) — reset do chrome de botão,
   mantém a aparência do nome e ganha affordance de clique (sublinha no hover). */
.carteira-cliente-btn { border: 0; background: none; padding: 0; margin: 0;
    color: inherit; font: inherit; text-align: left; cursor: pointer; }
.carteira-cliente-btn:hover { text-decoration: underline; color: var(--link); }
.kanban-card-link { display: block; margin-top: 7px; }
.kanban-card .painel-sub { gap: 3px 10px; margin-top: 5px; font-size: 11.5px; }
/* R45 — CARD LIMPO. `.painel-sub` é a meta COMPARTILHADA por 21 telas (lista da
Ativação, SD, SAP, comercial, GP, carteira...): ela NÃO pode ganhar alinhamento à
direita, senão as outras 20 mudam junto. Por isso o modificador `.kanban-card-meta`
— molde da casa, o mesmo de `.painel-linha--central`. Dentro dele, `-meta-dir` é o
BLOCO da direita (tempo na etapa + status): `margin-left:auto` come o espaço livre
e encosta os dois à direita, fundindo o que antes eram duas fileiras numa só.
⚠️ Precisa de DOIS seletores de classe para vencer `.painel-sub span` (que vem
DEPOIS no arquivo e fixa gap:4px). */
/* ⚠️⚠️ R48 — O ORÇAMENTO DESTA LINHA, MEDIDO NA LARGURA REAL. O mockup da R45 foi
   desenhado num card de ~290px que NÃO EXISTE: `.kanban-coluna` é
   `flex: 1 1 216px; min-width: 216px` com `padding: 0 6px`, e o card tem borda 1 +
   borda-esquerda 3 + padding 11/11 — sobram **178px de conteúdo**. Medido no
   navegador, peça por peça:

     responsável (avatar+lápis) 42.0   ·  CNPJs 26.2  ·  balão 28.0
     chip do tempo COM ícone    68.2   ·  timer 50.9
     selo "Bloqueado" 78.8  ·  "Inconsistência" 97.4  ·  gap × 3

   Com o gap de 10px a linha mais COMUM (87% dos cards: responsável + CNPJs +
   balão + tempo, sem selo) pedia **194.4px** para 178 — quebrava sempre.

   ⚠️ E O GAP SOZINHO NÃO RESOLVE: medido, `gap: 6px` leva a linha a 182.4px e ela
   CONTINUA quebrando. Foram precisas DUAS mudanças. A segunda é o ícone do chip de
   tempo (13px + 4 de gap): "19d 8h" é auto-evidente como tempo, e o `title` traz a
   frase inteira. Resultado medido: **166px de 178** — os 87% em UMA linha, com 12px
   de folga.

   ⚠️ Os casos ANÔMALOS continuam quebrando, e isso é APROVADO: "Bloqueado" pede
   251px e "Inconsistência" 270px. O card cresce uma linha **só quando algo está
   errado** — que é justamente o card que deve puxar o olho.

   ⚠️ NÃO toque na `.painel-sub` base: 22 templates. O gap daqui é do modificador. */
.kanban-card-meta { align-items: center; }
.kanban-card .kanban-card-meta { gap: 3px 6px; }
.kanban-card-meta-dir .chip svg { display: none; }
.kanban-card-meta .kanban-card-meta-dir { margin-left: auto; display: inline-flex;
    align-items: center; gap: 6px; min-width: 0; }
/* O TIMER (R45) abre a fileira do rodapé, à esquerda dos 4 informativos, separado
por um TRAÇO FINO. `min-width:0` desfaz os 66px que o `.rastreador-clock` reserva
para HH:MM:SS — aqui o relógio é HH:MM (ver `data-timer-formato` em base.html) e
66px abririam um buraco no meio do rodapé. */
/* ⚠️ R48 — O TIMER MUDOU DE CASA. Na R45 ele vivia na barra do rodapé, separado
   dos informativos por um traço fino; o dono viu no ar e decidiu que ele pertence à
   linha de meta, no lugar do TEMPO DE ESPERA (os dois respondem a mesma pergunta).
   Sem o rodapé, some o traço fino — aqui ele é só mais um item da fileira.
   `min-width: 0` continua desfazendo os 66px que o `.rastreador-clock` reserva para
   HH:MM:SS: aqui o relógio é HH:MM (`data-timer-formato` em base.html). */
.kanban-card-meta .kanban-card-timer { display: inline-flex; align-items: center;
    gap: 5px; flex: none; }
.kanban-card-timer .rastreador-clock { min-width: 0; font-size: 12px; }
/* F6: o SELO de status vive na LINHA DO TEMPO (painel-sub) do card, ao lado do chip
   "há Xh" — saiu do meio da fileira de ícones (que estourava quando os ícones cresciam).
   Compacto e sem ícone, para não competir com o termômetro na mesma linha. */
.kanban-card-selo-tempo { display: inline-flex; align-items: center; }
/* R45: status LONGO ("Voltou do SAP — valide", "Voltou da correção — revalide")
era o que empurrava a meta para uma segunda fileira. Agora ele TRUNCA com
reticências e o texto inteiro vive no `title` do `.kanban-card-selo-tempo`
(o template o lê de `status_exibicao`, a mesma fonte do selo). `inline-block`
porque `text-overflow` não corta conteúdo de flex — o `.selo` base é inline-flex.
⚠️ ERRATA R57: aqui estava escrito que `.kanban-card-selo-tempo` era usada por UM
template só (o card da Ativação). **Deixou de ser verdade neste pacote**, e a frase
ficaria mentindo: o achado 7 ("pode replicar, aprovo pelo mockup") levou o bloco da
direita aos irmãos, e hoje a classe é usada pelo card da ATIVAÇÃO, pelo do SERVICE
DESK (via `servicedesk/_ticket_sub.html`, só quando `em_card`) e pelo do SAP. Quem
for mexer no truncamento mexe nos três. */
.kanban-card-selo-tempo .selo { display: inline-block; min-width: 0; max-width: 118px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
.kanban-card-selo-tempo .selo svg { display: none; }
/* F7a: botão compacto de REATIVAR CNPJ, inline na lista de CNPJs do detalhe. */
.btn-reativar-cnpj { padding: 1px 8px; font-size: .78rem; line-height: 1.5; margin-left: 6px;
    vertical-align: middle; }
.btn-reativar-cnpj svg { width: 12px; height: 12px; }
.kanban-card-icones { display: flex; align-items: center; justify-content: space-between;
    gap: 6px; flex-wrap: wrap; margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--borda); }

/* Carteira dos Guardiões — card de GERENTE DE CONTAS. REUSA o frame .kanban-card
   (borda/cor da coluna/cursor) e as classes irmãs (.kanban-card-topo/-cliente/-sub,
   .painel-sub); estas regras só LAYOUTAM o conteúdo NOVO que os cards irmãos não têm
   (subtítulo, churn em âmbar, blocos de indicadores). NÃO reimplementa
   o card — compõe com ele (por isso `.carteira-card`, não uma classe paralela). */
.carteira-card .kanban-card-topo { align-items: flex-start; flex-wrap: nowrap; }
.carteira-ident { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.carteira-ident .kanban-card-cliente { font-size: 13.5px; }
.carteira-ident .kanban-card-sub { margin-top: 0; }
/* Divisória entre blocos (cabeçalho | operacional | relacionamento), como no molde. */
.carteira-card .carteira-sep { margin-top: 9px; padding-top: 9px; border-top: 1px solid var(--borda); }
.carteira-churn { color: var(--aviso); font-weight: 600; }
.carteira-fase { margin-top: 9px; }
/* 2ª linha do cabeçalho da coluna (totais lojas·abertos): a .painel-sub dá o
   ícone+valor discreto; aqui só encosta sob o título (o .kanban-cabecalho tem respiro
   embaixo) e alinha à esquerda com ele. */
.carteira-cab-resumo { margin: -6px 4px 8px; font-size: 12px; }

/* Ativação — CABEÇALHO do card em destaque: bloco de identidade VERTICAL ao lado
   das fotos ([ID] NOME em NEGRITO PRETO em cima, cliente discreto embaixo). Mesmo
   padrão de coluna do .carteira-ident. O `.painel-titulo-destaque` (também usado na
   LINHA da lista) só engrossa o título (a cor preta vem do .painel-titulo base) —
   NÃO toca o .painel-titulo compartilhado do SD/SAP/comercial. */
.kanban-card-ident { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
/* 2 classes p/ vencer o `.painel-titulo` base (font-weight:600), que vem DEPOIS no
   arquivo; a COR fica a do base (var(--texto) = preto). */
.painel-titulo.painel-titulo-destaque { font-weight: 700; flex-wrap: wrap; }
.painel-titulo-destaque .painel-titulo-txt { min-width: 0; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
/* ⚠️⚠️ CADERNO DO DONO (25/08) — O NOME QUEBRA EM ATÉ 2 LINHAS, SÓ ONDE ELE PEDIU.
   Ele viu `[4896] POUPE JÁ VIANOPO...` truncado e pediu a quebra no card da Ativação.
   ⚠️ A regra ACIMA (o `nowrap`) NÃO foi tocada de propósito: ela serve NOVE telas
   (aeroporto, Central de Trabalho, card de lead, listar, portal ×2, projetos, SAP,
   SD) e trocá-la faria todas quebrarem — o dono pediu UMA. Modificador na variante,
   nunca na base; é a mesma régua do `.painel-sub` / `.kanban-card-meta`.
   ⚠️ A dupla classe (`.painel-titulo-txt.painel-titulo-txt-quebra`) vence a regra de
   cima por ESPECIFICIDADE (0,3,0 contra 0,2,0), não por ordem no arquivo: quem
   reordenar o CSS amanhã não reabre o truncamento sem perceber.
   ⚠️⚠️ **O CLAMP MORA NUM FILHO, E ISSO NÃO É ENFEITE — foi MEDIDO no navegador.**
   A primeira versão punha `display:-webkit-box` no próprio `.painel-titulo-txt`, que é
   FILHO DIRETO de um `inline-flex` (`.painel-titulo`). O navegador **BLOCKIFICA** todo
   item de flex: o `display` computado virou `flow-root` e o `-webkit-line-clamp` foi
   **ignorado em silêncio** — o nome era cortado a seco pelo `overflow:hidden`, sem
   reticências, no meio da palavra. Medido: `scrollHeight` 90px dentro de uma caixa de
   44,8px. ⚠️ **Teste Django não pega isto** (o CSS declarava tudo certo); quem pegou foi
   o painel do navegador.
   ⚠️ `flex: 1 1 0` é o que deixa a TAG DE PILOTO caber na MESMA linha do título: com o
   `auto` que vinha antes, a caixa do nome reservava a largura toda e a tag quebrava
   para uma linha só dela — o card do piloto crescia 24px.
   ⚠️ `overflow-wrap: anywhere` quebra nome de ambiente SEM espaço (um único token longo
   estouraria a coluna em vez de quebrar). */
.painel-titulo-destaque .painel-titulo-txt.painel-titulo-txt-quebra {
    white-space: normal; overflow-wrap: anywhere; text-overflow: clip;
    overflow: hidden; min-width: 0; flex: 1 1 0; }
.painel-titulo-txt-quebra > .painel-titulo-clamp {
    display: -webkit-box; -webkit-box-orient: vertical;
    -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
/* No card, a 2ª linha DISCRETA sob o título (I5: o AMBIENTE no SD). */
.kanban-card-ident .kanban-card-cliente { font-weight: 500; font-size: 12px; color: var(--texto-suave); }
/* I5/T1: a MESMA 2ª linha discreta na LINHA da lista (o card mora em
   .kanban-card-ident; a lista, em .painel-corpo) — paridade card ⇄ lista. */
.painel-corpo .kanban-card-cliente { font-weight: 500; font-size: 12px; color: var(--texto-suave); }
/* I4: célula de identidade da LISTA de integrações — fotos + ambiente/cliente
   lado a lado, no molde do topo do card. */
.lista-identidade { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.lista-identidade .kanban-card-ident { flex: 1; min-width: 0; }

/* Ativação — LINHA DE ÍCONES numa fileira só (triagem · selo · ações). Modificador
   `-compacto` presente SÓ no card de ativação: encolhe ícones/gaps (o card é estreito).
   O rodapé de ações dos IRMÃOS reusa a MESMA linha divisória (border-top): SAP
   (_chamado_card) via `.kanban-card-rodape`, SD (_ticket_card) via `.kanban-chips
   .kanban-card-rodape`. No aperto extremo, as AÇÕES descem JUNTAS p/ a 2ª linha, à
   direita (margin-left:auto) — nunca ícones soltos; o selo do meio não força a quebra. */
.kanban-card-icones-compacto { gap: 4px; }
.kanban-card-icones-compacto .btn-icone,
.kanban-card-icones-compacto .tri-icone { width: 24px; height: 24px; }
.kanban-card-icones-compacto .painel-triagem,
.kanban-card-icones-compacto .painel-acoes { gap: 3px; }
.kanban-card-icones-compacto .painel-acoes { flex: none; margin-left: auto; }
/* A fileira ESTOURAVA em 2-3 linhas quando havia selo largo + 4 ações (o caso comum
   da Triagem — ex.: card INCONSISTENTE): 3 chips de triagem + o selo + 4 ícones não
   cabem num card de ~200px, e o selo (flex:1) ainda se jogava numa linha só sua,
   virando uma bagunça de 3 linhas. FIX: (1) o selo do card dispensa o ÍCONE — a cor
   da borda/fundo já grita o estado e o rótulo é explícito; (2) o selo pode ENCOLHER
   (min-width:0) e fica ao lado da triagem, então SÓ as ações descem — e como um BLOCO
   à direita, nunca ícones soltos. Em tela larga tudo volta a caber em UMA linha. */
.kanban-card-icones-compacto .selo svg { display: none; }
.kanban-card-icones-compacto .kanban-card-selo-meio { min-width: 0; }
.kanban-card-icones-compacto .selo { display: inline-block; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Variantes de status no card.
   F1.2 — CORES DE ESTADO padronizadas: BLOCK = VERMELHO (mais grave; prevalece
   quando há SAP junto), SAP em andamento = AMARELO (ver seção do SAP). */
/* B4: block e crítico (SLA/atrasada) têm o MESMO realce — regra única (o
   .kanban-card-critico de baixo virou alias desta). */
.kanban-card-block,
.kanban-card-critico { border-left-color: var(--alerta) !important;
    background: linear-gradient(0deg, var(--alerta-bg), var(--alerta-bg)), var(--superficie); }
.kanban-card-cancelada { opacity: 0.72; border-left-color: var(--neutro); }
/* B4: o riscado do CANCELADO nunca casava — os cards de Ativação/SD usam
   .painel-titulo no título (só o SAP usa .kanban-card-titulo). */
.kanban-card-cancelada .kanban-card-titulo,
.kanban-card-cancelada .painel-titulo { text-decoration: line-through; text-decoration-color: var(--texto-rotulo); }
.kanban-card-concluida { border-left-color: var(--sucesso); }

.avatar-mini { width: 24px; height: 24px; border-radius: 50%; background: linear-gradient(135deg, var(--vermelho), var(--vinho));
    color: #fff; font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; flex: none; }

/* Chips (rótulos pequenos com ícone) usados nos cards */
.chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600;
    padding: 2px 8px; border-radius: 999px; background: var(--superficie-2); color: var(--texto-suave);
    border: 1px solid var(--borda); }
.chip svg { width: 12px; height: 12px; flex: none; }
.chip-suave { background: var(--superficie-2); color: var(--texto-rotulo); }
/* ⚠️ P3.1 (BLOCO 15) — `.chip-ativo` era referenciada em TRÊS templates (nove
   ocorrências, medido por mim hoje) e definida em lugar NENHUM desde 29/07
   (`ae85fe4`): a aba selecionada dos chips "Ativos"/"Arquivados",
   "Quadro"/"Perdidos"/"Arquivados" e "No quadro"/"Arquivadas" simplesmente NÃO
   PINTAVA. Só existiam `.chip` e `.chip-suave`, que têm o MESMO fundo e diferem
   apenas na cor do texto (dois cinzas praticamente iguais).
   Molde: `.filtro-pilula-ativa`, o "selecionado" desta casa.
   ⚠️ NÃO use `var(--primaria)`: medido, esse token NÃO EXISTE neste projeto — é
   gotcha REINCIDENTE aqui, e CSS que referencia token fantasma não pinta e
   ninguém percebe. `--info`/`--info-bg` existem nos DOIS temas (conferido).
   ⚠️ Sem número de linha de outro arquivo neste comentário, de propósito: ele
   envelheceria na primeira edição alheia — e este pacote inteiro existe para
   punir prosa que declara o que não mediu. */
.chip-ativo, .chip-ativo:hover { background: var(--info-bg); color: var(--info);
    border-color: color-mix(in srgb, var(--info) 28%, transparent); }
/* ⚠️⚠️ R54 — A TAG DO PILOTO GANHA CLASSE PRÓPRIA. Ela nasceu (R50-f3) EMPRESTANDO
   `.chip-ativo`, e não por escolha: o CSS era território proibido naquele pacote.
   `.chip-ativo` é o "SELECIONADO" das abas de escopo — Ativos/Arquivados,
   Quadro/Perdidos/Arquivadas, o chip do início (MEDIDO hoje: 5 arquivos, 15
   ocorrências, e NENHUMA delas é a tag). Emprestar classe de outro significado é
   como esta casa acumula surpresa: quem mudar o "selecionado" amanhã muda a tag do
   piloto sem saber que existe.

   Mesma FAMÍLIA VISUAL de propósito (`--info`, a cor que o mapa da casa dá a
   "derivado/informativo") — o que muda é o DONO da regra, não o desenho: a tag
   continua exatamente como o dono a viu no ar.

   ⚠️ `color` EXPLÍCITO, e é o que salva o TEMA ESCURO: `--info` tem valor nos dois
   (#2563eb claro, #60a5fa escuro). Um `<span>` sem cor própria herda a do pai — e
   no card o pai é `.kanban-card-cliente`, cinza suave; foi assim que o alternador
   da Ativação perdeu a cor.
   ⚠️ E o `svg` herda a cor do texto (`fill: currentColor` do sprite), então o ícone
   da versão compacta acende junto — não precisa de regra própria. */
.chip-piloto, .chip-piloto:hover { background: var(--info-bg); color: var(--info);
    border-color: color-mix(in srgb, var(--info) 28%, transparent); }
/* ⚠️ A VARIANTE SÓ-ÍCONE do card: sem texto, o `padding` lateral de 8px vira uma
   bolha larga em volta de um ícone de 12px. 4px devolve ~8px à coluna do NOME, que
   é o recurso escasso do card (medido: o nome pede 150px e tem 133). */
.chip-piloto-icone { padding: 2px 5px; }
/* TERMÔMETRO DE TEMPO — o MESMO chip de idade colorido por régua nos três funis
   (Ativação = por etapa/dias; Service Desk = por SLA do tipo; SAP = horas desde a
   última tentativa). Tons SUAVES/lavados do design system (têm variante escura);
   NEUTRO = .chip-suave (cinza). Aplicado junto de .chip .chip-suave. */
.chip-termo-verde { background: var(--sucesso-bg); color: var(--sucesso);
    border-color: color-mix(in srgb, var(--sucesso) 28%, transparent); }
.chip-termo-amarelo { background: var(--aviso-bg); color: var(--aviso);
    border-color: color-mix(in srgb, var(--aviso) 28%, transparent); }
.chip-termo-vermelho { background: var(--alerta-bg); color: var(--alerta);
    border-color: color-mix(in srgb, var(--alerta) 28%, transparent); }
.chip-alerta { background: var(--alerta-bg); color: var(--alerta); border-color: transparent; }
.chip-block { background: var(--aviso-bg); color: var(--aviso); border-color: var(--aviso-borda); }

/* =========================================================================
   Selos (pílulas) de STATUS — reutilizados no board, detalhe e histórico.
   B3 — MAPA ÚNICO conceito→cor (vale para selo-*, badge-* e chip-*):
     em andamento / aberto-fluxo / derivação  → --info    (azul)
     atenção / esperando terceiro / agendado  → --aviso   (âmbar)
     BLOQUEIO (só bloqueio de verdade)        → --aviso   (selo-block)
     crítico / atrasado / SLA / insucesso     → --alerta  (vermelho)
     concluído / sucesso / realizada          → --sucesso (verde)
     cancelado / inativo / pausado            → --neutro  (cinza)
   ========================================================================= */
.selo { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 700;
    padding: 2px 9px; border-radius: 999px; white-space: nowrap; }
.selo svg { width: 13px; height: 13px; flex: none; }
/* MAIS DE UMA pílula na mesma célula (ex.: status "Gerada" + a marca "ajustada" da
   cobrança). O `.selo` e o `.badge` têm paddings diferentes; o flex com `align-items`
   os alinha pelo centro e o `gap` substitui o espaço em branco do HTML. O `wrap`
   evita que a 2ª pílula estoure a coluna em tela estreita. */
.celula-selos { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.selo-andamento { color: var(--info); background: var(--info-bg); }
.selo-block { color: var(--aviso); background: var(--aviso-bg); box-shadow: inset 0 0 0 1px var(--aviso-borda); }
/* B3: "atenção/urgente" (ex.: ocorrência ABERTA da GP) tem a MESMA cara âmbar,
   mas classe própria — selo-block volta a significar SÓ bloqueio. */
.selo-atencao { color: var(--aviso); background: var(--aviso-bg); box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.selo-cancelada { color: var(--neutro); background: var(--neutro-bg); text-decoration: line-through; text-decoration-thickness: 1px; }
/* F2: Pendente (cinza neutro, sem responsável) — distinto do Cancelado. */
.selo-pendente { color: var(--texto-suave); background: var(--superficie-2); box-shadow: inset 0 0 0 1px var(--borda); }
/* TA-2.2: INCONSISTÊNCIA — os dados do pedido não fecham entre si e um humano
   precisa olhar. VERMELHO (--alerta), a família do "tem coisa errada", e não o
   âmbar do .selo-block: block é ESPERA (alguém já sabe e decidiu parar);
   inconsistência é ERRO NÃO DESCOBERTO — ninguém olhou ainda. */
.selo-alerta { color: var(--alerta); background: var(--alerta-bg);
    box-shadow: inset 0 0 0 1px var(--alerta); }
.selo-concluida { color: var(--sucesso); background: var(--sucesso-bg); }

/* Cabeçalho de cartão com selo ao lado do título */
.cabecalho-com-selo { display: inline-flex; align-items: center; gap: 12px; }

/* Barra de ações de status (detalhe da integração). A barra quebra em várias
   linhas (flex-wrap); align-items:center impede que os <form> estiquem (default
   stretch) e desalinhem os botões. Cada <form> vira um grupo flex (o do Atalho
   tem rótulo + seletor + botão, que agrupam e quebram juntos, sem sobrepor). */
.barra-acoes { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 16px; }
.barra-acoes > form { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 0; }
.barra-acoes .btn { white-space: nowrap; }
/* F2.1 — os DESTINOS da triagem ficam numa LINHA só (escopo só à triagem para
   não afetar as outras 6 telas que usam .barra-acoes). Se não couberem no modal
   estreito, rola na horizontal em vez de quebrar em várias linhas. */
.triagem-painel .barra-acoes,
.triagem-painel .barra-acoes > form { flex-wrap: nowrap; }
.triagem-painel .barra-acoes { overflow-x: auto; padding-bottom: 2px; }
.triagem-painel .barra-acoes .mover-select { min-width: 0; }

/* Aviso destacado (travada em block / finalizada) */
.aviso-status { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600;
    padding: 10px 14px; border-radius: var(--raio-sm); margin-bottom: 16px; }
.aviso-status svg { width: 16px; height: 16px; flex: none; }
.aviso-status-em_block { color: var(--aviso); background: var(--aviso-bg); box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.aviso-status-cancelada { color: var(--neutro); background: var(--neutro-bg); }
.aviso-status-concluida { color: var(--sucesso); background: var(--sucesso-bg); }
/* TA-2.5: banner da INCONSISTÊNCIA — VERMELHO (--alerta), coerente com o selo
   `.selo-alerta` e o card `.kanban-card-inconsistente`. Antes reusava o
   `-em_block` (ÂMBAR), e as três camadas do MESMO sinal ficavam em cores
   diferentes: block é ESPERA (âmbar), inconsistência é ERRO (vermelho). */
.aviso-status-alerta { color: var(--alerta); background: var(--alerta-bg); box-shadow: inset 0 0 0 1px var(--alerta); }

/* Transição no histórico de status */
.transicao-status { display: inline-flex; align-items: center; gap: 8px; }
.seta-transicao { width: 15px; height: 15px; color: var(--texto-rotulo); }

/* Seletor "Mover para etapa…" no detalhe */
.mover-etapa { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 2px 0 16px; }
/* R46 — O DESTINO EM UMA LINHA. `.mover-etapa` é irmã compartilhada (o Comercial tem a
   sua cópia, com mecânica OPOSTA — lá é POST direto, aqui é o modal-porteiro), então o
   aperto entra por MODIFICADOR. `nowrap` + `flex:1` no select é o que tira as três
   faixas que o dono viu: rótulo, select e botão passam a caber numa fileira só, e o
   select encolhe em vez de empurrar o botão para baixo. */
.mover-etapa--linha { flex-wrap: nowrap; margin: 0; }
.mover-etapa--linha .detalhe-rotulo { margin: 0; flex: none; }
.mover-etapa--linha .mover-select { flex: 1 1 auto; min-width: 0; }
.mover-etapa--linha .btn { flex: none; }

/* O ESTADO virou a PRIMEIRA faixa do rodapé: "onde isto está e de quem é" antes de "o
   que eu faço". `.detalhe-rotulo` (34 templates) é usada como micro-rótulo; a única
   coisa que muda é a margem, escopada aqui. */
.funil-estado { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 24px; }
.funil-estado-par { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.funil-estado .detalhe-rotulo { margin: 0; flex: none; }
.funil-estado-editar { padding: 3px 7px; }

/* O MENU "MAIS". ⚠️ NÃO É PADRÃO NOVO: reusa a caixa `.sino-painel` e o molde do sino
   (`base_app.html`), o mesmo que o chip de acessos do SAP copiou. O que muda é a
   largura, a ancoragem à ESQUERDA (o botão vive no meio de uma barra, não no canto
   direito do cabeçalho) e o Z-INDEX.
   ⚠️ Z-INDEX: a escala documentada da casa é cabeçalho 5 · dropdowns 30 · MODAL 50, e
   este popover nasce DENTRO do modal do detalhe. A 30 ele sumiria atrás dele — sem
   erro nenhum, apenas invisível. Há teste exigindo > 50. */
.acoes-mais { position: relative; display: inline-flex; }
.acoes-mais-painel { width: 260px; right: auto; left: 0; z-index: 60; padding: 6px; }
.acoes-mais-item { width: 100%; justify-content: flex-start; }
.acoes-mais-painel form { margin: 0; }
/* ⚠️⚠️ ACHADO 2-A DO DONO: *"o campo de busca das telas é maior do que os outros
   filtros da mesma página, criando um desalinhamento."* A CAUSA foi MEDIDA no
   navegador (não deduzida), e não é estilo de agente nem o `appearance:none` do
   select — é ESPECIFICIDADE, e é determinística:

     a regra base (bem acima, "input[type=…], select, textarea") casa o input por
     seletor de ATRIBUTO — `input[type="search"]` = (0,0,1,1) — e o select por
     seletor de TIPO — `select` = (0,0,0,1).
     `.mover-select` é (0,0,1,0): PERDE do primeiro e GANHA do segundo.

   Resultado medido: `<input type="search" class="mover-select">` sai com 41px
   (padding 10px, fonte 14px — os valores da BASE) e `<select class="mover-select">`
   com 34px. Como `.painel-filtros` alinha pelo RODAPÉ (align-items:flex-end), os
   7px viram um rótulo mais alto — exatamente o que o dono circulou.

   ⚠️ A classe estava MUDA em 25 `<input>` de ~15 telas: quem a escreveu achava que
   estava padronizando e não estava. Por isso a cura é a CAUSA (alcançar o input),
   não um remendo por tela.

   Os quatro seletores num bloco só, para não haver dois pontos de verdade:
     · `.mover-select`            — o uso geral (selects e o que mais a use);
     · `input.mover-select`       — (0,0,1,1): empata com a base e vence por ORDEM;
     · `.painel-filtros input/select` — cobre as 4 telas cujo campo de busca NÃO
       tem a classe (relatórios ×2, usuários ×2) e qualquer campo novo que nasça ali.
   ⚠️ `:not(checkbox/radio)` porque `padding:7px 10px` numa caixinha a deformaria.
   Medido: hoje não há nenhuma em `.painel-filtros` — a guarda é para a próxima. */
.mover-select,
input.mover-select,
.painel-filtros input:not([type="checkbox"]):not([type="radio"]),
.painel-filtros select { padding: 7px 10px; border: 1px solid var(--borda-forte);
    border-radius: var(--raio-sm);
    background: var(--superficie); color: var(--texto); font-size: 13.5px; }

/* Arraste no Kanban (SortableJS) */
.kanban-dropzone { min-height: 46px; }
/* Feedback de arraste (padrão KANBAN): ao arrastar, as zonas de soltura ganham
   contorno tracejado ("droppable") e a coluna sob o cursor se destaca ("solte
   aqui"). O placeholder (fantasma) já preserva a altura — a coluna não "pula". */
.kanban.arrastando .kanban-dropzone {
    outline: 2px dashed var(--borda);
    outline-offset: -4px;
    border-radius: var(--raio-sm);
    transition: background .15s ease, outline-color .15s ease;
}
.kanban.arrastando .kanban-dropzone:hover {
    outline-color: var(--vermelho);
    background: var(--vermelho-suave);
}
.kanban-card:not(.nao-arrasta) { cursor: grab; }
.kanban-card:not(.nao-arrasta):active { cursor: grabbing; }
.kanban-card-fantasma { opacity: 0.35; }

/* ---- Timer + contagens de tempo --------------------------------------- */
.tempo-etapa { border: 1px solid var(--borda); border-radius: var(--raio); padding: 14px 16px; margin-bottom: 18px; background: var(--superficie-2); }
.tempo-grade { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px 20px; }
.tempo-bloco { display: flex; flex-direction: column; gap: 2px; }
.tempo-rotulo { font-size: 12px; color: var(--texto-rotulo); font-weight: 600; }
.tempo-valor { font-size: 18px; font-weight: 700; color: var(--texto); font-variant-numeric: tabular-nums; }
.tempo-block { color: var(--aviso); }
.timer-controles { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; }
.timer-andamento { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--sucesso); margin: 10px 0 0; }
.timer-andamento svg { width: 13px; height: 13px; }

/* ---- Triagem inteligente ---------------------------------------------- */
.selo-adicao { color: var(--info); background: var(--info-bg); }
.aviso-status-virou_adicao { color: var(--info); background: var(--info-bg); }
.triagem-titulo { font-size: 12px; font-weight: 700; color: var(--texto-rotulo);
    text-transform: uppercase; letter-spacing: 0.04em; margin: 16px 0 6px; }
.triagem-resumo { font-size: 13.5px; margin: 0 0 12px; }

/* ---- SLA (Service Desk) ------------------------------------------------ */
.selo-sla { display: inline-flex; align-items: center; gap: 5px; font-size: 12px;
    font-weight: 700; padding: 2px 9px; border-radius: 999px; white-space: nowrap; }
.selo-sla svg { width: 13px; height: 13px; flex: none; }
.sla-dentro { color: var(--sucesso); background: var(--sucesso-bg); }
.sla-perto { color: var(--aviso); background: var(--aviso-bg); box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.sla-estourado { color: var(--alerta); background: var(--alerta-bg); box-shadow: inset 0 0 0 1px var(--alerta); }
/* Card com SLA estourado (crítico): B4 — a regra vive junto com a de block
   (mesmo realce, um único modificador; ver .kanban-card-block acima). */

/* ---- Alerta de TEMPO por etapa (funil de ativação: lista + kanban) ------ */
/* Amarelo = atenção; vermelho = atrasado. Reusa os tokens --aviso*/--alerta*
   (adaptam claro/escuro). NÃO sobrepõe estados finais: block/cancelada/concluída
   vêm ANTES na cadeia de classes do card (mesma técnica do -critico). */
.kanban-card-tempo-amarelo { border-left-color: var(--aviso-borda);
    background: linear-gradient(0deg, var(--aviso-bg), var(--aviso-bg)), var(--superficie); }
.kanban-card-tempo-vermelho { border-left-color: var(--alerta);
    background: linear-gradient(0deg, var(--alerta-bg), var(--alerta-bg)), var(--superficie); }
.painel-linha.alerta-tempo-amarelo { box-shadow: inset 3px 0 0 var(--aviso-borda);
    background: linear-gradient(0deg, var(--aviso-bg), var(--aviso-bg)), transparent; }
.painel-linha.alerta-tempo-vermelho { box-shadow: inset 3px 0 0 var(--alerta);
    background: linear-gradient(0deg, var(--alerta-bg), var(--alerta-bg)), transparent; }

/* Selo textual redundante (cor NUNCA é o único sinal). */
.chip-tempo { display: inline-flex; align-items: center; gap: 3px; font-size: 11px;
    font-weight: 700; padding: 1px 7px; border-radius: 999px; white-space: nowrap;
    vertical-align: middle; margin-left: 4px; }
.chip-tempo svg { width: 12px; height: 12px; flex: none; }
.chip-tempo-amarelo { color: var(--aviso); background: var(--aviso-bg);
    box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.chip-tempo-vermelho { color: var(--alerta); background: var(--alerta-bg);
    box-shadow: inset 0 0 0 1px var(--alerta); }

/* Pulsação SUTIL (respiração) só no VERMELHO, no selo — não mexe na sombra do
   card (que tem transição de hover). Envolta em no-preference: quem desliga
   animações não vê pulsar. */
@keyframes pulso-chip-tempo {
    0%, 100% { box-shadow: inset 0 0 0 1px var(--alerta), 0 0 0 0 var(--alerta-bg); }
    50%      { box-shadow: inset 0 0 0 1px var(--alerta), 0 0 0 4px transparent; }
}
@media (prefers-reduced-motion: no-preference) {
    .chip-tempo-vermelho { animation: pulso-chip-tempo 2.4s ease-in-out infinite; }
}

/* ---- SAP: status do chamado (funil) + estado da origem nos boards -------- */
.selo-sap-aguardando_agente { color: var(--info); background: var(--info-bg); }
.selo-sap-realizando_tentativas { color: var(--aviso); background: var(--aviso-bg);
    box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.selo-sap-insucesso { color: var(--alerta); background: var(--alerta-bg);
    box-shadow: inset 0 0 0 1px var(--alerta); }
.selo-sap-sucesso { color: var(--sucesso); background: var(--sucesso-bg); }
.selo-sap-cancelado { color: var(--neutro); background: var(--neutro-bg); }
.sap-linha-acoes { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
/* (.sap-resp-chip removido no B5/review: o responsável do SAP usa o componente
   padrão {% responsavel %} em todo lugar — board, cabeçalho e rodapé do modal.) */

/* Estado SAP pintado nos cards das ORIGENS (ativação/Service Desk).
   F1.2 — AMARELO = SAP em andamento (aguardando/tentativas/insucesso);
   verde = acesso liberado (saiu do SAP); BLOCK é VERMELHO e PREVALECE
   (a ordem dos elif nos templates põe o block antes do SAP). */
.kanban-card-sap-aguardando { border-left-color: var(--aviso-borda) !important;
    background: linear-gradient(0deg, var(--aviso-bg), var(--aviso-bg)), var(--superficie); }
.kanban-card-sap-saiu { border-left-color: var(--sucesso) !important;
    background: linear-gradient(0deg, var(--sucesso-bg), var(--sucesso-bg)), var(--superficie); }
/* TA-2.3: card/linha INCONSISTENTE — mesmo mecanismo dos irmãos do SAP (pinta o
   card inteiro), na cor de alerta. O card já tem termômetro, selo, avatar, ações,
   balão e as fotos: NÃO entra ícone novo — a cor é o sinal, e o "qual é o
   problema" mora no painel de triagem, que é onde se investiga. */
.kanban-card-inconsistente { border-left-color: var(--alerta) !important;
    background: linear-gradient(0deg, var(--alerta-bg), var(--alerta-bg)), var(--superficie); }
.painel-linha.inconsistente { box-shadow: inset 3px 0 0 var(--alerta);
    background: linear-gradient(0deg, var(--alerta-bg), var(--alerta-bg)), transparent; }
.painel-linha.em-block { box-shadow: inset 3px 0 0 var(--alerta);
    background: linear-gradient(0deg, var(--alerta-bg), var(--alerta-bg)), transparent; }
.painel-linha.sap-aguardando { box-shadow: inset 3px 0 0 var(--aviso-borda);
    background: linear-gradient(0deg, var(--aviso-bg), var(--aviso-bg)), transparent; }
.painel-linha.sap-saiu { box-shadow: inset 3px 0 0 var(--sucesso);
    background: linear-gradient(0deg, var(--sucesso-bg), var(--sucesso-bg)), transparent; }
/* F6: URGÊNCIA (terceiro eixo, ORTOGONAL) — NÃO pinta a borda (que já sinaliza
   block/inconsistência/SAP): é uma TARJA VERMELHA no topo do card, que convive com
   qualquer status e PULSA (a urgência é rara, precisa gritar; o pulso a separa do
   vermelho ESTÁTICO do bloqueio). Ordenação (server-side) põe os urgentes no topo. */
.kanban-card-urgente-tarja { display: flex; align-items: center; gap: 6px;
    margin: 0 0 9px; padding: 4px 8px; border-radius: var(--raio-sm);
    background: var(--alerta); color: #fff;
    font-size: 11px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.kanban-card-urgente-tarja svg { width: 13px; height: 13px; flex: none; }
/* Na LISTA a urgência é um selo inline (a linha não tem topo próprio). */
.painel-linha .selo-urgente, .selo-urgente { color: #fff; background: var(--alerta);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--alerta) 55%, transparent); }
/* O pulso só toca para quem NÃO pediu menos animação (acessibilidade). Quem
   desativa efeitos vê a tarja vermelha ESTÁTICA — a cor+texto já bastam. */
@keyframes pulso-urgente {
    0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--alerta) 65%, transparent); }
    50% { box-shadow: 0 0 0 5px transparent; }
}
@media (prefers-reduced-motion: no-preference) {
    .kanban-card-urgente-tarja, .selo-urgente { animation: pulso-urgente 1.3s ease-in-out infinite; }
}
/* B3: "aguardando SAP" tinha 3 cores (azul no funil SAP, fundo âmbar no card
   e selo VERMELHO por cima) — o selo da origem alinha ao âmbar do fundo:
   esperar o SAP é "esperando terceiro", não crítico. */
.selo-sap-origem-aguardando { color: var(--aviso); background: var(--aviso-bg);
    box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.selo-sap-origem-saiu { color: var(--sucesso); background: var(--sucesso-bg); }
/* SC-1.7: "Voltou do SAP — valide" (o dado veio de FORA; alguém confere antes de
   passar adiante). Selo PRÓPRIO e não o verde acima: aquele é "pode acessar o
   servidor" e some no 1º movimento; este é uma PENDÊNCIA de conferência humana e
   fica aceso até a integração AVANÇAR. Azul-informativo = "olhe para mim", sem o
   alarme do vermelho — nada está errado, só falta conferir. */
.selo-valida-sap { color: var(--info); background: var(--info-bg);
    box-shadow: inset 0 0 0 1px var(--info); }

/* ---- Bloco 4: @menção, sininho de notificações, anexo no feed ------------ */
.mencao { color: var(--info); font-weight: 700; }

.sino-wrap { position: relative; }
.sino-badge { position: absolute; top: 1px; right: 1px; min-width: 15px; height: 15px;
    padding: 0 3px; border-radius: 999px; background: var(--vermelho); color: #fff;
    font-size: 10px; font-weight: 700; line-height: 15px; text-align: center;
    border: 2px solid var(--superficie); box-sizing: content-box; }
.sino-painel { position: absolute; top: 112%; right: 0; width: 340px; max-width: 90vw;
    max-height: 430px; overflow-y: auto; background: var(--superficie);
    border: 1px solid var(--borda); border-radius: var(--raio); box-shadow: var(--sombra); z-index: 30; }
.sino-painel-cab { display: flex; align-items: center; justify-content: space-between;
    gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--borda); }
.sino-lista { display: flex; flex-direction: column; }
.sino-item { margin: 0; display: flex; align-items: stretch; gap: 4px;
    border-bottom: 1px solid var(--borda); padding-right: 8px; }
.sino-item-nova { border-left: 3px solid var(--vermelho); }
.sino-item-icone { display: flex; align-items: center; padding-left: 10px; color: var(--texto-suave); }
.sino-item-form { flex: 1; min-width: 0; }
.sino-item-btn { width: 100%; text-align: left; background: none; border: 0;
    padding: 10px 8px; cursor: pointer; display: flex; flex-direction: column;
    gap: 3px; color: var(--texto); }
.sino-item-btn:hover { background: var(--superficie-2); }
.sino-item-texto { font-size: 13px; line-height: 1.35; }
.sino-item-quando { font-size: 11px; color: var(--texto-suave); }
.sino-painel-rodape { padding: 8px 12px; border-top: 1px solid var(--borda); text-align: center; }
.sino-painel-rodape a { font-size: 12px; font-weight: 600; color: var(--info); }
.btn-link { background: none; border: 0; color: var(--info); cursor: pointer;
    font-size: 12px; font-weight: 600; padding: 0; align-self: center; white-space: nowrap; }
.menu-badge { margin-left: auto; background: var(--vermelho); color: #fff; font-size: 10px;
    font-weight: 700; min-width: 16px; height: 16px; line-height: 16px; text-align: center;
    border-radius: 999px; padding: 0 4px; }

/* Notificações: cor por TIPO (ícone/selo) + filtros/tela completa. */
.notif-tipo-mencao { color: var(--info); }
.notif-tipo-sla { color: var(--alerta); }
.notif-tipo-atribuicao { color: var(--sucesso); }
.notif-tipo-status { color: var(--aviso); }
.notif-tipo-sistema { color: var(--texto-suave); }
.notif-filtros { display: flex; gap: 8px; margin-bottom: 14px; }
.notif-filtros .chip { text-decoration: none; }
.notif-tipo { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; }
.notif-linha-nova { background: linear-gradient(0deg, var(--alerta-bg), var(--alerta-bg)), transparent; }
/* R1: abrir a notificação pela tela "todas" (botão com cara de link, texto longo quebra). */
.notif-abrir { font-size: 13.5px; font-weight: 500; text-align: left; white-space: normal; color: var(--texto); }
.notif-abrir:hover { color: var(--info); text-decoration: underline; }
/* R1: texto completo do recado no modal de leitura (quebras via linebreaksbr). */
.notif-leitura { font-size: 14.5px; line-height: 1.6; }

/* ---- Mural / Feed de notícias (Início) ---------------------------------- */
/* B2: o feed ocupa a LARGURA TOTAL da área de conteúdo (ref Bitrix). */
.mural { max-width: 100%; }
.mural-compositor { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 12px;
    background: var(--superficie); border: 1px solid var(--borda); border-radius: 14px; padding: 14px; }
/* B2: busca do mural (filtra os posts client-side) — abaixo do compositor. */
.mural-busca { display: flex; align-items: center; gap: 8px; margin-bottom: 18px;
    background: var(--superficie); border: 1px solid var(--borda); border-radius: 12px; padding: 8px 12px; }
.mural-busca svg { color: var(--texto-suave); flex: none; }
.mural-busca input { flex: 1; border: 0; background: transparent; color: var(--texto);
    font-size: 14px; outline: none; min-width: 0; }
.mural-busca-limpar { border: 0; background: transparent; color: var(--texto-suave); cursor: pointer;
    font-size: 18px; line-height: 1; padding: 0 4px; }
.mural-vazio-busca { padding: 22px; text-align: center; color: var(--texto-suave); }
/* B4: editar/excluir + marca "editado" + comentários (estilo Bitrix). */
.mural-post-acoes { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; }
.mural-editado { font-size: 11px; color: var(--texto-suave); font-style: italic; }
.mural-comentarios { margin-top: 12px; border-top: 1px solid var(--borda); padding-top: 12px;
    display: flex; flex-direction: column; gap: 10px; }
.mural-comentario { display: flex; gap: 10px; }
.mural-comentario-corpo { flex: 1; min-width: 0; background: var(--superficie-2);
    border: 1px solid var(--borda); border-radius: 10px; padding: 8px 12px; }
.mural-comentario-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 3px; }
.mural-comentario-autor { font-weight: 700; font-size: 12.5px; }
.mural-comentario-meta .mural-post-quando { font-size: 11px; }
.mural-comentario-meta .btn-icone { padding: 2px; }
.mural-comentario-texto { font-size: 13.5px; line-height: 1.5; word-break: break-word; }
.mural-comentar { display: flex; align-items: center; gap: 8px; }
.mural-comentar-avatar { flex: none; }
.mural-comentar-campo { flex: 1; min-width: 0; }
.mural-editar-campo { position: relative; }
.mural-compositor-avatar { flex: none; }
/* position:relative = âncora do dropdown .mencao-sugestoes (senão ele posiciona
   contra o viewport e some acima da tela — era o bug do "@ não aparece nada"). */
.mural-compositor-campo { flex: 1; display: flex; flex-direction: column; gap: 10px; min-width: 0; position: relative; }
.mural-compositor textarea { width: 100%; resize: vertical; }
.mural-compositor-acoes { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mural-feed { display: flex; flex-direction: column; gap: 12px; }
.mural-post { display: flex; gap: 14px; padding: 15px 18px; border: 1px solid var(--borda);
    border-radius: 14px; background: var(--superficie); border-left: 4px solid var(--neutro); }
.mural-post-icone { display: flex; align-items: center; justify-content: center; width: 34px; height: 34px;
    border-radius: 10px; background: var(--superficie-2); color: var(--texto-suave); flex: none; }
.mural-post-corpo { flex: 1; min-width: 0; }
.mural-post-meta { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; flex-wrap: wrap; }
.mural-post-autor { font-weight: 700; font-size: 13.5px; }
.mural-post-quando { font-size: 11px; color: var(--texto-suave); }
.mural-post-texto { font-size: 14px; line-height: 1.55; word-break: break-word; }
.mural-selo { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
    padding: 2px 8px; border-radius: 999px; }
/* Estilos DISTINTOS por tipo (o feed celebra o coletivo; nada individual). */
/* B17: avatar da persona "Pegê" no lugar do ícone, nos posts automáticos. */
.mural-post-pege { overflow: hidden; padding: 0; }
.mural-post-pege img { width: 100%; height: 100%; object-fit: cover; }
.mural-post-atualizacao { border-left-color: var(--info); }
.mural-post-atualizacao .mural-post-icone { background: var(--info-bg); color: var(--info); }
.mural-post-alerta { border-left-color: var(--aviso);
    background: linear-gradient(0deg, var(--aviso-bg), var(--aviso-bg)), var(--superficie); }
.mural-post-alerta .mural-post-icone { background: var(--aviso-bg); color: var(--aviso); }
.mural-post-aviso { border-left-color: var(--vermelho);
    background: linear-gradient(0deg, var(--vermelho-suave), var(--vermelho-suave)), var(--superficie);
    box-shadow: 0 5px 18px -10px rgba(0, 0, 0, .3); }
.mural-post-aviso .mural-post-icone { background: var(--vermelho); color: #fff; }
.mural-post-distintivo { border-left-color: #f59e0b; }
.mural-post-distintivo .mural-post-icone { background: #fef3c7; color: #b45309; }
.mural-post-resumo { border-left-color: var(--sucesso);
    background: linear-gradient(0deg, var(--sucesso-bg), var(--sucesso-bg)), var(--superficie); }
.mural-post-resumo .mural-post-icone { background: var(--sucesso-bg); color: var(--sucesso); }
/* B3: comemoração de aniversário — festivo (fúcsia), distinto do resumo/distintivo. */
.mural-post-aniversario { border-left-color: #d946ef;
    background: linear-gradient(0deg, #fdf4ff, #fdf4ff), var(--superficie); }
.mural-post-aniversario .mural-post-icone { background: #fae8ff; color: #a21caf; }
.mural-selo-atualizacao { background: var(--info-bg); color: var(--info); }
.mural-selo-alerta { background: var(--aviso-bg); color: var(--aviso); box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.mural-selo-aviso { background: var(--vermelho); color: #fff; }
.mural-selo-distintivo { background: #fef3c7; color: #b45309; }
.mural-selo-resumo { background: var(--sucesso-bg); color: var(--sucesso); }
.mural-selo-aniversario { background: #fae8ff; color: #a21caf; }
/* B4: post FIXADO no topo (+ selo), botão de fixar (admin) e imagem anexada. */
.mural-post-fixado { border-left-color: var(--vermelho); box-shadow: inset 0 0 0 1px var(--vermelho-suave); }
.mural-selo-fixado { background: var(--vermelho-suave); color: var(--vinho);
    display: inline-flex; align-items: center; gap: 3px; }
.mural-selo-fixado svg { width: 11px; height: 11px; }
.mural-post-pin { margin-left: auto; display: inline-flex; }
.mural-post-pin .btn-icone { color: var(--texto-suave); }
.mural-post-fixado .mural-post-pin .btn-icone { color: var(--vermelho); }
.mural-post-imagem { display: inline-block; margin-top: 10px; max-width: 360px;
    border-radius: 10px; overflow: hidden; border: 1px solid var(--borda); }
.mural-post-imagem img { display: block; max-width: 100%; height: auto; }
/* B6 SAP: resumo do servidor no modal de tentativa + campos em 2 colunas. */
.form-duas-colunas { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   ⚠️⚠️ O CORPO DOS MODAIS DE FORMULÁRIO — item 15 do caderno do dono
   ═══════════════════════════════════════════════════════════════════════════
   DONO: "tem muito modal do sistema que está muito alto na vertical. Ele é fino na
   horizontal e alto na vertical, gerando scroll e atrapalhando a navegabilidade."

   ⚠️ NÃO É UM DEGRAU NOVO DE LARGURA. A largura continua vindo da escada que já
   existe: estes modais passaram a incluir o cabeçalho com `classe="modal-amplo"`, e
   quem alarga é `.modal-caixa:has(.modal-amplo)`. Aqui só mora o CORPO.

   ⚠️ AS DUAS METADES, e a segunda foi MEDIDA depois que a primeira não bastou:
   1. DUAS COLUNAS — alargar sem reorganizar dá um modal largo e IGUALMENTE ALTO, com
      uma coluna de campos no meio e vazio dos dois lados (a queixa que o dono já fez
      sobre a tabela de feedbacks: "metade da tela vazia");
   2. CORPO ROLÁVEL com cabeçalho e botões FIXOS. Medido: mesmo em duas colunas,
      `cliente` e `servidor` ficam acima de 1080px — a promessa "sem scroll vertical" é
      IMPOSSÍVEL para eles só alargando. Rolar o CORPO é melhor que rolar a página,
      porque o "Salvar" não foge da vista, e é o que o dono pediu de verdade
      ("scroll ATRAPALHANDO A NAVEGABILIDADE"). Precedente da casa: `.modal-gp`.

   ⚠️⚠️ ERRATA (27/08) — ESTE BLOCO AFIRMAVA QUE O `:has()` NÃO REAVALIA NO SWAP DO
   htmx, E ERA FALSO. A medição original saiu de um painel de navegador CONGELADO.
   Re-medido com a SONDA verde (retângulo de 333×111 em `rgb(7,199,3)`, conferido
   antes de anotar qualquer número) a 1366×768, trocando o conteúdo por `innerHTML`:
   o `:has()` reavalia nos DOIS sentidos, e `CSS.supports('selector(:has(*))')` é
   `true`. A consequência prática daquela linha falsa foi CARA: a largura que o dono
   pediu ("explorar 80% da tela na horizontal") ficou dois dias por fazer.
   ⚠️ **A LARGURA VEM DA ESCADA**, pelo `.modal-caixa:has(.modal-amplo)` — os modais
   de formulário incluem o cabeçalho com `classe="modal-amplo"`.
   ⚠️ O CORPO, por outro lado, continua se limitando sozinho com o `calc` abaixo, e
   isso é por outro motivo (bom): a altura depende do VIEWPORT, não do conteúdo do
   ancestral — `calc` é a ferramenta certa para isso, `:has()` não seria.

   ⚠️ O `calc` desconta, na ordem: o `padding` do overlay (`6vh` + `24px`, medido:
   46,08px no topo a 768px) e o que fica FORA do corpo dentro da caixa — o cabeçalho, a
   barra de ações e o `padding: 26px 28px` da própria caixa (~200px somados, medidos).
   A 1ª versão usava `62vh` fixo e o `servidor` ficou com 761px num viewport de 768:
   cabia na conta e **os botões saíam da tela**, porque ninguém descontava o `6vh`.

   ⚠️ ABAIXO DE 900px A GRADE VOLTA A UMA COLUNA: com a caixa estreita, dois campos
   lado a lado ficam ilegíveis — duas colunas só ajudam quando há largura para elas. */
.form-modal-corpo {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 18px;
    align-content: start;
    max-height: calc(100vh - 6vh - 24px - 242px);
    overflow-y: auto;
    /* respiro à direita para o foco não ficar sob a barra de rolagem */
    padding-right: 6px;
}
/* ⚠️ O que NÃO se divide ao meio: erros do formulário, seções com título próprio,
   avisos e o bloco de contato do cliente final. Eles atravessam as duas colunas —
   sem isto um <h3> de seção vira meia largura e a leitura quebra. */
/* ⚠️ `form-erro-geral` e NÃO `form-erros`: a classe `form-erros` não existe em
   template NENHUM do projeto (medido) — a regra era CSS MORTO e nunca teve efeito.
   O bloco real é `templates/_erros_form.html`, que desenha `.form-erro-geral`, e
   ele passou a ficar DENTRO do corpo que rola no mesmo commit. */
.form-modal-corpo > .form-secao,
.form-modal-corpo > .form-erro-geral,
.form-modal-corpo > .aviso,
.form-modal-corpo > [data-campo-largo] { grid-column: 1 / -1; }
/* A seção interna volta a ser uma coluna só — ela já tem a sua própria régua. */
.form-modal-corpo > .form-secao > .form-campo { max-width: none; }
@media (max-width: 900px) {
    .form-modal-corpo { grid-template-columns: 1fr; }
}
.sap-resumo-servidor {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
    padding: 10px 14px; margin: 0 0 14px;
    background: var(--superficie-2); border-radius: var(--raio-sm); font-size: 13px;
}
.chip-sucesso { background: var(--sucesso-bg); color: var(--sucesso); }
/* Comentários do projeto — os FIXADOS destacados no topo. */
.comentarios-fixados { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px;
    padding: 10px 12px; border-radius: var(--raio-sm); background: var(--aviso-bg);
    box-shadow: inset 0 0 0 1px var(--aviso-borda); }
.feed-item-fixado .avatar-mini { background: var(--aviso); color: #fff; }

/* ---- Gamificação (Super Trunfo) ----------------------------------------- */
.gam-topo { display: flex; gap: 20px; flex-wrap: wrap; margin-bottom: 6px; }
.gam-topo > div { flex: 1; min-width: 280px; }
/* Carta SUPER TRUNFO (B18) — colecionável dark/gold, ref supertrunfo_pgfarma.html.
   Paleta própria da carta (independe do tema claro/escuro da página). Sem fontes
   de CDN: usa a stack local com peso/uppercase p/ o ar "display". */
.trunfo-deck { display: flex; flex-wrap: wrap; gap: 28px; justify-content: center; align-items: flex-start; margin: 6px 0; }
.trunfo-card { width: 300px; max-width: 100%; border-radius: 20px; padding: 5px; position: relative;
    background: linear-gradient(150deg, #f3d98b 0%, #8f6a22 26%, #f3d98b 50%, #8f6a22 74%, #f3d98b 100%);
    box-shadow: 0 22px 44px rgba(0,0,0,.5), 0 2px 0 rgba(255,255,255,.25) inset;
    transition: transform .25s ease, box-shadow .25s ease; }
.trunfo-card:hover { transform: translateY(-6px); }
.trunfo-champ { box-shadow: 0 0 0 2px rgba(243,217,139,.55), 0 26px 54px rgba(122,21,32,.55), 0 24px 60px rgba(0,0,0,.5); }
.trunfo-inner { border-radius: 16px; padding: 14px 14px 16px; overflow: hidden; position: relative; color: #f4ece0;
    background: radial-gradient(120% 80% at 50% 0%, #3a1620 0%, transparent 55%), linear-gradient(180deg, #26121a, #1c0d13); }
.trunfo-toprow { display: flex; justify-content: space-between; align-items: center; margin-bottom: 11px; }
.trunfo-classe { font-weight: 700; text-transform: uppercase; letter-spacing: .16em; font-size: 11px; color: #f3d98b;
    border: 1px solid rgba(201,154,63,.5); padding: 4px 10px; border-radius: 6px; background: rgba(0,0,0,.25); }
.trunfo-num { font-weight: 700; font-size: 13px; color: #c9b9a6; letter-spacing: .08em; }
.trunfo-portrait { height: 148px; border-radius: 12px; position: relative; overflow: hidden;
    border: 1px solid rgba(201,154,63,.45);
    background: radial-gradient(90% 120% at 50% 15%, #c6303a 0%, #7a1520 45%, #4c0d15 100%); }
.trunfo-rays { position: absolute; inset: 0; opacity: .16;
    background: repeating-conic-gradient(from 0deg at 50% 60%, #fff 0deg 6deg, transparent 6deg 12deg); }
.trunfo-glow { position: absolute; inset: 0; background: radial-gradient(60% 50% at 50% 120%, rgba(0,0,0,.55), transparent); }
.trunfo-avatar { position: absolute; left: 50%; top: 52%; transform: translate(-50%,-50%);
    font-weight: 800; font-size: 50px; color: rgba(255,255,255,.92); text-shadow: 0 3px 12px rgba(0,0,0,.45); letter-spacing: .03em; }
/* T2: a moldura é PAISAGEM (148px de altura) e o `cover` de uma foto vertical
   cortava a cabeça no centro. `object-position` puxa o enquadramento para o terço
   SUPERIOR (onde o rosto costuma estar) — 22% e não `top` absoluto para não colar
   no topo/cortar o queixo das fotos já recortadas em quadrado. */
.trunfo-avatar-img { position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; object-position: center 22%; }
.trunfo-nameplate { margin: 12px 0 4px; text-align: center; }
.trunfo-name { font-weight: 800; text-transform: uppercase; font-size: 23px; line-height: 1; letter-spacing: .02em; color: #fff;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trunfo-role { color: #c9b9a6; font-size: 11.5px; margin-top: 5px; letter-spacing: .03em; }
.trunfo-attrs { margin-top: 14px; display: flex; flex-direction: column; gap: 11px; }
.trunfo-attr { display: grid; grid-template-columns: 22px 1fr auto; align-items: center; gap: 10px; }
.trunfo-ico { width: 20px; height: 20px; color: #f3d98b; }
.trunfo-lab { font-weight: 600; text-transform: uppercase; letter-spacing: .1em; font-size: 12px; color: #f4ece0; }
.trunfo-val { font-weight: 800; font-size: 18px; color: #fff; min-width: 30px; text-align: right; font-variant-numeric: tabular-nums; }
.trunfo-bar { grid-column: 2 / 4; height: 7px; border-radius: 99px; background: #3a1f26; overflow: hidden; margin-top: -3px; }
.trunfo-bar > i { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, #c6303a, #f3d98b); }
.trunfo-lead .trunfo-val { color: #f3d98b; }
.trunfo-score { margin-top: 16px; border-top: 1px solid rgba(201,154,63,.32); padding-top: 13px;
    display: flex; align-items: center; justify-content: space-between; }
.trunfo-lb { font-weight: 700; text-transform: uppercase; letter-spacing: .22em; font-size: 12px; color: #c9b9a6; }
.trunfo-pts { font-weight: 800; font-size: 30px; line-height: 1; color: #f3d98b; font-variant-numeric: tabular-nums; }
.trunfo-seal { position: absolute; top: -14px; right: -12px; z-index: 3; font-weight: 800; text-transform: uppercase;
    font-size: 10px; letter-spacing: .06em; color: #3a0e14; text-align: center; line-height: 1.15; width: 78px; height: 78px;
    border-radius: 50%; background: radial-gradient(circle at 50% 35%, #f3d98b, #c99a3f 70%, #8f6a22);
    border: 2px solid #fff3d6; box-shadow: 0 8px 20px rgba(0,0,0,.5);
    display: flex; flex-direction: column; align-items: center; justify-content: center; transform: rotate(9deg); }
.trunfo-seal b { font-size: 14px; display: block; }
.trunfo-extras { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11px; color: #a9987f; }
.trunfo-extras .trunfo-chip { color: #e7dcc8; font-weight: 600; }
.gam-eu { background: var(--info-bg); }
.gam-pos { font-weight: 800; color: var(--vinho); }

/* ---- Projetos ----------------------------------------------------------- */
.btn-mini { padding: 3px 9px; font-size: 12px; line-height: 1.2; }
.proj-progresso { height: 6px; border-radius: 999px; background: var(--superficie-2);
    overflow: hidden; margin-bottom: 3px; max-width: 170px; }
.proj-progresso-barra { display: block; height: 100%; background: var(--sucesso); }

.feed-compositor { position: relative; flex: 1; min-width: 220px; }
.mencao-sugestoes { position: absolute; bottom: 100%; left: 0; margin: 0 0 4px; list-style: none;
    padding: 4px; background: var(--superficie); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); box-shadow: var(--sombra); z-index: 15; min-width: 170px; }
.mencao-sugestoes { max-height: 280px; overflow-y: auto; min-width: 260px; }
.mencao-sugestoes li { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 6px; cursor: pointer; font-size: 13px; }
.mencao-sugestoes li:hover { background: var(--superficie-2); }
.mencao-emoji { flex: none; font-size: 14px; line-height: 1; }
.mencao-sug-rotulo { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mencao-sug-tipo { flex: none; font-size: 10px; text-transform: uppercase; letter-spacing: .04em; color: var(--texto-suave);
    background: var(--superficie-2); border: 1px solid var(--borda); border-radius: 999px; padding: 1px 7px; }
/* B3: a @menção de ENTIDADE no feed = um chip-link que abre o modal. */
.mencao-ent { display: inline-flex; align-items: baseline; gap: 3px; padding: 0 6px; border-radius: 6px;
    background: var(--info-bg); color: var(--info); font-weight: 700; text-decoration: none;
    box-shadow: inset 0 0 0 1px var(--info-borda, transparent); cursor: pointer; }
.mencao-ent:hover { text-decoration: underline; }
.mencao-ent .mencao-emoji { font-size: 12px; }
.mural-post-abrir { display: inline-flex; align-items: center; gap: 5px; margin-top: 8px; font-size: 12.5px;
    font-weight: 600; color: var(--info); text-decoration: none; }
.mural-post-abrir:hover { text-decoration: underline; }
.feed-anexo { display: inline-flex; align-items: center; gap: 5px; margin-top: 6px;
    font-size: 12px; color: var(--info); text-decoration: none; }
.feed-anexo:hover { text-decoration: underline; }
.feed-anexo-tam { color: var(--texto-suave); }
.feed-anexo-btn { cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.feed-anexo-nome { font-size: 12px; color: var(--texto-suave); max-width: 120px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- Rastreador de tempo (barra do topo) -------------------------------- */
/* P4 — CHIP de ACESSOS na barra superior (vizinho do rastreador). Pílula do
   mesmo tamanho do `.rastreador-ativo`, para os dois não brigarem. Só existe
   quando há o que resolver: com zero, o endpoint devolve vazio e o wrap fica
   sem altura. VENCIDO usa o vermelho de alerta (a cor NÃO é o único sinal — o
   `title` diz o que é). ⚠️ `color: inherit` no `<a>` não é opcional: sem ele o
   texto cai no padrão do navegador e some no modo escuro (gotcha do CLAUDE.md). */
.chip-acessos { display: inline-flex; align-items: center; gap: 6px;
    background: var(--superficie-2); border: 1px solid var(--borda);
    border-radius: 999px; padding: 4px 12px; font-size: 13px; font-weight: 600;
    color: inherit; text-decoration: none; white-space: nowrap; }
.chip-acessos:hover { background: var(--superficie); text-decoration: none; }
.chip-acessos-num { font-weight: 700; }
.chip-acessos--vencido { color: var(--alerta); background: var(--alerta-bg);
    border-color: color-mix(in srgb, var(--alerta) 35%, transparent); }
#chip-acessos-wrap { display: flex; align-items: center; }
/* P4.2 — o chip virou PAINEL SUSPENSO (antes era link que levava embora da tela).
   A âncora do posicionamento é este wrap, exatamente como `.sino-wrap` faz para o
   `.sino-painel` — que é a caixa REUSADA aqui (mesma largura, borda, sombra e
   anatomia cabeçalho/lista/rodapé). Reusar em vez de clonar mantém os dois
   dropdowns do cabeçalho idênticos quando um deles mudar. */
.chip-acessos-wrap { position: relative; display: flex; align-items: center; }
/* O chip é mais estreito que o sino: o painel não precisa dos 340px. */
.chip-acessos-painel { width: 300px; }
.chip-acessos-painel .sino-item-btn { display: flex; flex-direction: column;
    gap: 2px; color: inherit; text-decoration: none; }

/* P4 — os 3 botões de desfecho no overlay: coluna, largura cheia, o escolhido
   em destaque. `color: inherit` pelo mesmo motivo acima (são <button>). */
.desfecho-opcoes { display: flex; flex-direction: column; gap: 8px; }
.desfecho-opcao { justify-content: flex-start; width: 100%; color: inherit; }
.desfecho-opcao.ativo { border-color: var(--vermelho);
    background: color-mix(in srgb, var(--vermelho) 10%, transparent); }

.rastreador-wrap { position: relative; display: flex; align-items: center; }
.rastreador { position: relative; }
/* ⚠️ ACHADO 4-A — O NOME ERA CORTADO COM ESPAÇO DE SOBRA. Medido no navegador:
   "[1253] Triagem → COLETA (auto)" precisa de 189.6px e o `.rastreador-alvo` estava
   capado em 150px — cortava mesmo SEM o `truncatechars:20` que o template tinha por
   cima (dois cortes cegos empilhados; os 8 do template saíram).
   ⚠️ `min(440px, 32vw)` e não um número seco: o chip vive no cabeçalho, ao lado do
   sino e do chip de acessos. Largura fixa maior resolveria no monitor do dono e
   empurraria o cabeçalho num notebook — que é o defeito que "só aumentar o número"
   produz. Com `vw` ele ENCOLHE, e quem corta é o `text-overflow` do alvo, que se
   adapta. (`.rastreador-alvo` já tem `overflow:hidden`, então o `min-width:auto` do
   flex resolve para 0 e ele pode mesmo encolher.) */
.rastreador-ativo { display: inline-flex; align-items: center; gap: 8px;
    background: var(--superficie-2); border: 1px solid var(--borda);
    border-radius: 999px; padding: 3px 6px 3px 12px; max-width: min(440px, 32vw); }
/* T5 — indicador ÚNICO de "timer rodando": BOLINHA VERDE com PLAY BRANCO
   dentro. O mesmo em todo lugar: card e lista da Ativação, card de projeto
   e rastreador do topo (aposenta o dot pelado e o play verde avulso). */
.timer-indicador { display: inline-flex; align-items: center; justify-content: center;
    width: 16px; height: 16px; border-radius: 50%; background: var(--sucesso);
    flex: none; vertical-align: -3px; box-shadow: 0 0 0 0 var(--sucesso-bg); }
.timer-indicador svg { width: 9px; height: 9px; fill: #fff; stroke: none; margin-left: 1px; }
@media (prefers-reduced-motion: no-preference) {
    .timer-indicador { animation: pulso-timer 2s ease-in-out infinite; }
}
@keyframes pulso-timer { 0%,100% { box-shadow: 0 0 0 0 var(--sucesso-bg); } 50% { box-shadow: 0 0 0 4px transparent; } }
.rastreador-alvo { font-size: 13px; font-weight: 600; color: var(--texto); text-decoration: none;
    max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rastreador-alvo:hover { text-decoration: underline; }
.rastreador-clock { font-variant-numeric: tabular-nums; font-weight: 700; font-size: 13px;
    color: var(--sucesso); min-width: 66px; text-align: center; }
.rastreador-btn { display: inline-flex; align-items: center; justify-content: center;
    width: 28px; height: 28px; border-radius: 50%; border: 0; cursor: pointer;
    background: var(--superficie); color: var(--texto-suave); }
.rastreador-btn:hover { color: var(--texto); background: var(--superficie-3, var(--superficie-2)); }
.rastreador-iniciar { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
    background: var(--superficie-2); border: 1px solid var(--borda); border-radius: 999px;
    padding: 5px 12px; color: var(--texto-suave); font-size: 13px; font-weight: 600; }
.rastreador-iniciar:hover { color: var(--texto); }
.rastreador-menu { position: absolute; top: 120%; right: 0; width: 300px; max-width: 88vw;
    max-height: 380px; overflow-y: auto; background: var(--superficie);
    border: 1px solid var(--borda); border-radius: var(--raio); box-shadow: var(--sombra); z-index: 30; padding: 6px; }
.rastreador-menu-titulo { font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
    color: var(--texto-suave); padding: 6px 8px 4px; margin: 0; }
.rastreador-menu-item { width: 100%; display: flex; align-items: center; gap: 8px;
    background: none; border: 0; cursor: pointer; text-align: left; padding: 8px;
    border-radius: 8px; color: var(--texto); font-size: 13px; }
.rastreador-menu-item:hover { background: var(--superficie-2); }
.rastreador-menu-nome { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⚠️ No MENU o corte estava do lado errado: medido, o rótulo da ETAPA ocupava
   121px dos 300px do painel — sem reticências, `flex:none` — e ROUBAVA a largura do
   NOME, que é o que a pessoa procura. Agora quem trunca é a etapa. */
.rastreador-menu-etapa { font-size: 11px; color: var(--texto-suave); flex: none;
    max-width: 92px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Dica "assumir": item ainda NÃO atribuído a mim (o play assume automaticamente). */
.rastreador-menu-disp { font-size: 11px; color: var(--link); flex: none; font-weight: 600; }
.rastreador-menu-vazio { padding: 12px 8px; font-size: 12px; color: var(--texto-suave); margin: 0; }
@media (max-width: 720px) { .rastreador-iniciar-txt, .rastreador-alvo { display: none; } }

/* ---- Estado vazio ------------------------------------------------------- */
.vazio { text-align: center; padding: 56px 24px; color: var(--texto-suave);
    border: 1px solid var(--borda); border-radius: var(--raio); background: var(--superficie); }
.vazio-icone {
    width: 58px; height: 58px; border-radius: 50%;
    background: var(--superficie-2); color: var(--texto-rotulo);
    display: inline-flex; align-items: center; justify-content: center; margin-bottom: 14px;
}
.vazio h3 { color: var(--texto); font-size: 16px; margin-bottom: 6px; font-weight: 600; }

/* ---- Detalhe (pares rótulo/valor) --------------------------------------- */
.detalhe-lista { display: grid; grid-template-columns: 1fr 1fr; gap: 20px 30px; }
.detalhe-item { border-bottom: 1px solid var(--borda); padding-bottom: 15px; }
.detalhe-rotulo { font-size: 11px; font-weight: 600; text-transform: uppercase;
    letter-spacing: 0.6px; color: var(--texto-rotulo); margin-bottom: 5px; }
.detalhe-valor { color: var(--texto); }
.detalhe-largo { grid-column: 1 / -1; }
.aviso-sensivel {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; color: var(--alerta); background: var(--alerta-bg);
    padding: 5px 11px; border-radius: var(--raio-pill);
}

/* Aviso de EXCLUSÃO com processo vivo (Pacote 3 / T3.1) — avisa, não bloqueia. */
.aviso-exclusao {
    background: var(--alerta-bg); border-radius: var(--raio-sm);
    padding: 12px 14px; margin: 4px 0 16px;
    box-shadow: inset 0 0 0 1px var(--alerta);
}
.aviso-exclusao-titulo { display: flex; align-items: center; gap: 7px;
    color: var(--alerta); font-weight: 700; font-size: 13.5px; margin-bottom: 7px; }
.aviso-exclusao-lista { margin: 0 0 8px 20px; color: var(--texto); font-size: 13.5px; }
.aviso-exclusao-lista li { margin: 2px 0; }
.aviso-exclusao-pergunta { margin: 0; color: var(--texto); font-weight: 600; font-size: 13.5px; }

/* Bloco "Iniciar onboarding" do dossiê do cliente (Pacote 3 / T3.8). */
.dossie-onboarding {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    background: var(--neutro-bg); border-radius: var(--raio-sm);
    padding: 10px 13px; margin-bottom: 14px; font-size: 13.5px;
}

/* Carimbo de PROCEDÊNCIA do anexo mesclado (Pacote 3 / T3.13). */
.carimbo-mesclagem {
    display: inline-block; margin-left: 8px;
    font-size: 11.5px; color: var(--texto-suave);
    background: var(--neutro-bg); border-radius: var(--raio-pill);
    padding: 2px 9px; white-space: nowrap;
}

/* Confirmação de DESATIVAÇÃO de etapa (Pacote 3 / T3.3) — avisa, não impede. */
.aviso-desativacao {
    background: var(--aviso-bg); border-radius: var(--raio-sm);
    padding: 12px 14px; margin: 4px 0 16px;
    box-shadow: inset 0 0 0 1px var(--aviso);
}
.aviso-desativacao .aviso-exclusao-titulo { color: var(--aviso); }

/* Chip "Arquivados" das listas de cadastro (Pacote 3 / T3.6). */
.barra-arquivados { display: flex; align-items: center; gap: .4rem; margin-bottom: 14px; }
.faixa-arquivados {
    display: flex; align-items: center; gap: 8px;
    background: var(--neutro-bg); color: var(--texto-suave);
    border-radius: var(--raio-sm); padding: 9px 13px; margin-bottom: 14px;
    font-size: 13.5px;
}

/* Utilitários */
.texto-suave { color: var(--texto-suave); }
.mt-16 { margin-top: 18px; }
.cartao-estreito { max-width: 640px; }        /* cartão de formulário centrado/estreito */
.dash-nota { color: var(--texto-suave); font-size: 13px; margin: -2px 0 16px; }  /* nota discreta sob KPIs */
.link-voltar { display: inline-flex; align-items: center; gap: 6px; color: var(--texto-suave); font-weight: 600; font-size: 13.5px; }
.link-voltar:hover { color: var(--vermelho); text-decoration: none; }
.htmx-indicator { opacity: 0; transition: opacity .2s; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

/* =========================================================================
   MODAL (criar/editar) — fundo embaçado
   ========================================================================= */
.modal-overlay {
    position: fixed; inset: 0; z-index: 50;
    display: flex; align-items: flex-start; justify-content: center;
    padding: 6vh 20px 24px;
    background: rgba(15, 18, 24, 0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    overflow-y: auto;
}
.modal-caixa {
    background: var(--superficie);
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
    width: 100%; max-width: 640px;
    padding: 26px 28px;
}
/* F1.5 — modal SOBREPOSTO (nível 2): acompanhamento de pendência (block/SAP)
   por cima do modal principal (50); o descarte (60) fica acima de tudo. */
.modal-overlay-2 { z-index: 55; align-items: center; }
.modal-overlay-2 .modal-caixa { max-width: 720px; }

/* F2.3 — AVISO DE ENTRADA (leitura forçada): overlay acima de TUDO. */
.aviso-entrada-overlay { z-index: 70; align-items: center; display: flex; }
.aviso-entrada { max-width: 560px; border-top: 5px solid var(--info); }
.aviso-entrada-comemoracao { border-top-color: var(--sucesso); }
.aviso-entrada-alerta { border-top-color: var(--alerta); }
.aviso-entrada-neutro { border-top-color: var(--info); }
.aviso-entrada-cab { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.aviso-entrada-cab h2 { font-size: 18px; font-weight: 700; }
.aviso-entrada-icone { width: 44px; height: 44px; border-radius: 12px; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--info); background: var(--info-bg); }
.aviso-entrada-comemoracao .aviso-entrada-icone { color: var(--sucesso); background: var(--sucesso-bg); }
.aviso-entrada-alerta .aviso-entrada-icone { color: var(--alerta); background: var(--alerta-bg); }
.aviso-entrada-corpo { margin-bottom: 6px; }
/* Realce pulsante do "aguarde" SÓ para quem aceita movimento (a contagem em
   texto não anima — prefers-reduced-motion respeitado). */
@media (prefers-reduced-motion: no-preference) {
    .aviso-entrada-aguarde { animation: aviso-pulso 1.2s ease-in-out infinite; }
    @keyframes aviso-pulso { 50% { opacity: 0.65; } }
}

/* B2 — BANNER FESTIVO DE ANIVERSÁRIO: cartão pequeno, NÃO bloqueante, que some
   sozinho em ~60s. Fica abaixo do modal (z-45) e do aviso de entrada (z-70).
   Só o NOME é exibido — a idade/ano NUNCA aparece (regra do B1). */
.aniversario-banner {
    position: fixed; top: 74px; left: 50%; transform: translateX(-50%);
    z-index: 45; max-width: calc(100% - 32px);
    display: inline-flex; align-items: center; gap: 12px;
    padding: 10px 12px 10px 16px; border-radius: 999px;
    background: var(--superficie); color: var(--texto);
    border: 1px solid var(--sucesso); box-shadow: var(--sombra-forte, var(--sombra)); }
.aniversario-emoji { font-size: 22px; line-height: 1; flex: none; }
.aniversario-texto { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
.aniversario-texto strong { font-size: 11px; font-weight: 700; color: var(--sucesso);
    text-transform: uppercase; letter-spacing: .04em; }
.aniversario-nome { font-size: 15px; font-weight: 600;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.aniversario-contador { flex: none; font-size: 11px; font-weight: 600; color: var(--texto-suave);
    background: var(--sucesso-bg); border-radius: 999px; padding: 2px 8px; }
.aniversario-fechar { flex: none; border: none; background: none; cursor: pointer;
    color: var(--texto-suave); display: inline-flex; padding: 4px; border-radius: 8px; }
.aniversario-fechar:hover { background: var(--superficie-2); color: var(--texto); }

/* confete DECORATIVO — cobre a tela mas não recebe cliques (pointer-events:none).
   Só anima quando o usuário aceita movimento; sob reduced-motion fica fora de tela. */
.aniversario-confete { position: fixed; inset: 0; z-index: 44; pointer-events: none; overflow: hidden; }
.aniversario-confete i { position: absolute; top: -12vh; width: 8px; height: 14px;
    border-radius: 2px; opacity: .9; }
@media (prefers-reduced-motion: no-preference) {
    .aniversario-confete i { animation: aniversario-cair linear infinite; }
    @keyframes aniversario-cair {
        0%   { transform: translateY(-12vh) rotate(0); }
        100% { transform: translateY(112vh) rotate(600deg); } }
}
.aniversario-confete i:nth-child(1)  { left: 4%;  background: var(--info);    animation-duration: 3.4s; animation-delay: 0s; }
.aniversario-confete i:nth-child(2)  { left: 11%; background: var(--sucesso); animation-duration: 4.2s; animation-delay: .6s; }
.aniversario-confete i:nth-child(3)  { left: 18%; background: var(--alerta);  animation-duration: 3.8s; animation-delay: .2s; }
.aniversario-confete i:nth-child(4)  { left: 25%; background: var(--info);    animation-duration: 4.6s; animation-delay: 1.1s; }
.aniversario-confete i:nth-child(5)  { left: 32%; background: var(--sucesso); animation-duration: 3.2s; animation-delay: .4s; }
.aniversario-confete i:nth-child(6)  { left: 39%; background: var(--alerta);  animation-duration: 4.9s; animation-delay: 1.6s; }
.aniversario-confete i:nth-child(7)  { left: 46%; background: var(--info);    animation-duration: 3.6s; animation-delay: .9s; }
.aniversario-confete i:nth-child(8)  { left: 53%; background: var(--sucesso); animation-duration: 4.3s; animation-delay: .1s; }
.aniversario-confete i:nth-child(9)  { left: 60%; background: var(--alerta);  animation-duration: 3.9s; animation-delay: 1.3s; }
.aniversario-confete i:nth-child(10) { left: 67%; background: var(--info);    animation-duration: 4.7s; animation-delay: .3s; }
.aniversario-confete i:nth-child(11) { left: 74%; background: var(--sucesso); animation-duration: 3.3s; animation-delay: 2.0s; }
.aniversario-confete i:nth-child(12) { left: 81%; background: var(--alerta);  animation-duration: 4.4s; animation-delay: .7s; }
.aniversario-confete i:nth-child(13) { left: 88%; background: var(--info);    animation-duration: 3.7s; animation-delay: 1.8s; }
.aniversario-confete i:nth-child(14) { left: 94%; background: var(--sucesso); animation-duration: 4.5s; animation-delay: 1.0s; }
.aniversario-confete i:nth-child(15) { left: 15%; background: var(--info);    animation-duration: 5.0s; animation-delay: 2.4s; }
.aniversario-confete i:nth-child(16) { left: 70%; background: var(--alerta);  animation-duration: 4.0s; animation-delay: 2.2s; }

/* Diálogo de DESCARTE (Fase 2, item 1) — sobrepõe o modal de formulário. */
/* ⚠️ 80 — ACIMA do `.aviso-entrada-overlay` (70), e o motivo é um incidente real:
   este popup é o veículo de TODO aviso e recusa (inclusive o fallback de erro do
   `base.html`). Em z-60 ele era pintado ATRÁS do overlay BLOQUEANTE do desfecho do
   acesso, borrado pelo blur e inclicável — então a tela que mais precisa avisar era
   justamente a única onde o aviso não aparecia. O dono clicou duas vezes sem
   resposta e na terceira registrou um desfecho FALSO para escapar, corrompendo a
   métrica que aquele ciclo existe para produzir.
   REGRA: o popup de confirmação/aviso responde a QUALQUER modal, logo fica ACIMA
   de todos eles. Quem criar um overlay novo com z >= 80 recria o defeito. */
.modal-overlay-confirmar { z-index: 80; align-items: center; }
.modal-caixa-confirmar { max-width: 420px; }
.modal-confirmar-titulo { font-size: 17px; font-weight: 600; margin: 0; }
/* Estado de CARREGANDO e ERRO do modal (fetch HTMX) */
.modal-carregando { display: flex; align-items: center; justify-content: center; gap: 10px;
    padding: 32px; color: var(--texto-suave); font-size: 14px; }
.spinner { width: 18px; height: 18px; flex: none; border: 2px solid var(--borda-forte);
    border-top-color: var(--vermelho); border-radius: 50%; animation: girar 0.7s linear infinite; }
@keyframes girar { to { transform: rotate(360deg); } }
.modal-erro { padding: 22px; margin: 6px; border-radius: var(--raio-sm);
    color: var(--alerta); background: var(--alerta-bg); }

/* Botão "Voltar" da navegação interna do modal (aparece quando há histórico). */
.modal-voltar {
    display: inline-flex; align-items: center; gap: 5px; margin-bottom: 14px;
    background: none; border: none; cursor: pointer; padding: 4px 6px;
    color: var(--texto-suave); font-size: 13px; font-weight: 600; border-radius: var(--raio-sm);
}
.modal-voltar:hover { color: var(--vermelho); background: var(--superficie-2); }

.modal-cabecalho {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 12px; margin-bottom: 22px;
}
.modal-cabecalho h2 { font-size: 18px; font-weight: 700; letter-spacing: -0.2px; }
.modal-subtitulo { color: var(--texto-suave); font-size: 13.5px; margin-top: 4px; }
.modal-acoes { display: flex; align-items: center; justify-content: flex-end;
    gap: 10px; margin-top: 24px; }
.obrigatorio { color: var(--vermelho); margin-left: 2px; font-weight: 700; }

/* ---- Detalhe dentro do MODAL ------------------------------------------- */
/* Caixa mais larga só quando o conteúdo é um detalhe (usa :has). O detalhe
   dispensa a moldura do .cartao (evita "caixa dentro de caixa"); cartões
   seguintes ganham um separador simples. */
.modal-caixa:has(.modal-corpo-detalhe) { max-width: 940px; }
/* Modais IMPORTANTES ocupam 70% da tela (~15% de margem por lado); em telas
   menores mantêm pelo menos a largura do detalhe comum. Marque o conteúdo com
   .modal-amplo (hoje: Integração/Ativação, Ticket do Service Desk e os modais
   do SAP). Nasceu no 4F-3.1 (só Integração) e virou classe genérica. */
.modal-caixa:has(.modal-amplo) { max-width: max(70vw, 940px); }
.modal-corpo-detalhe .cartao { border: none; box-shadow: none; padding: 0; }
.modal-corpo-detalhe .cartao + .cartao { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--borda); }
/* RESPIRO GARANTIDO entre QUAISQUER blocos do detalhe (bloco-form, cartão da
   linha do tempo, ações…): sem esta regra, um .bloco-form seguido do .cartão da
   linha do tempo ficava com gap ZERO e "subia em cima" dela. As regras
   específicas acima (cartão+cartão, bloco+bloco) têm mais especificidade e
   continuam valendo; no fluxo normal as margens colapsam (não dobram). */
.modal-corpo-detalhe > * + * { margin-top: 16px; }

/* Linha de tabela clicável — abre o detalhe em modal */
.linha-clicavel { cursor: pointer; }
.linha-clicavel:hover { background: var(--superficie-2); }
/* A linha do registro que já está aberto (ex.: o próprio ticket no "Histórico de
   tickets desta integração"): destacada e SEM link — dá a noção de "este é o 3º
   de 5" sem oferecer um clique que não leva a lugar nenhum.
   O que a distingue do .linha-clicavel:hover (que antes a deixava idêntica ao
   passar o mouse num irmão) é o FUNDO: --info-bg contra o --superficie-2 do
   hover. A faixa é reforço, não a marca — o comentário anterior dizia o
   contrário e isso era perigoso: quem revertesse o fundo confiando na faixa
   ressuscitaria o bug inteiro.
   ⚠️ A faixa mora no PRIMEIRO td, não no <tr>: a .tabela é border-collapse:
   collapse e navegador nenhum (Blink/Gecko) pinta box-shadow de <tr> no modelo
   colapsado — no <tr> ela era INERTE, código morto que parecia vivo. No td:
   first-child ela é uma faixa só, na borda esquerda da linha (em TODO td viraria
   uma listra por célula). */
.linha-atual { background: var(--info-bg); }
.linha-atual > td { font-weight: 600; }
.linha-atual > td:first-child { box-shadow: inset 3px 0 0 var(--info); }

/* =========================================================================
   LOGIN (duas colunas)
   ========================================================================= */
.login { display: grid; grid-template-columns: 1fr 1fr; min-height: 100vh; }
.login-marca {
    background: linear-gradient(150deg, var(--vinho), var(--vermelho) 72%, #7a1414);
    color: #fff; padding: 60px; display: flex; flex-direction: column; justify-content: space-between;
}
.login-marca .marca { color: #fff; font-size: 30px; }
.login-marca .marca .marca-pg { color: #ffd7d7; }
.login-frase { font-size: 30px; font-weight: 700; line-height: 1.32; max-width: 460px; }
.login-frase span { color: #ffd7d7; }
.login-legenda { color: rgba(255,255,255,0.82); }
.login-form-lado { display: flex; align-items: center; justify-content: center; padding: 44px; background: var(--fundo); }
.login-form { width: 100%; max-width: 380px; }
.login-form h1 { font-size: 26px; margin-bottom: 5px; }
.login-form .subtitulo { color: var(--texto-suave); margin-bottom: 28px; }
@media (max-width: 860px) {
    .login { grid-template-columns: 1fr; }
    .login-marca { display: none; }
}

/* Responsivo: menu vira topo em telas estreitas */
@media (max-width: 780px) {
    .app, .app.menu-recolhido { grid-template-columns: 1fr; }
    /* O trilho de presença é cromo de DESKTOP. No mobile o grid vira 1 coluna e um
       aside height:100vh viraria um bloco vazio gigante empurrando a página — some. */
    .trilho-presenca { display: none; }
    /* ⚠️ O BOTÃO DE FEEDBACK E O TRILHO SÃO O MESMO ASSUNTO, e por isso a regra mora
       AQUI, no mesmo bloco: sem o trilho, a faixa da direita fica livre e o botão
       ocupa o canto de verdade. Em tela estreita ele fica SÓ COM O ÍCONE — a barra
       de menu virou horizontal no topo e o polegar trabalha embaixo; um botão com
       texto ali come um pedaço do conteúdo sem precisar. O rótulo continua no
       `title`/`aria-label`, então ele não fica mudo para quem usa leitor de tela. */
    /* ⚠️ 44px É O PISO DO ALVO DE TOQUE, e a primeira medição deu 42 — por isso o
       `min-width`/`min-height` explicitos em vez de confiar no padding: o ícone pode
       mudar de tamanho e o alvo não pode encolher junto. */
    .botao-feedback { right: 20px; padding: 12px; min-width: 44px; min-height: 44px;
        justify-content: center; }
    .botao-feedback-txt { display: none; }
    .menu { position: static; height: auto; flex-direction: row; flex-wrap: wrap; }
    .menu-nav { display: flex; gap: 4px; overflow-x: auto; }
    .menu-grupo { margin: 0; display: flex; align-items: center; }
    /* Sem rótulo visível aqui, a caixa do grupo aberto viraria uma pílula solta no
       meio da barra horizontal — o destaque é cromo de menu LATERAL. */
    .menu-grupo.grupo-aberto { background: none; padding: 0; }
    .menu-rotulo { display: none; }
    /* Accordion NÃO vale no mobile (barra horizontal): o wrapper vira transparente
       (display:contents) e os itens ficam SEMPRE visíveis; sem chevron/pin. */
    .menu-grupo-itens { display: contents !important; }
    .menu-chevron, .menu-pin { display: none; }
    /* Bloco 4: no mobile o menu é barra horizontal — o "recolhido"/hover-expand
       NÃO vale (anula largura fixa/overlay e mantém rótulos dos itens). */
    .app.menu-recolhido .menu,
    .app.menu-recolhido .menu:hover,
    .app.menu-recolhido .menu:focus-within { width: auto; box-shadow: none; }
    .app.menu-recolhido .menu-item span { display: inline; }
    .app.menu-recolhido .menu-usuario-info { display: block; }
    .app.menu-recolhido .menu-rodape form { display: block; }
    .app.menu-recolhido .menu-item { justify-content: center; padding: 9px 12px; }
    .busca { display: none; }
    .conteudo { padding: 22px 18px; }
    .detalhe-lista { grid-template-columns: 1fr; }
    .dash-grade { grid-template-columns: 1fr; }
    .kpi-grade { grid-template-columns: repeat(2, 1fr); }
}

/* =========================================================================
   Dashboard do Service Desk (KPIs, barras de métrica, distribuições)
   ========================================================================= */
.periodo-nav { display: inline-flex; align-items: center; gap: 8px; }
.periodo-atual { font-weight: 700; font-size: 14.5px; min-width: 130px; text-align: center; }

.kpi-grade { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 20px; }
.kpi { background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio);
    padding: 16px 18px; display: flex; flex-direction: column; gap: 2px; box-shadow: var(--sombra-sm); }
.kpi-rotulo { font-size: 12.5px; color: var(--texto-suave); font-weight: 600; }
.kpi-num { font-size: 30px; font-weight: 800; line-height: 1.15; font-variant-numeric: tabular-nums; }
.kpi-nota { font-size: 12px; color: var(--texto-suave); }
.kpi-critico { border-color: var(--alerta); }
.kpi-critico .kpi-num { color: var(--alerta); }

.dash-grade { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; align-items: start; }
.dash-subtitulo { font-size: 13px; margin: 16px 0 8px; color: var(--texto-suave); font-weight: 700; }

.metricas { display: flex; flex-direction: column; gap: 10px; }
.metrica-linha { display: grid; grid-template-columns: 130px 1fr 44px; align-items: center; gap: 10px; }
.metrica-rotulo { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.metrica-trilho { background: var(--superficie-2); border-radius: 999px; height: 12px; overflow: hidden; }
.metrica-barra { height: 100%; border-radius: 999px; background: var(--info); min-width: 2px; transition: width .3s; }
.metrica-valor { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.metrica-barra-entrada { background: var(--info); }
.metrica-barra-conclusao { background: var(--sucesso); }
.metrica-barra-tipo { background: var(--vermelho); }
.metrica-barra-aberto, .metrica-barra-em_andamento { background: var(--info); }
.metrica-barra-em_block { background: var(--aviso); }
.metrica-barra-concluido { background: var(--sucesso); }
.metrica-barra-cancelado { background: var(--neutro); }
/* P4/T5.8: a distribuição do painel passou a usar o vocabulário do SELO
   (pendente/andamento/bloqueado/concluido/cancelado). As três primeiras não
   tinham regra — barra sem cor. `concluido` e `cancelado` acima já servem. */
.metrica-barra-pendente { background: var(--info); }
.metrica-barra-andamento { background: var(--info); }
.metrica-barra-bloqueado { background: var(--aviso); }

.tempo-destaque { display: flex; flex-direction: column; gap: 3px; margin-bottom: 6px; }
.tempo-destaque-num { font-size: 28px; font-weight: 800; font-variant-numeric: tabular-nums; }
/* ⚠️ ACHADO 2-B — A FAIXA DOS TRÊS NÚMEROS do "Registro de tempo". O big number
   vivia no MEIO da prosa do cabeçalho (título + 28px + frase suave, tudo no mesmo
   flex): não era hierarquia, era ruído. Agora é faixa própria, os três lado a lado,
   rótulo em cima de cada um.
   ⚠️ Os três NÃO se comportam igual — o primeiro segue o seletor de período, os
   outros dois são fixos. `--periodo` marca essa diferença com a faixa lateral na cor
   de destaque; o resto está no rótulo e no `title` de cada um.
   ⚠️ Classes PRÓPRIAS: `.tempo-destaque`/`-num` continuam servindo o dashboard do
   Service Desk (outro agente nesta rodada) e não foram tocadas. */
.tempo-resumo { display: flex; flex-wrap: wrap; gap: 10px 28px; margin: 4px 0 16px; }
.tempo-resumo-item { display: flex; flex-direction: column; gap: 2px;
    padding-left: 10px; border-left: 3px solid var(--borda); }
.tempo-resumo-item--periodo { border-left-color: var(--vermelho); }
.tempo-resumo-rotulo { font-size: 11px; font-weight: 600; text-transform: uppercase;
    letter-spacing: .04em; color: var(--texto-suave); }
.tempo-resumo-num { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums;
    line-height: 1.15; }
.tabela .num { text-align: right; font-variant-numeric: tabular-nums; }

/* =========================================================================
   Linha do tempo unificada (o "caderno de registro") — trilho vertical.
   R4 (redesenho): ponto maior com anel, título+quando na mesma linha, autor
   como chip discreto, detalhe vira CITAÇÃO (filete lateral) e as mudanças
   viram linhas campo · de → para. 100% em variáveis (tema claro/escuro).
   ========================================================================= */
.timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.timeline::before { content: ""; position: absolute; left: 14px; top: 8px; bottom: 8px;
    width: 2px; background: var(--borda); }
.timeline-item { position: relative; display: flex; gap: 14px; padding: 0 0 20px 0; }
.timeline-item:last-child { padding-bottom: 0; }
.timeline-ponto { flex: none; width: 30px; height: 30px; border-radius: 50%; z-index: 1;
    display: flex; align-items: center; justify-content: center;
    background: var(--superficie-2); color: var(--texto-suave);
    border: 1px solid var(--borda);
    box-shadow: 0 0 0 3px var(--superficie); }
.timeline-ponto .icone-sm { width: 14px; height: 14px; }
.timeline-corpo { flex: 1; min-width: 0; padding-top: 4px; }
.timeline-cab { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.timeline-titulo { font-weight: 650; font-size: 13.5px; letter-spacing: -0.1px; }
.timeline-quando { font-size: 11.5px; color: var(--texto-suave); white-space: nowrap;
    font-variant-numeric: tabular-nums; }
.timeline-meta { margin-top: 3px; }
.timeline-quem { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px;
    font-weight: 600; color: var(--texto-suave); background: var(--superficie-2);
    border: 1px solid var(--borda); border-radius: 999px; padding: 1px 8px; }
.timeline-quem .icone-sm { width: 11px; height: 11px; }
.timeline-quem-sistema { font-style: italic; font-weight: 500; }
/* V-F5: MOTIVO/observação em destaque (balão de citação) — o "porquê" salta. */
.timeline-detalhe { font-size: 13px; margin-top: 7px; padding: 7px 11px;
    border-left: 3px solid var(--info); background: var(--superficie-2);
    color: var(--texto); border-radius: 0 var(--raio-sm) var(--raio-sm) 0; }
.timeline-mudancas { list-style: none; margin: 7px 0 0; padding: 8px 12px; font-size: 12.5px;
    background: var(--superficie-2); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); display: flex; flex-direction: column; gap: 5px; }
.timeline-mudancas li { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.timeline-campo { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.03em; color: var(--texto-suave); min-width: 90px; }
.timeline-seta { width: 11px; height: 11px; color: var(--texto-suave); flex: none; }
.timeline-mudancas .timeline-de { color: var(--texto-suave); text-decoration: line-through;
    text-decoration-color: var(--borda-forte); }
.timeline-mudancas .timeline-para { color: var(--texto); font-weight: 600; }
.timeline-vazia { display: inline-flex; align-items: center; gap: 6px; color: var(--texto-suave);
    font-size: 13px; }
/* V-F5: cor do ponto por SIGNIFICADO do evento (não só por tipo): avançou/
   concluído=verde, bloqueado=âmbar, desbloqueado=azul, cancelado=vermelho,
   acesso/cobrança=vinho, criação=roxo, o resto=neutro. */
.timeline-cor-sucesso .timeline-ponto { color: var(--sucesso); background: var(--sucesso-bg); border-color: transparent; }
.timeline-cor-info .timeline-ponto { color: var(--info); background: var(--info-bg); border-color: transparent; }
.timeline-cor-aviso .timeline-ponto { color: var(--aviso); background: var(--aviso-bg); border-color: transparent; }
.timeline-cor-alerta .timeline-ponto { color: var(--alerta); background: var(--alerta-bg); border-color: transparent; }
.timeline-cor-vinho .timeline-ponto { color: var(--vinho); background: var(--vermelho-suave); border-color: transparent; }
.timeline-cor-roxo .timeline-ponto { color: var(--roxo); background: color-mix(in srgb, var(--roxo) 15%, transparent); border-color: transparent; }
.timeline-cor-neutro .timeline-ponto { color: var(--texto-suave); background: var(--superficie-2); border-color: var(--borda); }
/* V-F5: transição "X → Y" (etapa) — discreta, abaixo do título. */
.timeline-transicao { margin-top: 5px; font-size: 12.5px; }
.timeline-transicao-txt { display: inline-flex; align-items: center; gap: 6px;
    padding: 2px 9px; border-radius: 999px; background: var(--superficie-2);
    border: 1px solid var(--borda); color: var(--texto); }
/* V-F5: login técnico do autor entre parênteses (discreto ao lado do nome). */
.timeline-quem-login { color: var(--texto-rotulo); }
/* V-F5: log técnico campo-a-campo RECOLHIDO — um clique discreto por card. */
.timeline-tecnicos { margin-top: 8px; }
.timeline-tecnicos > summary { cursor: pointer; list-style: none; user-select: none;
    display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px;
    color: var(--texto-suave); padding: 2px 0; }
.timeline-tecnicos > summary::-webkit-details-marker { display: none; }
.timeline-tecnicos > summary::before { content: "▸"; font-size: 9px; line-height: 1; }
.timeline-tecnicos[open] > summary::before { content: "▾"; }
.timeline-tecnicos > summary:hover { color: var(--texto); }
/* Título das tabelas de auditoria detalhada dentro do bloco da linha do tempo. */
.secao-historico-titulo { font-size: 13px; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.03em; color: var(--texto-suave); margin: 20px 0 10px; }

/* Financeiro — controle de gerar cobranças e linha de total */
.form-gerar { display: inline-flex; align-items: center; gap: 8px; }
.tabela .linha-total td { border-top: 2px solid var(--borda-forte); font-size: 15px; }
/* Fatura — linha do DESCONTO (dedução no valor a cobrar): valor em âmbar para o
   abatimento se distinguir das linhas de cálculo acima dele. */
.tabela .linha-desconto td.num { color: var(--aviso); font-weight: 600; }

/* =========================================================================
   PAINEL DE AEROPORTO (Fase 2, item 15) — a lista rica da ativação.
   Estrutura/legibilidade; o acabamento fino (paleta/tipografia) = sessão de design.
   ========================================================================= */
.painel-filtros { display: flex; gap: 16px; flex-wrap: wrap; margin-bottom: 16px; align-items: flex-end; }
.painel-filtro { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--texto-suave); }
/* D3 — flags do card do Service Desk (SAP/restrição): .flag-icone (estático) e
   .flag-btn (clicável) agora são a FAMÍLIA ÚNICA (box quadrado) definida lá em
   cima junto de .btn-icone; as cores por conceito (.flag-neutro/aviso/alerta/
   sucesso/critico) pintam o BOX e também estão na família única. */

/* U1 — POPUP padronizado (substitui os confirm()/alert() do navegador).
   Ícone em círculo + cor POR CONCEITO: alerta=vermelho, aprovação=verde,
   restrito (senha de supervisor)=âmbar+cadeado. Minimalista: ícone,
   título, mensagem, dois botões. */
.popup-pg-icone { width: 44px; height: 44px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; margin-bottom: 12px; }
.popup-pg-icone svg { width: 22px; height: 22px; }
.popup-pg-alerta .popup-pg-icone { background: var(--alerta-bg); color: var(--alerta); }
.popup-pg-aprovacao .popup-pg-icone { background: var(--sucesso-bg); color: var(--sucesso); }
.popup-pg-restrito .popup-pg-icone { background: var(--aviso-bg); color: var(--aviso); }

/* U1 — faixa "MOVIMENTAÇÃO RESTRITA" dos modais com senha de supervisor. */
.faixa-restrito { display: flex; gap: 10px; align-items: center; padding: 10px 12px;
    border-radius: var(--raio); background: var(--aviso-bg); color: var(--aviso);
    box-shadow: inset 0 0 0 1px var(--aviso-borda); font-size: 12.5px; margin-bottom: 14px; }
.faixa-restrito-icone { width: 30px; height: 30px; border-radius: 50%; flex: none;
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--aviso) 16%, transparent); }
.faixa-restrito-icone svg { width: 15px; height: 15px; }
.faixa-restrito strong { display: block; font-size: 11.5px; text-transform: uppercase; letter-spacing: .4px; }

/* T1 — filtro-pílula (liga/desliga) do board: neutro apagado, --info quando ativo. */
/* B2: pílula INATIVA com fundo claro (não transparente) e ATIVA com destaque
   óbvio (fundo + anel + borda info). Seleção ÚNICA é controlada no Alpine. */
.filtro-pilula { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--borda);
    border-radius: 999px; padding: 6px 12px; background: var(--superficie-2); color: var(--texto-suave);
    font-size: 12.5px; font-weight: 600; cursor: pointer; align-self: flex-end;
    transition: background .12s, border-color .12s, color .12s; }
.filtro-pilula:hover { border-color: var(--info); color: var(--texto); background: var(--superficie-3); }
.filtro-pilula-ativa, .filtro-pilula-ativa:hover { background: var(--info-bg); color: var(--info);
    border-color: var(--info); box-shadow: inset 0 0 0 1px var(--info); font-weight: 700; }
/* B6 — Cliente-hub: chip de filtro por cliente (limpável) + atalhos no detalhe. */
.barra-filtro-cliente { margin-bottom: 14px; }
.chip-filtro-cliente { display: inline-flex; align-items: center; gap: 6px;
    background: var(--info-bg); color: var(--info); border: 1px solid var(--info);
    border-radius: 999px; padding: 5px 6px 5px 12px; font-size: 12.5px; font-weight: 600; }
.chip-filtro-x { display: inline-flex; align-items: center; justify-content: center;
    width: 20px; height: 20px; border-radius: 50%; background: var(--info); color: #fff;
    text-decoration: none; font-size: 11px; line-height: 1; flex: none; }
.chip-filtro-x:hover { background: var(--alerta); }
.cliente-hub-acoes { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.cliente-hub-acoes .btn-icone { width: 40px; height: 40px; }
/* B15: barra que junta os filtros (esquerda) e o alternador de visão (direita). */
.painel-barra { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; margin-bottom: 14px; }

/* ═══ R49 — A BARRA DE FILTROS (achado 5-B) ═══════════════════════════════════
   O dono: *"eu acho essa parte superior de filtros muito feia. Não teria nenhuma
   sugestão de algo mais moderno e minimalista?"* — opção B: busca larga · botão
   "Filtros" com CONTADOR · CHIPS removíveis embaixo · alternador na mesma faixa.

   ⚠️ O QUE DECIDIU NÃO FOI ESTÉTICA: com 4 filtros aplicados não dava para saber o
   que estava filtrando sem varrer a barra com o olho. Os chips existem para tornar o
   estado VISÍVEL — se eles ficarem discretos demais, o componente falhou.

   ⚠️ `.painel-filtros` (15 telas) NÃO foi tocada: as 13 telas que não são piloto
   continuam com a barra antiga, e vão migrar quando o dono vir esta no ar. Estas
   classes são NOVAS e vivem ao lado dela. */
.barra-filtros { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }
/* ⚠️⚠️ R64 — A LINHA DE CHIPS DE QUEM **NÃO** USA O COMPONENTE DE FILTROS.
   Quatro telas (Etapas do funil, Jornada do cliente, Integrações e Service Desk)
   tinham uma `<div class="barra-filtros" style="display:flex;...">` própria, escrita
   à mão. O estilo inline declarava `display:flex` e **não** declarava
   `flex-direction` — então a regra da classe acima (que é `column` DE PROPÓSITO,
   porque o componente empilha as suas linhas) vencia, e os nove chips de status
   saíam **empilhados numa coluna à direita**. Na página cheia passava despercebido;
   no MODAL, estreito, saltava aos olhos — e foi lá que o dono viu.
   ⚠️ O conserto NÃO foi `flex-direction:row` no inline: isso deixaria duas
   `.barra-filtros` significando coisas opostas. Nome próprio, e o inline morre. */
.linha-de-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.barra-filtros-linha { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* A BUSCA é o campo que mais se usa e ganha o espaço: `flex: 1` com um teto, para
   não empurrar o botão e o alternador numa tela larga. O ícone mora DENTRO. */
.barra-filtros-busca { display: flex; align-items: center; gap: 8px; flex: 1 1 260px;
    max-width: 420px; min-width: 0; padding: 0 12px;
    background: var(--superficie); border: 1px solid var(--borda-forte);
    border-radius: 999px; color: var(--texto-suave); }
.barra-filtros-busca:focus-within { border-color: var(--vermelho); box-shadow: var(--anel-foco); }
/* ⚠️ O seletor traz o TIPO junto (`input.classe`) de propósito: a regra base casa o
   campo por `input[type="search"]`, que é (0,0,1,1) — uma classe sozinha (0,0,1,0)
   PERDERIA dela e o campo voltaria a ter altura própria. É a mesma pegadinha que
   causou o desalinhamento do achado 5-A. */
input.barra-filtros-busca-campo { flex: 1; min-width: 0; padding: 8px 0; border: 0;
    background: none; color: var(--texto); font-size: 13.5px; }
input.barra-filtros-busca-campo:focus { outline: none; box-shadow: none; border: 0; }

/* ⚠️ O ícone da busca é um `type="submit"` no motor SERVIDOR — o ÚNICO botão de
   enviar que sobra numa tela sem popover (ver o comentário do componente).
   ⚠️ `color: inherit` mora AQUI, na classe, e não num `style` inline: assim ele herda
   o `--texto-suave` da caixa da busca sem sobrescrever cor nenhuma. É a diferença
   que o R49 errou em sete botões. */
.barra-filtros-busca-botao { display: inline-flex; align-items: center; border: 0;
    background: none; padding: 0; margin: 0; color: inherit; cursor: pointer; line-height: 0; }
.barra-filtros-busca-botao:hover { color: var(--texto); }

.barra-filtros-alvo { position: relative; display: inline-flex; flex: none; }
.barra-filtros-botao { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
/* R50 — o botão AVISA que há filtro sem depender só do número: quem olha a faixa de
   longe vê a borda. É reforço do mesmo estado, lido da MESMA lista. */
.barra-filtros-botao-ativo { border-color: var(--vermelho); color: var(--vermelho); }
/* O CONTADOR: some quando é zero (x-show), então nunca há "Filtros (0)". */
.barra-filtros-contador { display: inline-flex; align-items: center; justify-content: center;
    min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
    background: var(--vermelho); color: #fff; font-size: 11px; font-weight: 700; line-height: 1; }

/* ═══ R50 — O POPOVER GANHOU DESENHO ══════════════════════════════
   O dono, depois de usar: *"o mini modalzinho que abre ao clicar nos filtros está bem
   feio. Podia trabalhar mais nele."* — e o diagnóstico foi que o R49 entregou a
   MECÂNICA (abre, fecha no Esc, fecha no clique fora) e nenhum desenho.
   ANTES, medido na bancada: painel de 300×376, três selects de largura cheia
   empilhados (270px cada, 57px de altura, 12px de respiro) e as 4 pílulas soltas logo
   abaixo com `margin-top: 0`, `padding-top: 0` e `border-top: none` — nenhuma
   separação entre coisas de naturezas diferentes.
   ⚠️ NÃO É PADRÃO NOVO: a caixa continua sendo `.sino-painel`, com `.sino-painel-cab`
   no topo, como o sino e o menu "Mais". O que entra aqui é só o MIOLO. */
/* ⚠️ z-index: a escala da casa é cabeçalho 5 · dropdowns 30 · modal 50. Esta barra
   vive na PÁGINA, não dentro de modal — 30 é o lugar dela (o mesmo do sino). */
.barra-filtros-painel { width: 400px; right: auto; left: 0; z-index: 30; padding: 0; }
.barra-filtros-cab { position: sticky; top: 0; background: var(--superficie); z-index: 1; }
.barra-filtros-cab strong { font-size: 13px; }
.barra-filtros-fechar { width: 26px; height: 26px; }
/* OS CAMPOS em GRADE de duas colunas: o painel deixa de ser uma coluna alta e vira um
   bloco largo e baixo. `minmax(0, 1fr)` (e não `1fr`) porque `<select>` tem largura
   mínima intrínseca — com `1fr` o nome de projeto mais longo estoura a célula. */
.barra-filtros-campos { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px 12px; padding: 12px 14px; }
.barra-filtros-campo-largo { grid-column: 1 / -1; }
/* A SEÇÃO separa o que é de outra natureza: o campo ESCOLHE UM VALOR ("Etapa:
   Triagem"), a pílula LIGA/DESLIGA um recorte. A divisão tem de SE VER. */
.barra-filtros-secao { display: flex; flex-direction: column; gap: 7px;
    padding: 10px 14px 12px; border-top: 1px solid var(--borda); }
.barra-filtros-secao-nome { font-size: 11px; font-weight: 700; letter-spacing: .5px;
    text-transform: uppercase; color: var(--texto-suave); }
.barra-filtros-pilulas { display: flex; flex-wrap: wrap; gap: 6px; }
/* ⚠️ `.filtro-pilula` traz `align-self: flex-end` de onde ela nasceu (a faixa antiga,
   alinhada pela base). Dentro do popover isso deixaria as pílulas de alturas
   diferentes desencontradas na quebra de linha. */
.barra-filtros-secao .filtro-pilula { align-self: auto; }
/* O RODAPÉ — a metade que faz os dois motores parecerem a mesma coisa mesmo fazendo
   coisas diferentes: no servidor ENVIA ("Aplicar filtros"), no navegador FECHA
   ("Pronto"). Mesma posição, mesmo peso. */
.barra-filtros-rodape { display: flex; justify-content: flex-end; gap: 8px;
    padding: 10px 14px; border-top: 1px solid var(--borda); background: var(--superficie-2); }
.barra-filtros-rodape .btn { padding: 7px 14px; font-size: 13px; }
.barra-filtros-ajuda { font-size: 12px; margin: 0; }

/* ═══ R50 — O ALTERNADOR VOLTA PARA O CANTO DIREITO ═══════════════════
   Literal do dono: *"o botão de QUADRO E LISTA foi alterado de local. Deixa ele no
   canto direito mesmo, mas ALINHADO com os outros componentes."* — são DUAS metades,
   e cumprir só uma troca um desalinhamento por outro.
   ⚠️ A CAUSA DO DESALINHAMENTO, MEDIDA: `.alternar-visao` carrega
   `margin-bottom: 20px` de quando ela vivia SOZINHA acima do board. Dentro de um
   `align-items: center`, uma margem embaixo empurra o item para CIMA em metade dela —
   medido: busca e botão no topo 76, alternador no topo 66 (10px acima), e a faixa
   inteira 20px mais alta do que os seus itens (56 contra 36).
   ⚠️ O seletor é DESCENDENTE (0,0,2,0) e vence a classe nua (0,0,1,0) por
   ESPECIFICIDADE, não por ordem — ao contrário da cura do R47, que empata e depende de
   vir depois. Aqui reorganizar o arquivo não traz o defeito de volta.
   ⚠️ E é ESCOPADO: `.alternar-visao` serve 15 telas fora desta barra (abas, pílulas de
   período/escopo) e continua com a margem dela em todas. */
.barra-filtros-linha .alternar-visao { margin: 0 0 0 auto; }

/* OS CHIPS — a metade que torna o estado visível. Some a faixa inteira quando não há
   nenhum (`:empty`), para a barra não deixar um buraco no caso mais comum. */
.barra-filtros-chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
/* ⚠️ R50 — aqui havia `.barra-filtros-chips:empty { display: none }`, e ele DEIXOU DE
   CASAR no momento em que o `<template>` do x-for passou a morar dentro desta faixa:
   um `<template>` conta como filho mesmo não pintando nada, e `:empty` só casa sem
   NENHUM filho. Quem some com a faixa agora é um `x-show` lendo a MESMA lista de todo
   o resto — uma régua a menos, e reativa. */
.chip-filtro-envelope { display: contents; }
/* ⚠️ R50 — `color` EXPLÍCITO aqui, e não `style="color: inherit"` no `<button>`: o chip
   tem DUAS formas (um `<a>` no motor servidor, um `<button>` no navegador) e elas
   herdavam cores DIFERENTES — medido no tema escuro, o `<a>` pegava o azul de link
   (#60a5fa) e o `<button>` pegava o texto do corpo. Não aparecia porque
   `.chip-filtro-rotulo` e `.chip-filtro-valor` declaram a sua, mas duas formas do mesmo
   componente com heranças diferentes é divergir esperando a vez. Com a cor aqui, as
   duas são idênticas e o `<button>` deixa de precisar de `color: inherit`. */
.chip-filtro { display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 6px 3px 10px; border: 1px solid var(--borda-forte); border-radius: 999px;
    background: var(--superficie-2); color: var(--texto); font: inherit; font-size: 12px;
    font-weight: 600; text-decoration: none; cursor: pointer; }
.chip-filtro:hover { border-color: var(--alerta); color: var(--alerta); text-decoration: none; }
.chip-filtro-rotulo { color: var(--texto-suave); font-weight: 600; }
.chip-filtro-rotulo::after { content: ":"; }
.chip-filtro-valor { color: var(--texto); }
.chip-filtro-x { opacity: .55; }
.chip-filtro:hover .chip-filtro-x { opacity: 1; }
.barra-filtros-limpar { border: 0; background: none; font: inherit; font-size: 12px;
    font-weight: 600; color: var(--texto-suave); text-decoration: underline;
    cursor: pointer; padding: 3px 4px; }
.barra-filtros-limpar:hover { color: var(--texto); }
.painel-barra .painel-filtro-busca .mover-select { min-width: 190px; }
.painel-bloco { margin-bottom: 14px; border: 1px solid var(--borda); border-radius: var(--raio); overflow: hidden;
    border-left: 4px solid var(--cor-etapa, var(--borda));  /* cor da etapa (ou borda) */
    /* Fundo SÓLIDO (como os cards do Mural): o texto fica legível sobre o fundo
       decorativo, que só aparece nos respiros entre os blocos. */
    background: var(--superficie); box-shadow: var(--sombra-sm); }
.painel-bloco-cab { width: 100%; display: flex; align-items: center; gap: 10px; padding: 12px 16px;
    background: var(--superficie-2); border: none; cursor: pointer; font-weight: 600; color: var(--texto); font-size: 14px; }
.painel-bloco-dot { width: 10px; height: 10px; border-radius: 50%; flex: none;
    background: var(--cor-etapa, var(--texto-suave)); }
.painel-seta { transition: transform 0.15s ease; }
.painel-seta-aberta { transform: rotate(90deg); }
.painel-bloco-nome { flex: 1; text-align: left; }
.painel-contador { background: var(--superficie); border: 1px solid var(--borda); border-radius: 999px;
    padding: 1px 10px; font-size: 12px; color: var(--texto-suave); }
/* 6 tracks: foto | corpo | resp | triagem | ações | status — a Ativação usa as
   6; listas com menos filhos só ocupam as primeiras (R3: com 5 tracks o
   .painel-status caía numa linha implícita e o selo vazava da célula). */
.painel-linha { display: grid; grid-template-columns: 48px 1fr auto auto auto auto; align-items: center; gap: 14px;
    padding: 12px 16px; border-top: 1px solid var(--borda); }
/* B1/TA-4: só as listas com a identidade DUPLA (cliente + ERP lado a lado)
   alargam a 1ª track. Subiu de 68px (2×30+4) para 84px (2×40+4) junto com o
   crescimento das fotos. ⚠️ NÃO mexer na `.painel-linha` base (48px, acima): é
   compartilhada por 6+ telas (comercial/guardiões/projetos/sap) com UMA foto de
   40px, e subir a base deixaria um buraco nelas. */
.painel-linha--identidade { grid-template-columns: 84px 1fr auto auto auto auto; }
/* CENTRAL DE TRABALHO: a MESMA linha da identidade + DUAS colunas próprias —
   o RESPONSÁVEL (a tela é a única que mistura gente diferente na mesma lista,
   no escopo de equipe) e a PREVISTA para execução. Classe à parte, e declarada
   DEPOIS da irmã de propósito: `--identidade` é compartilhada por 4 telas
   (aeroporto da Ativação e do SD, lista do SAP) e subir de 6 para 8 tracks lá
   deixaria dois buracos em cada uma. ⚠️ A ordem dos filhos é obrigatória — com
   filho a menos o `.painel-status` cai numa linha implícita e o selo vaza. */
.painel-linha--central { grid-template-columns: 84px 1fr auto auto auto auto auto auto; }
/* Topo da Central: a faixa de ABAS (8 rótulos, quebra em 2 linhas) e o seletor
   de ESCOPO, que governa a tela inteira e por isso fica ao lado delas. */
.central-topo { display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap;
    justify-content: space-between; margin-bottom: 16px; }
.central-abas { display: flex; flex: 1; min-width: 0; row-gap: 3px; margin-bottom: 0; }
.central-escopo { flex: none; margin-bottom: 0; }
.central-abas .painel-contador { margin-left: 5px; }
.painel-previsto { display: inline-flex; flex-direction: column; align-items: flex-end;
    line-height: 1.2; white-space: nowrap; font-size: 12px; }
.painel-previsto-rotulo { color: var(--texto-suave); font-size: 10.5px; text-transform: uppercase;
    letter-spacing: .3px; }
.painel-foto img { width: 40px; height: 40px; object-fit: cover; border-radius: 8px; border: 1px solid var(--borda); display: block; }
.painel-foto-vazia { width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
    border-radius: 8px; background: var(--superficie-2); color: var(--texto-suave); border: 1px solid var(--borda); }
.painel-titulo { font-weight: 600; color: var(--texto); text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }
.painel-titulo:hover { text-decoration: underline; }
/* Responsável fixado à DIREITA da linha (padrão de lista, ref. Pilares): avatar +
   nome, antes das ações/status. "sem resp." quando não atribuído. */
/* B1: coluna de STATUS com largura CONSTANTE (dimensionada pelo maior rótulo,
   "Virou adição"/"Em andamento") — a track `auto` variava com o selo e desalinhava
   os ícones de linha para linha. Fixar aqui vale p/ Ativação e SD (mesma classe). */
.painel-status { min-width: 120px; }
/* ⚠️⚠️ ACHADO 2-A (segunda metade) — A GRADE É POR LINHA, e por isso as colunas
   NÃO se falam. `.painel-linha` é `display:grid` em CADA linha: cada uma calcula
   as próprias tracks, e as da direita são `auto` (content-sized). Uma linha com 3
   ícones de ação mede 92px ali; a de baixo, com 1, mede 28px — e como a 2ª track é
   `1fr`, ela ENGOLE a diferença e empurra TUDO. Medido no navegador, com o
   conteúdo real do `_trabalho_linha.html`:

     coluna            largura MÁX   largura MÍN   deslocamento
     chip da origem      127.6px        54.7px        213.7px
     prevista             62.3px        46.3px        140.8px
     passos (triagem)     60.8px           0px        124.8px
     ações                92.0px        28.0px         64.0px
     status              120.0px       120.0px          0.0px   ← já tinha min-width

   A cura JÁ ESTAVA NA CASA, aplicada pela metade: é o `min-width: 120px` da linha
   acima — é ELE que faz os selos "Em andamento" serem os únicos alinhados hoje.
   Aqui ela se completa nas outras quatro, com os números MEDIDOS (o pior caso real
   de cada coluna, arredondado para cima), não chutados.

   ⚠️ ESCOPADO EM `--central`, que é de UM template só. `.painel-resp` (9 telas),
   `.painel-triagem` (6) e `.painel-acoes` (3) são compartilhadas — pinar a base
   mexeria em listas que ninguém pediu para mexer.
   ⚠️ `.painel-resp + .painel-resp`: os slots 3 (avatar) e 4 (chip da origem) usam a
   MESMA classe no template, e `_trabalho_linha.html` não é território desta rodada
   — separar em CSS é a única saída sem tocar nele. O slot 3 não precisa de piso: o
   avatar tem 30px fixos, e com os vizinhos pinados ele alinha sozinho (medido).
   ⚠️ Os pisos são MÍNIMOS, não fixos: rótulo mais longo no futuro ALARGA a coluna
   (e volta a desalinhar) em vez de ser cortado. Alargar o piso é a manutenção. */
.painel-linha--central .painel-resp + .painel-resp { min-width: 130px; }
.painel-linha--central .painel-previsto { min-width: 64px; }
.painel-linha--central .painel-triagem { min-width: 62px; }
.painel-linha--central .painel-acoes { min-width: 92px; }
/* B1: o SELO saiu do TOPO do card (lá ele reservava min-width:104px dos ~179px
   úteis e não sobrava espaço p/ a identidade maior + nome) e desceu para a ÚLTIMA
   LINHA, CENTRALIZADO entre o grupo de ícones da esquerda e o da direita. O
   `flex:1` come a folga e centra o selo nela.

   SEM `min-width: 0` aqui — foi o que fez o selo TRANSBORDAR por cima dos ícones:
   ele desliga o *automatic minimum size*, então o item nunca encolhe nem empurra
   ninguém, só herda a sobra; como o `.selo` é `white-space: nowrap`, sobra < selo
   virava vazamento (metade p/ cada lado, por `center`) sobre os irmãos — o
   `.kanban-card` não tem overflow:hidden. Com `min-width: auto` (default) o
   tamanho mínimo vira o min-content do selo e a linha QUEBRA: os 3 containers
   (.kanban-card-icones, .kanban-chips, .sap-linha-acoes) já são flex-wrap:wrap.
   `flex-wrap` aqui dentro cobre o pior caso do SD (2 selos: "Em andamento" +
   "Acesso liberado" = 234px num card de ~178px), e `safe center` garante que, se
   ainda assim não couber, o alinhamento caia p/ o início em vez de sangrar dos
   DOIS lados. `center` fica declarado antes como fallback de suporte. */
.kanban-card-selo-meio { flex: 1; display: flex; flex-wrap: wrap;
    align-items: center; gap: 4px;
    justify-content: center;
    justify-content: safe center; }
.painel-resp { display: inline-flex; align-items: center; gap: 6px; justify-self: end;
    color: var(--texto-suave); font-size: 12.5px; }
.painel-resp .avatar-comp { flex: none; }
.painel-resp-nome { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* B1 — componente ÚNICO de responsável ({% responsavel %}): avatar padrão +
   nome (get_full_name→username) + "Sem responsável" único + Pegar opcional.
   Mesma cara do .painel-resp (as listas passam painel-resp em `classe`). */
.resp-comp { display: inline-flex; align-items: center; gap: 6px;
    color: var(--texto-suave); font-size: 12.5px; }
.resp-comp .avatar-comp { flex: none; }
.resp-comp-nome { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.resp-comp-vazio { font-style: italic; }
/* F2.2 — responsável (operador) editável inline: um chip clicável que revela o
   lápis no hover; funciona também vazio (clique para definir). */
.resp-editar {
    display: inline-flex; align-items: center; gap: 6px;
    border: none; background: none; cursor: pointer; padding: 2px 6px;
    border-radius: 999px; color: var(--texto-suave); font: inherit; font-size: 12.5px;
    max-width: 100%; transition: background 0.12s, color 0.12s;
}
.resp-editar:hover { background: var(--superficie-2); color: var(--texto); }
.resp-editar .avatar-comp { flex: none; }
/* SAP-ARQ: na identidade DUPLA do board do SAP, o 2º slot é o avatar de QUEM
   PEDIU (o SOLICITANTE). Deixa-o QUADRADO (40px, raio 7px), igual à foto do
   CLIENTE ao lado — os irmãos põem uma <img> de ERP no 2º slot (já quadrada);
   no SAP é um avatar (ou o Pegê), então é aqui que arredondamos o quadrado. O
   avatar do RESPONSÁVEL (à direita, .resp-editar) segue REDONDO como nos irmãos. */
.fotos-identidade .painel-foto .avatar-comp {
    width: 40px; height: 40px; border-radius: 7px; font-size: 15px;
}
.fotos-identidade .painel-foto .avatar-comp svg { width: 20px; height: 20px; }
.resp-editar-nome { max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.resp-editar-vazio { color: var(--texto-suave); font-style: italic; }
.resp-editar-lapis { width: 13px; height: 13px; opacity: 0; flex: none; transition: opacity 0.12s; }
.resp-editar:hover .resp-editar-lapis, .resp-editar:focus-visible .resp-editar-lapis { opacity: 0.85; }
.resp-editar-compacto { padding: 2px; gap: 3px; }
/* F2.4 — balão de comentários com contagem: usa o BOX da família única (lá em
   cima) + a contagem vira um badge no canto. */
.int-balao { position: relative; }
.int-balao:hover { color: var(--link); }
.int-balao-tem { color: var(--link); }
.int-balao-num {
    position: absolute; top: -3px; right: -3px;
    font-size: 9px; font-weight: 700; line-height: 1;
    min-width: 14px; height: 14px; padding: 0 3px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--link); color: #fff; border-radius: 999px;
}
/* Detalhe de ATIVIDADE em modal (Guardiões e Projetos/Minhas Atividades —
   R2: era <style> inline no template do Guardiões; agora compartilhado). */
.atividade-detalhe .detalhe-linha { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--borda); }
.atividade-detalhe .detalhe-rotulo { min-width: 130px; color: var(--texto-rotulo); font-size: .8rem; text-transform: uppercase; letter-spacing: .02em; }
.atividade-detalhe .detalhe-resp { display: inline-flex; align-items: center; gap: 6px; }
.atividade-detalhe .detalhe-bloco-texto { padding-top: 12px; }
.atividade-detalhe .detalhe-bloco-texto p { margin: 6px 0 0; }
/* B10: o NOME do item vira o link (herda o peso do título, sem cor de link). */
.painel-titulo-link { color: inherit; text-decoration: none; cursor: pointer; }
.painel-titulo-link:hover { text-decoration: underline; }
a.kanban-card-titulo { color: var(--texto); text-decoration: none; cursor: pointer; }
a.kanban-card-titulo:hover { text-decoration: underline; }
.painel-flag { color: var(--vermelho); }
.painel-sub { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 4px; font-size: 12.5px; color: var(--texto-suave); }
.painel-sub span { display: inline-flex; align-items: center; gap: 4px; }
.painel-triagem { display: flex; gap: 6px; }
/* .tri-icone e .tri-cinza/amarelo/vermelho agora são a FAMÍLIA ÚNICA (box) lá em
   cima junto de .btn-icone — a triagem já era o modelo do box. */
.painel-acoes { display: flex; gap: 4px; align-items: center; }
.painel-vazio { padding: 16px; color: var(--texto-suave); font-size: 13px; }
@media (max-width: 720px) {
    .painel-linha { grid-template-columns: 40px 1fr; }
    /* B1/TA-4: a variante da identidade dupla acompanha os 84px também aqui. */
    .painel-linha--identidade { grid-template-columns: 84px 1fr; }
    .painel-linha--central { grid-template-columns: 84px 1fr; }
    .painel-triagem, .painel-acoes, .painel-status { grid-column: 2; justify-self: start; }
    /* As 2 colunas próprias da Central empilham junto com as irmãs no estreito. */
    .painel-linha--central .painel-resp,
    .painel-linha--central .painel-previsto { grid-column: 2; justify-self: start; align-items: flex-start; }
}

/* =========================================================================
   GESTÃO PREVENTIVA — lista de rodadas (2 blocos) + modal por urgência
   ========================================================================= */
/* Linha SEM logo: chip de ambiente | corpo | autor. Grid PRÓPRIO (não mexe na
   .painel-linha base, compartilhada por 6+ telas). */
.gp-linha { grid-template-columns: 56px 1fr auto; cursor: pointer; }
.gp-linha:hover { background: var(--superficie-2); }
.gp-amb-chip { display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 26px; border-radius: 7px; font-size: 11px; font-weight: 800;
    letter-spacing: .04em; border: 1px solid var(--borda); color: var(--texto-suave);
    background: var(--superficie-2); }
.gp-amb-chip--prod { color: var(--vinho); border-color: var(--vinho); background: var(--vermelho-suave); }
.gp-amb-chip--dev { color: var(--info); border-color: var(--info); background: var(--info-bg); }
.gp-sub-alerta { color: var(--vermelho); font-weight: 600; }
.gp-boletim { color: var(--texto-suave); font-variant-numeric: tabular-nums; }
.gp-barra-topo { display: flex; align-items: center; justify-content: space-between;
    flex-wrap: wrap; gap: 12px; margin: 4px 0 16px; }

/* Modal QUASE-FULLSCREEN (4 baldes por urgência) — variante :has(), no molde do
   .modal-amplo, mas maior e com corpo rolável. */
.modal-caixa:has(.modal-gp) { max-width: min(96vw, 1400px); width: 96vw; }
.modal-gp { max-height: 82vh; overflow-y: auto; }
.gp-modal-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 10px; }
.gp-modal-boletim { display: flex; flex-wrap: wrap; gap: 14px; padding: 10px 14px;
    background: var(--superficie-2); border: 1px solid var(--borda); border-radius: var(--raio);
    margin-bottom: 14px; font-size: 13px; }
.gp-modal-boletim b { font-variant-numeric: tabular-nums; }
/* Linha de servidor dentro de um balde do modal. */
.gp-serv-linha { display: flex; align-items: center; gap: 12px; padding: 10px 12px;
    border-top: 1px solid var(--borda); }
.gp-serv-corpo { flex: 1; min-width: 0; }
.gp-serv-nome { font-weight: 600; font-size: 14px; }
.gp-serv-sub { font-size: 12.5px; color: var(--texto-suave); margin-top: 3px;
    display: flex; flex-wrap: wrap; gap: 10px; }
.gp-serv-acoes { display: flex; align-items: center; gap: 6px; flex: none; }

/* =========================================================================
   BLOCOS RECOLHÍVEIS DO FORMULÁRIO PÚBLICO (porta de entrada)
   No espírito do bloco do funil (.painel-bloco): moldura arredondada + FAIXA
   lateral colorida (4px) + cabeçalho com número da cor + chevron que gira +
   corpo recolhível. UMA variável --bloco-cor por bloco (.bloco-cN) alimenta
   faixa, número, tag, subcartão e checkbox. Theme-aware. Usa color-mix (2023+).
   ========================================================================= */
.bloco-form {
    --bloco-cor: var(--info);                                  /* fallback */
    --bloco-cor-suave: color-mix(in srgb, var(--bloco-cor) 12%, transparent);
    --bloco-cor-borda: color-mix(in srgb, var(--bloco-cor) 40%, transparent);
    /* número em chip suave: texto escurecido (claro) — legível até em âmbar/teal */
    --bloco-cor-num: color-mix(in srgb, var(--bloco-cor) 62%, #000);
    border: 1px solid var(--borda);
    border-left: 4px solid var(--bloco-cor);                   /* a FAIXA lateral */
    border-radius: var(--raio);
    background: var(--superficie);
    overflow: hidden;
    box-shadow: var(--sombra-sm);
}
.bloco-form + .bloco-form { margin-top: 14px; }

/* AÇÕES DO FUNIL fora de bloco (sempre visíveis, sem recolher), com a faixa
   lateral na COR DA ETAPA. V-F1/F2: no modal da Integração e do Service Desk as
   ações moram no RODAPÉ (.funil-acoes-rodape); .funil-acoes-topo segue para
   quem ainda usa o topo. Mesmo visual; só muda a margem de separação. */
.funil-acoes-topo,
.funil-acoes-rodape {
    border: 1px solid var(--borda);
    border-left: 4px solid var(--cor-etapa, var(--info));
    border-radius: var(--raio);
    background: var(--superficie);
    box-shadow: var(--sombra-sm);
    padding: 14px 16px;
    display: grid; gap: 12px;
}
.funil-acoes-topo { margin-bottom: 14px; }
.funil-acoes-rodape { margin-top: 14px; }

.bloco-form-cab {
    display: flex; align-items: center; gap: 12px;
    width: 100%; margin: 0; padding: 14px 16px;
    background: var(--superficie-2); border: 0; cursor: pointer;
    text-align: left; color: var(--texto); font: inherit;
    transition: background .15s ease;
}
.bloco-form-cab:hover { background: var(--superficie-3); }
.bloco-form-cab:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--bloco-cor); }
/* "vivo" quando aberto: cabeçalho levemente tingido da cor do bloco */
.bloco-form.esta-aberto .bloco-form-cab {
    background: color-mix(in srgb, var(--bloco-cor) 9%, var(--superficie-2));
}
.bloco-form-num {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; border-radius: 50%;
    font-size: 12px; font-weight: 700; line-height: 1;
    background: var(--bloco-cor-suave); color: var(--bloco-cor-num);
}
.bloco-form-titulo {
    flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--texto);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bloco-form-tag {
    flex: none; font-size: 12px; font-weight: 600;
    color: var(--bloco-cor-num); background: var(--bloco-cor-suave);
    padding: 3px 9px; border-radius: 999px;
}
.bloco-form-seta { flex: none; color: var(--texto-suave); transition: transform .18s ease; }
.bloco-form-seta--aberta { transform: rotate(90deg); }

.bloco-form-corpo {
    padding: 16px; background: var(--superficie);
    border-top: 1px solid var(--borda);
    display: grid; gap: 14px;
}
.bloco-form-linha {
    display: grid; gap: 12px;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.bloco-campo { display: flex; flex-direction: column; gap: 6px; }
.bloco-campo > label { font-weight: 600; font-size: 13px; color: var(--texto); }

.bloco-form-check {
    display: flex; align-items: center; gap: 10px;
    font-size: 14px; color: var(--texto); cursor: pointer; user-select: none;
}
.bloco-form-check input[type="checkbox"] { width: auto; margin: 0; flex: none; accent-color: var(--bloco-cor); }

/* nota do bloco 2 "encolhido" (usar o mesmo do legal) */
.bloco-form-nota {
    display: flex; align-items: center; gap: 8px; margin: 0;
    font-size: 13px; color: var(--texto-suave);
    background: var(--bloco-cor-suave);
    border: 1px dashed var(--bloco-cor-borda);
    border-radius: var(--raio-sm); padding: 10px 12px;
}
.bloco-form-nota svg { color: var(--bloco-cor); }
/* Variante ÂMBAR: no Portal, aviso de "obrigatório para este cliente" (o modo
   real vem do código, client-side). */
.bloco-form-nota--alerta {
    background: var(--aviso-bg);
    border: 1px solid var(--aviso-borda);
    color: var(--aviso);
}
.bloco-form-nota--alerta svg { color: var(--aviso); }

/* subcartão de CNPJ dinâmico (bloco 3) — herda a cor do bloco */
.bloco-cnpj {
    border: 1px solid var(--borda); border-left: 3px solid var(--bloco-cor);
    border-radius: var(--raio-sm); padding: 12px; background: var(--superficie-2);
}
.bloco-cnpj + .bloco-cnpj { margin-top: 10px; }
.bloco-cnpj-cab { font-size: 12px; font-weight: 600; color: var(--texto-rotulo); margin-bottom: 8px; }

/* cores por bloco — tema CLARO */
.bloco-c1 { --bloco-cor: #3b82f6; }   /* azul    — responsável legal   */
.bloco-c2 { --bloco-cor: #8b5cf6; }   /* violeta — responsável técnico */
.bloco-c3 { --bloco-cor: #ec4899; }   /* rosa    — CNPJs               */
.bloco-c4 { --bloco-cor: #f59e0b; }   /* âmbar   — dados técnicos      */
.bloco-c5 { --bloco-cor: #14b8a6; }   /* teal    — observações         */

/* cores por bloco — tema ESCURO (tons 400 p/ contraste) + número clareado */
:root[data-tema="escuro"] .bloco-form { --bloco-cor-num: color-mix(in srgb, var(--bloco-cor) 60%, #fff); }
:root[data-tema="escuro"] .bloco-c1 { --bloco-cor: #60a5fa; }
:root[data-tema="escuro"] .bloco-c2 { --bloco-cor: #a78bfa; }
:root[data-tema="escuro"] .bloco-c3 { --bloco-cor: #f472b6; }
:root[data-tema="escuro"] .bloco-c4 { --bloco-cor: #fbbf24; }
:root[data-tema="escuro"] .bloco-c5 { --bloco-cor: #2dd4bf; }

@media (prefers-reduced-motion: reduce) {
    .bloco-form-seta, .bloco-form-cab { transition: none; }
}

/* =========================================================================
   DETALHE EM BLOCOS RECOLHÍVEIS (modais de Integração e Ticket)
   Reaproveita a máquina do .bloco-form (faixa lateral + cabeçalho + chevron).
   Cabeçalho de IDENTIDADE fixo no topo + blocos com COR COM SIGNIFICADO.
   ========================================================================= */

/* Cabeçalho de identidade — foto do Cliente + título + selo + ações. Não recolhe. */
.modal-identidade {
    display: flex; align-items: center; gap: 14px; margin-bottom: 18px;
}
.modal-identidade-foto { flex: none; }
.modal-identidade-foto img {
    width: 46px; height: 46px; border-radius: 10px; object-fit: cover;
    border: 1px solid var(--borda); display: block;
}
.modal-identidade-foto .painel-foto-vazia { width: 46px; height: 46px; border-radius: 10px; }
/* SAP C1: quando não há cliente direto, o slot recebe o avatar de QUEM PEDIU
   (GP/manual) — que preenche a mesma caixa de 46px (redondo, forma natural). */
.modal-identidade-foto .avatar-comp { width: 46px; height: 46px; font-size: 16px; }
.modal-identidade-corpo { flex: 1; min-width: 0; }
.modal-identidade-titulo {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    font-size: 17px; font-weight: 700; letter-spacing: -0.2px; color: var(--texto);
}
.modal-identidade-sub { font-size: 13px; color: var(--texto-suave); margin-top: 3px; }
.modal-identidade-acoes { flex: none; display: flex; align-items: center; gap: 8px; }

/* Ícone dentro do "número" do bloco (aqui é semântico, não sequencial). */
.bloco-form-num svg { width: 15px; height: 15px; }

/* Partials reaproveitados (.cartao: linha do tempo, parcelas, triagem) DENTRO de
   um bloco perdem a moldura e o cabeçalho duplicado — o cabeçalho do bloco manda. */
.bloco-form-corpo > .cartao { border: none; box-shadow: none; padding: 0; margin: 0; background: none; }
.bloco-form-corpo > .cartao > .cartao-cabecalho { display: none; }

/* ⚠️⚠️ R56 (BLOCO 0) — E A `.lista` TAMBÉM. O dono achou USANDO, com print:
   *"quando eu abro o anexo, ele fica de fora, parecendo que são componentes
   diferentes"*.

   MEDIDO: a tabela dos anexos é uma `.lista`, que JÁ é um quadro leve (borda +
   sombra + fundo próprios); logo abaixo, o formulário de envio não tem quadro
   nenhum. Três coisas soltas dentro de um bloco que deveria ser UMA coisa —
   **cartão dentro de cartão**.

   ⚠️ A CURA JÁ EXISTIA NA CASA, só não alcançava a forma certa: a linha do
   `.cartao` acima faz exatamente isto desde sempre. `.lista` não é `.cartao`,
   então escapava.

   ⚠️ **DESCENDENTE, não filho direto (`>`)**, e é decisão medida: no bloco de
   anexos há uma `.lista` que é FILHA (a tabela do pedido) e outra que é NETA
   (dentro de `.anexos-grupo`, a evidência por rodada da vistoria). Com `>`, uma
   perderia a moldura e a outra não — dentro do MESMO bloco. Inconsistência é pior
   que a moldura.
   ⚠️ E o escopo continua estreito: só vale DENTRO de `.bloco-form-corpo`. A
   `.lista` de tela (dezenas delas) não é tocada — há contra-vácuo medindo isso.

   ⚠️ O `overflow: auto` da `.lista` FICA: é ele que segura a tabela larga em
   telas estreitas. O que sai é só a MOLDURA (borda, sombra, fundo) — o que fazia
   parecer outro componente. */
.bloco-form-corpo .lista {
    border: none; box-shadow: none; background: none; border-radius: 0;
}

/* CORES COM SIGNIFICADO — reusa tokens do sistema (não é arco-íris decorativo):
   funil = cor da etapa; SLA/bloqueio = âmbar; financeiro = vinho; rastreio e
   linha do tempo = cinza (auditoria). Cadastro/técnico/triagem/atividades usam
   tons próprios estáveis. A cor nunca é o único sinal (ícone + rótulo no cabeçalho). */
.bloco-cadastro   { --bloco-cor: var(--info); }
.bloco-triagem    { --bloco-cor: #8b5cf6; }
.bloco-tecnico    { --bloco-cor: #0d9488; }
.bloco-funil      { --bloco-cor: var(--cor-etapa, var(--info)); }
.bloco-bloqueio   { --bloco-cor: var(--aviso); }
.bloco-financeiro { --bloco-cor: var(--vinho); }
.bloco-anexos     { --bloco-cor: var(--neutro); }
.bloco-feed       { --bloco-cor: var(--info); }
.bloco-atividades { --bloco-cor: var(--sucesso); }
.bloco-rastreio   { --bloco-cor: var(--neutro); }
.bloco-timeline   { --bloco-cor: var(--neutro); }
/* ⚠️ RESUMO-WL — o bloco "Engajamento" (o detalhe de acesso que veio do dossiê).
   Esta linha NÃO é opcional: sem o seu `--bloco-cor` a faixa lateral cai no
   fallback do `.bloco-form` e o bloco nasce com a cor de outro — "CSS fantasma",
   que teste Django não pega (a cor não está no HTML). Cor = INFO, a mesma das
   barras do próprio componente (`.eng-barra > i`), para o bloco e o miolo não
   discordarem. */
.bloco-engajamento { --bloco-cor: var(--info); }
:root[data-tema="escuro"] .bloco-triagem { --bloco-cor: #a78bfa; }
:root[data-tema="escuro"] .bloco-tecnico { --bloco-cor: #2dd4bf; }

/* ===== B5: FUNDO DECORATIVO GLOBAL "espaço" (arte do Davi) ===================
   Fixo atrás de TODO o layout (z-index:-1), sem capturar cliques. Tema CLARO é o
   base; o ESCURO sobrescreve por :root[data-tema="escuro"]. Os blocos de conteúdo
   (.cartao/.lista/.kanban-card/.mural-post/.modal-caixa/inputs) já são SÓLIDOS
   (var(--superficie)), então o texto fica legível e o fundo aparece só nos
   respiros/bordas (como no Bitrix). O menu e o cabeçalho seguem opacos (painéis).
   A arte é ESTÁTICA (não anima) — nada a congelar em prefers-reduced-motion.
   Para trocar a arte: substitua o bloco .bg-espaco em base_app.html + estes CSS. */
.bg-espaco { position: fixed; inset: 0; width: 100%; height: 100%; overflow: hidden; z-index: -1;
    pointer-events: none; background: linear-gradient(180deg, #f7f8fc 0%, #f4f6fb 100%); }
.bg-espaco .aurora-1 { position: absolute; inset: 0; opacity: .5; filter: blur(28px);
    background: linear-gradient(115deg, rgba(201,212,255,0) 8%, rgba(201,212,255,.35) 24%, rgba(167,216,192,.32) 42%, rgba(246,201,168,.28) 60%, rgba(227,216,245,.32) 78%, rgba(201,212,255,0) 94%); }
.bg-espaco .aurora-2 { position: absolute; inset: 0; opacity: .35; filter: blur(34px);
    background: linear-gradient(75deg, rgba(167,216,192,0) 12%, rgba(201,212,255,.3) 34%, rgba(246,201,168,.26) 56%, rgba(167,216,192,.3) 76%, rgba(167,216,192,0) 92%); }
.bg-espaco .planeta { position: absolute; left: -210px; bottom: -210px; width: 660px; height: 660px; }
.bg-espaco .planeta .corpo { position: absolute; inset: 0; border-radius: 50%;
    background: radial-gradient(circle at 34% 30%, #fff, #ffe4d0); box-shadow: inset -42px -42px 96px rgba(214,150,110,.18); }
.bg-espaco .planeta .anel { position: absolute; left: -90px; top: 240px; width: 840px; height: 168px;
    border: 6px solid rgba(214,150,110,.30); border-radius: 50%; transform: rotate(-18deg); }
.bg-espaco .planeta .anel-tras { clip-path: inset(0 0 50% 0); }
.bg-espaco .planeta .anel-frente { clip-path: inset(50% 0 0 0); }
.bg-espaco .foguete { position: absolute; right: 150px; top: 104px; transform: rotate(30deg); opacity: .4; }
.bg-espaco .estrela { position: absolute; }
.bg-espaco .estrela svg { display: block; width: 100%; height: 100%; }

/* ---- Tema ESCURO: espaço profundo ---- */
:root[data-tema="escuro"] .bg-espaco { background: linear-gradient(180deg, #0c1024 0%, #141a33 55%, #1a2140 100%); }
:root[data-tema="escuro"] .bg-espaco .aurora-1 { opacity: .55; filter: blur(30px); }
:root[data-tema="escuro"] .bg-espaco .aurora-2 { opacity: .4; filter: blur(36px); }
:root[data-tema="escuro"] .bg-espaco .planeta { opacity: .5; }
:root[data-tema="escuro"] .bg-espaco .planeta .corpo {
    background: radial-gradient(circle at 34% 30%, #9fb0d8, #4a5578); box-shadow: inset -46px -46px 110px rgba(8,12,28,.7); }
:root[data-tema="escuro"] .bg-espaco .planeta .anel { border-color: rgba(210,222,255,.28); }
:root[data-tema="escuro"] .bg-espaco .foguete { opacity: .55; }

/* Destaque temporário do item aberto por uma NOTIFICAÇÃO (âncora #post/#atividade).
   A JS adiciona .destaque-anchor por ~2.5s. Anel estático + pulso (congela em
   prefers-reduced-motion). */
.destaque-anchor { box-shadow: 0 0 0 3px var(--info), 0 0 0 7px var(--info-bg) !important; border-radius: var(--raio); }
@media (prefers-reduced-motion: no-preference) {
    .destaque-anchor { animation: destaque-anchor 2.4s ease; }
}
@keyframes destaque-anchor {
    0% { box-shadow: 0 0 0 4px var(--info), 0 0 0 10px var(--info-bg); }
    100% { box-shadow: 0 0 0 3px var(--info), 0 0 0 7px var(--info-bg); }
}

/* F1.2: responsável do lead no modal = avatar + nome inline. */
.detalhe-valor-resp { display: inline-flex; align-items: center; gap: 6px; }

/* =========================================================================
   Minhas Atividades (4F-2.2) — cards de resumo + painéis opacos
   ========================================================================= */
/* 4 cards compactos do topo: faixa de cor à ESQUERDA + ícone + número grande
   + rótulo. A cor entra por --cor-resumo/--cor-resumo-bg (tokens do tema). */
.resumo-grade { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 22px; }
.card-resumo { position: relative; display: flex; align-items: center; gap: 14px;
    background: var(--superficie); border: 1px solid var(--borda); border-radius: var(--raio);
    box-shadow: var(--sombra-sm); padding: 16px 18px 16px 24px; overflow: hidden; }
.card-resumo::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px;
    background: var(--cor-resumo); }
.card-resumo-icone { width: 38px; height: 38px; border-radius: 10px; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--cor-resumo); background: var(--cor-resumo-bg); }
.card-resumo-icone .icone-sm { width: 19px; height: 19px; }
.card-resumo-num { display: block; font-size: 26px; font-weight: 800; line-height: 1.1;
    font-variant-numeric: tabular-nums; }
.card-resumo-rotulo { display: block; font-size: 12.5px; color: var(--texto-suave); font-weight: 600; }
/* Variante CLICÁVEL do card-resumo (drill-down do dossiê 360º): reset do chrome de
   botão + affordance de clique. Alerta = número em vermelho (área com pendência). */
.card-resumo-clicavel { width: 100%; text-align: left; color: inherit; font: inherit; cursor: pointer; }
.card-resumo-clicavel:hover { border-color: var(--link); box-shadow: var(--sombra); }
/* LIGADO: na Central de Trabalho os 4 cards são os FILTROS por banda, então o
   estado selecionado tem de ser óbvio — a faixa colorida sozinha não diz se o
   filtro está ativo (ela existe nos 4 o tempo todo). */
.card-resumo-clicavel.ativo { border-color: var(--cor-resumo);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--cor-resumo) 32%, transparent); }
.card-resumo-alerta .card-resumo-num { color: var(--vermelho); }
@media (max-width: 1100px) { .resumo-grade { grid-template-columns: repeat(2, 1fr); } }
/* Variante 1-LINHA (modal do Servidor): os 4 big numbers NUNCA quebram em 2
   linhas (regra dura). Grid por COLUNA que rola no eixo-x quando falta largura —
   independe da media query ≤1100px acima (as 2 classes vencem em especificidade).
   NÃO altera a .resumo-grade compartilhada dos outros módulos. */
.resumo-grade.resumo-grade--uma-linha {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(150px, 1fr);
    overflow-x: auto;
}

/* Painéis da tela (Atividades / Registro de tempo): blocos OPACOS e distintos
   sobre o fundo — reusam .cartao; aqui só os ajustes internos. */
.painel-ma .cartao-cabecalho h2 { display: inline-flex; align-items: center; gap: 8px; margin: 0; }
.painel-ma .alternar-visao { margin-bottom: 14px; }
.painel-ma .lista { margin-top: 0; }

/* Avatar do responsável alinhado à DIREITA da linha. */
.col-avatar-dir { text-align: right; width: 64px; }

/* Origem/etapa da linha em ÍCONES (integração/ticket/projeto · etapa). */
.celula-origem { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.celula-origem > span { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.celula-origem .icone-sm { width: 15px; height: 15px; flex: none; }

/* =========================================================================
   Bloco "Atendimento SAP" nas origens (4F-4.1) — só leitura
   ========================================================================= */
.sap-atend-chamado { padding: 10px 0; border-bottom: 1px solid var(--borda); }
.sap-atend-chamado:last-child { border-bottom: 0; }
.sap-atend-topo { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 4px; }
.sap-atend-justif { font-size: 12.5px; margin: 0 0 8px; }
.sap-atend-tentativas { margin-top: 6px; }
/* Modal "SAP já em andamento" (_chamados_modal) — antes num <style> inline no
   template; centralizado aqui (B6). */
.sap-modal-chamado { padding: 10px 0; border-bottom: 1px solid var(--borda); }
.sap-modal-chamado:last-child { border-bottom: 0; }
.sap-modal-chamado-topo { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.sap-modal-chamado-sub { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12.5px; }
.sap-modal-chamado-sub span { display: inline-flex; align-items: center; gap: 5px; }

/* ============================================================================
   FORMULÁRIO PÚBLICO — PASSO A PASSO NEUTRO (embedável em qualquer white label)
   ----------------------------------------------------------------------------
   O form vive DENTRO da marca do WL, então a base é cinza/branco e NÃO usa a cor
   da marca do PGFARMA (--vermelho). Regra de cor: AZUL (--link) só no liga/desliga;
   VERDE (--sucesso) só na ETAPA (trilha de progresso); AÇÃO em neutro escuro
   (--texto). Tudo escopado em .pubform — reusa .bloco-campo/.form-erro/.form-ajuda/
   .campo-interruptor; troca só o "chrome" de bloco pelo de passos.
   ========================================================================== */
.pubform { max-width: 560px; margin: 0 auto; --anel-foco-neutro: 0 0 0 3px color-mix(in srgb, var(--texto) 14%, transparent); }
.pubform-topo { margin-bottom: 24px; }
.pubform-topo h1 { font-size: 22px; margin: 0 0 4px; letter-spacing: -.01em; }

/* base NEUTRA: foco cinza (não o vermelho global), asterisco discreto */
.pubform input:focus, .pubform select:focus, .pubform textarea:focus {
    border-color: var(--texto); box-shadow: var(--anel-foco-neutro);
}
.pubform .obrigatorio { color: var(--texto-rotulo); }
/* foco por TECLADO dos botões: neutro escuro, não o vermelho global da marca
   (:focus-visible global em pgfarma.css usa --vermelho — não pode vazar no embed).
   Cobre navegação (.btn), os botões "editar" da Revisão e o .pub-add. */
.pubform button:focus-visible,
.pubform .btn:focus-visible,
.pubform .pub-add:focus-visible { outline-color: var(--texto); }
/* AÇÃO em neutro escuro (o global é o vermelho da marca) */
.pubform .btn-primario { background: var(--texto); color: var(--superficie); border-color: var(--texto); }
.pubform .btn-primario:hover { background: color-mix(in srgb, var(--texto) 86%, var(--superficie)); color: var(--superficie); }
/* liga/desliga: o TEXTO ocupa a linha à ESQUERDA e a chave fica à DIREITA, na MESMA
   linha (o padrão global põe a chave à esquerda / pode quebrar "chave em cima, texto
   embaixo"). row-reverse: no DOM é [input][label] → vira [label ... input]. Vence o
   .bloco-campo (column) que algumas perguntas Sim/Não também carregam. */
.pubform .campo-interruptor {
    display: flex; flex-direction: row-reverse; align-items: center; gap: 14px;
}
.pubform .campo-interruptor > label { flex: 1; margin: 0; font-size: 14px; color: var(--texto); }
.pubform .campo-interruptor input[type="checkbox"] { flex: none; }
/* liga/desliga em AZUL (o global fica verde; aqui o verde é da ETAPA) */
.pubform .campo-interruptor input[type="checkbox"]:checked { background: var(--link); }
.pubform .campo-interruptor input[type="checkbox"]:focus-visible { box-shadow: 0 0 0 3px color-mix(in srgb, var(--link) 30%, transparent); }

/* B2 — PAINEL DE INFORMAÇÕES do wizard: 2 colunas (painel lateral fixo + passo a passo).
   flex-wrap com o painel PRIMEIRO no DOM: largo = painel à esquerda; estreito = painel
   colapsa para o TOPO (faixa acima do passo a passo). Sem media query. */
.wiz-layout { display: flex; gap: 20px; flex-wrap: wrap; align-items: flex-start; }
.wiz-painel { flex: 1 1 190px; min-width: 0; box-sizing: border-box;
    background: var(--superficie-2); border: 1px solid var(--borda);
    border-radius: 10px; padding: 12px 14px; }
.wiz-main { flex: 3 1 320px; min-width: 0; }
.wiz-painel-titulo { display: flex; align-items: center; gap: 6px; margin: 0 0 8px;
    font-size: 12px; font-weight: 700; color: var(--texto-rotulo);
    text-transform: uppercase; letter-spacing: .04em; }
.wiz-painel-item { display: flex; flex-direction: column; gap: 1px; padding: 8px 0;
    border-top: 1px solid var(--borda); }
.wiz-painel-item:first-of-type { border-top: 0; padding-top: 2px; }
.wiz-painel-ent { font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
    color: var(--texto-suave); }
.wiz-painel-rotulo { font-size: 12px; font-weight: 600; color: var(--texto-rotulo); }
.wiz-painel-valor { font-size: 13.5px; color: var(--texto); word-break: break-word;
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 1px; }
.wiz-painel-mascara { letter-spacing: 2px; color: var(--texto-suave); }

/* trilha de progresso — VERDE (--sucesso) */
/* F5: CARROSSEL dos anexos já enviados na etapa — os arquivos ficam UM DO LADO DO
   OUTRO numa faixa que rola na horizontal (setas + deslize), com a barra de scroll
   ESCONDIDA. Não empilha nem cria scroll vertical na modal. */
.wiz-anexos { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--borda); }
.wiz-anexos-topo { display: flex; align-items: center; justify-content: space-between;
    gap: 8px; margin: 0 0 10px; }
.wiz-anexos-titulo { display: flex; align-items: center; gap: 6px; margin: 0;
    font-size: 13px; font-weight: 600; color: var(--texto-suave); }
.wiz-anexos-navegar { display: flex; gap: 4px; flex: none; }
.wiz-anexos-trilho { display: flex; gap: 8px; overflow-x: auto; scroll-snap-type: x proximity;
    scrollbar-width: none; -ms-overflow-style: none; padding-bottom: 2px; }
.wiz-anexos-trilho::-webkit-scrollbar { display: none; }
.wiz-anexo-card { flex: 0 0 132px; scroll-snap-align: start; text-decoration: none;
    display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center;
    padding: 12px 8px; border: 1px solid var(--borda); border-radius: var(--raio-sm);
    background: var(--superficie-2); color: var(--texto);
    transition: border-color .15s, background .15s; }
.wiz-anexo-card:hover { border-color: var(--vermelho); background: var(--vermelho-suave); }
.wiz-anexo-icone { width: 22px; height: 22px; flex: none; color: var(--vermelho);
    stroke: currentColor; fill: none; stroke-width: 1.8; }
.wiz-anexo-nome { font-size: 12px; font-weight: 600; line-height: 1.25; word-break: break-word; }
.wiz-anexo-passo { font-size: 10.5px; color: var(--texto-suave); line-height: 1.2; }

/* F3: com muitos grupos a trilha estoura a largura do modal; rola na horizontal
   em vez de espremer/quebrar os marcadores. O padding-block evita que a bolinha
   :focus e a barra de rolagem cortem o topo/baixo.
   Ajuste do Davi: a trilha virou FAIXA de LARGURA TOTAL no topo do modal (subiu para
   fora do .wiz-layout) — cabe sem apertar. Separador sutil da área de conteúdo abaixo. */
.wiz-rail { display: flex; align-items: center; margin: 0 0 20px;
    overflow-x: auto; padding: 6px 0 18px; border-bottom: 1px solid var(--borda); }
.wiz-rail-step { display: flex; align-items: center; gap: 9px; flex: none; }
/* o marcador é um <button> (clicável p/ voltar a um grupo já feito) — zera o chrome
   nativo do botão, senão vem com borda/fundo do navegador em volta da bolinha. */
button.wiz-rail-step { border: 0; background: none; padding: 0; font: inherit; cursor: pointer; }
button.wiz-rail-step[disabled] { cursor: not-allowed; opacity: .55; }
.wiz-rail-b { position: relative; width: 27px; height: 27px; border-radius: 50%;
    border: 1.5px solid var(--borda-forte); display: grid; place-items: center;
    font-size: 12.5px; font-weight: 700; color: var(--texto-rotulo); background: var(--superficie);
    font-variant-numeric: tabular-nums; transition: border-color .16s, background .16s, box-shadow .16s; }
.wiz-rail-b svg { width: 14px; height: 14px; display: none; stroke: #fff; stroke-width: 3; fill: none; }
.wiz-rail-t { font-size: 12.5px; color: var(--texto-rotulo); font-weight: 600; white-space: nowrap; }
.wiz-rail-line { flex: 1; height: 1.5px; background: var(--borda-forte); margin: 0 10px; min-width: 12px; position: relative; overflow: hidden; }
.wiz-rail-line::after { content: ""; position: absolute; inset: 0; background: var(--sucesso);
    transform: scaleX(0); transform-origin: left; transition: transform .25s ease; }
.wiz-rail-line.is-filled::after { transform: scaleX(1); }
.wiz-rail-step.is-now .wiz-rail-b { border-color: var(--sucesso); color: var(--sucesso);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--sucesso) 16%, transparent); }
.wiz-rail-step.is-now .wiz-rail-t { color: var(--texto); font-weight: 650; }
.wiz-rail-step.is-done .wiz-rail-b { background: var(--sucesso); border-color: var(--sucesso); }
.wiz-rail-step.is-done .wiz-rail-b .wiz-n { display: none; }
.wiz-rail-step.is-done .wiz-rail-b svg { display: block; }
.wiz-rail-step.is-done .wiz-rail-t { color: var(--texto-suave); }
/* passo com ERRO (re-render do POST): pontinho de atenção no marcador */
.wiz-rail-step.tem-erro .wiz-rail-b { border-color: var(--alerta); color: var(--alerta); }
.wiz-rail-step.tem-erro .wiz-rail-b::after { content: ""; position: absolute; top: -2px; right: -2px;
    width: 8px; height: 8px; border-radius: 50%; background: var(--alerta); border: 1.5px solid var(--superficie); }
@media (max-width: 520px) { .wiz-rail-t { display: none; } .wiz-rail-line { min-width: 8px; } }

/* passos */
.wiz-passo { display: none; }
.wiz-passo.wiz-ativo { display: block; }
.wiz-passo-rotulo { font-size: 11px; color: var(--texto-rotulo); letter-spacing: .08em;
    text-transform: uppercase; font-weight: 650; margin: 0 0 4px; font-variant-numeric: tabular-nums; }
.wiz-passo-titulo { font-size: 20px; font-weight: 650; margin: 0 0 5px; letter-spacing: -.01em; }
.wiz-passo-sub { font-size: 14px; color: var(--texto-suave); margin: 0 0 22px; }
.wiz-corpo { display: grid; gap: 15px; }
.wiz-corpo .bloco-form-linha { grid-template-columns: 1fr 1fr; }
@media (max-width: 440px) { .wiz-corpo .bloco-form-linha { grid-template-columns: 1fr; } }

/* SUB-BLOCO dentro de um passo: TÍTULO claro (caixa-alta) + explicação em fonte
   pequena guiando quem preenche (ex.: Responsável legal / Contato técnico). Dois
   sub-blocos se separam por um fio fino. */
.wiz-sub { display: grid; gap: 14px; }
.wiz-sub + .wiz-sub { margin-top: 8px; padding-top: 22px; border-top: 1px solid var(--borda); }
.wiz-sub-cab { display: grid; gap: 3px; }
.wiz-sub-titulo { margin: 0; font-size: 12.5px; font-weight: 680; letter-spacing: .07em; text-transform: uppercase; color: var(--texto); }
.wiz-sub-desc { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--texto-suave); }

/* navegação */
.wiz-nav { display: flex; align-items: center; gap: 10px; margin-top: 26px; padding-top: 20px; border-top: 1px solid var(--borda); }
.wiz-nav .wiz-cresce { margin-left: auto; }

/* revisão */
.wiz-rev-grupo { border: 1px solid var(--borda); border-radius: var(--raio-sm); padding: 14px 16px; }
.wiz-rev-grupo + .wiz-rev-grupo { margin-top: 11px; }
.wiz-rev-grupo h4 { margin: 0 0 9px; font-size: 11.5px; color: var(--texto-suave); text-transform: uppercase;
    letter-spacing: .07em; font-weight: 650; display: flex; justify-content: space-between; align-items: center; }
.wiz-rev-grupo h4 button { background: none; border: 0; font: inherit; text-transform: none; letter-spacing: 0;
    font-size: 12.5px; font-weight: 500; color: var(--texto); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.wiz-rev-dl { display: grid; grid-template-columns: auto 1fr; gap: 7px 18px; margin: 0; font-size: 13.5px; }
.wiz-rev-dl dt { color: var(--texto-rotulo); }
.wiz-rev-dl dd { margin: 0; color: var(--texto); }
.wiz-rev-cripto { display: inline-flex; align-items: center; gap: 6px; color: var(--sucesso); font-size: 13px; font-weight: 560; margin-top: 8px; }
.wiz-rev-cripto svg { width: 15px; height: 15px; stroke: var(--sucesso); stroke-width: 2.4; fill: none; }

/* notas NEUTRAS do wizard (substituem as .bloco-form-nota coloridas por bloco) */
.pub-nota { display: flex; align-items: flex-start; gap: 9px; margin: 0; font-size: 12.5px;
    color: var(--texto-suave); background: var(--superficie-2); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); padding: 10px 12px; }
.pub-nota svg { flex: none; width: 15px; height: 15px; stroke: var(--texto-rotulo); fill: none; margin-top: 1px; }
.pub-nota--alerta { background: var(--aviso-bg); border-color: var(--aviso-borda); color: var(--aviso); }
.pub-nota--alerta svg { stroke: var(--aviso); }
.pub-nota--alerta b { color: var(--aviso); }
/* item de CNPJ (dinâmico) — neutro, sem a faixa colorida do bloco */
.pub-cnpj { border: 1px solid var(--borda); border-radius: var(--raio-sm); padding: 12px; background: var(--superficie-2); }
.pub-cnpj + .pub-cnpj { margin-top: 10px; }
.pub-cnpj-cab { font-size: 12px; font-weight: 600; color: var(--texto-rotulo); margin-bottom: 8px; }
.pub-add { display: inline-flex; align-items: center; justify-content: center; gap: 7px; width: 100%;
    font-size: 13px; font-weight: 540; color: var(--texto-suave); background: none;
    border: 1px dashed var(--borda-forte); border-radius: var(--raio-sm); padding: 9px 12px; cursor: pointer; font-family: inherit; }
.pub-add svg { width: 15px; height: 15px; stroke: currentColor; fill: none; }
.pub-add:hover { border-color: var(--texto-rotulo); color: var(--texto); }

/* seção PLANA (form curto de tela única — ex.: chamado): rótulo discreto + fio fino,
   sem bloco colorido. Mesma base neutra do wizard. */
.pub-sec { padding: 22px 0; border-top: 1px solid var(--borda); }
.pub-sec:first-of-type { border-top: 0; padding-top: 2px; }
.pub-sec-rotulo { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--texto-rotulo); font-weight: 650; margin: 0 0 3px; }
.pub-sec-desc { font-size: 13px; color: var(--texto-suave); margin: 0 0 14px; }
.pub-sec .wiz-corpo { margin-top: 2px; }

/* ==========================================================================
   F4 — VISUALIZADOR de anexos: miniaturas + lightbox
   Só imagem RASTER chega aqui (o template filtra por `a.e_imagem`). Sem lib
   externa — o comportamento é o Alpine `galeriaAnexos` do base.html.
   ========================================================================== */
.anexo-galeria { margin: 10px 0 4px; }

.anexo-galeria-tiras {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* A miniatura é um BOTÃO (abre o lightbox) — foco visível, como os irmãos. */
.anexo-miniatura {
    width: 84px;
    height: 84px;
    padding: 0;
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    background: var(--fundo-suave);
    overflow: hidden;
    cursor: zoom-in;
    transition: border-color .15s, transform .15s;
}
.anexo-miniatura:hover { border-color: var(--vermelho); transform: translateY(-1px); }
.anexo-miniatura:focus-visible { outline: 2px solid var(--vermelho); outline-offset: 2px; }

/* `cover` na MINIATURA (recorte bonito na grade); no lightbox é `contain`. */
.anexo-miniatura img { width: 100%; height: 100%; object-fit: cover; display: block; }

.anexo-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1200;                     /* acima dos modais (que ficam em 1000/1100) */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 24px;
    background: rgba(0, 0, 0, .82);
}

.anexo-lightbox-palco {
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    max-width: 92vw;
    max-height: 92vh;
}

/* RESOLUÇÃO ORIGINAL: os max-* fazem caber sem ESTICAR — uma imagem menor que a
   tela continua no tamanho dela (nítida), nunca interpolada para cima. */
.anexo-lightbox-img {
    max-width: 92vw;
    max-height: 80vh;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: var(--raio);
    background: var(--fundo);
}

.anexo-lightbox-legenda {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    color: #fff;
    font-size: 13px;
    text-align: center;
}
.anexo-lightbox-nome { font-weight: 600; }
.anexo-lightbox-meta { opacity: .78; font-size: 12px; }

.anexo-lightbox-seta,
.anexo-lightbox-fechar {
    border: 1px solid rgba(255, 255, 255, .35);
    background: rgba(255, 255, 255, .12);
    color: #fff;
    border-radius: var(--raio);
    cursor: pointer;
    line-height: 1;
    transition: background .15s;
}
.anexo-lightbox-seta:hover,
.anexo-lightbox-fechar:hover { background: rgba(255, 255, 255, .26); }
.anexo-lightbox-seta:focus-visible,
.anexo-lightbox-fechar:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

.anexo-lightbox-seta { flex: 0 0 auto; width: 44px; height: 64px; font-size: 30px; }
.anexo-lightbox-fechar { position: absolute; top: 16px; right: 16px; padding: 8px 10px; }

@media (max-width: 640px) {
    .anexo-lightbox { padding: 12px; }
    .anexo-lightbox-seta { width: 36px; height: 52px; font-size: 24px; }
}

/* ---------------------------------------------------------------------------
   GATE DE PRÉ-REQUISITO — o estado-vazio que TRAVA (nucleo/prerequisitos.py).
   Some do caminho assim que o cadastro existe, então não compete com nada: é um
   bloco só, com o ícone de alerta à esquerda e um botão por falta.
   --------------------------------------------------------------------------- */
.gate-prereq { display: flex; gap: 16px; align-items: flex-start; padding: 22px 4px; }
.gate-prereq-icone {
    width: 28px; height: 28px; flex: 0 0 28px; margin-top: 2px;
    color: var(--aviso); fill: none; stroke: currentColor; stroke-width: 1.7;
    stroke-linecap: round; stroke-linejoin: round;
}
.gate-prereq-titulo { margin: 0 0 4px; font-size: 17px; }
.gate-prereq-intro { margin: 0 0 16px; color: var(--texto-suave); font-size: 14px; }
.gate-prereq-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.gate-prereq-lista li {
    display: grid; gap: 6px; justify-items: start;
    padding: 14px 16px; border: 1px solid var(--borda); border-radius: 10px;
    background: var(--superficie-2);
}
.gate-prereq-lista strong { font-size: 14px; }
.gate-prereq-lista span { color: var(--texto-suave); font-size: 13px; line-height: 1.6; }
.gate-prereq-lista .btn { margin-top: 4px; }
@media (max-width: 640px) { .gate-prereq { padding: 16px 0; gap: 12px; } }

/* =========================================================================
   RECORTE DE IMAGEM — o overlay do enquadramento (pgfarma-inputs.js).
   z-index 1300 = acima de TUDO: o teto real é o lightbox de anexos (1200);
   os modais ficam bem abaixo (.modal-overlay 50 … aviso-entrada 70). Ele pode
   ser aberto de DENTRO de um modal (Cliente, ERP, usuário) e precisa cobri-lo.
   ========================================================================= */
.pg-recorte-fundo {
    position: fixed;
    inset: 0;
    z-index: 1300;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(0, 0, 0, .82);
}

.pg-recorte-caixa {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: min(92vw, 540px);
    padding: 20px;
    border-radius: var(--raio, 10px);
    background: var(--superficie);
    color: var(--texto);
    box-shadow: 0 18px 48px rgba(0, 0, 0, .38);
}

.pg-recorte-titulo { margin: 0; font-size: 16px; font-weight: 600; }
.pg-recorte-apoio { margin: 0; font-size: 13px; line-height: 1.5; color: var(--texto-suave); }

/* Fundo quadriculado: deixa VISÍVEL a transparência de um PNG de logo — sem
   ele, um logotipo branco em fundo branco parece uma imagem vazia. */
.pg-recorte-palco {
    display: flex;
    justify-content: center;
    padding: 10px;
    border-radius: 8px;
    background-color: var(--superficie-2);
    background-image:
        linear-gradient(45deg, rgba(128, 128, 128, .18) 25%, transparent 25%),
        linear-gradient(-45deg, rgba(128, 128, 128, .18) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, rgba(128, 128, 128, .18) 75%),
        linear-gradient(-45deg, transparent 75%, rgba(128, 128, 128, .18) 75%);
    background-size: 16px 16px;
    background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}

/* `touch-action: none` é o que permite ARRASTAR com o dedo: sem ele o navegador
   captura o gesto para rolar a página e o recorte não se move no celular.
   Sem `max-width`: o JS dimensiona o canvas a partir da largura REAL do palco
   (já anexado ao DOM), então ele sempre cabe — deixar o CSS encolher só a
   largura distorceria o recorte (largura limitada, altura fixa). */
.pg-recorte-tela {
    display: block;
    border-radius: 6px;
    cursor: grab;
    touch-action: none;
}
.pg-recorte-tela:active { cursor: grabbing; }

.pg-recorte-zoom { display: flex; align-items: center; gap: 10px; }
.pg-recorte-zoom input[type="range"] { flex: 1; }

.pg-recorte-acoes { display: flex; justify-content: flex-end; gap: 8px; }

@media (max-width: 640px) {
    .pg-recorte-caixa { padding: 14px; gap: 10px; }
    .pg-recorte-acoes .btn { flex: 1; }
}

/* ================= HUB de navegação (menu único → tiles → modal) ================= */
/* Cada menu longo virou 1 link (.menu-hub) que abre a página-HUB: uma grade de
   ATALHOS (.hub-tile). O tile abre a tela no modal (hx-select do miolo). */
.hub-grade {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 14px;
}
.hub-tile {
    display: flex; align-items: flex-start; gap: 14px;
    padding: 16px 18px;
    background: var(--superficie);
    border: 1px solid var(--borda);
    border-radius: var(--raio);
    box-shadow: var(--sombra-sm);
    text-decoration: none; color: inherit;
    transition: border-color .12s, box-shadow .12s, transform .05s;
}
.hub-tile:hover { border-color: var(--vermelho); box-shadow: var(--sombra); }
.hub-tile:active { transform: scale(.99); }
.hub-tile:focus-visible { outline: none; box-shadow: var(--anel-foco); }
.hub-tile-ic {
    flex: 0 0 44px; width: 44px; height: 44px; border-radius: 11px;
    background: var(--vermelho-suave); color: var(--vermelho);
    display: flex; align-items: center; justify-content: center;
}
.hub-tile-ic .icone { width: 22px; height: 22px; }
.hub-tile-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.hub-tile-tt { font-weight: 600; font-size: 15px; color: var(--texto); }
.hub-tile-ds { font-size: 13px; color: var(--texto-suave); line-height: 1.4; }
.hub-tile-ext { width: 13px; height: 13px; opacity: .6; vertical-align: -1px; }

/* O link do hub no menu = entrada de TOPO (como os grupos que ele substituiu). */
.menu-nav > .menu-hub { font-weight: 500; }

/* Risco fino separando os hubs (Financeiro/Registros/Configurações) dos grupos-drill
   acima. No menu recolhido (ícones), o traço encolhe junto com a barra. */
.menu-sep { height: 0; border: 0; border-top: 1px solid var(--borda); margin: 8px 12px; }
.app.menu-recolhido .menu-sep { margin: 8px 8px; }

/* Tela aberta DENTRO do modal (miolo .area-conteudo extraído): alarga a caixa
   para caber a tela; some o max-width padrão de 640px. */
.modal-caixa:has(.area-conteudo) { max-width: max(78vw, 1000px); }

/* === Conversa UNIFICADA da integração (leva do feed) — balões estilo WhatsApp === */
/* R46 — O FILTRO FICOU LEVE (texto, não pílula) e ganhou RÓTULO. Antes NADA na tela
   dizia o que aquelas seis palavras faziam — o rótulo é conserto de compreensão, não
   enfeite. Sem a classe `chip`, estas regras passam a definir o próprio tamanho/forma.
   ⚠️ `.conv-filtro` é o seletor que o `onclick` inline consulta
   (`querySelectorAll('.conv-filtro')`): o NOME é contrato, só a aparência mudou. */
.conv-filtros { display: flex; gap: 2px; flex-wrap: wrap; align-items: center; margin-bottom: 10px; }
.conv-filtros-rotulo { font-size: 11px; font-weight: 600; text-transform: uppercase;
    letter-spacing: .04em; color: var(--texto-suave); margin-right: 6px; }
.conv-filtro { cursor: pointer; border: 0; border-radius: var(--raio-sm); background: none;
    color: var(--texto-suave); font: inherit; font-size: 12px; font-weight: 600;
    padding: 3px 8px; white-space: nowrap; }
.conv-filtro:hover { color: var(--texto); background: var(--superficie-2); }
.conv-filtro-on { color: var(--bloco-cor-num, var(--info)); background: var(--bloco-cor-suave, var(--superficie-2)); }
.conversa { display: flex; flex-direction: column; gap: 8px; padding: 4px 0; }
.conv-item { display: flex; }
.conv-dentro { justify-content: flex-end; }
.conv-fora { justify-content: flex-start; }
.conv-balao { max-width: 80%; border-radius: 12px; padding: 8px 10px; border: 1px solid var(--borda); background: var(--superficie); }
.conv-dentro .conv-balao { border-bottom-right-radius: 3px; }
.conv-fora .conv-balao { background: var(--fundo-suave); border-bottom-left-radius: 3px; }
.conv-chip { font-size: 11px; color: var(--texto-suave); display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-bottom: 3px; }
.conv-chip strong { color: var(--texto); }
.conv-texto { white-space: pre-wrap; word-break: break-word; }
.conv-quando { font-size: 10px; color: var(--texto-suave); text-align: right; margin-top: 3px; }
.conv-sys { text-align: center; }
.conv-sys span { display: inline-block; background: var(--fundo-suave); color: var(--texto-suave); border-radius: 10px; padding: 2px 10px; font-size: 11px; }
.chip-cliente { background: var(--info); color: var(--texto-inverso); }
.conv-dica { font-size: 11px; margin: 6px 0; display: flex; gap: 4px; align-items: center; }
/* Filtro por fonte: data-conv-filtro fica na .bloco-feed (não trocada pelo polling). */
/* ⚠️ R46 — O `.conversa` NO MEIO NÃO É ENFEITE, É O CONSERTO DE UM VAZAMENTO.
   Estes seletores eram `.bloco-feed[data-conv-filtro=X] [data-fonte]…` — descendente
   QUALQUER. O LOG renderiza `<div class="log-item" data-fonte="...">`
   (`integracao/_log_integracao.html`) DENTRO da MESMA `<section class="bloco-feed">`,
   então filtrar a CONVERSA por "Esteira" escondia linhas do LOG também. Dava para
   ver: filtre, troque para a aba LOG, e metade dele sumiu. Com as abas subindo para o
   cabeçalho (R46) as duas coisas ficaram a um clique uma da outra. */
.bloco-feed[data-conv-filtro="esteira"] .conversa [data-fonte]:not([data-fonte="esteira"]),
.bloco-feed[data-conv-filtro="ticket"] .conversa [data-fonte]:not([data-fonte="ticket"]),
.bloco-feed[data-conv-filtro="sap"] .conversa [data-fonte]:not([data-fonte="sap"]),
.bloco-feed[data-conv-filtro="gp"] .conversa [data-fonte]:not([data-fonte="gp"]),
.bloco-feed[data-conv-filtro="cliente"] .conversa [data-cliente="0"] { display: none; }
/* Abas Conversa/LOG + itens do LOG */
/* R46 — AS ABAS SUBIRAM PARA O CABEÇALHO e deixaram de ser PÍLULA. A causa da
   confusão do dono era exatamente esta: `class="chip conv-aba"` e
   `class="chip conv-filtro"` — o MESMO componente para trabalhos opostos (a de cima
   TROCA o conteúdo, a de baixo FILTRA dentro dele). Aba sublinhada é a forma que diz
   "navegação"; a casa não tinha nenhuma reusável (medido), então nasce aqui.
   ⚠️ `.conv-abas`/`.conv-aba` são de UM template só (o bloco de conversa da
   Integração) — medido antes de reescrever. Os NOMES ficam: três asserções da suíte
   (`ativacao/tests_historico.py:272`, `ativacao/tests.py:683`) os afirmam literalmente. */
.conv-abas { display: flex; gap: 2px; align-items: stretch; margin: 0; padding: 0; border: 0; }
.conv-aba { cursor: pointer; border: 0; border-bottom: 2px solid transparent; border-radius: 0;
    background: none; color: var(--texto-suave); font: inherit; font-size: 13px; font-weight: 600;
    padding: 6px 10px; white-space: nowrap; }
.conv-aba:hover { color: var(--texto); }
.conv-aba-on { color: var(--bloco-cor-num); border-bottom-color: var(--bloco-cor); background: none; }

/* A LINHA do cabeçalho da conversa: alvo de recolher (compacto) + as abas.
   ⚠️ `.bloco-form-cab` é de 12 templates — ela é EMPRESTADA aqui, nunca alterada. O
   que muda é local: o PADDING sai dela e vai para os filhos, senão o botão interno o
   duplicaria. E como o contêiner virou `<div>`, o `:focus-visible` de `.bloco-form-cab`
   (que só dispara em elemento focável) precisa de um par no botão interno. */
.bloco-feed-cab { padding: 0; gap: 0; }
.bloco-feed-cab-alvo { display: flex; align-items: center; gap: 12px; flex: none; min-width: 0;
    padding: 14px 12px 14px 16px; margin: 0; background: none; border: 0;
    font: inherit; color: inherit; text-align: left; cursor: pointer; }
.bloco-feed-cab-alvo:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--bloco-cor); }
.bloco-feed-cab .bloco-form-titulo { flex: none; }
.bloco-feed-cab .conv-abas { align-self: flex-end; }
/* No tema escuro --info clareia (#60a5fa); força azul cheio p/ o texto branco manter contraste. */
:root[data-tema="escuro"] .conv-filtro-on,
:root[data-tema="escuro"] .conv-aba-on,
:root[data-tema="escuro"] .chip-cliente { background: #2563eb; }
.log-lista { display: flex; flex-direction: column; gap: 8px; padding: 4px 0; }
.log-item { border-left: 2px solid var(--borda); padding-left: 8px; }
.log-meta { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; font-size: 11px; color: var(--texto-suave); margin-bottom: 2px; }
.log-titulo { font-size: 13px; }
.log-detalhe { font-size: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   A BUSCA GLOBAL DO TOPO — o painel suspenso e a página de resultados.
   ⚠️ BLOCO PURAMENTE ADITIVO, no fim do arquivo de propósito: este CSS é
   DISPUTADO por vários agentes, e nenhuma regra existente foi tocada. O
   `.busca` (a caixa do campo) continua como estava — ele só virou um `<form>`
   dentro do `.busca-wrap`, que é quem ancora o painel.
   ⚠️ Cor SEMPRE por token do design system, para acompanhar o tema escuro
   sozinho. Nada de hex cru aqui.
   ═══════════════════════════════════════════════════════════════════════════ */
.busca-wrap { position: relative; flex: none; }
.busca-painel {
    position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
    width: 360px; max-width: 90vw; max-height: 70vh; overflow-y: auto;
    background: var(--superficie); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); box-shadow: var(--sombra);
}
.busca-painel:empty { display: none; }
.busca-painel-caixa { padding: 8px 0; }
.busca-painel-tudo {
    display: block; padding: 8px 14px; border-top: 1px solid var(--borda);
    font-size: 12px; color: var(--texto-rotulo); text-decoration: none;
}
.busca-painel-tudo:hover { background: var(--superficie-2); color: var(--texto); }
.busca-grupo + .busca-grupo { margin-top: 6px; }
.busca-grupo-tt {
    margin: 0; padding: 4px 14px; font-size: 11px; font-weight: 600;
    text-transform: uppercase; letter-spacing: 0.4px; color: var(--texto-suave);
}
.busca-lista { list-style: none; margin: 0; padding: 0; }
.busca-item a, .busca-item-sem-link {
    display: block; padding: 6px 14px; font-size: 13px;
    /* ⚠️ `color: inherit` NÃO basta aqui: o padrão do <a> é a cor de link do
       navegador, e a casa já perdeu texto no modo escuro por isso. Token. */
    color: var(--texto); text-decoration: none;
}
.busca-item a:hover { background: var(--superficie-2); }
.busca-item-sem-link { color: var(--texto-suave); cursor: default; }
.busca-vazio { margin: 0; padding: 10px 14px; font-size: 12.5px; color: var(--texto-suave); }
/* A PÁGINA de resultados usa o mesmo miolo, com respiro de página. */
.busca-pagina { background: var(--superficie); border: 1px solid var(--borda);
    border-radius: var(--raio-sm); padding: 10px 0; }
.busca-pagina .busca-grupo-tt { padding-left: 18px; }
.busca-pagina .busca-item a, .busca-pagina .busca-item-sem-link { padding-left: 18px; }
