:root {
  /* ★★ v12 (QA Layout Comercial V2, grupo 5): A PALETA DA MARCA, num lugar so.

     ★ Duas das quatro JA existiam com o valor exato — o coral (`--cor-laranja`)
     e o azul. Faltavam o grafite e o azul suave, acrescentados abaixo.

     ★★ E O CONTRASTE FOI MEDIDO, porque a instrucao mandava parar se algum
     par ficasse ilegivel (WCAG: 4.5 para texto normal, 3.0 para texto grande):

       grafite #2F3943     branco 11.75  fundo 10.95   OK para texto
       azul    #094C85     branco  8.81  fundo  8.21   OK para texto
       azul suave #749BBD  branco  2.93  fundo  2.73   ★ NAO serve para texto
       coral   #ED6D5F     branco  3.02  fundo  2.82   ★ so texto GRANDE

     ★ Por isso o azul suave e o coral ficam para BORDA, FUNDO e ICONE — e
     para texto grande no caso do coral. Usar qualquer um deles em texto
     pequeno deixaria a tela ilegivel, e a instrucao pedia para relatar em vez
     de escolher outro tom por conta propria. Esta relatado. */
  --cor-laranja: #ED6D5F;   /* coral da marca: alertas, pendencias, acao */
  --cor-azul: #094C85;      /* azul: destaques fortes */
  --cor-azul-suave: #749BBD;  /* ★ destaques medianos — borda/fundo/icone */
  --cor-grafite: #2F3943;   /* ★ texto, no lugar do preto */
  /* ★★ v12 (decisao do Guto): OS TONS DE TEXTO da paleta, medidos.

     O coral e o azul suave servem para FUNDO, ICONE, BORDA e SEPARADOR. Para
     TEXTO sobre fundo claro eles nao passam o contraste, e a regra e' usar uma
     variacao mais escura da MESMA cor.

     ★ O tom foi escolhido medindo os TRES fundos em que o texto aparece, nao
     dois — e foi o terceiro que decidiu:

       #C43D2C  sobre branco  #FFFFFF  5.18   OK
                sobre cinza   #F6F7F8  4.83   OK
                sobre rosa    #FDEDEA  4.56   OK  ★ e' este que exclui o #C9412F

     ★ O #C9412F daria 4.91 no branco e so 4.32 no rosa — reprovado. E o coral
     de hoje (#ED6D5F) dava ★ 2.66 no rosa: era o chip, o badge e o selo de
     salvamento, todos ilegiveis pela regra, e ninguem tinha medido.

     ★ #C0392B ficou de fora de proposito: ele JA E' --cor-status-bloqueada, e
     reusar o hex confundiria cor de MARCA com cor de FUNCAO. */
  --cor-coral-texto: #C43D2C;
  --cor-azul-suave-texto: #4A7699;  /* branco 4.84 | cinza 4.51 */
  /* ★★ v12 (DECISAO do Guto): O CORAL ESCURO, para FUNDO com texto CLARO.

     Branco sobre o coral da marca da ★ 3,02:1 — serve para texto GRANDE
     (>=18,66px bold) e nao para um badge de 0.72rem (~11,5px). A decisao foi
     escurecer o FUNDO ate o branco passar de 4,5.

     ★ MESMA FAMILIA, e isto foi medido em HSL, nao a olho:
       coral da marca  #ED6D5F = HSL(6°, 80%, 65%)
       ★ coral escuro  #D82B18 = HSL(6°, 80%, 47%)
     Mesmo matiz, mesma saturacao, 18 pontos de luminosidade. E' a mesma cor
     mais escura, nao outra cor.

     ★ Branco sobre #D82B18 = 4,91:1. O limite era #E12D19 (4,57), mais
     parecido com o coral mas com margem minima — preferi a margem.

     ★★ So os TRES lugares de fundo CORAL com texto claro usam este tom. Os
     ONZE de fundo AZUL ficam como estao: branco sobre #094C85 da 8,81 e ja
     passa. Trocar o que ja passa seria mexer sem medir. */
  --cor-coral-escuro: #D82B18;
  --cor-cinza: #575756;
  --cor-fundo: #F6F7F8;
  /* ★ v13: largura do ✕ da norma — usada tambem como espaco reservado na
     linha do item, para as duas colunas de seletor alinharem. */
  --largura-remover-norma: 20px;
  --cor-branco: #FFFFFF;
  --cor-borda: #E1E4E8;
  --cor-laranja-suave: #FDEDEA;
  --cor-verde: #237A47;  /* C1: era #2E8B57 (4,25 como texto); o verde aprovado */
  --cor-verde-suave: #E7F4EC;
  --cor-neutro-suave: #ECEEF0;
  /* ★ A2 (AJUSTES_TELA_FASE_B): a linha SOB O MOUSE nas listas de item (caixa +
     seletor por linha). Cinza-azulado claro: diferente do roxo da caixa marcada
     (que é a cor de destaque do sistema operacional — `accent-color: auto`, medido)
     e sem reusar hex de cor de FUNÇÃO. Grafite sobre ele: 10,4. */
  --cor-linha-sob-mouse: #EDF2F7;
  /* Cores dos badges de status da tarefa (5.2) — deliberadamente separadas dos
     tokens acima (chips/realces existentes) para não afetar outros usos. */
  --cor-status-bloqueada: #C0392B;
  --cor-status-bloqueada-suave: #FBEAE8;
  --cor-status-pendente: #575756;  /* C1: era #6B6E72 (4,41 no fundo do selo) */
  --cor-status-pendente-suave: #ECEEF0;
  --cor-status-avaliado: #094C85;
  --cor-status-avaliado-suave: #E5EDF5;
  --cor-status-concluida: #237A47;  /* C1: era #2E9E5B (3,02 no fundo do selo) */
  --cor-status-concluida-suave: #E5F5EC;
  /* v26 (INSTRUCAO_CC_kanban_fase2): único tom novo — âmbar sóbrio, pro
     follow-up "hoje"/ícone Perder/termômetro Morno (nada chamativo,
     mesmo espírito dos outros tons já definidos acima). */
  --cor-amarelo: var(--cor-atencao);  /* C1: era #C98A1F (2,94 como texto) */
  --cor-amarelo-suave: #FBF1DE;
  /* v26 (INSTRUCAO_CC_kanban_fase3): ícone "Cancelar" muda de cinza pra
     roxo (nova escala: verde Contratar / âmbar Perder / roxo Cancelar). */
  --cor-roxo: #6B4E9E;
  /* ★★ (20/10/2026, QA-009 acréscimo 2, cores aprovadas pelo Guto) o termômetro do Calor: Frio azul claro,
     Morno amarelo-âmbar, Quente laranja, Muito quente vermelho. Contraste com o branco (ícone, ≥ 3:1):
     3,85 · 3,27 · 3,91 · 5,44. ★ Tokens PRÓPRIOS: o Muito quente coincide com `--cor-status-bloqueada`
     (#C0392B), mas é cor de nível, não de estado — trocar um não pode trocar o outro. */
  --cor-calor-frio: #2F86D1;
  --cor-calor-morno: #B98500;
  --cor-calor-quente: #D25F00;
  --cor-calor-muito-quente: #C0392B;
  /* v27 (INSTRUCAO_CC_finalizacao_arquivamento, decisão 8): "suave" pro
     badge de LinhaFluxoFinanceiro.Status.CANCELADO — mesmo padrão claro/
     escuro dos outros `--cor-status-*-suave` acima; reaproveita `--cor-
     roxo` (já é "roxo = Cancelar" nesta escala, ver comentário acima —
     bate exatamente com o pedido da instrução). */
  --cor-roxo-suave: #EFEAF7;
  --fonte-titulo: 'Montserrat', 'Segoe UI', Arial, sans-serif;
  --fonte-texto: 'Inter', system-ui, 'Segoe UI', Roboto, Arial, sans-serif;
  /* ★★★ C1 (Fase C, paleta aprovada na amostra da marca — 01/10/2026).

     ATENÇÃO × ERRO, variante A: a atenção é ÂMBAR ESCURO, o erro é VERMELHO, e
     o CORAL fica só como cor de DESTAQUE da marca (item ativo do menu, aba
     ativa, contadores de "não visto", Sair, delegação ativa). Antes da C1 o
     coral fazia as duas coisas — alerta e marca —, e com o vermelho de erro no
     mesmo matiz (6°) atenção e erro se confundiam.

       --cor-atencao   #8F5E10  sobre o âmbar claro 4,96 · branco 5,56
       --cor-erro      #C0392B  (= bloqueada) sobre o rosa 4,67 · branco 5,44
       sucesso         #237A47  sobre o verde claro 4,71
       pendente        #575756  sobre o cinza claro 6,22

     ★ Medidos na amostra da marca (fora do ar desde a C4), no navegador. ★ Isto é
     a régua de HOJE (aprovação do Guto):
     o `smoke_c1_base_visual` a confere nas telas — quem mudar a régua muda lá. */
  --cor-atencao: #8F5E10;
  --cor-atencao-suave: #FBF1DE;
  --cor-erro: var(--cor-status-bloqueada);
  --cor-erro-suave: var(--cor-status-bloqueada-suave);
  /* a borda de CAMPO (input/select/textarea) — mais escura que a de cartão
     (--cor-borda, 1,3 no branco), para o campo se ver como campo */
  --cor-borda-campo: #C9D2DC;
  --raio: 10px;
  --sombra: 0 1px 3px rgba(9, 76, 133, 0.08), 0 1px 2px rgba(9, 76, 133, 0.06);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--fonte-texto);
  color: var(--cor-cinza);
  background: var(--cor-fundo);
}

h1, h2, h3, .marca {
  font-family: var(--fonte-titulo);
  color: var(--cor-azul);
}

a {
  color: var(--cor-azul);
}

.app-shell {
  display: grid;
  /* v23, item 4.3: reduzida de 220px — referência é a largura do logo/
     wordmark "MODERACON" no topbar, os itens de nav não precisavam de
     220px. Libera espaço pra coluna Tarefa da tabela de tarefas absorver
     (ver .th-tarefa/.celula-editavel abaixo). Mexeu aqui? `.barra-lote`
     tem `left` hardcoded a partir desta largura + padding do .main.
     v27 (INSTRUCAO_CC_lote6, ML1): reduzida de novo, de 168px pra 64px —
     a sidebar virou uma barra só de ícones (o rótulo/itens de cada
     seção agora vivem no submenu flutuante, que não ocupa espaço fixo
     no grid). Mexeu aqui de novo? `.barra-lote` (mesmo aviso de cima)
     precisa do valor atualizado também. */
  grid-template-columns: 64px 1fr;
  grid-template-rows: 56px 1fr;
  grid-template-areas:
    "topbar topbar"
    "sidebar main";
  min-height: 100vh;
}

.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  background: var(--cor-branco);
  border-bottom: 1px solid var(--cor-borda);
}

.topbar .marca {
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.04em;
}

.topbar .usuario {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 0.9rem;
}

.topbar .usuario form {
  margin: 0;
}

.topbar .usuario button {
  background: none;
  border: none;
  color: var(--cor-coral-texto);
  font-family: var(--fonte-texto);
  font-size: 0.9rem;
  cursor: pointer;
  padding: 0;
}

/* v27 (INSTRUCAO_CC_lote6, ML1): sidebar virou uma barra estreita só de
   ícones (era uma lista de texto — ver `.app-shell` acima, largura da
   coluna também mudou). `overflow: visible` é necessário — o submenu
   flutuante (`.sidebar-submenu`) precisa "vazar" pra fora da barra. */
.sidebar {
  grid-area: sidebar;
  background: var(--cor-branco);
  border-right: 1px solid var(--cor-borda);
  padding: 12px 0;
  overflow: visible;
  /* ★ ESTE `z-index` É O QUE MANTÉM O SUBMENU POR CIMA DO CONTEÚDO, e ele
     precisa estar AQUI, na barra, e não no submenu.

     `position: sticky` (ver o @media abaixo) SEMPRE cria contexto de
     empilhamento, mesmo com `z-index: auto` — diferente de `relative` e
     `absolute`, que só criam quando têm z-index. Quando a barra virou
     sticky, o `z-index: 20` do `.sidebar-submenu` passou a valer só DENTRO
     dela, e a barra inteira foi competir na raiz como `auto`: ordem de DOM.
     Como o `<aside>` vem antes do `<main>`, qualquer coisa do conteúdo com
     z-index positivo passou a cobrir o menu — inclusive o `thead` das
     tabelas (1) e as colunas congeladas (3).

     Subir o número DO SUBMENU não resolveria: preso no contexto da barra,
     ele pode ser 9999 que continua abaixo. Quem tem que subir é a barra.

     60 porque precisa passar do maior do conteúdo (`.barra-lote`, 50) e
     ficar abaixo do modal (100), que DEVE cobrir o menu. O smoke
     `smoke_empilhamento` guarda esses dois limites.

     Fora do @media de propósito: `.sidebar` é item de grid, e z-index vale
     em item de grid mesmo sem `position` — assim o empilhamento é o mesmo
     com a barra sticky ou não, em vez de mudar com a altura da janela. */
  z-index: 60;
}

/* v27 — o menu ACOMPANHA a rolagem, em telas que o comportem.

   O PROBLEMA: a `.topbar` e a `.sidebar` rolam junto com a página (nenhuma
   das duas tem `position`), então numa tela longa — o Relatório de Mercado
   tem onze gráficos — o menu sai de vista e trocar de módulo obriga a
   voltar ao topo.

   `sticky` E NÃO `fixed`, e não é preferência: a `.sidebar` é item de um
   grid de duas colunas (`64px 1fr`). Tirá-la do fluxo com `fixed`
   colapsaria a coluna e obrigaria a recalcular a largura em dois lugares,
   incluindo o `left` cravado em `.barra-lote` — que o comentário do
   `.app-shell` já avisa que depende deste valor.

   `top: 0` porque a `.topbar` também rola: quando ela sai, o menu tem que
   grudar no topo da viewport, não 56px abaixo dele.

   `align-self: start` é OBRIGATÓRIO. Item de grid estica até a altura da
   linha por padrão, e um elemento tão alto quanto o container nunca gruda —
   é a razão mais comum de `sticky` "não funcionar" e não dar erro nenhum.

   `min-height` porque `align-self: start` encolhe o elemento até o conteúdo
   (440px) e a `border-right` pararia ali, deixando o resto da página sem o
   divisor. Uma viewport de altura mantém a borda cobrindo o que se vê,
   sempre.

   ★ A MEDIA QUERY POR ALTURA é o ponto todo desta regra.

   O menu tem 8 ícones de 52px mais 24px de padding = 440px; com a topbar de
   56px, ele só cabe inteiro a partir de 496px de viewport. Fixo abaixo
   disso, os dois últimos ícones — Certificação e Relatório — ficariam fora
   do alcance, sem rolagem que os trouxesse.

   E NÃO DÁ pra resolver com `overflow-y: auto`: o `overflow: visible` acima
   existe porque o submenu flutuante precisa vazar pra fora da barra.
   Qualquer overflow que permita rolagem corta os submenus — troca um
   problema por outro pior, porque submenu cortado não tem sintoma óbvio.

   Por isso o `sticky` é CONDICIONAL. Abaixo de 520px (os 496 medidos, com
   folga) o menu volta a rolar com a página, como sempre foi: nada preso,
   nada cortado, tudo alcançável. A degradação é para o comportamento
   anterior, que funciona.

   Não é cenário de laboratório: num notebook de 768px com zoom em 150%, a
   viewport cai pra ~412px depois do chrome do navegador.

   MEXEU NO NÚMERO DE ÍCONES DO MENU? O `min-height` da media query tem que
   subir junto: cada ícone novo são 52px. */
@media (min-height: 520px) {
  .sidebar {
    position: sticky;
    top: 0;
    align-self: start;
    min-height: calc(100vh - 56px);
  }
}

.sidebar-icones {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sidebar-item {
  position: relative;
}

.sidebar-icone {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 52px;
  color: var(--cor-cinza);
  cursor: pointer;
  border-left: 3px solid transparent;
  position: relative;
}

.sidebar-icone svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sidebar-item:hover .sidebar-icone,
.sidebar-item:focus-within .sidebar-icone {
  background: var(--cor-fundo);
  color: var(--cor-azul);
}

.sidebar-item--ativa .sidebar-icone {
  border-left-color: var(--cor-laranja);
  color: var(--cor-azul);
  background: var(--cor-fundo);
}

.sidebar-item--desabilitada .sidebar-icone {
  color: #B0B4B8;
  cursor: default;
}

/* v27 (lote6, ML1): submenu flutuante — some por padrão (opacity/
   visibility, não `display`, pra permitir transição e pra
   `:focus-within` no `.sidebar-item` continuar enxergando o conteúdo)
   e aparece ao passar o mouse ou focar (Tab) em qualquer parte da
   seção. `left: 100%` encosta na borda direita da barra de ícones. */
.sidebar-submenu {
  position: absolute;
  top: 0;
  left: 100%;
  min-width: 200px;
  background: var(--cor-branco);
  border: 1px solid var(--cor-borda);
  border-radius: 0 6px 6px 0;
  box-shadow: var(--sombra);
  padding: 8px 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s ease;
  z-index: 20;
}

.sidebar-item:hover .sidebar-submenu,
.sidebar-item:focus-within .sidebar-submenu {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.sidebar-submenu__titulo {
  display: block;
  padding: 4px 20px 8px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--cor-cinza);
}

.sidebar-submenu a,
.sidebar-submenu .item-desabilitado {
  display: block;
  padding: 8px 20px;
  font-size: 0.92rem;
  text-decoration: none;
  color: var(--cor-cinza);
  white-space: nowrap;
}

.sidebar-submenu a:hover {
  background: var(--cor-fundo);
  color: var(--cor-azul);
}

.sidebar-submenu a.ativo {
  color: var(--cor-azul);
  font-weight: 600;
  background: var(--cor-fundo);
}

.sidebar-submenu .item-desabilitado {
  color: #B0B4B8;
  cursor: default;
}

/* v27 (lote6, ML1): círculo vermelho sobreposto no ÍCONE (Gestão/
   Financeiro) — mesma contagem de `.menu-badge`, só que aqui precisa
   ficar visível SEM abrir o submenu, então é um círculo pequeno preso
   no canto do ícone, não uma pílula ao lado de um rótulo. Vermelho
   (não a cor laranja de destaque já usada em `.menu-badge`/item ativo)
   porque aqui ele compete visualmente com o próprio ícone — precisa
   destacar mais, mesmo padrão "notificação" de badge de app. */
.sidebar-badge {
  position: absolute;
  top: 4px;
  right: 10px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #C0392B;
  color: var(--cor-branco);
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

/* v27 (INSTRUCAO_CC_lote2_telas_invoice_fluxo, F2): badge de contagem
   "Fluxo (N)"/"Processos (N)" — só aparece quando há item novo (o
   template já esconde em 0), mesma cor de destaque já usada no item de
   menu ATIVO (`--cor-laranja`), pra chamar atenção sem introduzir uma
   cor nova ao sistema. Usado DENTRO do submenu (`.sidebar-submenu`),
   ao lado do rótulo — ver `.sidebar-badge` acima pro círculo que fica
   sobreposto no ícone (fora do submenu).
   v27 (lote6, ML1): antes vivia direto em `.sidebar nav a`; agora
   dentro de `.sidebar-submenu a` (ver regra acima).  */
.menu-badge {
  display: inline-block;
  min-width: 18px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--cor-coral-escuro);
  color: var(--cor-branco);
  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;
  line-height: 1.4;
}

/* v27 (lote6, ML1): ícone de "Configuração" na topbar (era um link de
   texto na sidebar) — mesmo padrão visual de `.icone-campo` (círculo,
   opacidade 0.5 -> 1 no hover), cor herdada do texto/laranja do botão
   "Sair" ao lado. */
.topbar-icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  color: var(--cor-cinza);
  opacity: 0.6;
}

.topbar-icone:hover {
  opacity: 1;
  background: var(--cor-fundo);
  color: var(--cor-azul);
}

.topbar-icone svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* v27 (INSTRUCAO_CC_permissao_edicao): toggle "delegar meus projetos"
   na topbar — pill discreta, ganha cor/negrito só quando ATIVA (mesmo
   princípio visual do resto da topbar: item neutro até virar relevante). */
.topbar-delegacao {
  background: none;
  border: 1px solid var(--cor-borda);
  border-radius: 999px;
  padding: 3px 10px;
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  color: var(--cor-cinza);
  cursor: pointer;
}

.topbar-delegacao:hover {
  border-color: var(--cor-azul);
  color: var(--cor-azul);
}

.topbar-delegacao--ativa {
  border-color: var(--cor-laranja);
  color: var(--cor-coral-texto);
  font-weight: 600;
}

.main {
  grid-area: main;
  padding: 28px 32px;
  /* v27 (INSTRUCAO_CC_lote6, GB1): "grid blowout" clássico do CSS — um
     item de grid tem `min-width: auto` por padrão, ou seja, NUNCA
     encolhe abaixo do conteúdo intrínseco de dentro dele, mesmo que
     esse conteúdo já tenha seu próprio `overflow-x: auto` (ex.:
     `.tabela-tarefas-container`, que rolaria internamente sozinha se
     pudesse). Sem isto, uma tabela larga o bastante empurra `.main`
     (e com ele `.app-shell`/`.topbar`) pra além da viewport inteira —
     bug pré-existente, só ficou visível agora porque o cabeçalho fixo
     da Tela B (o cartão antigo, sticky) tem um botão posicionado
     `absolute` na borda direita do cartão, que saía de vista quando a
     página inteira "estourava" a largura. */
  min-width: 0;
}

.cartao {
  background: var(--cor-branco);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  padding: 20px 24px;
}

.filtros {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 20px;
}

.filtros input, .filtros select {
  font-family: var(--fonte-texto);
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 0.9rem;
  background: var(--cor-branco);
  color: var(--cor-cinza);
}

.filtros input[type="text"] {
  min-width: 220px;
}

.filtros button {
  font-family: var(--fonte-texto);
  border: none;
  border-radius: 6px;
  padding: 8px 16px;
  background: var(--cor-azul);
  color: var(--cor-branco);
  cursor: pointer;
  font-size: 0.9rem;
}

table.tabela-gestao {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

table.tabela-gestao th {
  text-align: left;
  font-family: var(--fonte-texto);
  font-weight: 600;
  color: var(--cor-cinza);
  background: var(--cor-fundo);
  padding: 10px 12px;
  border-bottom: 2px solid var(--cor-borda);
  white-space: nowrap;
  font-size: 0.78rem;
}

table.tabela-gestao td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--cor-borda);
  vertical-align: middle;
}

table.tabela-gestao tbody tr {
  cursor: pointer;
}

table.tabela-gestao tbody tr:hover {
  background: var(--cor-fundo);
}

table.tabela-gestao tbody tr.linha-vazia:hover {
  background: none;
  cursor: default;
}

/* v27 (INSTRUCAO_CC_lote2_telas_invoice_fluxo, F2): item novo/não visto
   (fluxo_lista.html e gestao_lista.html) — negrito, mesmo estilo
   "e-mail não lido"; some sozinho na próxima visita (a view marca
   visto ao abrir o detalhe). */
table.tabela-gestao tbody tr.linha-nao-vista td {
  font-weight: 700;
}

/* v27 (INSTRUCAO_CC_cadastro_proprio, Parte A): Cliente/Fabricante/
   Fornecedor arquivado — esmaecido na lista, mesmo espírito de "não
   some, só fica discreto" que o resto do app já usa pra arquivamento. */
table.tabela-gestao tbody tr.linha-arquivada td {
  color: var(--cor-cinza);
  font-style: italic;
}

.barra-progresso {
  width: 90px;
  height: 6px;
  background: var(--cor-borda);
  border-radius: 4px;
  overflow: hidden;
  display: inline-block;
  vertical-align: middle;
  margin-right: 8px;
}

.barra-progresso__preenchida {
  display: block;
  height: 100%;
  width: 0;
  background: var(--cor-azul);
  transition: width 300ms ease, background-color 300ms ease;
}

.barra-progresso__preenchida--completa {
  background: #2E9E5B;
}

.pendencia {
  color: var(--cor-atencao);
  font-weight: 600;
}

.pendencia-zero {
  color: var(--cor-cinza);
  opacity: 0.6;
}

.badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  background: var(--cor-fundo);
  color: var(--cor-cinza);
}

.cabecalho-produto {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  margin-bottom: 24px;
}

.cabecalho-produto dt {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--cor-cinza);
  opacity: 0.7;
  margin-bottom: 2px;
}

.cabecalho-produto dd {
  margin: 0;
  font-size: 0.95rem;
  color: var(--cor-azul);
  font-weight: 600;
}

.aviso-construcao {
  padding: 40px;
  text-align: center;
  color: var(--cor-cinza);
  opacity: 0.8;
}

/* Linha expansível da Tela A */
.celula-chevron {
  width: 28px;
  text-align: center;
}

.chevron {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1rem;
  color: var(--cor-azul);
  display: inline-block;
  transition: transform 0.15s ease;
  padding: 2px 6px;
}

.chevron--aberto {
  transform: rotate(90deg);
}

.linha-detalhe td {
  background: var(--cor-fundo);
  padding: 0;
}

.conteudo-expandido {
  padding: 16px 20px;
}

/* Bloco de fornecedores (OC / LAB), reutilizado na Tela A e Tela B */
.bloco-fornecedores {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
}

.bloco-fornecedores h4 {
  margin: 0 0 8px;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--cor-cinza);
  opacity: 0.8;
}

.bloco-fornecedores p {
  margin: 0 0 6px;
  font-size: 0.88rem;
}

.bloco-fornecedor__nome {
  font-weight: 600;
  color: var(--cor-azul);
}

.bloco-lab-item {
  padding-bottom: 14px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--cor-borda);
}

.bloco-lab-item:last-child {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

/* Chips de Normas/Atos (Tela B) */
.chip {
  display: inline-block;
  border: none;
  border-radius: 999px;
  padding: 3px 10px;
  margin: 2px 4px 2px 0;
  font-size: 0.78rem;
  font-family: var(--fonte-texto);
  font-weight: 600;
  cursor: pointer;
  background: var(--cor-neutro-suave);
  color: var(--cor-cinza);
}

.chip--verde {
  background: var(--cor-verde-suave);
  color: var(--cor-verde);
}

.chip--laranja {
  background: var(--cor-erro-suave);
  color: var(--cor-erro);
}

.painel-norma {
  margin: 8px 0;
  padding: 10px 12px;
  background: var(--cor-branco);
  border: 1px solid var(--cor-borda);
  border-radius: 8px;
}

.item-ensaio {
  display: flex;
  gap: 16px;
  padding: 4px 0;
  font-size: 0.85rem;
}

.item-ensaio__nome {
  flex: 1;
}

.badge--pendente {
  background: var(--cor-neutro-suave);
  color: var(--cor-cinza);
}

.badge--em_andamento {
  background: var(--cor-status-avaliado-suave);
  color: var(--cor-status-avaliado);
}

.badge--aprovado {
  background: var(--cor-verde-suave);
  color: var(--cor-verde);
}

.badge--reprovado {
  background: var(--cor-erro-suave);
  color: var(--cor-erro);
}

/* ★★ AS REGRAS DO CARTAO ANTIGO DA TELA B FORAM REMOVIDAS (v11).

   A classe saiu dos templates no commit a956079 ("QA-006 v10, item 1:
   cabecalho unificado") e as regras ficaram. Varredura antes de apagar:
   ZERO ocorrencias da classe em .html, .py e .js de `core/`,
   `services/` e `config/` — so aqui.

   ★ O que existe hoje e' `.cabecalho-gestao` (com `id="cabecalho-gestao"`).
   Este bloco era o cartao ANTIGO da Tela B, com o botao absoluto
   "Envio ao contratante".

   ★ E esta nota NAO escreve o nome da classe de proposito: escrever o
   literal aqui faria a proxima varredura casar com o texto que explica a
   remocao e concluir que a classe ainda esta em uso. Ja aconteceu neste
   projeto, com credencial.

   ★ Achado de tabela: um smoke procurava a classe velha no HTML, nao a
   achava (`find` devolvia -1) e ficava vermelho num codigo certo. CSS morto
   nao quebra tela, mas alimenta teste que mede o passado. */


.linha-compacta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  font-size: 0.82rem;
  color: var(--cor-cinza);
  padding: 6px 0;
  border-top: 1px solid var(--cor-borda);
}

.linha-compacta strong {
  color: var(--cor-azul);
}

/* v24, item 3.5: separador mais forte que "·" entre blocos de laboratório
   (2+ labs deixavam ambíguo a quem pertencia o "REL: <data>" do último). */
.linha-labs__bloco + .linha-labs__bloco {
  padding-left: 10px;
  border-left: 1px solid var(--cor-borda);
}

.campo-ch {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.input-ch {
  font-family: var(--fonte-texto);
  font-size: 0.82rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 2px 6px;
  width: 150px;
}

.botao-detalhes {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--cor-azul);
  font-family: var(--fonte-texto);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 6px;
}

.detalhes-labs {
  padding-top: 12px;
}

.detalhes-labs .bloco-lab-item {
  padding: 8px 0;
}

.detalhes-labs p {
  margin: 0 0 4px;
  font-size: 0.85rem;
}

/* v27 (INSTRUCAO_CC_finalizacao_arquivamento, §5): read-only genérico —
   aplicada em `#dados-processo`/`#tabela-tarefas` (elemento raiz de cada
   hx-target, ver os templates) quando `Produto.gestao_arquivada`.
   `pointer-events: none` desliga clique/foco em TODO input/select/botão
   descendente numa tacada só, sem precisar de `{% if %}` campo a campo —
   texto continua 100% legível (sem opacidade reduzida), só deixa de ser
   clicável. O back-end (`bloqueado_se_gestao_arquivada`, core/
   decorators.py) é quem garante de verdade — isto é só a camada visual. */
.arquivado-somente-leitura {
  pointer-events: none;
}

/* Tabela de tarefas (Tela B, Parte 8) */
.tabela-tarefas-container {

  margin-top: 20px;
  /* v23, item 4.3: rede de segurança — num caso extremo (nome de tarefa
     muito comprido + todas as colunas em nowrap), a tabela cresce mais que
     a viewport; rola na horizontal em vez de quebrar a linha em duas
     alturas ou truncar o nome. */
  overflow-x: auto;
}

/* v10b, item 3: o <h2>Tarefas</h2> saiu do topo (a aba já diz isso), e
   com ele o primeiro filho deste `space-between`. Sem a troca por
   `flex-end` os botões iriam para a esquerda — o título não era só
   texto, era o contrapeso do layout. A regra do h2 saiu junto por não
   ter mais nenhum elemento para casar. */
.tabela-tarefas__topo {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-bottom: 16px;
}

/* v27 (INSTRUCAO_CC_lote6, GB3): agrupa "Lista de Tarefas" + "Gerar
   tarefas do serviço" — sem isto, `justify-content: space-between` do
   `.tabela-tarefas__topo` (3 filhos agora, era 2) deixaria o botão do
   meio "flutuando" sozinho longe dos outros 2. */
.tabela-tarefas__topo-acoes {
  display: flex;
  align-items: center;
  gap: 10px;
}

.botao-gerar-tarefas {
  background: var(--cor-azul);
  color: var(--cor-branco);
  border: none;
  border-radius: 6px;
  padding: 8px 16px;
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.aviso-geracao {
  background: var(--cor-verde-suave);
  color: var(--cor-verde);
  padding: 8px 12px;
  border-radius: 6px;
  font-size: 0.85rem;
  margin-bottom: 10px;
}

.aviso-geracao--alerta {
  background: var(--cor-atencao-suave);
  border-left: 4px solid var(--cor-atencao);
  color: var(--cor-atencao);
}

.secao-tarefas {
  margin-bottom: 28px;
}

/* "Etapa inicial" recolhível (v15.1, item 7) — tarefas gerais de Testes. */
.etapa-inicial__cabecalho {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 0;
  margin-bottom: 4px;
  font-family: var(--fonte-texto);
}

.etapa-inicial__seta {
  color: var(--cor-azul);
  font-size: 0.8rem;
}

.etapa-inicial__titulo {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--cor-cinza);
}

.etapa-inicial__resumo {
  font-size: 0.8rem;
  color: var(--cor-verde);
}

.secao-tarefas__resumo-linha {
  margin: -4px 0 8px;
}

.grupo-resumo-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px 0;
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--cor-verde);
}

.grupo-resumo-link__seta {
  color: var(--cor-azul);
  font-size: 0.75rem;
}

.secao-tarefas__cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.secao-tarefas__cabecalho h3 {
  margin: 0;
  font-family: var(--fonte-titulo);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--cor-azul);
}

.secao-tarefas__vazio {
  color: var(--cor-cinza);
  opacity: 0.6;
  font-size: 0.85rem;
  font-style: italic;
}

.botao-nova-tarefa {
  background: none;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 4px 10px;
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  color: var(--cor-azul);
  cursor: pointer;
}

.tabela-tarefas {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.tabela-tarefas th {
  text-align: left;
  font-family: var(--fonte-texto);
  font-weight: 600;
  color: var(--cor-cinza);
  background: var(--cor-fundo);
  padding: 8px 10px;
  border-bottom: 2px solid var(--cor-borda);
  font-size: 0.78rem;
}

.tabela-tarefas td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--cor-borda);
  vertical-align: middle;
}

.linha-atrasada {
  background: var(--cor-atencao-suave);
}

.badge-idioma {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  border: 1px solid var(--cor-borda);
  background: var(--cor-neutro-suave);
  color: var(--cor-cinza);
  font-size: 0.7rem;
  font-weight: 700;
  cursor: pointer;
}

.select-status {
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  border: 1px solid var(--cor-borda-campo);
  border-radius: 13px;
  padding: 3px 18px 3px 4px;
  /* v25 §3.1: largura fixa (maior rótulo, "Bloqueada", + seta + respiro) —
     antes o <select> sobrava espaço morto à direita; o ganho vira espaço
     pra coluna Tarefa. text-align-last é o que centraliza de verdade o
     valor exibido de um <select> (text-align sozinho não é respeitado
     nesse elemento em todos os navegadores). */
  width: 100px;
  text-align: center;
  text-align-last: center;
  /* appearance:none: alguns navegadores/temas de SO ignoram parte do
     background/color custom de <select> quando mantêm o "chrome" nativo do
     controle — isso fazia o badge "Avaliado" (e os demais) saírem neutros
     em vez da cor definida abaixo. Com appearance:none o browser sempre
     respeita nosso background/color; a seta é redesenhada via background-image. */
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 9px top 55%, right 5px top 55%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
}

.celula-data {
  cursor: pointer;
  white-space: nowrap;
  /* v24, item 3.1: fixa a largura (o conteúdo é sempre "18-JUL-26", 9
     caracteres) — a causa raiz do estouro era o Flatpickr: `altInput`
     cria um SEGUNDO <input> visível sem herdar `.input-data-inline`
     (width: 74px), então o campo visto pelo usuário ficava com a largura
     padrão do navegador. Corrigido via `altInputClass` no base.html; esta
     largura de coluna é o reforço/garantia. */
  width: 92px;
}

.th-data {
  width: 92px;
  white-space: nowrap;
}

.celula-data:hover {
  text-decoration: underline dotted;
}

/* Setas de prazo — COLUNA PRÓPRIA (v15, item 5, revisado): antes eram
   pequenas/erráticas dentro da célula Prazo, só no hover; agora ficam numa
   coluna dedicada entre Prazo e Conclusão, sempre visíveis, com espaçamento
   confortável entre os dois botões.
   v15.1, item 4: os botões perderam o texto "-5"/"+5" (só as setas ‹ ›); o
   rótulo "−5 | +5" migrou para o cabeçalho da coluna, então a coluna encolhe
   bastante. */
.th-setas-prazo {
  min-width: 56px;
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--cor-cinza);
  white-space: nowrap;
}

.celula-setas-prazo {
  white-space: nowrap;
}

.botao-seta-prazo {
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  cursor: pointer;
  color: var(--cor-azul);
  font-size: 0.85rem;
  font-weight: 700;
  padding: 4px 7px;
  line-height: 1;
}

.botao-seta-prazo--menos {
  margin-right: 6px;
}

.botao-seta-prazo:disabled {
  color: var(--cor-borda);
  cursor: not-allowed;
  background: var(--cor-fundo);
}

/* v15.1, item 3: colunas de data estreitadas ao máximo — só cabe o formato
   compacto "dd-MMM-aa" (ex.: 14-JUL-26). O Flatpickr não deve alargar o
   campo (a caixa de alt-input herda esta mesma classe). */
.input-data-inline {
  font-family: var(--fonte-texto);
  font-size: 0.76rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 2px 3px;
  width: 74px;
  box-sizing: border-box;
  text-align: center;
}

/* v18, item 3.3: estado por PREENCHIMENTO, não por cor nova — vazio: contorno,
   cinza (--cor-cinza) a 50% de opacidade (nunca abaixo de 40%); preenchido:
   traço mais forte + leve tinta de fundo, azul (--cor-azul), opacidade cheia;
   hover: opacidade cheia + círculo de fundo #F6F7F8, nos dois estados. */
.icone-campo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: none;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--cor-cinza);
  opacity: 0.5;
  padding: 2px;
}

.icone-campo svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.icone-campo--ativo {
  color: var(--cor-azul);
  opacity: 1;
}

.icone-campo--ativo svg {
  fill: currentColor;
  fill-opacity: 0.15;
  stroke-width: 2.4;
}

/* v21, item 6: Observação preenchida usa cor própria (âmbar) — Link
   preenchido continua azul (--cor-azul), regra da v18 inalterada. */
.icone-campo--observacao.icone-campo--ativo {
  color: #bf9000;
}

/* v23, item 4.4: reverte a v21 item 6 — vermelho permanente na coluna
   inteira competia com o realce laranja das linhas atrasadas (a informação
   prioritária da tela). Volta ao padrão (contorno #575756 a 50%, herdado de
   .icone-campo); só fica vermelho no hover. */
.icone-remover-tarefa:hover {
  color: #990000;
}

.icone-campo:hover {
  opacity: 1;
  background: #F6F7F8;
}

.icone-remover {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.9rem;
  opacity: 0.5;
  padding: 2px;
}

/* v24, item 3.1(a) — REABERTO: `white-space: nowrap` sozinho não bastava;
   sem largura fixa o auto-layout da tabela ainda podia espremer a coluna e
   estourar os 4 ícones (gerar/variante, baixar, reemitir, remover) em 2
   linhas (3 em cima, lixeira embaixo — o caso mais comum da tela, qualquer
   documento já gerado cai nele). Largura fixa para os 4 lado a lado. */
/* ★★ v11 (decisão do Guto, 23/09): A COLUNA DE AÇÕES FICA PRESA À DIREITA.

   O DEFEITO: a tabela tem 13 colunas e, a partir de 1366 px, a última fica
   FORA da área visível — o Guto não conseguia excluir uma linha de
   Regularização. Medido, na Regularização: 1495 px de tabela contra 1238 /
   1152 / 896 px de área útil em 1366 / 1280 / 1024.

   ★ Não era regressão: nenhum commit tirou a coluna. Ela sempre esteve no
   HTML (13 `th` e 13 `td`), só que além da borda. Encurtar o nome do
   responsável ajudou (−171 a −274 px) e NÃO bastou: a tabela ainda mede
   1221 px, e a Regularização continuava cortada em 3 das 5 larguras.

   ★ `background: inherit` e NÃO uma cor fixa: a linha pode ter fundo
   próprio (`.linha-atrasada` é laranja). Com cor fixa, a coluna presa
   apagaria esse aviso justamente nas linhas que mais importam. O `tr`
   ganha um fundo explícito logo abaixo para que o `inherit` tenha o que
   herdar — sem isso a célula fica transparente e o conteúdo rolado
   aparece POR BAIXO dela. */
.tabela-tarefas tbody tr {
  background: var(--cor-branco);
}

/* ★★ E2-1 (decisão do Guto, 08/10/2026): o REALCE da linha atrasada. A regra de cima
   (0,1,2) vencia `.linha-atrasada` (0,1,0) desde o f21d1f4, e a tarefa vencida saía
   BRANCA na Gestão — medido no navegador. Mesma especificidade da de cima e depois
   dela, então vence; e a célula presa (`background: inherit`) herda o realce. Guarda:
   `smoke_v11_acoes_sticky`, controle 4. */
.tabela-tarefas tbody tr.linha-atrasada {
  background: var(--cor-atencao-suave);
}

.th-acoes,
.celula-acoes {
  position: sticky;
  right: 0;
  z-index: 2;
  background: inherit;
  /* a borda substitui a "sombra de corte": diz que há mais tabela à
     esquerda, sem pintar por cima da coluna vizinha. */
  border-left: 1px solid var(--cor-borda);
}

.tabela-tarefas thead tr {
  background: var(--cor-branco);
}

.th-acoes {
  width: 140px;
  white-space: nowrap;
}

.celula-acoes {
  width: 140px;
  white-space: nowrap;
}

.icone-remover:hover {
  opacity: 1;
}

/* v26 (INSTRUCAO_CC_blocoA_rodada3_ajustes, C5): mesmo visual do
   .icone-remover (ação neutra, não "perigosa" — a cor não deve remeter a
   deletar, é limpar/marcar em massa), classes próprias só pra manter o
   nome semântico certo no HTML. */
.icone-limpar,
.icone-marcar-tudo {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.9rem;
  opacity: 0.6;
  padding: 2px;
}

.icone-limpar:hover,
.icone-marcar-tudo:hover {
  opacity: 1;
}

/* v26 (C5): linha "Antena – TX | RX:" logo abaixo de cada linha de
   padrão — TX/RX por frequência marcada, os 2 campos "mesclados" numa
   célula só (visualmente um par, não 2 colunas separadas). */
.linha-antena-txrx td:first-child {
  font-style: italic;
  color: var(--cor-cinza);
  font-size: 0.78rem;
}

.celula-antena-txrx {
  white-space: nowrap;
}

.celula-antena-txrx .input-rf-txrx {
  width: 2.2em;
}

.separador-txrx {
  color: var(--cor-cinza);
  padding: 0 2px;
}

.editor-inline {
  display: flex;
  gap: 6px;
  align-items: flex-start;
}

.editor-inline input, .editor-inline textarea {
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 3px 6px;
  min-width: 160px;
}

.editor-inline button {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  border: none;
  border-radius: 4px;
  padding: 3px 8px;
  background: var(--cor-azul);
  color: var(--cor-branco);
  cursor: pointer;
}

.form-nova-tarefa {
  display: none;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 10px;
  padding: 10px;
  background: var(--cor-fundo);
  border-radius: 8px;
}

.form-nova-tarefa input, .form-nova-tarefa select {
  font-family: var(--fonte-texto);
  font-size: 0.82rem;
  border: 1px solid var(--cor-borda-campo);
  border-radius: 4px;
  padding: 5px 8px;
}

.form-nova-tarefa button {
  font-family: var(--fonte-texto);
  font-size: 0.82rem;
  border: none;
  border-radius: 4px;
  padding: 6px 12px;
  cursor: pointer;
}

.form-nova-tarefa button[type="submit"] {
  background: var(--cor-azul);
  color: var(--cor-branco);
}

.select-biblioteca-tarefa {
  min-width: 220px;
}

.aviso-tarefa-avulsa {
  flex-basis: 100%;
  margin: 0;
  font-size: 0.78rem;
  color: var(--cor-alerta, #b45309);
}

/* Paginação (Tela A) */
.paginacao {
  display: flex;
  align-items: center;
  gap: 14px;
  justify-content: center;
  margin-top: 16px;
  font-size: 0.85rem;
  color: var(--cor-cinza);
}

.paginacao a {
  color: var(--cor-azul);
  font-weight: 600;
  text-decoration: none;
}

.paginacao a:hover {
  text-decoration: underline;
}

/* Edição em lote (10.4) */
.celula-checkbox {
  width: 26px;
  text-align: center;
}

/* Barra de edição em lote — "linha fantasma" alinhada às colunas da tabela
   (Tipo, Responsável, Status, Início, Prazo, Conclusão), na paleta da marca.
   Largura = largura do conteúdo principal (sidebar 64px + padding do .main
   32px de cada lado — ver .app-shell/.main — v23, item 4.3 reduziu de
   220px pra 168px; v27, INSTRUCAO_CC_lote6 ML1, reduziu de novo pra 64px
   (sidebar virou barra de ícones); ajustar aqui também se a largura do
   sidebar mudar de novo), para ficar do tamanho da tabela em vez de
   encolher ao conteúdo. O rótulo "Múltiplas (N)" NUNCA encolhe
   (flex: 0 0 auto) — só os campos de seleção encolhem, e nunca a ponto de
   precisar de rolagem horizontal. */
.barra-lote {
  display: none;
  position: fixed;
  left: 96px;
  right: 32px;
  bottom: 20px;
  background: var(--cor-azul);
  color: var(--cor-branco);
  border-radius: 8px;
  padding: 6px 16px;
  gap: 14px;
  align-items: flex-start;
  box-shadow: 0 6px 20px rgba(9, 76, 133, 0.35);
  z-index: 50;
  font-size: 0.8rem;
  box-sizing: border-box;
}

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

.barra-lote__rotulo-campo {
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.7);
  white-space: nowrap;
}

.barra-lote__rotulo {
  flex: 0 0 auto;
  padding-right: 14px;
  border-right: 1px solid rgba(255, 255, 255, 0.3);
}

.barra-lote__linha-principal {
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 700;
  white-space: nowrap;
}

.barra-lote__contagem {
  font-weight: 400;
  opacity: 0.85;
}

.barra-lote__campo-tipo, .barra-lote__campo-responsavel {
  flex: 1 1 100px;
  max-width: 140px;
}

.barra-lote__campo-status {
  flex: 1 1 90px;
  max-width: 120px;
}

.barra-lote__campo-data {
  flex: 0 1 74px;
}

.barra-lote__acao {
  flex: 0 0 auto;
  margin-left: auto;
}

.barra-lote select {
  width: 100%;
  font-family: var(--fonte-texto);
  font-size: 0.75rem;
  border: none;
  border-radius: 4px;
  padding: 5px 4px;
}

.barra-lote .input-data-inline {
  border: none;
  width: 100%;
}

.barra-lote__aplicar {
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  border: none;
  border-radius: 4px;
  padding: 6px 14px;
  background: var(--cor-branco);
  color: var(--cor-azul);
  cursor: pointer;
  font-weight: 700;
  margin-top: 1px;
}

.barra-lote__fechar {
  background: rgba(255, 255, 255, 0.15);
  border: none;
  color: var(--cor-branco);
  border-radius: 50%;
  width: 20px;
  height: 20px;
  cursor: pointer;
  font-size: 0.68rem;
  line-height: 1;
  padding: 0;
  flex-shrink: 0;
}

/* Edição por duplo-clique (10.3) */
.celula-editavel {
  cursor: pointer;
  /* v23, item 4.3: Tarefa/Tipo/Responsável nunca quebram em 2 linhas — a
     largura reduzida do sidebar libera espaço pra coluna Tarefa (a única
     sem largura fixa) absorver nomes longos numa linha só, sem truncar. */
  white-space: nowrap;
}

.celula-editavel:hover {
  background: var(--cor-fundo);
}

.input-inline-edit, .select-inline-edit {
  font-family: var(--fonte-texto);
  font-size: 0.82rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 3px 6px;
  width: 100%;
}

.texto-enviar {
  color: var(--cor-cinza);
  opacity: 0.6;
  font-size: 0.78rem;
  font-style: italic;
}

/* Orientação em texto rico (Parte 11) */
.celula-orientacao {
  position: relative;
}

.popover-orientacao {
  position: absolute;
  z-index: 40;
  top: 100%;
  left: 0;
  width: 320px;
  background: var(--cor-branco);
  border: 1px solid var(--cor-borda);
  border-radius: 8px;
  box-shadow: var(--sombra);
  padding: 12px;
  font-size: 0.85rem;
}

.popover-orientacao__conteudo {
  max-height: 220px;
  overflow-y: auto;
  margin-bottom: 8px;
}

.popover-orientacao__conteudo p {
  margin: 0 0 8px;
}

.botao-editar-orientacao {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 4px 10px;
  background: var(--cor-fundo);
  color: var(--cor-azul);
  cursor: pointer;
}

.editor-orientacao .quill-container {
  background: var(--cor-branco);
  min-height: 100px;
}

.editor-orientacao__acoes {
  display: flex;
  gap: 6px;
  margin-top: 8px;
}

.editor-orientacao__acoes button {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  border: none;
  border-radius: 4px;
  padding: 5px 10px;
  cursor: pointer;
}

.editor-orientacao__acoes button:first-child {
  background: var(--cor-azul);
  color: var(--cor-branco);
}

.quill-container-admin {
  background: var(--cor-branco);
  min-height: 90px;
  margin-bottom: 4px;
}

/* Cores do status da tarefa (5.2). O laranja de atraso continua vindo de
   .linha-atrasada (fundo da linha) — são coisas visualmente distintas. */
.select-status--bloqueada {
  background: var(--cor-status-bloqueada-suave);
  color: var(--cor-status-bloqueada);
  font-weight: 700;
}

.select-status--pendente {
  background: var(--cor-status-pendente-suave);
  color: var(--cor-status-pendente);
}

.select-status--avaliado {
  background: var(--cor-status-avaliado-suave);
  color: var(--cor-status-avaliado);
}

.select-status--concluida {
  background: var(--cor-status-concluida-suave);
  color: var(--cor-status-concluida);
}

/* ★ b4: Cancelada (com o processo) — neutra, riscada: não é pendência nem feito.
   #575756 sobre #F6F7F8 = 6,74 (medido para texto pequeno). */
.select-status--cancelada {
  background: var(--cor-fundo);
  color: var(--cor-cinza);
  text-decoration: line-through;
}

/* Colunas Orientação/Obs expansíveis, estilo Excel (5.1) */
.th-coluna-expansivel {
  white-space: nowrap;
}

.botao-alternar-coluna {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.8rem;
  color: var(--cor-azul);
  opacity: 0.6;
  padding: 0 0 0 4px;
}

.botao-alternar-coluna:hover {
  opacity: 1;
}

.th-coluna-expansivel--expandida .botao-alternar-coluna {
  opacity: 1;
}

.celula-orientacao--expandida,
.celula-observacao--expandida {
  width: 260px;
  max-width: 320px;
  white-space: normal;
}

.celula-orientacao--expandida .conteudo-expandido,
.celula-observacao--expandida .conteudo-expandido {
  cursor: pointer;
  font-size: 0.8rem;
  max-height: 140px;
  overflow-y: auto;
}

.celula-orientacao--expandida .conteudo-expandido p {
  margin: 0 0 6px;
}

/* Blocos por laboratório na seção Testes (item 3 v13): cada LAB tem sua
   própria tabela numerada (1..N) e seu próprio ciclo (teste/re-teste). */
/* Laboratório = sub-nível de Testes (v15.1, item 1): recuado, com barra
   vertical à esquerda (estilo Google) para marcar o aninhamento — sem isso,
   a seção "Testes" e cada laboratório tinham o mesmo peso visual. */
.bloco-laboratorio {
  margin-top: 18px;
  padding: 10px 0 10px 16px;
  border-left: 3px solid var(--cor-azul);
  margin-left: 4px;
}

.bloco-laboratorio__cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.bloco-laboratorio__cabecalho h4 {
  margin: 0;
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--cor-cinza);
  display: flex;
  align-items: center;
  gap: 8px;
}


/* Abas de ciclo por laboratório (v15, item 2): Teste · Re-teste 1 (SEG) · Re-teste 1 (EMC)... */
.fita-abas-ciclo {
  display: flex;
  gap: 2px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--cor-borda);
}

.aba-ciclo {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  border: none;
  background: none;
  padding: 6px 12px;
  cursor: pointer;
  color: var(--cor-cinza);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}

.aba-ciclo--ativa {
  color: var(--cor-azul);
  font-weight: 700;
  border-bottom-color: var(--cor-azul);
}

.painel-ciclo--leitura {
  opacity: 0.75;
}

.painel-ciclo--leitura .tabela-tarefas {
  pointer-events: none;
}

.aviso-leitura {
  font-size: 0.78rem;
  color: var(--cor-cinza);
  font-style: italic;
  margin: 0 0 8px;
}

.norma-relatorio-item__nota {
  font-size: 0.72rem;
  font-style: italic;
  color: var(--cor-cinza);
}

.form-norma-status {
  display: inline-flex;
  gap: 6px;
  align-items: center;
}

.select-status-norma {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 3px 6px;
}

.select-status-norma--pendente {
  background: var(--cor-neutro-suave);
  color: var(--cor-cinza);
}

.select-status-norma--aprovado {
  background: var(--cor-status-concluida-suave);
  color: var(--cor-status-concluida);
}

.select-status-norma--reprovado {
  background: var(--cor-erro-suave);
  color: var(--cor-erro);
  font-weight: 700;
}

.link-discreto {
  font-size: 0.78rem;
  color: var(--cor-azul);
  opacity: 0.75;
  text-decoration: underline dotted;
  cursor: pointer;
}

/* v19: mesma cara do .link-discreto, mas em <button> (hx-post, sem href
   fake) — usado nos links de "amostra nova"/"vincular amostra existente". */
.link-discreto-botao {
  font-family: var(--fonte-texto);
  background: none;
  border: none;
  padding: 0;
  font-size: 0.78rem;
  color: var(--cor-azul);
  opacity: 0.75;
  text-decoration: underline dotted;
  cursor: pointer;
  margin-right: 8px;
}

.link-discreto-botao:hover,
.link-discreto:hover {
  opacity: 1;
}

/* v21, item 4: mesmo visual do "+ adicionar amostra", para "+ adicionar
   relatório" (Terceiros) e outras linhas do painel Dados do Processo. */
.botao-adicionar-linha {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  border: 1px dashed var(--cor-borda);
  border-radius: 4px;
  padding: 3px 10px;
  margin-top: 4px;
  background: none;
  cursor: pointer;
  color: var(--cor-azul);
}

.dados-processo__grade--relatorio {
  align-items: end;
  margin-bottom: 6px;
}

.lista-itens-ensaio {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 0 6px 14px;
  border-left: 2px solid var(--cor-borda);
}

.item-ensaio {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.78rem;
}

.badge-retestado {
  color: var(--cor-atencao);
  font-weight: 700;
  font-size: 0.7rem;
}

.select-item-status {
  font-family: var(--fonte-texto);
  font-size: 0.75rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 2px 4px;
}

/* ★ Fase B, Etapa 1 — o resultado por item: o nº do relatório do laboratório,
   o contexto (Modelo / Laboratório, só leitura), o aviso de recusa e o selo da
   norma, que agora é derivado e só leitura. */
.input-numero-relatorio {
  font-family: var(--fonte-texto);
  font-size: 0.75rem;
  width: 11em;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 2px 6px;
}

.lista-itens-ensaio__contexto {
  display: flex;
  gap: 16px;
  font-size: 0.75rem;
  color: var(--cor-cinza);
}

.form-numero-relatorio-norma {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ★ texto de função sobre o rosa claro: o tom de TEXTO do coral (4,56 sobre
   #FDEDEA, medido na régua do CLAUDE.md), nunca o coral da marca. */
.aviso-item-ensaio {
  margin: 0;
  padding: 4px 8px;
  border-radius: 4px;
  background: var(--cor-atencao-suave);
  border-left: 4px solid var(--cor-atencao);
  color: var(--cor-atencao);
  font-size: 0.78rem;
}

/* ★ Fase B 2A — a proposta contratada no Comercial: o aviso no topo e o
   fieldset que desabilita as abas do produto sem desenhar moldura. */
.aviso-contratada {
  margin: 8px 0 12px;
  padding: 6px 10px;
  border-radius: 4px;
  background: var(--cor-atencao-suave);
  border-left: 4px solid var(--cor-atencao);
  color: var(--cor-atencao);
  font-size: 0.85rem;
  font-weight: 600;
}

/* ★ Fase B 2B.1 — o aviso depois de remover um modelo de uma contratada */
.aviso-remocao-modelo:not(:empty) {
  margin: 8px 0 12px;
  padding: 8px 12px;
  border-radius: 4px;
  background: var(--cor-atencao-suave);
  border-left: 4px solid var(--cor-atencao);
  color: var(--cor-atencao);
  font-size: 0.85rem;
}
.aviso-remocao-modelo p, .aviso-remocao-modelo ul { margin: 4px 0; }

/* ★ Fase B, Etapa 2 — a revisão do plano de teste */
.revisao-plano__titulo { font-size: 1.25rem; margin: 8px 0 4px; }
.revisao-plano__bloco { margin: 12px 0; padding: 12px 16px; }
.revisao-plano__erro {
  margin: 8px 0; padding: 8px 12px; border-radius: 4px;
  background: var(--cor-erro-suave); color: var(--cor-erro); font-weight: 600;
}
.revisao-plano__cabecalho { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.revisao-plano__diferenca { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.revisao-plano__diferenca h3 { font-size: 0.9rem; margin: 0 0 4px; }
.revisao-plano__diferenca ul, .revisao-plano__lista { margin: 0; padding-left: 18px; font-size: 0.85rem; }
.revisao-plano__comparar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
.revisao-plano__navegacao { font-size: 0.85rem; }
.plano-teste-item--excluido { color: var(--cor-cinza); }
.plano-teste-item__excluido-em { font-size: 0.75rem; }
/* ★ no painel de LEITURA não há o ✕ da norma no <summary>: o item não reserva o
   espaço dele, senão a coluna do laboratório desalinha (medido: 28 px) */
.plano-teste-painel__lista--leitura .plano-teste-item { padding-right: 0; }

/* ★ Fase B, Etapa 2C — a revisão aberta (alterar interface RF) */
.revisao-interface__aberta {
  margin: 8px 0; padding: 8px 12px; border-radius: 4px;
  background: var(--cor-atencao-suave);
  border-left: 4px solid var(--cor-atencao); color: var(--cor-atencao); font-size: 0.85rem;
}
.revisao-plano__botoes { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.revisao-plano__descartar { margin: 8px 0 24px; }
.revisao-interface__tabela { overflow-x: auto; }
.revisao-interface__tabela table { border-collapse: collapse; font-size: 0.85rem; min-width: 100%; }
.revisao-interface__tabela th, .revisao-interface__tabela td {
  text-align: left; padding: 4px 8px; border-bottom: 1px solid var(--cor-borda, #e1e4e8); vertical-align: top;
}

/* ★ Fase B 2B.2 — a condição contratada, ao lado da vigente no Fluxo */
.condicao-contratada {
  display: block;
  margin-top: 2px;
  font-size: 0.75rem;
  color: var(--cor-cinza);
}
.condicao-contratada--diferente {
  color: var(--cor-atencao);
  font-weight: 600;
}

fieldset.trava-comercial {
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
}

/* Modal "+ Novo ciclo (RE-TESTE)" */
.modal-novo-ciclo {
  position: fixed;
  inset: 0;
  background: rgba(9, 76, 133, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.modal-novo-ciclo__conteudo {
  background: var(--cor-branco);
  border-radius: var(--raio);
  padding: 20px;
  max-width: 480px;
  width: 90%;
  max-height: 80vh;
  overflow-y: auto;
  box-shadow: var(--sombra);
}

/* v26 (INSTRUCAO_CC_kanban_fase5_menu, 0-B.3a): checklist de Contratar
   tem mais conteúdo por linha (modelo + serviço) — modal mais largo só
   nesse caso, pra evitar quebra de texto ruim de ler. */
.modal-novo-ciclo__conteudo:has(.form-encerramento--contratar) {
  max-width: 640px;
}

.form-novo-ciclo-norma h4 {
  margin: 0 0 8px;
  color: var(--cor-azul);
  font-family: var(--fonte-titulo);
}

.item-selecao-reteste {
  display: block;
  font-size: 0.85rem;
  padding: 4px 0;
}

/* v19, item 2.2: pergunta "Será necessário enviar nova amostra?" ao criar
   o re-teste. */
.pergunta-nova-amostra {
  margin-top: 14px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 8px 12px;
}

.pergunta-nova-amostra legend {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--cor-cinza);
  padding: 0 4px;
}

.pergunta-nova-amostra label {
  display: block;
  font-size: 0.85rem;
  padding: 3px 0;
}

/* ★★ Fase B, Etapa 3: a fita de ciclos do plano — uma aba por número de ciclo,
   uma linha por laboratório. */
.fita-ciclos {
  margin-top: 16px;
}

.fita-ciclos__abas {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid var(--cor-borda);
}

.fita-ciclos__aba {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  padding: 6px 12px;
  border: 1px solid var(--cor-borda);
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  background: var(--cor-fundo);
  color: var(--cor-grafite);
  cursor: pointer;
}

.fita-ciclos__aba--ativa {
  background: var(--cor-branco);
  font-weight: 600;
  color: var(--cor-azul);
}

.fita-ciclos__linha {
  display: grid;
  grid-template-columns: minmax(140px, 220px) 1fr;
  gap: 6px 16px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--cor-borda);
  font-size: 0.85rem;
}

.fita-ciclos__linha--encerrada {
  color: var(--cor-cinza);
}

.fita-ciclos__lab {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
}

.fita-ciclos__nota {
  font-size: 0.78rem;
  color: var(--cor-cinza);
}

.fita-ciclos__encerrado {
  background: var(--cor-neutro-suave);
  color: var(--cor-status-pendente);
}

.fita-ciclos__normas {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
}

.fita-ciclos__norma {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.fita-ciclos__norma--fora {
  color: var(--cor-cinza);
}

.fita-ciclos__rodape {
  grid-column: 1 / -1;
  font-size: 0.82rem;
}

.fita-ciclos__rodape input {
  margin-left: 6px;
  min-width: 280px;
}

/* ★★ Fase B, Etapa 2D v2: "Haverá alteração de custo de laboratório?" — o mesmo
   pedaço nos três eventos e no Fluxo (`_pergunta_custo.html`). Sentido e
   laboratórios só aparecem no Sim; quem exige é o servidor. */
.pergunta-custo {
  margin-top: 14px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 8px 12px;
}

/* ★ A1: a pergunta sem resposta — destacada, com a mensagem dentro e o foco nela */
.pergunta-custo--pendente {
  border: 2px solid var(--cor-atencao);
  background: var(--cor-atencao-suave);
}

.pergunta-custo legend {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--cor-grafite);
  padding: 0 4px;
}

.pergunta-custo__opcoes {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  font-size: 0.85rem;
  padding: 3px 0;
}

.pergunta-custo__labs {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.85rem;
  padding: 3px 0;
}

.pergunta-custo__lab {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
}

.pergunta-custo__rotulo {
  margin: 8px 0 2px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--cor-cinza);
}

.pergunta-custo:not(:has(input[name="custo_resposta"][value="SIM"]:checked)) .pergunta-custo__sim {
  display: none;
}

/* O registro "a preencher" no bloco do Fluxo, e o "a confirmar" no topo. */
.custo-a-preencher {
  margin: 10px 0;
  padding: 10px 12px;
  border: 1px solid var(--cor-atencao);
  border-radius: 6px;
  background: var(--cor-atencao-suave);
}

.custo-a-preencher__titulo {
  font-weight: 600;
  color: var(--cor-atencao);
}

.custo-a-preencher__campos {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  align-items: flex-end;
  margin-top: 6px;
  font-size: 0.85rem;
}

.custo-a-preencher__campos label {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.custo-a-preencher__justificativa {
  flex: 1 1 280px;
}

.custo-a-preencher__aviso {
  margin: 4px 0 0;
  font-weight: 600;
  color: var(--cor-atencao);
}

.form-novo-ciclo-norma__acoes {
  margin-top: 14px;
}

.form-novo-ciclo-norma__acoes button {
  font-family: var(--fonte-texto);
  border: none;
  border-radius: 4px;
  padding: 8px 16px;
  background: var(--cor-azul);
  color: var(--cor-branco);
  cursor: pointer;
}

/* Dados do Processo (v16) — painel expansível no topo da Tela B. */
.dados-processo {
  margin-bottom: 20px;
  padding: 14px 24px;
}

.dados-processo__cabecalho {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 2px 0;
  width: 100%;
  text-align: left;
}

.dados-processo__seta {
  color: var(--cor-azul);
  font-size: 0.9rem;
}

.dados-processo__titulo {
  font-family: var(--fonte-titulo);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--cor-azul);
}

.dados-processo__painel {
  margin-top: 14px;
}

.dados-processo__secao {
  padding: 12px 0;
  border-top: 1px solid var(--cor-borda);
}

.dados-processo__secao:first-child {
  border-top: none;
  padding-top: 4px;
}

.dados-processo__secao h4 {
  margin: 0 0 10px;
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--cor-cinza);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.dados-processo__grade {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

/* v27 (INSTRUCAO_CC_lote7, GB-empresas): Empresa/País/CNPJ-ou-Endereço
   (topo de cada bloco Requerente/Fabricante/Unidade Fabril) — 3
   colunas EXPLÍCITAS (não `auto-fit`) — Empresa e País com largura
   parecida (pedido explícito, "País like Razão Social" — Empresa É a
   razão social aqui), a 3ª coluna (CNPJ OU Endereço, nunca os 2 juntos
   — ver template) um pouco mais estreita. */
.dados-processo__grade--empresa-topo {
  grid-template-columns: 1.3fr 1.3fr 1fr;
}

/* ★ (07/10/2026, QA-006 plus D1) Tipo · Uso · Local · Alimentação · Tensão numa linha só.
   O mínimo de cada coluna é a MAIOR opção da lista, medida no navegador (Inter 13,6px +
   18px de padding): Tipo 84, Uso 146, Local 187, Alimentação 175; a Tensão é o dropdown.
   Soma 860px + folgas: em 1366 (seção de 1190px) sobra; abaixo, a linha QUEBRA em vez de
   cortar — a grade genérica (`auto-fit`) volta. */
.dados-processo__grade--operacao-alimentacao {
  grid-template-columns: minmax(100px, 0.7fr) minmax(160px, 1fr) minmax(200px, 1.2fr)
                         minmax(190px, 1.1fr) minmax(200px, 1.2fr);
}
/* ★ (07/10/2026, QA-006 plus D2) Vínculo empresarial (Comercial e Gestão) e Cadastros:
   larguras SOB MEDIDA, por nome de campo (`data-campo`, o mesmo nas três telas). As linhas
   QUEBRAM em vez de cortar: o `flex-basis` dos campos fixos é o mínimo que o conteúdo pede
   (medido no navegador, Inter 13,6px + 18px): País pelo maior nome da lista (296 px), CNPJ
   com 18 caracteres e o alfanumérico comum, UF pela sigla, CEP com 9, Telefone com
   "(00) 00000-0000". O que sobra vai para Razão Social, Logradouro e e-mail; o endereço
   estrangeiro ocupa a linha inteira. */
/* ★ (08/10/2026, QA-006 plus 2B) a moldura do badge da aba (`_abas_badge.html`): existe só
   para ter um id que o OOB troque — não muda o desenho. ★ O nome NÃO começa por
   `abas-processo__badge`: com esse prefixo, toda busca de texto pelo badge contava a moldura
   (a 1ª versão quebrou 5 smokes assim — o vocabulário do alvo casando com o do instrumento). */
.abas-processo__lugar-badge { display: contents; }

/* ★ (08/10/2026, QA-006 plus 2B, item 3) Vínculo empresarial: destaque LEVE entre as três
   empresas — subtítulo no azul institucional, barra fina à esquerda, mais espaço entre os
   blocos. Sem fundo e sem caixa (decisão do Guto). */
.vinculo-bloco {
  border-left: 3px solid var(--cor-azul);
  padding-left: 14px;
  margin-bottom: 24px;
}
.dados-processo__subtitulo.dados-processo__subtitulo--vinculo { color: var(--cor-azul); font-weight: 600; }

.dados-processo__grade--sob-medida {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.dados-processo__grade--sob-medida > .dados-processo__campo { flex: 1 1 180px; min-width: 0; }
.dados-processo__grade--sob-medida > [data-campo="pais"] { flex: 0 0 300px; }
.dados-processo__grade--sob-medida > [data-campo="cnpj"],
.dados-processo__grade--sob-medida > [data-campo="documento"] { flex: 0 0 180px; }
.dados-processo__grade--sob-medida > [data-campo="endereco_estado"] { flex: 0 0 76px; }
.dados-processo__grade--sob-medida > [data-campo="endereco_cep"] { flex: 0 0 104px; }
.dados-processo__grade--sob-medida > [data-campo="endereco_numero"] { flex: 0 0 84px; }
.dados-processo__grade--sob-medida > [data-campo="telefone"],
.dados-processo__grade--sob-medida > [data-campo="contato_telefone"] { flex: 0 0 150px; }
.dados-processo__grade--sob-medida > [data-campo="cidade"] { flex: 1 1 170px; }
.dados-processo__grade--sob-medida > [data-campo="empresa"],
.dados-processo__grade--sob-medida > [data-campo="nome"],
.dados-processo__grade--sob-medida > [data-campo="razao_social"] { flex: 3 1 320px; }
.dados-processo__grade--sob-medida > [data-campo="endereco_logradouro"] { flex: 2 1 260px; }
.dados-processo__grade--sob-medida > [data-campo="email"],
.dados-processo__grade--sob-medida > [data-campo="contato_email"] { flex: 2 1 260px; }
.dados-processo__grade--sob-medida > [data-campo="endereco_internacional"] { flex: 1 1 100%; }
/* No Cadastro a Razão Social divide a linha com País e CNPJ; com 760 px de mínimo ela vai
   para uma linha própria e ocupa a largura toda — o maior nome gravado hoje (87 caracteres)
   pede 738 px. */
#cadastro-detalhe .dados-processo__grade--sob-medida > [data-campo="nome"],
#cadastro-detalhe .dados-processo__grade--sob-medida > [data-campo="razao_social"] { flex: 1 1 760px; }
/* a linha de CONTATOS do Cadastro: e-mail e nome com espaço, telefone fixo */
.fluxo-tag-faturamento__linha > input[id^="campo-contato-"] { flex: 1 1 200px; min-width: 0; }
.fluxo-tag-faturamento__linha > input[id^="campo-contato-"][id$="-nome"] { flex: 2 1 280px; }
.fluxo-tag-faturamento__linha > input[id^="campo-contato-"][id$="-email"] { flex: 2 1 300px; }
.fluxo-tag-faturamento__linha > input[id^="campo-contato-"][id$="-telefone"] { flex: 0 0 190px; }

@media (max-width: 1180px) {
  .dados-processo__grade--operacao-alimentacao {
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  }
}

/* v27 (INSTRUCAO_CC_lote7, GB-produto): Nome comercial + Marca lado a
   lado, ocupando 1 SÓ slot da grade `auto-fit` de fora (ver comentário
   no template) — cada campo com ~metade da largura que "Nome
   comercial" sozinho tinha antes. */
.dados-processo__campo-par {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* v26 (INSTRUCAO_CC_blocoA_rodada6_ajustes, F2): Plano de Teste — itens
   em 1 coluna só (um abaixo do outro), não lado a lado como o grid
   genérico acima. */
.dados-processo__grade--vertical {
  grid-template-columns: 1fr;
  gap: 4px;
}

/* v26 (INSTRUCAO_CC_revisao_telas_proposta, 1.1): cabeçalho da Proposta
   numa linha só — Oportunidade/Órgão estreitos (só cabem um código
   curto), Cliente/Signatário levam o espaço que sobra.
   v26 (INSTRUCAO_CC_ajustes_finais_telas_proposta, J1/J2): usuário
   aumentou as caixas — Oportunidade 7ch->14ch, Órgão 9ch->18ch.
   v26 (INSTRUCAO_CC_kanban_fase1_dados, 6): Etiqueta entra entre
   Oportunidade e Cliente — texto curto (máx. 30 caracteres), largura
   intermediária (nem tão estreita quanto Oportunidade/Órgão, nem
   flexível como Cliente/Signatário). */
/* v26 (INSTRUCAO_CC_acertos_cabecalho_e_criacao, A1/A2): ordem nova das
   colunas = Nº Oport. | Cliente | Etiqueta | Órgão | Signatário.
   Etiqueta ganhou o espaço que era do Signatário (texto livre pode ser
   mais longo que um nome) — Signatário encolheu de 1.4fr pra 0.9fr. */
/* v26 (Proposta Comercial F1, Parte 1): +1 coluna — "Contato
   financeiro" ao lado de "Signatário", mesma largura (minmax(140px,
   0.9fr)) — eram 5 colunas, viram 6. */
.dados-processo__grade--cabecalho-proposta {
  grid-template-columns: 14ch minmax(160px, 1.2fr) minmax(160px, 1.4fr) 18ch minmax(140px, 0.9fr) minmax(140px, 0.9fr);
}

/* v26 (INSTRUCAO_CC_revisao_telas_proposta, 1.3): Status sai do quadro
   Cabeçalho e vira um destaque ao lado do título — campo que muda com
   frequência, alto contraste (mesmo azul da marca do restante do app). */
.comercial-proposta__titulo-linha {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.comercial-proposta__titulo-linha h3 {
  margin: 0;
}

/* v26 (INSTRUCAO_CC_revisao_telas_proposta, 2.1): cabeçalho de quadro
   com o(s) botão(ões) de gerar documento alinhados à direita do título. */
.comercial-proposta__secao-cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}

.comercial-proposta__secao-cabecalho h4 {
  margin: 0;
}

.comercial-proposta__acoes-documento {
  display: flex;
  gap: 8px;
}

.comercial-proposta__status select {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--cor-branco);
  background: var(--cor-azul);
  border: 1px solid var(--cor-azul);
  border-radius: 999px;
  padding: 5px 14px;
  cursor: pointer;
}

.dados-processo__campo {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--cor-cinza);
}

.dados-processo__campo input,
.dados-processo__campo select {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  font-weight: 400;
  color: #1a1a1a;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 6px 8px;
  /* v27 (INSTRUCAO_CC_lote7, GB-empresas/GB-produto): causa raiz do
     "campo X sobrepondo campo Y" reportado (País/CNPJ,
     Classificação/CH+Nº certificado) — `.dados-processo__campo` é
     `display:flex; flex-direction:column`, e sem `width:100%` um
     `<select>` (ou `<input>`) vira do tamanho do CONTEÚDO (a opção
     mais larga, ex. nome de país longo), não da célula do grid —
     transborda por cima do vizinho em vez de respeitar a largura
     alocada. `min-width: 0` é o mesmo ajuste de "grid blowout" já
     usado em `.main` (GB1/Lote6) — sem ele, um item de grid/flex com
     conteúdo largo TAMBÉM não encolhe abaixo do próprio conteúdo. */
  width: 100%;
  min-width: 0;
}

/* v27 (INSTRUCAO_CC_lote7, GB-empresas/GB-produto): agora que o select
   respeita a largura da célula (regra acima), texto que ainda não
   couber é OCULTADO com reticências em vez de continuar transbordando
   — só faz efeito com `width` já travado. Só em `select` (o valor
   completo de um `<input>` continua acessível rolando o cursor nele,
   um `<select>` fechado não tem como "rolar" o texto escondido). */
.dados-processo__campo select {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* v26 (INSTRUCAO_CC_varredura_telaB): campo protegido por 2 cliques — dado
   sensível, evita edição acidental com 1 clique só. Estático (readonly) por
   padrão; 1º clique arma (destaque laranja, ainda travado); 2º clique
   libera de verdade (destaque azul, editável). Clicar fora/Escape sem
   chegar a "editando" reverte sem gravar nada. */
.campo-protegido[readonly],
.campo-protegido-select select:disabled {
  background: var(--cor-fundo);
  color: var(--cor-cinza);
  cursor: pointer;
}

/* Bug reportado: <select disabled> não dispatcha (nem propaga) evento de
   clique nenhum - comportamento nativo do navegador, não da trava. Sem
   isso o clique nunca chegava a alcançar o onclick do wrapper
   .campo-protegido-select (mesmo problema de "tooltip em botão disabled").
   pointer-events:none tira o <select> da detecção de clique enquanto
   travado - o clique "atravessa" e cai no wrapper, que continua clicável
   normalmente. Some sozinho ao liberar (deixa de bater no :disabled). O
   mesmo vale pro checkbox de Autorização de Vínculo - clicar exatamente
   em cima do quadradinho tinha a mesma falha (clicar no texto do label
   já funcionava, por não passar pelo próprio input). */
.campo-protegido-select select:disabled,
.dados-processo__checkbox input:disabled {
  pointer-events: none;
}

.campo-armado,
.campo-protegido.campo-armado,
.campo-protegido-select.campo-armado select,
.campo-protegido-select.campo-armado input {
  border-color: var(--cor-atencao) !important;
  background: var(--cor-atencao-suave) !important;
  box-shadow: 0 0 0 2px var(--cor-atencao-suave);
}

.campo-editando,
.campo-protegido.campo-editando,
.campo-protegido-select.campo-editando input {
  border-color: var(--cor-azul) !important;
  background: var(--cor-branco) !important;
  color: #1a1a1a;
  cursor: text;
  box-shadow: 0 0 0 2px rgba(9, 76, 133, 0.15);
}

.campo-protegido-select.campo-editando select {
  cursor: pointer;
}

/* campo-protegido-data (Vencimento/flatpickr): o input interno já herda
   .campo-protegido, então as regras acima de [readonly] cobrem o estado
   estático; as duas regras "input" acima cobrem armado/editando. */

.dados-processo__checkbox.campo-armado {
  outline: 2px solid var(--cor-atencao);
  outline-offset: 2px;
  border-radius: 4px;
}

/* v20, item 3: características da família (PT/EN) — grade mais larga que a
   padrão, já que são textareas, não inputs curtos. */
.dados-processo__grade--familia {
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

.dados-processo__campo--textarea textarea {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  font-weight: 400;
  color: #1a1a1a;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 6px 8px;
  resize: vertical;
}

.botao-traduzir {
  align-self: flex-start;
  font-family: var(--fonte-texto);
  font-size: 0.72rem;
  font-weight: 600;
  border: 1px solid var(--cor-azul);
  border-radius: 4px;
  padding: 2px 8px;
  background: none;
  color: var(--cor-azul);
  cursor: pointer;
}

.botao-traduzir:disabled {
  border-color: var(--cor-borda);
  color: var(--cor-cinza);
  opacity: 0.6;
  cursor: not-allowed;
}

.dados-processo__aviso {
  font-size: 0.78rem;
  color: #b45309;
  margin: 0 0 8px;
}

.dados-processo__valor-fixo {
  font-size: 0.85rem;
  font-weight: 400;
  color: #1a1a1a;
  padding: 6px 0;
}

.dados-processo__subtitulo {
  margin: 12px 0 6px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--cor-cinza);
}

/* v24, item 2.1: marca qual Certificado ISO a geração de documento usa de
   verdade — o documento não nomeia a Unidade Fabril, então iso_numero é a
   única pista; escolha errada sai silenciosa e só é percebida depois de
   assinada. */
.dados-processo__badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 4px;
  background: var(--cor-verde-suave);
  color: var(--cor-verde);
  font-size: 0.7rem;
  font-weight: 700;
}

.dados-processo__nota {
  font-size: 0.78rem;
  font-style: italic;
  color: var(--cor-cinza);
  opacity: 0.8;
  margin: 6px 0 0;
}

.dados-processo__vazio {
  font-size: 0.82rem;
  color: var(--cor-cinza);
  opacity: 0.6;
  font-style: italic;
}

.dados-processo__lista, .dados-processo__lista-simples {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.dados-processo__lista li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 0.82rem;
  background: var(--cor-fundo);
  border-radius: 4px;
  padding: 6px 10px;
}

/* v27 (INSTRUCAO_CC_lote_bugs_melhorias, M-4): checkbox "Segue a
   contratação" em Serviços/produtos — antes do nome do produto,
   `span` (que já tem flex:1 embutido pelo justify-content) segue certo
   à direita dele.
   v27 (INSTRUCAO_CC_lote5, SP1): `display: flex` (bloco) empurrava o
   checkbox pra CIMA da linha modelo+serviço — um flex container vira
   block-level por padrão. `inline-flex` resolve: alinha o checkbox
   verticalmente com o texto (mesmo `align-items: center`) SEM quebrar
   linha, junto com o link/nome do produto no mesmo `<span>`. */
.comercial-proposta__incluir-contratacao {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

/* v26 (INSTRUCAO_CC_revisao_telas_proposta, 3.1): input que deve OCUPAR
   o espaço livre da linha (não o tamanho natural pequeno de um <input>
   solto) — ex. motivo da Revisão, entre o rótulo e o botão de remover. */
.dados-processo__campo-flex {
  flex: 1 1 auto;
  min-width: 200px;
}

/* v26 (INSTRUCAO_CC_blocoA_rodada2_parte1_bug_ajustes, B3): rótulo inline
   pros campos da linha de modelo (Modelo / Modelo comercial) — igual
   .dados-processo__campo em espírito, mas em linha (a lista é flex-row,
   não uma grade de colunas). */
.dados-processo__lista-rotulo {
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 600;
  color: var(--cor-cinza);
  white-space: nowrap;
}

.dados-processo__lista-rotulo input {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  font-weight: 400;
  color: #1a1a1a;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 4px 6px;
}

/* v26 (INSTRUCAO_CC_blocoA_rodada2_parte1_bug_ajustes, B4): dropdown de
   seleção múltipla reutilizável — ver _multiselect_dropdown.html e
   iniciarMultiSelects em base.html. */
.multiselect {
  position: relative;
}

.multiselect__cabecalho {
  width: 100%;
  text-align: left;
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  font-weight: 400;
  color: #1a1a1a;
  background: #fff;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 6px 8px;
  cursor: pointer;
}

.multiselect__cabecalho:hover {
  border-color: var(--cor-primaria, #999);
}

.multiselect__painel {
  display: none;
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  margin-top: 2px;
  min-width: 100%;
  max-height: 220px;
  overflow-y: auto;
  background: #fff;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 6px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
}

.multiselect--aberta .multiselect__painel {
  display: block;
}

.multiselect__item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.82rem;
  font-weight: 400;
  color: #1a1a1a;
  padding: 3px 2px;
  white-space: nowrap;
  cursor: pointer;
}

.multiselect__nativo {
  display: none;
}

.dados-processo__lista-simples li {
  font-size: 0.82rem;
  color: var(--cor-cinza);
}

/* v26 (INSTRUCAO_CC_comercial_blocoA_tela_produto): RF (InterfaceRF) —
   seção expansível nativa (<details>/<summary>), não pop-up — único
   padrão de interação usado no resto do app. */
.dados-processo__lista--rf {
  gap: 8px;
}

.rf-interface {
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 10px 12px;
  background: var(--cor-fundo);
}

.rf-interface + .rf-interface {
  margin-top: 8px;
}

.rf-interface summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.85rem;
  color: #1a1a1a;
}

.rf-interface[open] summary {
  margin-bottom: 10px;
}

.rf-interface .dados-processo__subtitulo:first-of-type {
  margin-top: 4px;
}

/* v26 (INSTRUCAO_CC_blocoA_ajustes_rodada1, A11/A14): tabela com checkbox
   das telas Wi-Fi (padrão x frequência) e Redes Celulares (banda x
   tecnologia) — muitas colunas, precisa rolar horizontal sem estourar o
   layout da página (mesma regra de qualquer tabela larga no app). */
.tabela-rf-scroll {
  overflow-x: auto;
  margin: 4px 0 10px;
}

.tabela-rf-matriz {
  border-collapse: collapse;
  font-size: 0.78rem;
  white-space: nowrap;
}

.tabela-rf-matriz th,
.tabela-rf-matriz td {
  border: 1px solid var(--cor-borda);
  padding: 3px 6px;
  text-align: center;
}

.tabela-rf-matriz th {
  background: var(--cor-fundo-alt, #f2f2f2);
  font-weight: 600;
}

.tabela-rf-matriz td:first-child,
.tabela-rf-matriz th:first-child {
  text-align: left;
  white-space: nowrap;
}

.celula-rf-matriz input[type="checkbox"] {
  margin: 0;
}

.celula-rf-indisponivel {
  color: var(--cor-cinza);
}

.input-rf-txrx {
  width: 2.5em;
  text-align: center;
}

/* v26 (INSTRUCAO_CC_blocoA_rodada4_wifi_ajustes, D5 + rodada5, E1):
   Selecionado sempre visível (em cima); Disponível volta a ficar
   ESCONDIDO até clicar "+ Normas/Itens" (E1 reverteu parcialmente o D5
   — os "dois painéis lado a lado" viraram só o de cima visível de novo,
   mesmo espírito do antigo .plano-teste-seletor/A15). */
.plano-teste-painel__lista {
  max-height: 340px;
  overflow-y: auto;
  margin: 6px 0;
}

/* v26 (Ajustes da 1a avaliacao, PT2): "Selecionado" + botão
   "Expandir/Recolher tudo" lado a lado. */
.plano-teste-painel__cabecalho-selecionado {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.plano-teste-expandir-tudo {
  margin-top: 0;
}

.plano-teste-disponivel--escondido {
  display: none;
}

/* v26 (C2, mantido): botão "✕" de remover — usado só no painel
   Selecionado agora (remove a norma inteira, itens voltam pra
   Disponível). */
.plano-teste-chip__remover {
  border: none;
  background: none;
  cursor: pointer;
  color: var(--cor-cinza);
  font-size: 0.8rem;
  line-height: 1;
  padding: 0 0 0 2px;
}

.plano-teste-chip__remover:hover {
  color: var(--cor-erro);
}

.plano-teste-norma summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 4px 0;
}

/* v26 (INSTRUCAO_CC_nota_de_teste_implementacao): "Nota de teste" —
   abaixo do último item da norma, levemente separada do grid de itens. */
.plano-teste-norma__nota {
  margin-top: 8px;
}

.dados-processo__form-inline {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.dados-processo__form-inline input,
.dados-processo__form-inline select {
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 6px 8px;
}

.dados-processo__form-inline button {
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  font-weight: 600;
  border: none;
  border-radius: 4px;
  padding: 6px 14px;
  background: var(--cor-azul);
  color: var(--cor-branco);
  cursor: pointer;
}

.dados-processo__checkbox {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.82rem;
  color: #1a1a1a;
  padding: 3px 0;
  font-weight: 400;
}

/* v26 (INSTRUCAO_CC_blocoA_rodada2_parte2_painel_cotacoes): "Composição
   de custos"/"Comparativo de cotações" no painel da Proposta.
   v26 (INSTRUCAO_CC_blocoA_rodada6_ajustes, F5b/F6): a matriz achatada
   proposta-wide (.painel-cotacoes__matriz e as linhas de adicional/
   totais que a acompanhavam) e o agrupamento por produto
   (.painel-cotacoes__produto) saíram — "Composição de custos" agora
   espelha a matriz por combinação (.combinacao-matriz, ver mais abaixo)
   e o Comparativo virou 1 bloco único com os cartões EMPILHADOS
   (F6a) — sem mais scroll horizontal entre combinações. */
/* v27 (INSTRUCAO_CC_lote5, SP2): título "Composição de custos" + toggle
   de moeda lado a lado — substitui o antigo `<select>` "Moeda desta
   proposta" (que ficava mais abaixo, com trava enquanto vazio). */
.painel-cotacoes__titulo-linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.painel-cotacoes__titulo-linha h3 {
  margin: 0;
}

.toggle-moeda {
  display: inline-flex;
  border: 1px solid var(--cor-borda);
  border-radius: 999px;
  overflow: hidden;
}

.toggle-moeda__opcao {
  border: none;
  background: var(--cor-branco);
  color: var(--cor-cinza);
  font-family: var(--fonte-texto);
  font-size: 0.82rem;
  font-weight: 600;
  padding: 5px 16px;
  cursor: pointer;
}

.toggle-moeda__opcao:first-child {
  border-right: 1px solid var(--cor-borda);
}

.toggle-moeda__opcao--ativa {
  background: var(--cor-azul);
  color: var(--cor-branco);
}

.painel-cotacoes__comparativo {
  margin-top: 12px;
}

.painel-cotacoes__comparativo > summary {
  cursor: pointer;
  font-weight: 600;
  color: #1a1a1a;
  padding: 6px 0;
}

/* ★★ (20/10/2026, QA-009 acréscimo 1) o subtópico CONTRATAÇÃO da aba Proposta (forma B: recolhido até a
   Aprovação). O título é o <summary>: o h4 de sempre, com o resumo ao lado. */
.comercial-contratacao__titulo {
  display: flex;
  align-items: baseline;
  gap: 12px;
  cursor: pointer;
  list-style-position: inside;
}
.comercial-contratacao__titulo h4 { display: inline; margin: 0; }
.comercial-contratacao__resumo { color: var(--cor-texto-suave, inherit); font-size: 0.85rem; }
.comercial-contratacao__pendencias { color: var(--cor-atencao); font-weight: 600; }

/* ★★ (20/10/2026, QA-009 item 4, forma B) a janela "Colar imagem" e o ícone das imagens do modelo */
.icone-imagens { display: inline-flex; vertical-align: middle; margin-left: 6px; }
.tabela-modelos__imagens .icone-imagens { margin-left: 0; }
/* ★ (21/10/2026, ajuste A) modelo único: o campo Marca e o ícone das imagens numa linha só */
.dados-processo__campo-com-icone { display: flex; align-items: center; gap: 6px; }
.dados-processo__campo-com-icone > input { flex: 1; min-width: 0; }
.dados-processo__campo-com-icone .icone-imagens { margin-left: 0; }
.janela-imagens { max-width: 640px; }
.janela-imagens__colar {
  border: 2px dashed var(--cor-borda); border-radius: 8px; padding: 22px 12px; text-align: center;
  color: var(--cor-cinza); cursor: pointer; background: var(--cor-branco);
}
.janela-imagens__colar:focus { outline: 2px solid var(--cor-azul-suave-texto, #4A7699); outline-offset: 2px; }
.janela-imagens__arquivo { display: inline-block; margin: 8px 0; font-size: 0.85rem; color: var(--cor-cinza); }
.janela-imagens__lista { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; padding: 0; margin: 10px 0; list-style: none; }
.janela-imagens__item { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.janela-imagens__item img { max-width: 100%; height: 90px; width: auto; object-fit: contain; border: 1px solid var(--cor-borda); background: var(--cor-branco); }
.janela-imagens__acoes { display: flex; gap: 6px; }
.janela-imagens--enviando { opacity: 0.6; pointer-events: none; }

.painel-cotacoes__total-proposta {
  font-weight: 700;
  margin: 8px 0;
  text-align: right;
}

/* v26 (INSTRUCAO_CC_servicos_adicionais_custos, 3): controles liga/
   desliga + valor dos 2 serviços adicionais fixos — nível Proposta
   (não por combinação), mesmo padrão HTMX inline do resto da tela. */
.painel-cotacoes__adicionais {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin: 4px 0 10px;
}

.painel-cotacoes__adicional {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.85rem;
  color: var(--cor-cinza);
  cursor: pointer;
}

.painel-cotacoes__adicional-valor {
  width: 90px;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 3px 6px;
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
}

.painel-cotacoes__adicional-valor:disabled {
  background: var(--cor-fundo);
  color: var(--cor-cinza);
  opacity: 0.6;
}

/* v26 (Fase 2 do Fluxo Financeiro): serviços complementares LIVRES com
   fornecedor — lista (nome/custo/fornecedor/remover, cada um editável
   inline) + form "+ Serviço complementar" logo abaixo. */
.painel-cotacoes__servicos-complementares {
  list-style: none;
  margin: 4px 0 8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.painel-cotacoes__servico-complementar {
  display: flex;
  align-items: center;
  gap: 6px;
}

.painel-cotacoes__servico-complementar input,
.painel-cotacoes__servico-complementar select,
.painel-cotacoes__servico-complementar-novo input,
.painel-cotacoes__servico-complementar-novo select {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 4px 6px;
}

.painel-cotacoes__servico-complementar-nome {
  flex: 1 1 auto;
  min-width: 0;
}

.painel-cotacoes__servico-complementar-custo {
  width: 90px;
  flex-shrink: 0;
}

/* ★★ Serviços avulsos, push 2: o prazo por linha (dias úteis), só no setor Complementares */
.painel-cotacoes__servico-complementar-prazo {
  width: 120px;
  flex-shrink: 0;
}

.painel-cotacoes__servico-complementar-fornecedor {
  width: 160px;
  flex-shrink: 0;
}

.painel-cotacoes__servico-complementar-novo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 10px;
}

.painel-cotacoes__servico-complementar-novo input[name="nome"] {
  flex: 1 1 200px;
}

/* v27 (QA-005, A5): o formulário passou a ter DOIS numéricos — Valor
   (`preco`, o que o cliente paga) e Custo (`custo`, o repasse interno).
   Mesma largura de propósito: são o mesmo tipo de dado e ficam lado a
   lado; larguras diferentes fariam um parecer mais importante que o
   outro. A linha já existente (`-custo`, 90px) usa o mesmo par. */
.painel-cotacoes__servico-complementar-novo input[name="preco"],
.painel-cotacoes__servico-complementar-novo input[name="custo"] {
  width: 110px;
}

.painel-cotacoes__servico-complementar-novo select {
  width: 160px;
}

/* v26 (F6a): combinações EMPILHADAS (uma abaixo da outra), cada uma
   ocupa a largura toda — nada de scroll horizontal entre elas (a
   matriz interna de cada uma tem seu próprio scroll quando precisa). */
.painel-cotacoes__combinacoes-pilha {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.painel-cotacoes__nova-combinacao-lista {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 6px 0;
}

/* v26 (INSTRUCAO_CC_blocoA_rodada5_ajustes, E5d; rodada6, F6a): cartão
   vira uma MATRIZ modelo×fornecedor, largura TOTAL (empilhado, não mais
   lado a lado) — a tabela interna tem seu PRÓPRIO scroll (horizontal e
   vertical) quando cresce demais. */
.combinacao-card {
  width: 100%;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 8px 10px;
  background: var(--cor-fundo);
}

/* v26 (INSTRUCAO_CC_validacao_tela_bloco_A, G2c): verde da IDENTIDADE
   (#2E9E5B, mesmo de .barra-progresso__preenchida--completa) — não o
   --cor-verde genérico (#2E8B57, usado noutros estados "confirmado" do
   app) — pedido explícito da validação. */
.combinacao-card--escolhida {
  border-color: var(--cor-status-concluida);
  background: var(--cor-verde-suave);
}

/* ★★ AJUSTE_COTACOES, A1: o selo "Escolhida" — texto no verde de "concluída" da C1
   (#237A47) sobre o fundo claro, com borda; contraste 5,0 sobre o verde suave. */
.selo-escolhida {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border: 1px solid var(--cor-status-concluida);
  border-radius: 999px;
  background: var(--cor-fundo);
  color: var(--cor-status-concluida);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.5;
  vertical-align: middle;
}

/* ★ A1: "+ Nova combinação" no topo da lista, separado dela */
.painel-cotacoes__nova-combinacao {
  margin: 0 0 10px;
}

.combinacao-card__cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 6px;
}

.combinacao-card__titulo {
  font-weight: 600;
  font-size: 0.82rem;
}

/* v27 (QA-005, 1.4 da rodada final): o botão que recolhe a caixa. Ocupa
   todo o cabeçalho à esquerda (alvo grande, é o clique mais frequente da
   tela depois de "Escolher") e não parece botão — parece o cabeçalho que
   já era, com uma seta. */
/* v27 (QA-005, conferência pós-deploy): o aviso que substitui o seletor de
   fornecedor quando não há nenhum do tipo cadastrado. Discreto, mas é um
   link — falta de cadastro se resolve num lugar só, e o caminho até lá é
   parte do aviso. */
.adicional-linha__sem-fornecedor {
  display: inline-block;
  font-size: 0.76rem;
  color: var(--cor-status-bloqueada);
  text-decoration: none;
  border: 1px dashed var(--cor-status-bloqueada);
  border-radius: 6px;
  padding: 5px 8px;
  white-space: nowrap;
}

.adicional-linha__sem-fornecedor:hover {
  background: var(--cor-fundo);
  text-decoration: underline;
}

.combinacao-card__recolher {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  border: none;
  background: none;
  padding: 2px 0;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: inherit;
}

.combinacao-card__seta {
  font-size: 0.7rem;
  color: var(--cor-cinza);
  transition: transform 0.12s ease;
}

.combinacao-card--recolhida .combinacao-card__seta {
  transform: rotate(-90deg);
}

/* O Total no cabeçalho: discreto com a caixa aberta (o rodapé da matriz
   já o mostra logo abaixo), e é a única informação de valor quando ela
   está recolhida. */
.combinacao-card__total-resumo {
  font-size: 0.78rem;
  color: var(--cor-cinza);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.combinacao-card--recolhida .combinacao-card__total-resumo {
  color: inherit;
  font-weight: 600;
}

.combinacao-card--recolhida .combinacao-card__corpo {
  display: none;
}

.combinacao-card--recolhida .combinacao-card__cabecalho {
  margin-bottom: 0;
}

.combinacao-card__escolher {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.78rem;
  white-space: nowrap;
}

.combinacao-card__remover-linha {
  border: none;
  background: none;
  color: var(--cor-cinza);
  opacity: 0.6;
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  padding: 0 2px;
}

.combinacao-card__remover-linha:hover {
  color: #990000;
  opacity: 1;
}

.combinacao-card__observacao {
  display: block;
  font-size: 0.78rem;
  margin: 6px 0;
}

.combinacao-card__observacao textarea {
  width: 100%;
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  resize: vertical;
}

/* Matriz modelo×fornecedor (E5d) — cabeçalho fixo (sticky) + scroll
   conforme a lista de modelos/colunas cresce.

   v27 (QA-003, C2): o teto era `max-height: 260px`, fixo em PIXELS, e
   cortava a tabela mesmo com meia tela sobrando — uma proposta de 3
   produtos já nascia com barra de rolagem sem precisar. O `overflow: auto`
   nunca foi o problema: `auto` já significa "barra só quando não couber";
   quem forçava era o 260px.

   Agora o teto é do TAMANHO DA JANELA. Com poucos produtos a tabela cresce
   até caber inteira e não há barra nenhuma; num notebook 16" com muitos
   produtos ela para em ~70% da altura e a barra volta — que é o ponto,
   porque sem teto a tabela empurraria o rodapé (Taxa/Total) pra fora da
   tela e obrigaria a rolar a PÁGINA pra ver o total.

   Diferente do Kanban, aqui o `overflow` FICA: é ele que faz o `thead`
   sticky grudar no topo da tabela. Sem ele o cabeçalho grudaria na janela,
   por baixo do cabeçalho do app. */
.combinacao-matriz__scroll {
  max-height: 70vh;
  overflow: auto;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
}

.combinacao-matriz {
  border-collapse: collapse;
  width: 100%;
  /* v26 (INSTRUCAO_CC_ajustes_finais_telas_proposta, J5): +1pt em relação
     ao 0.74rem anterior (~8.9pt -> ~9.9pt, considerando 1rem = 16px =
     12pt, raiz sem override neste projeto). O "Total" (geral) fica FORA
     da <table> (.combinacao-matriz__total-geral, no rodapé) — não herda
     este font-size, mantém o tamanho de sempre sem precisar de exceção. */
  font-size: 0.82rem;
}

.combinacao-matriz th,
.combinacao-matriz td {
  border: 1px solid var(--cor-borda);
  padding: 3px 5px;
  text-align: center;
  white-space: nowrap;
}

.combinacao-matriz thead {
  position: sticky;
  top: 0;
  z-index: 1;
}

.combinacao-matriz thead th {
  background: var(--cor-fundo);
  font-weight: 600;
}

.combinacao-matriz__select {
  font-size: 0.80rem;
  max-width: 96px;
}

.combinacao-matriz__campo {
  width: 60px;
  border: 1px solid var(--cor-borda);
  border-radius: 3px;
  padding: 2px 3px;
  font-size: 0.82rem;
  text-align: right;
}

/* v26 (INSTRUCAO_CC_ajustes_finais_telas_proposta, J5): "sem valor" (—)
   discreto/cinza — nem tão apagado quanto a borda, nem tão escuro quanto
   o texto normal da célula. */
.combinacao-matriz__sem-valor {
  color: var(--cor-cinza);
  opacity: 0.55;
}

/* v26 (INSTRUCAO_CC_servicos_adicionais_custos, 3): linha de serviço
   adicional (transporte de amostra/tradução de ISO) — itálico discreto
   pra diferenciar visualmente das linhas de modelo×serviço. */
.combinacao-matriz__adicional td:first-child {
  font-style: italic;
  color: var(--cor-cinza);
}

/* J5: Desconto em vermelho discreto (mesmo tom de .dados-processo__aviso/
   status bloqueada — "nada chamativo"), SEM fundo (só o Total parcial
   leva destaque de fundo, ver abaixo). */
/* v27 (QA-005, melhorias da composição 1.1): a linha de Desconto passa do
   VERMELHO para o VERDE da identidade (--cor-status-concluida, #2E9E5B) —
   o mesmo do rodapé do PDF.

   A divergência de cor entre tela e documento tinha sido decidida em
   11/09 (tela interna vermelha, documento verde) e o Guto REVOGOU: o
   desconto é a mesma coisa nos dois lugares, e vermelho na tela significa
   bloqueado no resto do sistema. Ver HISTORICO_DECISOES, seção 15. */
/* ★★ Fechamento da fase C (decisão do Guto, QA-005 §8 confirmado): DESCONTO e
   TOTAL em negrito; o VALOR PARCIAL sem — na tela e no documento. (Até aqui o
   desconto ficava sem negrito por uma decisão do QA-005, item 9, que esta
   substitui.) */
.combinacao-matriz__desconto {
  color: var(--cor-status-concluida);
  font-weight: 600;
}

.combinacao-matriz__desconto .combinacao-matriz__sem-valor {
  color: var(--cor-status-concluida);
  opacity: 0.5;
}

/* O CAMPO DE DIGITAÇÃO fica verde, mas sem sinal: quem digita um desconto
   de 10% digita "10", não "−10". O sinal aparece só onde o número é
   LEITURA — o total da linha. */
.combinacao-matriz__campo--desconto {
  color: var(--cor-status-concluida);
}

/* v27 (QA-005, 1.2): a linha "Valor subcontratação" mostra o DELTA (o que
   a taxa acrescenta), e fica em vermelho na linha inteira — é acréscimo
   de custo, o oposto do desconto ao lado.

   v27 (QA-005, item 9): SEM negrito. Ela herdava o `font-weight: 600` de
   `.combinacao-matriz__total-parcial`, e negrito + vermelho davam a uma
   linha de apoio o peso visual de um total. A cor fica; o peso sai. */
.combinacao-matriz__total-parcial--subcontratacao,
.combinacao-matriz__total-parcial--subcontratacao td {
  color: var(--cor-status-bloqueada);
  font-weight: 400;
}

/* v27 (QA-003, C2): a linha "Valor" — a soma antes do desconto — em
   negrito na LINHA INTEIRA, não só no rótulo. Ela abre a cadeia do rodapé
   (Valor -> Desconto -> Valor parcial) e só aparece quando há desconto,
   então destacar o ponto de partida ajuda a ler a subtração. */
.combinacao-matriz__valor-bruto td {
  font-weight: 600;
}

.combinacao-matriz__total-parcial {
  background: var(--cor-neutro-suave);
  /* ★★ fechamento da fase C: o Valor parcial SEM negrito (era 600) */
  font-weight: 400;
}

/* v27 (INSTRUCAO_CC_rev4_total_composicao): coluna "Total" no fim de
   cada linha (modelo/adicional) — só negrito, sem fundo (o fundo já
   marca as linhas de TOTAL POR COLUNA acima, "Total parcial (R$)" etc.;
   esta é por LINHA, mais discreta de propósito pra não confundir os
   dois conceitos). */
.combinacao-matriz__total-linha {
  font-weight: 600;
}

/* v26 (INSTRUCAO_CC_revisao_telas_proposta, 5.2): linha de checkbox
   "Subcontratação" acima de cada coluna de fornecedor, na matriz. */
.combinacao-matriz__subcontratacao-linha th {
  background: var(--cor-fundo);
}

.combinacao-matriz__subcontratado-label {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
  font-size: 0.68rem;
  font-weight: 400;
  white-space: nowrap;
}

.combinacao-matriz__total-parcial--subcontratacao {
  background: var(--cor-verde-suave);
}

/* Rodapé da matriz: Taxa de Subcontratação (só quando há algum
   fornecedor marcado) ao lado do Total geral. */
.combinacao-matriz__rodape {
  display: flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 16px;
  margin: 6px 0 0;
}

.combinacao-matriz__taxa-subcontratacao {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.78rem;
  white-space: nowrap;
}

.combinacao-matriz__taxa-subcontratacao input {
  width: 50px;
  border: 1px solid var(--cor-borda);
  border-radius: 3px;
  padding: 2px 3px;
  font-size: 0.78rem;
  text-align: right;
}

.combinacao-matriz__total-geral {
  font-weight: 700;
  margin: 0;
  text-align: right;
}

/* v26 (INSTRUCAO_CC_revisao_telas_proposta, 5.3): "Informações de
   Contratação" (era "Mais detalhes") — FIXA (sem <details>) abaixo do
   card da combinação ESCOLHIDA, dentro de "Composição de custos". */
.composicao-informacoes-contratacao {
  margin: 10px 0;
  border-top: 1px solid var(--cor-borda);
  padding-top: 8px;
}

.composicao-informacoes-contratacao h4 {
  font-size: 0.85rem;
  margin: 0 0 6px;
}

/* v26 (INSTRUCAO_CC_ajustes_finais_telas_proposta, J6): 1 card por
   fornecedor (Gestão/OC/LAB N), empilhados e visualmente separados —
   substitui a grade solta anterior. */
.informacoes-contratacao__cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.informacoes-contratacao-card {
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 8px 10px;
  background: var(--cor-fundo);
}

.informacoes-contratacao-card__titulo {
  font-weight: 700;
  font-size: 0.85rem;
  margin: 0;
  color: var(--cor-azul);
}

/* Razão social em linha PRÓPRIA, logo abaixo do título — cabe nome
   longo (ex.: "Fundação Cpqd - Centro De Pesquisa E Desenvolvimento Em
   Telecomunicações") sem forçar quebra estranha no layout. */
.informacoes-contratacao-card__razao-social {
  margin: 2px 0 8px;
  font-size: 0.8rem;
  color: var(--cor-cinza);
}

/* v26 (INSTRUCAO_CC_ajuste_final_info_contratacao, K2): UMA linha só —
   Custo | Prazo | Nº de rastreio | Condição de pagamento (Gestão: só
   Custo | Condição de pagamento, sem Prazo/Rastreio). */
.informacoes-contratacao-card__linha {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
}

.informacoes-contratacao-card__custo {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Prazo: caixa ESTREITA, ~do tamanho do rótulo "Prazo" — o "(dias
   úteis)" virou placeholder interno (não é mais parte do rótulo). */
.informacoes-contratacao-card__prazo {
  flex: 0 0 64px;
}

.informacoes-contratacao-card__prazo input {
  width: 100%;
  box-sizing: border-box;
}

/* Nº de rastreio: ~20 caracteres. */
.informacoes-contratacao-card__rastreio {
  flex: 0 0 auto;
}

.informacoes-contratacao-card__rastreio input {
  width: 20ch;
  box-sizing: border-box;
}

/* Condição de pagamento: ocupa o espaço que sobra na linha (flex),
   ao lado do Nº de rastreio (ou do Custo, na Gestão). */
.informacoes-contratacao-card__condicao {
  flex: 1 1 auto;
  min-width: 140px;
}

.informacoes-contratacao-card__condicao input {
  width: 100%;
  box-sizing: border-box;
}

/* ===========================================================================
   Kanban Comercial (INSTRUCAO_CC_kanban_fase2) — substitui a lista de
   Propostas. Estilo sóbrio: cabeçalho de coluna claro com linha fina azul
   no topo, corpo em cinza muito claro, cards brancos com borda suave. Sem
   barra lateral colorida no card, sem legenda de rodapé.
   =========================================================================== */
/* v27 (QA-003): aviso da Composição de Custos — coluna que só existe por
   ter preço lançado, sem serviço que a exija. Âmbar como os outros avisos
   informativos do app (não é erro: é "confira"). */
.combinacao-matriz__aviso {
  margin: 0 0 10px;
  padding: 8px 12px;
  border-left: 3px solid var(--cor-amarelo);
  background: var(--cor-amarelo-suave);
  color: var(--cor-cinza);
  font-size: 13px;
  border-radius: 0 var(--raio) var(--raio) 0;
}

/* v27 (QA-003): o select que substituiu o checkbox de subcontratação.
   Largura AUTOMÁTICA (o conteúdo é "Sim"/"Não", ~70px) — não `100%`.

   Medido no navegador antes de mexer: estreitar este select não muda a
   coluna em nada (214px -> 214px); quem manda na largura é o select de
   FORNECEDOR logo acima (214px -> 178px quando estreitado) somado ao fato
   de a tabela ocupar a largura toda e distribuir a sobra entre as colunas.
   O `100%` daqui não CAUSAVA a coluna larga — só fazia o campo esticar
   até a borda dela, que é o que dava a impressão de ser o culpado.

   Sem o `100%`, o campo fica do tamanho do que mostra e alinhado com o
   select de fornecedor acima. */
.combinacao-matriz__subcontratacao {
  font-size: 12px;
  font-weight: normal;
}

/* v27 (QA-003, ajuste 03/09): rótulo das linhas de rodapé da matriz
   (Subcontratação / Desconto / Total parcial / Total parcial
   subcontratação). Todos ocupam a MESCLA Modelo+Serviço — sem ela o texto
   cai na coluna estreita de Modelo e quebra em várias linhas. Alinhado à
   direita porque o rótulo aponta pros valores que vêm à direita dele. */
.combinacao-matriz__rotulo-linha {
  text-align: right;
  white-space: nowrap;
}

/* v27 (QA-003): "Subcontratação" sem negrito. Ele mora num <th> (está na
   faixa de cabeçalho da tabela, junto da linha de fornecedores), e <th>
   nasce bold — mas o que ele rotula é uma linha de escolha, não um
   cabeçalho de coluna. Desconto/Total parcial continuam como estavam. */
.combinacao-matriz__subcontratacao-linha .combinacao-matriz__rotulo-linha {
  font-weight: normal;
}


/* v27 (QA-003, C3): a linha de um serviço adicional da Moderacon —
   checkbox + Fornecedor + Preço + Custo + Rastreio, tudo numa linha só.
   `flex-wrap` porque são 5 controles e a coluna do painel é estreita: sem
   ele o Rastreio sairia da caixa em telas menores. */
.adicional-linha {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 6px 0;
}

.adicional-linha + .adicional-linha {
  border-top: 1px solid var(--cor-borda);
}

.adicional-linha__ligar {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 165px;
  font-size: 13px;
  white-space: nowrap;
}

.adicional-linha__campo {
  font-size: 12px;
  padding: 4px 6px;
}

.adicional-linha__campo--valor { width: 92px; text-align: right; }
.adicional-linha__campo--rastreio { width: 120px; }
/* O select-busca traz largura própria; aqui só se define o espaço dele. */
.adicional-linha__campo--fornecedor { flex: 0 1 190px; min-width: 150px; }


/* v27 (QA-003, C1): o seletor R$ / % do desconto, ao lado do rótulo. Fica
   pequeno e inline — é um toggle de 2 opções, não um campo de dado. */
.combinacao-matriz__desconto-modo {
  margin-left: 6px;
  font-size: 11px;
  font-weight: normal;
  padding: 1px 2px;
}


/* v27 (base ANATEL): a consulta à base de homologados. */
.anatel-busca {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.anatel-busca__campo {
  flex: 1 1 340px;
  max-width: 460px;
  padding: 7px 10px;
  font-size: 14px;
}

.anatel-busca__ocd { padding: 6px 8px; font-size: 13px; }

.anatel-busca__total {
  font-size: 13px;
  color: var(--cor-cinza);
  white-space: nowrap;
}

/* Teto pela JANELA, não em pixels — a mesma correção feita na matriz de
   custos: com poucos resultados a tabela não rola, e a barra volta só
   quando de fato não cabe. O `overflow` fica (é ele que segura o thead
   sticky no topo da tabela). */
.anatel-tabela__scroll {
  max-height: 66vh;
  overflow: auto;
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
}

.anatel-tabela {
  border-collapse: collapse;
  width: 100%;
  font-size: 12.5px;
}

.anatel-tabela th,
.anatel-tabela td {
  border-bottom: 1px solid var(--cor-borda);
  padding: 5px 8px;
  text-align: left;
  vertical-align: top;
}

.anatel-tabela thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--cor-fundo);
  font-weight: 600;
  white-space: nowrap;
}

/* Nº de homologação e CNPJ vêm mascarados e têm largura fixa — não devem
   quebrar em duas linhas. */
.anatel-tabela__numero { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Texto só pra leitor de tela: sai do fluxo visual sem sair da árvore de
   acessibilidade (`display:none` sumiria pros dois). É o que carrega o
   sentido da faixa de prazo pra quem não vê o glifo nem a cor. */
.visualmente-oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* v27 (Manutenção) — A FAIXA DE PRAZO na coluna de dias. TRÊS faixas
   (08/09/2026): vencido, até 125 dias, acima de 125.

   O corte de 65 saiu SÓ DA COR — a segunda cobrança do ciclo continua aos
   65 dias. Quatro faixas com vermelho e laranja vizinhos se liam pior de
   relance do que três.

   SEM GLIFO. Eles existiam pra faixa não depender só da cor, e quem faz esse
   trabalho aqui é O PRÓPRIO NÚMERO DE DIAS, que fica dentro do chip — diz
   mais que a cor diria, inclusive o sinal do vencido. O `title` e o texto
   oculto (`.visualmente-oculto`) FICAM: são eles que carregam o sentido pra
   quem não vê a cor. */
.prazo {
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.prazo--vencido {
  color: var(--cor-status-bloqueada);
  background: var(--cor-status-bloqueada-suave);
  border-color: #F0C5BF;
}

.prazo--atencao {
  color: var(--cor-amarelo);
  background: var(--cor-amarelo-suave);
  border-color: #EDDCB4;
}

.prazo--folga {
  color: var(--cor-verde);
  background: var(--cor-verde-suave);
  border-color: #C9E4D3;
}

/* v27 (08/09/2026) — a BUSCA entrou na mesma linha do Dono e da Pendência.
   São três recortes do MESMO conjunto, e separá-los em blocos sugeria que
   faziam coisas diferentes; quem filtrava por dono subia os olhos pra
   confirmar o que estava buscando.

   A busca ganha `flex: 1` porque é o único dos três que aceita texto de
   tamanho livre — os outros dois são selects de largura conhecida. */
.anatel-filtros { align-items: flex-end; }

.anatel-filtros__busca {
  flex: 1 1 260px;
  min-width: 200px;
}

.anatel-filtros__busca .anatel-busca__campo { width: 100%; }

/* A legenda das cores fica junto do resumo, e não num rodapé: agora que a
   lista é ordenada por prazo e não há mais filtro de faixa, ela é o que
   explica a coluna de dias — inclusive o que distingue o suspenso, que
   deixou de ter bloco próprio. */
.prazo-legenda {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: 11px;
}

.prazo-legenda .prazo { font-weight: 500; }

/* v27 (Manutenção) — o ARQUIVO recolhido. `<details>` nativo: sem JS, e o
   estado de aberto/fechado é decidido no servidor (ver o template), o que
   sobrevive ao swap do htmx — um `<details>` controlado por JS voltaria
   fechado a cada digitada na busca.

   O `summary` some do fluxo normal e vira o próprio cabeçalho do cartão,
   pra o contador ficar legível fechado. */
.manutencao-arquivo > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.manutencao-arquivo > summary::-webkit-details-marker { display: none; }

/* A seta vem do `::before` e gira ao abrir — o marcador nativo não aceita
   estilo consistente entre navegadores. */
.manutencao-arquivo > summary::before {
  content: "\25b8";
  color: var(--cor-cinza);
  transition: transform .12s ease;
}

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

.manutencao-arquivo > summary h2 { margin: 0; }

.manutencao-arquivo__contador {
  color: var(--cor-cinza);
  font-size: 12px;
  font-weight: 400;
}

/* v27 (Manutenção) — o aviso da regra por NOME de fabricante. Âmbar e não
   vermelho: não é erro nem impedimento, é uma escolha com um custo que só
   aparece meses depois. */
.manutencao-aviso {
  border-left: 3px solid var(--cor-amarelo);
  background: var(--cor-amarelo-suave);
  padding: 8px 10px;
  border-radius: 0 var(--raio) var(--raio) 0;
}

.manutencao-aviso__marca {
  color: var(--cor-amarelo);
  cursor: help;
}

/* v27 (Manutenção) — o botão "reabrir" da linha arquivada. Texto e não
   ícone: é uma ação rara, e um glifo sozinho numa coluna que só existe no
   bloco do arquivo não se explica. Mesmo desenho do `.botao-detalhes`, em
   tamanho de tabela. */
.botao-linha {
  background: none;
  border: none;
  padding: 2px 4px;
  color: var(--cor-azul);
  font-family: var(--fonte-texto);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.botao-linha:hover { text-decoration: underline; }

/* v27 (Manutenção) — a célula que VIRA campo ao clicar.

   Parece texto e é botão: o seletor de cliente passou a ser carregado sob
   demanda (era 92% do peso da tela), e a célula fechada precisa mostrar o
   nome POR EXTENSO — é a resposta de "de quem é este certificado?".

   `<button>` e não `<span>` pelo teclado: quem navega com Tab alcança e
   abre com Enter, como alcançava o seletor de antes.

   Sem `overflow: hidden` de propósito: dos 21 clientes em uso, 19 cabem nos
   256px da coluna e os dois maiores a esticam ~19px. Truncar economizaria
   pixel e custaria a informação. */
.celula-editavel {
  width: 100%;
  text-align: left;
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 3px 5px;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.celula-editavel:hover,
.celula-editavel:focus {
  border-color: var(--cor-borda);
  background: var(--cor-fundo);
}

/* v27 (Manutenção) — o alerta de renovação sem o nosso serviço, na célula
   do CCT. Âmbar por padrão (perda de serviço) e VERMELHO quando o OCD mudou
   — aí não é só "não precisou da gente", é portabilidade pra concorrência,
   e as duas não podem se ler igual de relance. */
.renovacao-alerta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid #EDDCB4;
  background: var(--cor-amarelo-suave);
  color: var(--cor-amarelo);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
}

.renovacao-alerta--outro-ocd {
  border-color: #F0C5BF;
  background: var(--cor-status-bloqueada-suave);
  color: var(--cor-status-bloqueada);
}

/* O CCT anterior em peso normal: ele é referência, não o alerta. */
.renovacao-alerta__antes { font-weight: 400; opacity: .85; }

.renovacao-alerta .botao-linha { color: inherit; font-size: 11px; }

/* v27 (Manutenção) — o histórico da linha. `<details>` nativo: fechado por
   padrão, sem JS e sem endpoint. O painel é absoluto pra não empurrar a
   altura da linha ao abrir — numa tabela de 125 linhas, abrir um histórico
   e ver a tabela inteira pular tira a referência de onde se estava. */
.manutencao-hist { position: relative; display: inline-block; }

.manutencao-hist > summary {
  cursor: pointer;
  color: var(--cor-azul);
  font-variant-numeric: tabular-nums;
}

.manutencao-hist__lista {
  position: absolute;
  right: 0;
  z-index: 5;
  min-width: 320px;
  max-height: 240px;
  overflow-y: auto;
  margin: 4px 0 0;
  padding: 8px 10px 8px 22px;
  background: var(--cor-branco);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  box-shadow: var(--sombra);
  font-size: 11px;
  line-height: 1.5;
}

/* O modelo mesclado chega a ~2.700 caracteres; sem teto ele empurra as
   outras colunas pra fora. O `title` da célula mostra o texto inteiro.

   v27 (ajuste, 11 colunas): teto menor. Com CCT, Tipo do produto e
   Requerimento na tabela, o Modelo a 260px empurrava o resto pra fora cedo
   demais; a 200px a rolagem horizontal só começa quando é inevitável. */
.anatel-tabela__modelo {
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ★ CADA TABELA ANATEL É DONA DAS PRÓPRIAS LARGURAS, POR NOME.

   Até 08/09/2026 havia uma regra Única por POSIÇÃO
   (`.anatel-tabela td:nth-child(4),(5),(10),(11)`) valendo para as três
   telas. Ela nasceu para a Homologação de 11 colunas — o comentário antigo
   dizia "Fabricante (4), Solicitante (5), Tipo (10), Requerimento (11)" — e
   pegava a Acumulativa POR ACIDENTE, onde aquelas posições são Cancelado,
   Ano, OCD e Validade. Era inofensivo por sorte (as quatro são curtas), e
   deixava sem teto justamente as colunas longas da Acumulativa.

   `nth-child` amarra largura a posição, e posição significa coisas
   diferentes em cada tela — então reordenar uma quebrava as outras sem dar
   erro. Agora cada uma declara as suas, e o nome da classe diz de quem é.

   Comum às três: teto de 190px com reticências e o texto inteiro no `title`.
   Sem teto, uma razão social longa ocupa 5 linhas e a altura da linha
   dispara. Numa tabela de consulta, altura fixa vale mais que ver o nome
   inteiro — que continua a um hover de distância. */

/* HOMOLOGAÇÃO — 11 colunas:
   Data · Nº · Modelo · Solicitante · CNPJ · Fabricante · Validade · OCD ·
   CCT · Tipo do produto · Requerimento */
.anatel-tabela--homologacao td:nth-child(6),    /* Fabricante */
.anatel-tabela--homologacao td:nth-child(10),   /* Tipo do produto */
.anatel-tabela--homologacao td:nth-child(11) {  /* Requerimento */
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ACUMULATIVA — 13 colunas. As longas são Solicitante (7) e Tipo (13); o
   Modelo (12) já tem `.anatel-tabela__modelo`. As duas estavam SEM TETO
   até aqui, porque a regra por posição mirava outras colunas. */
.anatel-tabela--acumulativa td:nth-child(7),
.anatel-tabela--acumulativa td:nth-child(13) {
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ★ HOMOLOGAÇÃO: AS QUATRO PRIMEIRAS COLUNAS SÃO CONGELADAS.

   MEDIDO com as métricas reais da Inter antes de escolher, e a escolha foi
   entre cenários: as quatro a plena largura davam 652px, 53% da largura útil
   num notebook de 1366 — mais de metade da tela para identificar a linha.

   Duas reduções sem custo de informação derrubaram para 550px (44%):

     • o cabeçalho virou "Data" (27,8px) em vez de "Homologação" (83,7px).
       Ali o CABEÇALHO mandava na largura, não o valor (49,6px) — numa
       coluna congelada isso custa a tela toda. O nome completo foi pro
       `title`.
     • o Solicitante caiu para 120px de texto. A 190px só 26% dos nomes
       cabiam inteiros; a 120px são 4% — mas 94 dos 95 solicitantes que são
       clientes cadastrados continuam com PREFIXO DISTINTO (a única colisão
       é Yamaha Amazônia × Yamaha Brasil), e o nome inteiro está no `title`.

   A mesma largura vale na Manutenção, de propósito: a mesma coluna com
   larguras diferentes entre abas incomoda a troca.

   `left` DERIVADO por `calc()` das larguras — ver a nota da Manutenção. */
.anatel-tabela--homologacao th:nth-child(1),
.anatel-tabela--homologacao td:nth-child(1),
.anatel-tabela--homologacao th:nth-child(2),
.anatel-tabela--homologacao td:nth-child(2),
.anatel-tabela--homologacao th:nth-child(3),
.anatel-tabela--homologacao td:nth-child(3),
.anatel-tabela--homologacao th:nth-child(4),
.anatel-tabela--homologacao td:nth-child(4) {
  position: sticky;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: var(--cor-branco);
}

.anatel-tabela--homologacao th:nth-child(1),
.anatel-tabela--homologacao td:nth-child(1) {
  left: 0;
  width: var(--hom-1);
  min-width: var(--hom-1);
  max-width: var(--hom-1);
}

.anatel-tabela--homologacao th:nth-child(2),
.anatel-tabela--homologacao td:nth-child(2) {
  left: var(--hom-1);
  width: var(--hom-2);
  min-width: var(--hom-2);
  max-width: var(--hom-2);
}

.anatel-tabela--homologacao th:nth-child(3),
.anatel-tabela--homologacao td:nth-child(3) {
  left: calc(var(--hom-1) + var(--hom-2));
  width: var(--hom-3);
  min-width: var(--hom-3);
  max-width: var(--hom-3);
}

.anatel-tabela--homologacao th:nth-child(4),
.anatel-tabela--homologacao td:nth-child(4) {
  left: calc(var(--hom-1) + var(--hom-2) + var(--hom-3));
  width: var(--hom-4);
  min-width: var(--hom-4);
  max-width: var(--hom-4);
  box-shadow: inset -1px 0 0 var(--cor-borda), 2px 0 4px rgba(9, 76, 133, 0.06);
}

.anatel-tabela--homologacao thead th:nth-child(-n+4) {
  z-index: 3;
  background: var(--cor-fundo);
}

.anatel-tabela--homologacao tbody td:nth-child(-n+4) {
  z-index: 1;
  box-shadow: inset 0 -1px 0 var(--cor-borda);
}

.anatel-tabela--homologacao tbody td:nth-child(4) {
  box-shadow: inset -1px 0 0 var(--cor-borda),
              inset 0 -1px 0 var(--cor-borda),
              2px 0 4px rgba(9, 76, 133, 0.06);
}

.anatel-tabela--homologacao {
  --hom-1:  88px;   /* Data — ★ (22/10/2026, Guto) dd/mm/aaaa: a 66px (dd/mm/aa) o ano virava reticência — medido
                       pelo smoke_datas_com_ano, 50 de 100 células cortadas (69px de texto numa caixa de 66) */
  --hom-2: 132px;   /* Nº — 14 caracteres TABULARES, mesma conta da Manutenção */
  --hom-3: 216px;   /* Modelo */
  --hom-4: 136px;   /* Solicitante — 120px de texto + padding */
  min-width: 1591px;   /* ★ +22: a coluna Data (66 → 88) */
}

/* v27 (Manutenção) — ★ A EXCLUSÃO ACIMA É O PONTO, e não detalhe de estilo.
   `nth-child` amarra largura a POSIÇÃO, e a posição significa coisas
   diferentes em cada tela: em Homologação e Acumulativa (11 colunas) a 4 é
   Fabricante e a 5 é Solicitante; na Manutenção, depois da reordenação, a 4
   é Fabricante e a 5 virou Validade. Sem o `:not`, esta tabela herdaria
   teto de 190px numa coluna de data e nenhum nas que precisam — e as OUTRAS
   DUAS TELAS quebrariam junto se alguém mexesse aqui achando que é só da
   Manutenção. As larguras desta tabela ficam todas no bloco abaixo, por
   nome do que a coluna É. */

/* AS TRÊS PRIMEIRAS COLUNAS SÃO CONGELADAS — Nº, Solicitante e Modelo ficam
   à vista enquanto o resto rola na horizontal.

   MEDIDO com as métricas reais da INTER — que é a fonte que renderiza:

     congelado 554px  →  31% da largura útil em 1920, 38% em 1600, 45% em 1366
     tabela inteira 1.884px  →  rola 92px em 1920, 412px em 1600, 646px em 1366

   ★ DUAS LIÇÕES CARAS, as duas sobre MEDIR A COISA ERRADA. A primeira versão
   usou Arial como proxy e errou 12% (a Inter é mais larga). A segunda mediu a
   Inter, mas os glifos PADRÃO — e a célula desenha os TABULARES, que são
   outros. Ver a nota da coluna 1. Só serve medir a fonte que renderiza, no
   estado em que ela renderiza.

   O CUSTO CONHECIDO, e ele foi aceito de olhos abertos: em notebook a janela
   que sobra é de 702px, e o bloco de trabalho (Status + Cliente + Dono + Obs
   + Hist.) soma 775px — ou seja, as quatro colunas editáveis NÃO cabem todas
   na vista ao mesmo tempo num 1366. Em 1600 cabem (936px). Se um dia isso
   incomodar, o ajuste barato é estreitar o Solicitante: a 120px ele ainda
   distingue 94 dos 95 solicitantes que são clientes cadastrados (a única
   colisão é Yamaha Amazônia × Yamaha Brasil), e libera os 70px que faltam.

   LARGURA FIXA, e não `max-width`: o `left` de cada congelada é a SOMA das
   anteriores. Com teto variável elas flutuariam umas por cima das outras ou
   deixariam fresta, conforme o conteúdo de cada página.

   `box-sizing: border-box` vale aqui (reset global no topo do arquivo), então
   estes valores JÁ INCLUEM os 16px de padding — e por isso os `left` batem
   com as larguras sem soma extra. Trocar o padding da tabela obriga a
   recalcular os três.

   FUNDO OPACO obrigatório: célula sticky sem fundo deixa o texto que rola por
   baixo aparecer através dela.

   BORDA POR `box-shadow`, e não `border-right`: com `border-collapse:
   collapse` o Chrome NÃO pinta a borda de célula sticky — a borda pertence à
   tabela, não à célula deslocada. A sombra é desenhada pela própria célula e
   acompanha o deslocamento. */
.anatel-tabela--manutencao th:nth-child(1),
.anatel-tabela--manutencao td:nth-child(1),
.anatel-tabela--manutencao th:nth-child(2),
.anatel-tabela--manutencao td:nth-child(2),
.anatel-tabela--manutencao th:nth-child(3),
.anatel-tabela--manutencao td:nth-child(3) {
  position: sticky;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  background: var(--cor-branco);
}

/* Nº — 130px. O NÚMERO É EXATO, não uma estimativa, e a razão está aqui.

   ★ DUAS TENTATIVAS ANTERIORES CORTARAM O VALOR, e a causa não era a largura
   nem a fonte: era O GLIFO. A célula tem `font-variant-numeric: tabular-nums`
   (herdado de `.anatel-tabela__numero`), e a Inter atende isso trocando os
   glifos por um conjunto SEPARADO, o `.tf`:

     dígitos  padrão 0,4067–0,6460 em (variáveis)  →  .tf 0,6484 em (uniforme)
     HÍFEN    padrão 0,4600 em                     →  .tf 0,6484 em

   Medir o `hmtx` pelo `cmap` entrega os glifos PADRÃO — que não são os
   desenhados. O erro grosso estava no hífen: contei dois estreitos onde o
   navegador desenha dois da largura de um dígito.

   Com tabular, os 14 caracteres têm largura IDÊNTICA, então o cálculo deixa
   de ser uma cota superior e passa a ser exato:

     14 × 0,6484 em × 12,5px = 113,47px de texto + 16 de padding = 129,47px

   132px, e os 2,53px de sobra NÃO são chute: são margem de ARREDONDAMENTO.
   O navegador resolve largura de layout em pixels físicos, e em tela com
   escala fracionária (125%, o padrão do Windows em notebook) o arredondamento
   come fração de pixel CSS. 0,5px de folga não sobrevive a isso; 2,5px sim.

   A métrica tabular é praticamente invariante ao peso (0,6484 em 400, 0,6470
   em 600), então o `<th>` semibold não desalinha a coluna do próprio título.

   O CABEÇALHO FOI ABREVIADO PARA "Nº" (15,6px) exatamente pra ele nunca
   disputar: aqui quem tem que caber inteiro é o valor. O nome completo foi
   pro `title` do `<th>`. */
.anatel-tabela--manutencao th:nth-child(1),
.anatel-tabela--manutencao td:nth-child(1) {
  left: 0;
  width: var(--congelada-1);
  min-width: var(--congelada-1);
  max-width: var(--congelada-1);
}

/* Modelo — 87% dos valores cabem inteiros aqui; o resto trunca com o texto
   completo no `title`. */
.anatel-tabela--manutencao th:nth-child(2),
.anatel-tabela--manutencao td:nth-child(2) {
  /* Derivado, e não escrito à mão: ver a nota do bloco de variáveis. */
  left: var(--congelada-1);
  width: var(--congelada-2);
  min-width: var(--congelada-2);
  max-width: var(--congelada-2);
}

/* Solicitante — 136px, A MESMA LARGURA DA HOMOLOGAÇÃO. A mesma coluna com
   larguras diferentes entre abas incomoda quem alterna, e aqui truncar custa
   ainda menos: em 125 das linhas o solicitante é "MODERACON", idêntico em
   todas — uma âncora que repete não ancora nada.

   O nome inteiro fica no `title`. Estreitar devolveu 70px às colunas de
   trabalho: em 1600 o bloco de Status/Cliente/Dono/Obs passou a caber
   inteiro na janela (988px para 777px); em 1366 ainda faltam 23px, contra
   93px antes. */
.anatel-tabela--manutencao th:nth-child(3),
.anatel-tabela--manutencao td:nth-child(3) {
  left: calc(var(--congelada-1) + var(--congelada-2));
  width: var(--congelada-3);
  min-width: var(--congelada-3);
  max-width: var(--congelada-3);
  box-shadow: inset -1px 0 0 var(--cor-borda), 2px 0 4px rgba(9, 76, 133, 0.06);
}

/* O `thead` já é sticky no topo (z-index 1). As três células de canto são
   sticky nos DOIS eixos e precisam vencer as duas camadas — senão o
   cabeçalho passa por cima da coluna congelada ou vice-versa, dependendo da
   ordem no documento. */
.anatel-tabela--manutencao thead th:nth-child(1),
.anatel-tabela--manutencao thead th:nth-child(2),
.anatel-tabela--manutencao thead th:nth-child(3) {
  z-index: 3;
  background: var(--cor-fundo);
}

.anatel-tabela--manutencao tbody td:nth-child(1),
.anatel-tabela--manutencao tbody td:nth-child(2),
.anatel-tabela--manutencao tbody td:nth-child(3) {
  z-index: 1;
  /* A borda de baixo também se perde no sticky, pelo mesmo motivo da
     lateral. Reposta por sombra pra a linha não "abrir" ao rolar. */
  box-shadow: inset 0 -1px 0 var(--cor-borda);
}

.anatel-tabela--manutencao tbody td:nth-child(3) {
  box-shadow: inset -1px 0 0 var(--cor-borda),
              inset 0 -1px 0 var(--cor-borda),
              2px 0 4px rgba(9, 76, 133, 0.06);
}

/* AS COLUNAS DE TRABALHO, dimensionadas PELO CONTEÚDO QUE RECEBEM — medido,
   não arbitrado (larguras de texto reais a 12px, o tamanho dos controles):

     Status  (4 opções, maior "Solicitada")  ...  89px + seta do select
     Dono    (lista fechada de internos)      ... 102px, "— sem dono —"
     Cliente (256 opções)                     ... 240px cobre 95% dos rótulos
     Obs     (texto livre)                    ... 240px, sem conteúdo a medir

   A ROLAGEM HORIZONTAL É CONSEQUÊNCIA ACEITA: a tabela passa a 1.866px, mais
   larga que a janela em qualquer tela abaixo de 1994px. O que não pode
   acontecer é o contrário — select de cliente estreito demais mostrando
   "Bay Area Complian…" em 40 linhas seguidas, indistinguíveis entre si. */
.anatel-tabela--manutencao td:nth-child(9),
.anatel-tabela--manutencao th:nth-child(9) { min-width: 105px; }

.anatel-tabela--manutencao td:nth-child(10),
.anatel-tabela--manutencao th:nth-child(10) { min-width: 256px; }

.anatel-tabela--manutencao td:nth-child(11),
.anatel-tabela--manutencao th:nth-child(11) { min-width: 118px; }

.anatel-tabela--manutencao td:nth-child(12),
.anatel-tabela--manutencao th:nth-child(12) { min-width: 256px; }

/* Fabricante (4) é a única outra coluna de texto longo que fica solta — p90
   de 292px de texto. Sem teto, uma razão social de 95 caracteres empurra as
   colunas de trabalho ainda mais pra fora. */
.anatel-tabela--manutencao td:nth-child(4) {
  max-width: 206px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ★ AS LARGURAS DAS CONGELADAS MORAM AQUI, E OS `left` SÃO DERIVADOS DELAS
   POR `calc()`.

   O `left` de cada congelada tem que ser a SOMA das anteriores. Escrito à
   mão, um ajuste de largura desencaixa o deslocamento e uma coluna passa a
   flutuar por cima da outra — sem erro de CSS, sem aviso, só texto sobreposto
   que alguém nota dias depois. Com `calc()` sobre estas variáveis, mexer numa
   largura arruma os deslocamentos sozinho.

   Em px e não em `ch`: `ch` resolveria contra a fonte do elemento onde é
   USADO, e o `<th>` tem `font-weight: 600` — cabeçalho e célula ganhariam
   larguras diferentes e a coluna desalinharia do próprio título.

   `min-width` na tabela inteira porque `width: 100%` sozinho a faria tentar
   caber na caixa e ignorar os `min-width` das colunas em tela estreita; com
   ele a tabela assume a largura de que precisa e o `__scroll` (que já tem
   `overflow: auto`) rola. */
.anatel-tabela--manutencao {
  --congelada-1: 132px;   /* Nº — 14 caracteres TABULARES, ver acima */
  --congelada-2: 216px;   /* Modelo */
  --congelada-3: 136px;   /* Solicitante — MESMA largura da Homologação */
  min-width: 1814px;      /* = 484 congelados + 1.330 do resto */
}

/* v27 (correção manual de OCD): a tela de Config e o botão da tela de
   Homologação. */
.ocd-tabela { width: 100%; font-size: 12.5px; }
.ocd-tabela th, .ocd-tabela td { padding: 4px 6px; text-align: left; vertical-align: middle; }
.ocd-campo { width: 100%; font-size: 12px; padding: 3px 5px; }
.ocd-campo--ordem { width: 56px; text-align: right; }
.ocd-numero { white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Regra desativada continua visível, só apagada — some da aplicação sem
   sumir da tela, que é o ponto de ter "ativa" em vez de só remover. */
.ocd-regra--inativa { opacity: 0.5; }

.ocd-nova {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.ocd-nova input { font-size: 12px; padding: 4px 6px; }
.ocd-nova input[name="texto"], .ocd-nova input[name="numero_homologacao"] { flex: 0 1 200px; }
.ocd-nova input[name="observacao"] { flex: 1 1 200px; }

/* O "não identificado" da tabela de Homologação vira botão. Parece link, não
   botão de ação: é um convite discreto, no meio de uma tabela de leitura. */
.ocd-corrigir {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--cor-atencao);
  text-decoration: underline dotted;
  cursor: pointer;
  white-space: nowrap;
}

.ocd-corrigir:hover { text-decoration: underline; }


.kanban-board {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding-bottom: 8px;
  /* v27 (C5): SEM overflow aqui, de propósito. `overflow-x: auto` faz o
     `overflow-y` computar `auto` junto (regra do CSS: um eixo não-visible
     arrasta o outro) — e aí o board vira o container de rolagem, e o
     `position: sticky` do cabeçalho passa a grudar NELE em vez de na
     janela, ou seja, não gruda em nada. Medido: cabeçalho ia a -510px ao
     rolar 700px. Sem overflow, a página é o único scroller e o cabeçalho
     gruda de verdade. A rolagem lateral volta só no breakpoint estreito
     abaixo, onde as 4 colunas não cabem — lá o sticky se perde, e é a
     troca certa: em tela estreita a coluna é curta e o cabeçalho está
     sempre à vista. */
}

/* 4 colunas de 250px + 3 gaps de 12px + respiro da página ≈ 1080px. */
@media (max-width: 1080px) {
  .kanban-board {
    overflow-x: auto;
  }
}

.kanban-coluna {
  flex: 1 1 0;
  min-width: 250px;
  max-width: 340px;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  /* v27 (QA-002, C5): `overflow: hidden` SAIU. Ele existia só pra o fundo
     respeitar o `border-radius`, e é ele que cortaria o cabeçalho sticky
     — um ancestral com overflow diferente de `visible` vira o container
     de rolagem do sticky, e o cabeçalho grudaria no topo da COLUNA (onde
     já está) em vez do topo da janela. O arredondamento é reposto no
     cabeçalho e no rodapé da lista. */
}

.kanban-coluna__cabecalho {
  background: var(--cor-branco);
  border-top: 3px solid var(--cor-azul);
  border-bottom: 1px solid var(--cor-borda);
  padding: 8px 10px;
  /* v27 (QA-002, C5): gruda no topo ao rolar — com a rolagem única, sem
     isto o nome da etapa, o contador, a soma e o "+" saem de vista e não
     se sabe mais em que coluna se está. `z-index` porque o card tem fundo
     próprio e passaria por cima. O arredondamento de cima vem pra cá
     (saiu do `overflow: hidden` da coluna). */
  position: sticky;
  top: 0;
  z-index: 2;
  border-top-left-radius: var(--raio);
  border-top-right-radius: var(--raio);
}

.kanban-coluna__titulo-linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.kanban-coluna__titulo {
  font-family: var(--fonte-titulo);
  font-weight: 700;
  font-size: 0.85rem;
  color: #1a1a1a;
}

/* Contador — bolha DISCRETA (pedido explícito: nada chamativo). */
.kanban-coluna__contador {
  background: var(--cor-neutro-suave);
  color: var(--cor-cinza);
  font-size: 0.72rem;
  font-weight: 700;
  border-radius: 999px;
  padding: 1px 8px;
  min-width: 1.4em;
  text-align: center;
}

.kanban-coluna__acoes {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 4px;
}

/* form do botão "+" — não deve ocupar espaço/quebrar o flex da linha
   acima dele, o <button> filho vira o item flex de verdade. */
.kanban-coluna__soma {
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--cor-status-concluida);
}

/* v26 (INSTRUCAO_CC_acertos_cabecalho_e_criacao, B): virou <button> de
   um <form method="post"> (era <a>) — cria a proposta na hora e
   redireciona pro detalhe, sem passar por formulário intermediário.
   Resets de <button> (background/padding/font) pra ficar idêntico ao
   "+" de antes.
   v26 (INSTRUCAO_CC_kanban_oportunidade_obrigatoria): virou <span>
   clicável (hx-get abre o modal pedindo o número de oportunidade,
   mesmo padrão de `.icone-decisao`) — mesmo visual, só a tag mudou. */
.kanban-coluna__novo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1px solid var(--cor-borda);
  background: transparent;
  color: var(--cor-azul);
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  font-weight: 700;
  text-decoration: none;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
}

.kanban-coluna__novo:hover {
  background: var(--cor-status-avaliado-suave);
}

.kanban-coluna__cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
  min-height: 60px;
  /* v27 (QA-002, C5): ROLAGEM ÚNICA. Eram `max-height: calc(100vh - 280px)`
     + `overflow-y: auto` — cada coluna rolava sozinha, e comparar duas
     etapas exigia rolar as duas. Agora quem rola é a página: as 4 colunas
     descem juntas e o corpo inteiro acompanha.

     Não há paginação nem lazy-load por coluna (o board vem inteiro numa
     query só), então nada mais precisou mudar pra "descer tudo junto". */
  border-bottom-left-radius: var(--raio);
  border-bottom-right-radius: var(--raio);
}

/* Card fantasma do SortableJS durante o arraste. */
.kanban-card--fantasma {
  opacity: 0.4;
}

.kanban-card {
  display: flex;
  gap: 8px;
  background: var(--cor-branco);
  border: 1px solid var(--cor-borda);
  border-radius: 8px;
  padding: 6px 8px;
  cursor: grab;
  /* v26 (INSTRUCAO_CC_nota_de_teste_implementacao, Frente B): +1pt — era
     0.78rem (~9.4pt), letra pequena demais pra ler no card. Escopado SÓ
     ao card (`.kanban-card`, não compartilhado com a barra de controles
     da tela de Proposta, que tem seu próprio namespace de classes
     `.comercial-proposta__*`) — não estica a barra. */
  font-size: 0.86rem;
}

.kanban-card:active {
  cursor: grabbing;
}

/* v26 (INSTRUCAO_CC_kanban_fase3, Parte A): coluna estreita à esquerda
   — avatar / follow-up / termômetro, de cima pra baixo. */
.kanban-card__esquerda {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding-top: 1px;
}

.kanban-card__direita {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.kanban-card__linha1 {
  display: flex;
  align-items: center;
  gap: 6px;
}

.kanban-card__codigo {
  color: var(--cor-azul);
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
  flex: 0 0 auto;
}

.kanban-card__codigo:hover {
  text-decoration: underline;
}

/* v26 (INSTRUCAO_CC_kanban_fase5_menu, 0): Cliente sobe pra linha 1, ao
   lado do Nº — trunca com "..." se não couber (o Nº nunca encolhe). */
.kanban-card__cliente {
  flex: 1 1 auto;
  min-width: 0;
  color: #1a1a1a;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Etiqueta editável DIRETO no card — parece texto solto até o hover/foco
   (sem caixa visível, "campo fantasma"). v26 (INSTRUCAO_CC_kanban_
   fase5_menu, 0): desceu pra linha 2, sozinha — ocupa a largura toda
   (texto livre pode ser maior que o nome do cliente). */
.kanban-card__etiqueta {
  display: block;
  width: 100%;
  /* v26 (INSTRUCAO_CC_kanban_icone_calendario, 3): margin-top 2px -> 16px
     — alinha o CENTRO vertical da linha da etiqueta com o CENTRO do
     ícone do calendário (coluna esquerda), que cresceu (18px -> 30px,
     item 1 desta instrução) e empurrou sua própria posição pra baixo.
     Medido ao vivo (Playwright): sem este ajuste a etiqueta ficava 14px
     ACIMA do centro do calendário; 16px de margin-top fecha a conta
     exatamente (era 2px, +14px). */
  margin: 16px 0 0;
  border: 1px solid transparent;
  background: transparent;
  color: var(--cor-cinza);
  font-family: var(--fonte-texto);
  /* +1pt, mesmo ajuste do resto do card (Frente B) — era 0.76rem. */
  font-size: 0.84rem;
  padding: 1px 3px;
  border-radius: 3px;
}

.kanban-card__etiqueta:hover,
.kanban-card__etiqueta:focus {
  border-color: var(--cor-borda);
  background: var(--cor-fundo);
  outline: none;
}

/* Rodapé do conteúdo à direita — valor à esquerda, ícones de decisão no
   canto inferior direito (empurrados pra baixo via margin-top:auto). */
.kanban-card__rodape {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: auto;
  padding-top: 4px;
}

.kanban-card__valor {
  color: var(--cor-status-concluida);
  font-weight: 700;
  white-space: nowrap;
}

/* v26 (INSTRUCAO_CC_kanban_fase3, A1): avatar do responsável — círculo
   com a inicial, topo da coluna esquerda, SEMPRE visível. */
.avatar-responsavel {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--cor-neutro-suave);
  color: var(--cor-cinza);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.66rem;
  font-weight: 700;
  flex-shrink: 0;
}

/* Termômetro — <select> nativo "disfarçado" (o navegador abre a lista de
   opções ao clicar nele normalmente — o "popover" pedido, sem JS extra).
   COMPARTILHADO card do Kanban + barra de controles da Proposta (Fase 3)
   — por isso sem o prefixo "kanban-".

   v26 (INSTRUCAO_CC_servicos_adicionais_custos, 4.2): tubo+bulbo de
   verdade, preenchimento interno com ALTURA proporcional ao nível
   (25/50/75/100%, definida inline no template — é dado de apresentação
   puro, não vale a pena um campo/filtro novo só pra isso). Cor por nível
   igual já era (mantida): Frio azul / Morno âmbar / Quente salmão /
   Muito quente vermelho. */
.termometro-calor {
  flex-shrink: 0;
  width: 14px;
  height: 20px;
  display: block;
  position: relative;
}

.termometro-calor__corpo {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  height: 100%;
}

.termometro-calor__tubo {
  width: 6px;
  height: 13px;
  border: 1.4px solid var(--cor-borda);
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  overflow: hidden;
  position: relative;
  background: var(--cor-branco);
}

.termometro-calor__preenchimento {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: currentColor;
}

.termometro-calor__bulbo {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1.4px solid var(--cor-borda);
  background: currentColor;
  margin-top: -2px;
  flex-shrink: 0;
}

.termometro-calor select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: none;
}

/* ★★ (20/10/2026, decisão do Guto) no cabeçalho da PROPOSTA, proporcional ao calendário (30 px): o 14 × 20 × 1,5.
   O Kanban fica com o tamanho de sempre. */
.termometro-calor--grande { width: 21px; height: 30px; }
.termometro-calor--grande .termometro-calor__tubo { width: 9px; height: 19.5px; border-width: 2.1px; border-radius: 4.5px 4.5px 0 0; }
.termometro-calor--grande .termometro-calor__bulbo { width: 15px; height: 15px; border-width: 2.1px; margin-top: -3px; }

.termometro-calor--frio { color: var(--cor-calor-frio); }
.termometro-calor--morno { color: var(--cor-calor-morno); }
.termometro-calor--quente { color: var(--cor-calor-quente); }
.termometro-calor--muito_quente { color: var(--cor-calor-muito-quente); }
.termometro-calor--vazio { color: var(--cor-branco); }

/* Follow-up. COMPARTILHADO card do Kanban + barra de controles da
   Proposta (Fase 3).

   v26 (INSTRUCAO_CC_kanban_fase4, 0.1): virou UM elemento clicável só —
   o indicador inteiro é o alvo do clique, que abre o Flatpickr (o antigo
   ícone de calendário separado saiu). O <input> real do Flatpickr some
   (`altInput:true` já dá type="hidden" nele — ver iniciarFlatpickrs,
   base.html); quem fica no DOM depois do Flatpickr montar é o alt-input
   (`.input-data-inline`) — vira um OVERLAY transparente por cima do
   indicador inteiro (clicar em qualquer parte abre o calendário).

   v26 (INSTRUCAO_CC_icone_followup_calendario): troca o relógio (commit
   625a7fd) por um CALENDÁRIO preenchido (opção B escolhida pelo
   usuário) — corpo branco com contorno na cor da escala + faixa
   colorida no topo + 2 argolinhas, número de dias DENTRO do corpo
   (`.followup-calendario__numero`, posicionado por cima do SVG via
   `position: absolute`, mesmo container `position: relative`). */
.followup-indicador {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.followup-calendario {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.followup-calendario__corpo {
  fill: var(--cor-branco);
  stroke: currentColor;
  stroke-width: 1.3px;
}

.followup-calendario__faixa {
  fill: currentColor;
}

.followup-calendario__argola {
  stroke: currentColor;
  stroke-width: 1.6px;
  stroke-linecap: round;
}

/* Número DENTRO do corpo (~50% da altura do ícone).

   ★★ v13 (decisão do Guto, 4ª saída): o número saiu de `currentColor` e passou
   a GRAFITE. Antes ele herdava a cor do estado — e com os tons do mockup dois
   deles reprovavam como texto: `#D99E1F` a **2,37** e `#749BBD` a **2,93**,
   medidos no navegador sobre o branco do corpo do calendário, num dígito de
   12,48px peso 800 (que NÃO é "texto grande" da WCAG, logo o limite é 4,5).

   ★ `--cor-grafite` (#2F3943) dá **11,75** sobre o branco do corpo e **10,95**
   sobre o cinza do cartão — passa nos quatro estados com folga, e por isso a
   escala do ícone deixou de ser limitada pela legibilidade do dígito.

   ★★ A COR DO ESTADO CONTINUA NO ÍCONE: contorno, faixa e argolas usam
   `currentColor`, que segue herdando de `.followup-calendario--*`. O que mudou
   foi só quem NÃO herda mais. */
.followup-calendario__numero {
  position: absolute;
  left: 0;
  right: 0;
  top: 44%;
  text-align: center;
  /* v26 (Ajustes da 1a avaliacao, K1): +2pt (era 0.62rem) — mesmo passo
     de conversao ja usado no ajuste de fonte do card (Frente B,
     +1pt = +0.08rem) — so o numero, o SVG do icone nao muda. */
  font-size: 0.78rem;
  font-weight: 800;
  line-height: 1;
  /* ★★ v13: GRAFITE, não `currentColor` — ver o comentário acima. */
  color: var(--cor-grafite);
  pointer-events: none;
}

/* Cores da escala do follow-up (mesma lógica de sempre — só a forma do
   ícone mudou). Amarelo usa um tom mais fechado (~#B98C3F, sugerido na
   instrução) — o `--cor-amarelo` padrão, usado como TEXTO sobre fundo
   branco (não mais sobre um fundo colorido), ficava pouco legível.

   ★★ v13: A ESCALA PASSA A TER VARIÁVEIS PRÓPRIAS, e os VALORES NÃO MUDARAM
   nesta leva — ver `RELATORIO_TRANSPORTE_PLANO.md` / o relatório do contador.

   ★ Por que ela precisava das próprias. Três dos cinco tons eram cores de
   FUNÇÃO emprestadas, e o `CLAUDE.md` já proíbe reusar hex de cor de função
   justamente porque "um dia alguém trocaria uma pensando na outra". Medido,
   em quantas regras do CSS cada uma é usada:

       --cor-status-bloqueada   15 regras   (o contador é 1)
       --cor-status-concluida   16 regras   (o contador é 1)
       --cor-status-avaliado     4 regras   (o contador é 1)
       --cor-cinza             106 regras   (o contador é 1)

   ★★ Ou seja: trocar o valor daquelas variáveis para os tons do mockup
   repintaria 14, 15, 3 e 105 outros lugares — inclusive o badge de status
   AVALIADO e o termômetro de calor. Com as variáveis abaixo, a troca de tom
   passa a ser UMA linha, e ela não sai da escala.

   ★ O amarelo estava SOLTO no CSS (`#B98C3F`, sem variável). Agora não está
   mais — era o que a instrução pedia: a paleta num lugar só. */
:root {
  /* ★★ v13 (decisão do Guto, 4ª saída): os tons do MOCKUP entram inteiros,
     porque agora eles pintam só o ÍCONE — o número saiu de `currentColor` e
     foi para grafite (ver `.followup-calendario__numero` abaixo). Era o único
     desenho em que os quatro tons entram exatamente como ele os escreveu.

     ★ Os números ao lado são o contraste sobre o branco do corpo do
     calendário, medido no navegador por pixel. Para o ÍCONE o limite é 3,0
     (contraste não-texto); o número não usa mais estes tons. */
  --cor-followup-vencido: #C43D2C;   /* dias < 0   — ícone, 5,18 */
  --cor-followup-hoje: #D99E1F;      /* dias == 0  — ícone, ★ 2,37 (ver o relatório) */
  --cor-followup-proximo: #749BBD;   /* 1 a 7 dias — ícone, ★ 2,93 (ver o relatório) */
  --cor-followup-folgado: #2F7A45;   /* > 7 dias   — ícone, 5,26; SEM número */
  --cor-followup-sem-data: #575756;  /* sem data   — ícone; SEM número */
}

.followup-calendario--vermelho { color: var(--cor-followup-vencido); }
.followup-calendario--amarelo { color: var(--cor-followup-hoje); }
.followup-calendario--azul { color: var(--cor-followup-proximo); }
.followup-calendario--verde { color: var(--cor-followup-folgado); }
.followup-calendario--cinza { color: var(--cor-followup-sem-data); }

/* Input original do Flatpickr — some incondicionalmente (o clicável de
   verdade é o alt-input abaixo, inserido pelo Flatpickr ao montar). */
.followup-input {
  display: none;
}

/* Alt-input do Flatpickr: overlay transparente por cima do indicador
   inteiro (calendário + número) — é ELE o clicável. */
.followup-indicador .input-data-inline {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
  background: transparent;
  opacity: 0;
  cursor: pointer;
  padding: 0;
  font-size: 0;
}

/* Ícones de decisão — COMPARTILHADO card do Kanban + barra de controles
   da Proposta.

   v26 (INSTRUCAO_CC_kanban_fase4, 0.2-0.4): ganharam FUNÇÃO (abrem
   modal de encerramento) — o visual virou cinza em repouso, cor real só
   no hover, pra não competir com o resto do card/barra. Nova paleta:
   verde = Contratar (inalterado), ROXO = Perder (era âmbar — o roxo
   "mudou de dono", antes era do Cancelar), vermelho = Cancelar (era
   roxo). Cancelar perde o círculo e fica maior (lixeira "solta", sem
   moldura) — Contratar/Perder mantêm o círculo. */
.icones-decisao {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.icone-decisao {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 1.5px solid var(--cor-borda);
  color: var(--cor-cinza);
  font-size: 0.7rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.icone-decisao--contratar:hover { color: var(--cor-status-concluida); border-color: var(--cor-status-concluida); }
.icone-decisao--perder:hover { color: var(--cor-roxo); border-color: var(--cor-roxo); }

/* ★★ v13 (decisão do Guto): Contratar virou 🤝 e Perder virou 🚫.
   O desenho de repouso é "cinza, cor real só no hover", e ele era feito por
   `color` — ★ que EMOJI IGNORA, porque o glifo traz a própria cor. Sem isto
   os dois ícones nasceriam coloridos e a distinção repouso/hover sumiria.
   O `filter` faz o mesmo trabalho no glifo colorido.
   ★ As regras de `color` acima FICAM de propósito: se a fonte de emoji não
   existir e o glifo cair para texto, `color` volta a valer. */
.icone-decisao--contratar,
.icone-decisao--perder {
  filter: grayscale(1);
  opacity: 0.55;
  transition: color 0.15s, border-color 0.15s, filter 0.15s, opacity 0.15s;
}

.icone-decisao--contratar:hover,
.icone-decisao--perder:hover {
  filter: none;
  opacity: 1;
}

/* ★★ (20/10/2026, QA-009 acréscimo 3, mockup aprovado) Contratar = aperto de mão VERDE e Perder = polegar
   para baixo ROXO, em SVG de CONTORNO (`{% icone %}`, core/templatetags/icones.py), SEM o círculo, na altura
   do termômetro (20 px). A cor é a da ação, sempre (o mockup): o "cinza em repouso" era do emoji, que
   ignorava `color` e precisava do `filter`. O hover só reforça. */
.icone-decisao--contratar,
.icone-decisao--perder {
  border: none;
  border-radius: 0;
  filter: none;
  opacity: 1;
}
.icone-decisao--contratar { color: var(--cor-verde); }
.icone-decisao--perder { color: var(--cor-roxo); }
.icone-decisao--contratar:hover,
.icone-decisao--perder:hover { opacity: 0.8; }

/* ★★ (20/10/2026, decisão do Guto) no cabeçalho da PROPOSTA: 30 px, proporcional ao calendário (a lixeira também) */
.icones-decisao--grande .icone-decisao { width: 30px; height: 30px; }
.icones-decisao--grande .icone-decisao--cancelar { width: 30px; height: 30px; font-size: 1.3rem; }

.icone-decisao--cancelar {
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 0;
  font-size: 1.05rem;
}

.icone-decisao--cancelar:hover { color: var(--cor-status-bloqueada); }

/* v26 (INSTRUCAO_CC_kanban_fase4): forms dos 3 modais de encerramento
   (Contratar/Perder/Cancelar) — mesmo container `.modal-novo-ciclo__
   conteudo`, classes próprias pro conteúdo (o checklist do Contratar é
   o mais denso dos 3). */
.form-encerramento h4 {
  margin: 0 0 8px;
  color: var(--cor-azul);
  font-family: var(--fonte-titulo);
}

.form-encerramento__erro {
  background: var(--cor-status-bloqueada-suave);
  color: var(--cor-status-bloqueada);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 0.82rem;
  margin-bottom: 10px;
}

/* v26 (INSTRUCAO_CC_proposta_F4_seletor_view): nota explicativa dentro do
   form (ex.: trava de VF por subcontratação) — mesmo espírito de
   `.dados-processo__nota`, só que dentro do modal de encerramento. */
.form-encerramento__nota {
  font-size: 0.78rem;
  font-style: italic;
  color: var(--cor-cinza);
  opacity: 0.8;
  margin: 6px 0 0;
}

.form-encerramento label.form-encerramento__campo {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--cor-cinza);
  margin-top: 10px;
}

.form-encerramento select,
.form-encerramento textarea,
/* v26 (INSTRUCAO_CC_kanban_oportunidade_obrigatoria): <input type="text">
   não tinha entrado nesta regra ainda (nenhum form de encerramento usava
   input solto até agora, só select/textarea) — mesmo estilo. */
.form-encerramento input[type="text"] {
  width: 100%;
  font-family: var(--fonte-texto);
  border: 1px solid var(--cor-borda-campo);
  border-radius: 4px;
  padding: 6px 8px;
  font-size: 0.85rem;
  margin-top: 4px;
  box-sizing: border-box;
}

.form-encerramento__acoes {
  margin-top: 14px;
  display: flex;
  gap: 8px;
}

.form-encerramento__acoes button[type="submit"] {
  font-family: var(--fonte-texto);
  border: none;
  border-radius: 4px;
  padding: 8px 16px;
  background: var(--cor-azul);
  color: var(--cor-branco);
  cursor: pointer;
}

.form-encerramento__acoes button[type="submit"]:disabled {
  background: var(--cor-borda);
  color: var(--cor-cinza);
  cursor: not-allowed;
}

.form-encerramento__acoes button[type="button"] {
  font-family: var(--fonte-texto);
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 8px 16px;
  background: var(--cor-branco);
  color: var(--cor-cinza);
  cursor: pointer;
}

/* Checklist do Contratar — 5 tópicos (Regulatório / Cadastro /
   Serviços-produtos / Fornecedores / Custo/pagamento), cada um com 1
   checkbox manual + corpo (v27 INSTRUCAO_CC_trava_cadastro_
   contratacao: tópico "Cadastro" novo, "Custo total" renomeado).

   v26 (INSTRUCAO_CC_kanban_fase5_menu, 0-B.1): sinaliza SÓ o que está
   pendente — sem pílula verde de "ok" nos itens corretos (ficam
   neutros/sem marcação). Pendência de um tópico vira 1 frase amarela
   no CANTO SUPERIOR do próprio box (`__pendencia`), não mais uma
   pílula por item. */
.checklist-contratacao__topico {
  position: relative;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 8px;
}

.checklist-contratacao__pendencia {
  margin: 0 0 6px;
  color: var(--cor-amarelo);
  font-weight: 700;
  font-size: 0.76rem;
}

/* ★★ v13 (decisão do Guto): a pendência LEVA até a aba onde se resolve.
   O azul suave de TEXTO é o tom já medido para texto pequeno — 4,84 sobre o
   branco, que é o fundo REAL aqui (`.modal-novo-ciclo__conteudo` é
   `--cor-branco`; `.checklist-contratacao__topico` não põe fundo próprio).
   ★ Azul porque é a convenção de link; e é o tom de TEXTO, não o
   `--cor-azul-suave` de fundo/borda, que dá 2,93 e reprovaria. */
.checklist-contratacao__ir {
  margin-left: 6px;
  color: var(--cor-azul-suave-texto);
  font-weight: 600;
  text-decoration: underline;
  white-space: nowrap;
}

.checklist-contratacao__ir:hover { color: var(--cor-azul); }

.checklist-contratacao__check {
  display: flex;
  align-items: flex-start;
  gap: 6px;
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
}

.checklist-contratacao__corpo {
  margin: 6px 0 0 22px;
  font-size: 0.8rem;
  color: var(--cor-cinza);
}

.checklist-contratacao__item {
  padding: 2px 0;
}

/* v26 (0-B.3b): Classificação ANATEL vira subitem indentado, embaixo
   do modelo — em vez de tudo numa linha só (quebrava feio). */
.checklist-contratacao__subitem {
  margin: 1px 0 4px 14px;
  color: var(--cor-cinza);
}

/* Texto neutro (cinza, itálico) pra sinalizar QUAL item falta, sem
   competir visualmente com a frase amarela do topo do box (única cor
   de alerta do checklist, 0-B.1). */
.checklist-contratacao__vazio {
  font-style: italic;
  color: var(--cor-cinza);
}

/* v26 (INSTRUCAO_CC_kanban_fase3, B1): barra de controles ACIMA do
   cabeçalho da Proposta — Status | Temperatura | Follow-up | ícones de
   decisão, da esquerda pra direita.

   v26 (INSTRUCAO_CC_regulatorio_e_botao_imprimir, 2): virou 2 grupos —
   `.comercial-proposta__barra-esquerda` (status+termômetro+follow-up+
   ícones, o mesmo bloco que ANTES ficava direto aqui) de um lado, botão
   "Imprimir/Gerar proposta" do outro — `space-between` entre os dois
   deixa o meio livre naturalmente. Corrige o `justify-content: flex-
   start` da rodada anterior (agrupava tudo à esquerda mas não reservava
   lugar pro botão à direita). */
.comercial-proposta__barra-controles {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--cor-borda);
}

.comercial-proposta__barra-esquerda {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

/* Placeholder — só reserva o lugar, função de gerar vem depois. */
.botao-adicionar-linha--desabilitado {
  opacity: 0.55;
  cursor: default;
}

/* v26 (Fase 3 do Fluxo Financeiro, Parte 2a): agrupa o link condicional
   "Fluxo Financeiro" + o placeholder "Imprimir/Gerar proposta" à
   direita da barra — mantém só 2 filhos diretos pro `space-between`
   de `.comercial-proposta__barra-controles` (esquerda/direita), mesmo
   se o link não aparecer (proposta ainda não contratada). */
.comercial-proposta__barra-direita {
  display: flex;
  align-items: center;
  gap: 10px;
}


/* ===========================================================================
   Financeiro > Fluxo (Fase 3 do Fluxo Financeiro, Parte 2a) — 1 bloco
   por fornecedor (Moderacon/OC/LAB): cabeçalho dinâmico (reaproveita
   .dados-processo__campo/.dados-processo__valor-fixo) + sub-tabela +
   nota de subcontratação.
   =========================================================================== */

.fluxo-fornecedor {
  margin-bottom: 20px;
}

.fluxo-fornecedor__titulo {
  margin: 0 0 14px;
  font-size: 1.05rem;
  color: var(--cor-azul);
}

/* v27 (INSTRUCAO_CC_lote_bugs_melhorias/T1): 3 linhas fixas e compactas
   (ver _fluxo_fornecedor_bloco.html) em vez do `.dados-processo__grade`
   genérico de antes — gap bem menor entre linhas/colunas, e o valor
   perde o padding vertical do padrão de tela de cadastro (denso demais
   pra este resumo). */
.fluxo-fornecedor__cabecalho {
  margin-bottom: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--cor-borda);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.fluxo-fornecedor__linha {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 4px 20px;
}

.fluxo-fornecedor__campo-largo {
  grid-column: 1 / -1;
}

.fluxo-fornecedor__cabecalho .dados-processo__valor-fixo {
  padding: 2px 0 0;
}

/* v27 (INSTRUCAO_CC_lote5, FF2): SEM `width: 100%` — a tabela deixa de
   ser esticada até a borda do card, cada coluna encolhe pro tamanho do
   próprio conteúdo (table-layout `auto`, padrão do navegador — mesma
   solução já validada na versão pra e-mail, `_ESTILOS_FLUXO_COPIAR`/
   core/comercial.py). Sem isto, "#"/Status/NFSe/Boleto (conteúdo
   curto) ficavam com o mesmo espaço sobrando de "Serviço"/"Modelo"
   (conteúdo longo) só porque a tabela era forçada a ocupar 100% do
   card. Padding reduzido de 8px/10px pra 6px/8px — mais compacto,
   ordenação das colunas intocada. */
table.tabela-fluxo {
  border-collapse: collapse;
  font-size: 0.9rem;
}

table.tabela-fluxo th {
  text-align: left;
  font-family: var(--fonte-texto);
  font-weight: 600;
  color: var(--cor-cinza);
  background: var(--cor-fundo);
  padding: 6px 8px;
  border-bottom: 2px solid var(--cor-borda);
  white-space: nowrap;
  font-size: 0.78rem;
}

table.tabela-fluxo td {
  padding: 6px 8px;
  border-bottom: 1px solid var(--cor-borda);
  vertical-align: middle;
}

/* Nota de subcontratação — só aparece no bloco Moderacon quando há
   custo embutido de coluna subcontratada (Parte 1). */
.fluxo-fornecedor__nota {
  margin-top: 14px;
  padding: 10px 12px;
  background: var(--cor-fundo);
  border-radius: 6px;
  font-size: 0.82rem;
  color: var(--cor-cinza);
}

.fluxo-fornecedor__nota-texto {
  margin: 6px 0 0;
  font-family: var(--fonte-texto);
  white-space: pre-wrap;
}

/* v27 (INSTRUCAO_CC_lote5, FF1): nota livre editável por empresa —
   mesmo padrão visual de `.combinacao-card__observacao` (Composição de
   Custos). */
.fluxo-fornecedor__nota-campo {
  display: block;
  font-size: 0.78rem;
  color: var(--cor-cinza);
  margin: 12px 0;
}

.fluxo-fornecedor__nota-campo textarea {
  width: 100%;
  font-family: var(--fonte-texto);
  font-size: 0.82rem;
  color: #1a1a1a;
  resize: vertical;
  margin-top: 4px;
}

/* v26 (Fase 3 do Fluxo Financeiro, Parte 2b): edição inline + aditivos. */

.select-status-fluxo {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 3px 6px;
}

.select-status-fluxo--pendente {
  background: var(--cor-status-pendente-suave);
  color: var(--cor-status-pendente);
}

.select-status-fluxo--agendado {
  background: var(--cor-status-avaliado-suave);
  color: var(--cor-status-avaliado);
}

.select-status-fluxo--faturado {
  background: var(--cor-amarelo-suave);
  color: var(--cor-amarelo);
}

.select-status-fluxo--pago {
  background: var(--cor-status-concluida-suave);
  color: var(--cor-status-concluida);
}

/* v27 (INSTRUCAO_CC_finalizacao_arquivamento, decisão 8): novo status
   terminal alternativo — roxo, mesmo tom já usado pro ícone "Cancelar"
   do Kanban (`--cor-roxo`, escala verde/âmbar/roxo já estabelecida). */
.select-status-fluxo--cancelado {
  background: var(--cor-roxo-suave);
  color: var(--cor-roxo);
}

table.tabela-fluxo input {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  border: 1px solid var(--cor-borda-campo);
  border-radius: 4px;
  padding: 4px 6px;
  box-sizing: border-box;
}

.input-fluxo-servico {
  width: 100%;
  min-width: 140px;
}

.input-fluxo-modelo {
  width: 100%;
  min-width: 100px;
}

/* ★★ v13 (item 2): o seletor de SERVIÇO do aditivo — a lista do bloco, com o
   campo livre logo abaixo. Mesma caixa do `.input-fluxo-servico` que ele
   acompanha, e os dois empilhados: lado a lado eles não caberiam na coluna, e o
   que importa é que se leia qual dos dois está preenchido. */
.select-fluxo-servico {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 4px 6px;
  box-sizing: border-box;
  width: 100%;
  min-width: 140px;
  margin-bottom: 4px;
}

/* v26 (Ajustes da 1a avaliação, C2): seletor de Modelo do aditivo —
   mesma caixa/tamanho do input que substituiu. */
.select-fluxo-modelo {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 4px 6px;
  box-sizing: border-box;
  width: 100%;
  min-width: 100px;
}

.input-fluxo-custo {
  width: 100px;
}

.input-fluxo-doc {
  width: 110px;
}

.fluxo-fornecedor__aditivo-novo {
  margin-top: 10px;
}

/* v26 (Fase 3 do Fluxo Financeiro, Parte 3): título + botão "Versão
   para e-mail" lado a lado, no topo da tela do fluxo. */
/* ★★★ v13 (validação do Guto): O TÍTULO NUMA LINHA, OS BOTÕES NA SEGUINTE —
   SEMPRE.

   ★ O que havia: `flex-wrap: wrap` com `justify-content: space-between`. Com um
   cliente de nome longo o `<h1>` tomava a linha e os botões quebravam **um a
   um** — o primeiro ao lado do título, o resto descendo desalinhado. Medido com
   "ENVISIA GERENCIAMENTO DE ATIVOS E SERVICOS LTDA" (47 caracteres), o caso que
   o Guto viu.

   ★★ Por que SEMPRE, e não um `@media`: um layout que muda de forma conforme o
   tamanho do dado é exatamente o que produz esse relato — hoje com 47
   caracteres, amanhã com 40 numa tela mais estreita. O maior `str(cliente)` da
   base tem 60, e o título inteiro chega a 87.

   ★ `align-items: flex-start` para o título não centralizar sobre a linha dos
   botões, e `gap` menor entre as duas linhas do que era entre os itens. */
.fluxo-detalhe__cabecalho {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

/* ★ Os botões: uma linha só, que ainda pode quebrar se forem muitos — mas aí
   quebra dentro do PRÓPRIO grupo, alinhada à esquerda, e não em volta do
   título. */
.fluxo-detalhe__acoes {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
}

/* v27 (INSTRUCAO_CC_trocar_senha): form de troca de senha (dentro do
   chrome normal do app, `.cartao` — diferente do login.html, que é
   uma página solta pra quem ainda não está logado). */
.conta-senha {
  max-width: 340px;
}

.conta-senha h1 {
  font-size: 1.15rem;
  margin: 0 0 4px;
}

.conta-senha__ajuda {
  margin: 0 0 16px;
  font-size: 0.85rem;
  color: var(--cor-cinza);
}

.conta-senha__erro {
  background: var(--cor-erro-suave);
  color: var(--cor-erro);
  padding: 8px 10px;
  border-radius: 6px;
  font-size: 0.85rem;
  margin-bottom: 14px;
}

.conta-senha__erro p {
  margin: 0;
}

.conta-senha form label {
  display: block;
  font-size: 0.85rem;
  margin-bottom: 4px;
  color: var(--cor-cinza);
}

.conta-senha form input {
  width: 100%;
  padding: 9px 10px;
  margin-bottom: 14px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  font-family: var(--fonte-texto);
  font-size: 0.9rem;
  box-sizing: border-box;
}

.conta-senha form button {
  padding: 10px 16px;
  border: none;
  border-radius: 6px;
  background: var(--cor-coral-escuro);
  color: #fff;
  font-family: var(--fonte-texto);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
}

/* v27 (INSTRUCAO_CC_pc_oc_tag_faturamento): PC/OC do cliente + TAG de
   faturamento pronta pra colar no BomControle, no topo do Fluxo
   Financeiro. */
.fluxo-tag-faturamento {
  margin-bottom: 16px;
}

.fluxo-tag-faturamento__linha {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.fluxo-tag-faturamento__linha code {
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 8px 10px;
  font-family: var(--fonte-texto);
  font-size: 0.9rem;
  flex: 1;
  min-width: 260px;
}

/* v27 (Adendo CC_cadastro_fornecedor_colaborador): contato arquivado —
   mesmo espírito esmaecido de .linha-arquivada, aplicado a uma linha de
   inputs (Contatos do Fornecedor) em vez de uma <tr>. */
.campo-desativado input {
  opacity: 0.55;
  font-style: italic;
}

/* v27 (INSTRUCAO_CC_relatorio_propostas): tela Propostas — blocos
   empilhados (histórico mensal total, histórico por responsável, funil
   unificado por temperatura total e por responsável), cada um com
   gráfico + os números exatos por baixo. Sucede o bloco da tela de
   Pipeline (INSTRUCAO_CC_relatorio_pipeline), que virou esta. */
.relatorio-propostas__bloco {
  margin-bottom: 24px;
}

.relatorio-propostas__titulo-bloco {
  margin: 0 0 16px;
  font-size: 1.1rem;
}

.relatorio-propostas__kpis {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 20px;
}

.relatorio-propostas__kpi {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 160px;
}

.relatorio-propostas__kpi-valor {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--cor-verde);
}

.relatorio-propostas__kpi-rotulo {
  font-size: 0.78rem;
  color: var(--cor-cinza);
}

.relatorio-propostas__graficos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 24px;
}

.relatorio-propostas__grafico h3 {
  margin: 0 0 10px;
  font-size: 0.9rem;
  color: var(--cor-cinza);
}

.relatorio-propostas__tabela {
  width: 100%;
  margin-top: 12px;
  border-collapse: collapse;
  font-size: 0.82rem;
}

.relatorio-propostas__tabela th, .relatorio-propostas__tabela td {
  text-align: left;
  padding: 4px 8px;
  border-bottom: 1px solid var(--cor-borda);
}

.relatorio-propostas__filtro-rotulo {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  color: var(--cor-cinza);
}

/* v27 (INSTRUCAO_CC_relatorio_propostas): peças novas da tela Propostas
   — nota explicativa, legenda de etapas (as 4 opacidades) e a coluna de
   quantidade da tabela temperatura × etapa. */
/* v27 — a nota de "data aproximada" sob o gráfico/tabela que ela afeta.
   Discreta de propósito: é uma ressalva sobre a leitura, não um alerta —
   quem lê o gráfico precisa saber, quem já sabe não precisa tropeçar. */
.relatorio-nota-aproximada {
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--cor-cinza);
  margin: 10px 0 0;
  padding-left: 10px;
  border-left: 2px solid var(--cor-borda);
  max-width: 78ch;
}

.relatorio-propostas__nota {
  margin: 0 0 12px;
  font-size: 0.78rem;
  color: var(--cor-cinza);
  text-align: left;
}

.relatorio-propostas__legenda {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
  font-size: 0.78rem;
  color: var(--cor-cinza);
}

.relatorio-propostas__legenda li {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Cinza nas 4 opacidades reais (40/60/80/100%) — a legenda ensina a
   ESCALA de opacidade, não a cor, que é a da temperatura de cada barra. */
.relatorio-propostas__legenda-cor {
  width: 14px;
  height: 14px;
  border-radius: 2px;
  background: #4a4a4a;
}

.relatorio-propostas__qtd {
  color: var(--cor-cinza);
  font-size: 0.75rem;
}

/* v27 (INSTRUCAO_CC_resultados_p3p4): abas do Relatório Comercial
   (Propostas | Resultados) e o par linha+donut de cada bloco das
   páginas 3/4. */
.relatorio-abas {
  display: flex;
  gap: 4px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--cor-borda);
}

.relatorio-abas__aba {
  padding: 8px 16px;
  font-size: 0.85rem;
  color: var(--cor-cinza);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}

.relatorio-abas__aba:hover {
  color: var(--cor-verde);
}

.relatorio-abas__aba--ativa {
  color: var(--cor-verde);
  font-weight: 600;
  border-bottom-color: var(--cor-verde);
}

.relatorio-resultados__titulo-pagina {
  margin: 24px 0 4px;
  font-size: 1.05rem;
}

/* Linha trimestral larga + donut estreito ao lado: a série conta a
   evolução, o donut fecha o período — leitura lado a lado, não empilhada.
   Abaixo de ~880px o grid quebra sozinho e o donut cai embaixo. */
.relatorio-resultados__graficos {
  display: grid;
  grid-template-columns: minmax(360px, 2.4fr) minmax(200px, 1fr);
  gap: 24px;
  align-items: center;
}

@media (max-width: 880px) {
  .relatorio-resultados__graficos {
    grid-template-columns: 1fr;
  }
}

.relatorio-resultados__donut {
  max-width: 260px;
  margin: 0 auto;
}

/* v27 (INSTRUCAO_CC_resultados_p5): os 6 gráficos da página 5 — Perda à
   esquerda, Ganho à direita, uma linha por dimensão. */
.relatorio-resultados__par {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 28px;
}

.relatorio-resultados__lado {
  margin: 0 0 8px;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.relatorio-resultados__lado--perda { color: #c0392b; }
.relatorio-resultados__lado--ganho { color: var(--cor-verde); }

/* v27 (compactação vertical): a altura dos gráficos passa a ser em px, no
   contêiner, com `maintainAspectRatio: false` no Chart.js. Antes vinha da
   razão do <canvas> (300×150 etc.), que deriva a altura da LARGURA — num
   card largo isso dava ~450px por gráfico e jogava os blocos de sócio pra
   fora da tela. */
.relatorio-propostas__funil,
.relatorio-resultados__linha,
.relatorio-resultados__donut {
  position: relative; /* exigido pelo Chart.js pra medir o contêiner */
}

/* Funil: Total mais alto (enquadra e fica prominente); sócios mais baixos,
   pra os dois caberem juntos. A espessura da barra sai da altura ÷ nº de
   temperaturas — 5 barras (com "sem temperatura definida") se acomodam
   sozinhas, sem tocar em nada. Alturas calibradas na tela pelo usuário. */
.relatorio-propostas__funil--total {
  height: 400px;
}

.relatorio-propostas__funil--socio {
  height: 175px;
}

/* Páginas 3-4: o bloco Total mantém a altura de antes; os de sócio caem
   ~40%, que é o que permite ver Luis e Diego na mesma tela. */
.relatorio-resultados__linha {
  height: 365px;
}

.relatorio-resultados__donut {
  height: 270px;
}

.relatorio-resultados__graficos--compacto .relatorio-resultados__linha {
  height: 230px;
}

.relatorio-resultados__graficos--compacto .relatorio-resultados__donut {
  height: 170px;
}

/* v27 (ajuste de layout): par por responsável EMPILHADO — Diego em cima,
   Luis embaixo (a ordem vem de `SOCIOS`, core/relatorios.py). Vale pra
   Quantidade Mensal/Anual; o funil e as páginas 3-4 já empilham sozinhos,
   porque cada bloco é um cartão de largura inteira. */
.relatorio-propostas__empilhado {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
}

/* Altura fixa é o que faz os dois caberem juntos na tela — sem ela a
   altura viria da razão do <canvas>, derivada da largura (~540px cada num
   cartão largo). */
.relatorio-propostas__historico-socio {
  position: relative;
  height: 200px;
}

/* v27 (INSTRUCAO_CC_ganhoperda_previsao_p6p10): páginas 6 e 10 — tabelas.
   A rolagem horizontal fica no CONTÊINER da tabela, não no corpo da
   página: 6-7 colunas em tela estreita não podem empurrar a tela inteira
   pro lado. */
.relatorio-tabela__rolagem {
  overflow-x: auto;
}

.relatorio-tabela__rodape {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 10px;
}

.relatorio-tabela__numero {
  text-align: right;
  white-space: nowrap;
}

/* KPI que ainda não tem como ser calculado (Saldo, que depende da META) —
   apagado, pra não competir com os números que são de verdade. */
.relatorio-propostas__kpi--pendente .relatorio-propostas__kpi-valor {
  color: var(--cor-cinza);
  font-weight: 500;
}

/* v27 (INSTRUCAO_CC_previsao_selecao_etapa1): linha marcada pra previsão —
   fundo verde bem leve, só pra a seleção se ler de relance numa tabela
   longa sem ter que varrer coluna de checkbox. */
.relatorio-previsao__linha--marcada > td {
  background: rgba(46, 139, 87, 0.07);
}

/* v27 (INSTRUCAO_CC_carteira_p11): Carteira — 2 grupos de filtro lado a
   lado (Oportunidade | Contratação) e as alturas dos 4 gráficos. */
.carteira__filtros {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
  margin-bottom: 20px;
}

.carteira__grupo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 10px 14px 12px;
}

.carteira__grupo legend {
  padding: 0 6px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--cor-cinza);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Mesma lógica das outras telas: altura em px no contêiner, não pela
   razão do <canvas> (que a derivaria da largura). */
.carteira__grafico {
  position: relative;
}

.carteira__grafico--mensal { height: 300px; }
.carteira__grafico--donut { height: 320px; }
.carteira__grafico--barras { height: 260px; }

/* v27 (INSTRUCAO_CC_meta_fundacao): grade de metas — 12 linhas por ano,
   células numéricas editáveis. */
.metas__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 16px;
}

.metas__importar {
  display: flex;
  align-items: center;
  gap: 8px;
}

.metas__mensagem {
  margin: 0 0 12px;
  padding: 8px 12px;
  border-radius: 4px;
  background: rgba(46, 139, 87, 0.1);
  color: var(--cor-verde);
  font-size: 0.82rem;
}

.metas__celula {
  width: 100%;
  min-width: 96px;
  text-align: right;
  font-size: 0.82rem;
}

/* Total é calculado — some da grade como campo e vira número puro, pra
   ninguém tentar digitar nele. */
.metas__total {
  text-align: right;
  font-weight: 600;
  white-space: nowrap;
}

.metas__grade tfoot td,
.metas__grade tfoot th {
  border-top: 2px solid var(--cor-borda);
  font-weight: 600;
  text-align: right;
}

.metas__grade tfoot th {
  text-align: left;
}

/* Diego + Luis não fecha o Total: sinaliza, não bloqueia — travar
   impediria o passo intermediário de uma edição. */
.metas__linha--divergente > td,
.metas__linha--divergente > th {
  background: rgba(224, 138, 44, 0.08);
}

.metas__aviso {
  color: #b8752a;
  font-weight: 700;
}

.metas__acoes {
  white-space: nowrap;
}

.metas__acoes button {
  font-size: 0.7rem;
  padding: 2px 6px;
}

/* v27 (INSTRUCAO_CC_vendas_p7p8p9): bloco Vendas. O gráfico mensal divide
   a linha com os 4 KPIs do bloco — abaixo de ~980px o KPI cai pra baixo
   do gráfico em vez de espremer os dois. */
.vendas__linha-kpis {
  display: grid;
  grid-template-columns: minmax(420px, 2.6fr) minmax(200px, 1fr);
  gap: 24px;
  align-items: center;
}

@media (max-width: 980px) {
  .vendas__linha-kpis { grid-template-columns: 1fr; }
}

.vendas__kpis {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.vendas__grafico {
  position: relative;
  height: 260px;
}

.vendas__grafico--alto { height: 320px; }
.vendas__grafico--donut { height: 300px; }

/* Saldo/variação negativos em vermelho: é a leitura de relance da página
   (bateu ou não bateu a meta). */
.relatorio-vendas__negativo { color: #c0392b; }
.relatorio-vendas__positivo { color: var(--cor-verde); }

/* Repassado não é receita — cinza, pra não competir com os dois
   faturamentos ao lado. */
.relatorio-propostas__kpi-valor--neutro { color: var(--cor-cinza); }

/* v27 (INSTRUCAO_CC_cores_e_carteira): donut de Valor por Cliente que veio
   da Carteira pro fim da aba Resultados — mais largo que os donuts dos
   blocos, porque a legenda traz nome de cliente inteiro. */
.relatorio-resultados__donut-cliente {
  position: relative;
  height: 340px;
}

/* v27 (QA-001, C1): ações do cadastro — inativar (neutro) e apagar
   (destrutivo, precisa se distinguir do outro à primeira vista). */
.cadastro__acoes {
  display: flex;
  align-items: center;
  gap: 8px;
}

.cadastro__apagar {
  color: #c0392b;
  border-color: #c0392b;
  background: transparent;
}

.cadastro__toggle-inativos {
  font-size: 0.8rem;
  color: var(--cor-cinza);
  white-space: nowrap;
}

/* v27 (QA-001, C8a): tag "Financeiro" na linha de contato do cliente —
   checkbox e rótulo na mesma linha dos campos de texto. */
.cadastro__tag-financeiro {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.78rem;
  color: var(--cor-cinza);
  white-space: nowrap;
}

/* v27 (QA-001, C6): grade da LPU — uma tabela por órgão dentro da seção. */
.lpu__orgao {
  margin: 14px 0 6px;
  font-size: 0.78rem;
  color: var(--cor-cinza);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.lpu__grade td { text-align: right; }
.lpu__grade th[scope="row"] { text-align: left; font-weight: 400; }

/* v27 (INSTRUCAO_CC_vendas_ajustes_grafico, 4): TCP e TCV lado a lado
   dentro da coluna de KPIs — os dois medem a mesma conversão (quantidade
   e valor), e ficam mais úteis um ao lado do outro que empilhados. */
.vendas__par-kpi {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

/* v27 (INSTRUCAO_CC_painel): dashboard inicial. */
.painel__usuario {
  font-size: 0.9rem;
  font-weight: 400;
  color: var(--cor-cinza);
}

.painel__grafico {
  position: relative;
  height: 280px;
}

/* O bloco da empresa fica visualmente separado dos KPIs pessoais — é
   outro assunto (o time), no meio da coluna do "meu". */
.painel__kpi-empresa {
  padding-top: 12px;
  border-top: 1px solid var(--cor-borda);
}

/* v27 (INSTRUCAO_CC_reorg_menu_abas): o ícone do Painel é um <a> (seção
   sem submenu, clique direto) — o resto da sidebar são <span>. Só o
   sublinhado do link precisa sair; cor e caixa já vêm de .sidebar-icone. */
a.sidebar-icone {
  text-decoration: none;
}

/* Selo de CADÊNCIA na aba do relatório (SEM/TRI). Discreto de propósito:
   é um lembrete de com que frequência aquela aba se olha, não um filtro —
   não muda dado, período nem nada. */
.relatorio-abas__selo {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 5px;
  border-radius: 8px;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  color: var(--cor-cinza);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  vertical-align: middle;
}

.relatorio-abas__aba--ativa .relatorio-abas__selo {
  border-color: var(--cor-azul);
  color: var(--cor-azul);
}

/* Área de Configuração: um cartão por tela, tudo restrito ao Admin. */
.config-cartoes {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
  margin-top: 16px;
}

.config-cartao {
  display: block;
  text-decoration: none;
  color: inherit;
}

.config-cartao:hover {
  border-color: var(--cor-azul);
}

.config-cartao__titulo {
  display: block;
  font-weight: 600;
  color: var(--cor-azul);
  margin-bottom: 6px;
}

.config-cartao__nota {
  display: block;
  font-size: 0.82rem;
  color: var(--cor-cinza);
  line-height: 1.45;
}

/* v27 (INSTRUCAO_CC_vendas_formatacao, 3-4-5): os 5 KPIs da página 7 saem
   na cor de texto do app, não no verde padrão do relatório. Ali eles
   convivem com o Saldo mensal do gráfico, que é colorido POR SINAL — dois
   verdes com significados diferentes na mesma caixa se leem errado. O
   verde continua valendo nos KPIs do resto do relatório. */
.vendas__kpis--neutro .relatorio-propostas__kpi-valor {
  color: var(--cor-cinza);
}

/* v27 (INSTRUCAO_CC_vendas_formatacao, extensão às págs. 8-9 e ao Painel):
   com a fileira inteira na cor de texto, o Repassado não se distingue mais
   por ser "o cinza no meio dos verdes". Recua por peso e tom — continua
   legível como o terceiro número, sem competir com os dois faturamentos. */
.vendas__kpis--neutro .relatorio-propostas__kpi-valor--neutro {
  color: #8b8e91;
  font-weight: 500;
}

/* v27 (Cadastro_Atualização_00): a coluna de ações da lista de Cadastro.
   Substituiu o texto "Ativo/Inativo": a chave liga/desliga e a lixeira
   apaga. Não há botão de editar — editar é clicar na linha. */
.cadastro-acoes__coluna { width: 1%; white-space: nowrap; }

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

/* Chave seletora. O rótulo fica ao lado do trilho porque "ligado" sem
   palavra depende de o leitor lembrar qual lado é qual — e esta chave
   decide se o cadastro aparece nas listas. */
.cadastro-chave {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: none;
  border: 0;
  padding: 2px;
  cursor: pointer;
  font: inherit;
  font-size: 0.78rem;
  color: var(--cor-cinza);
}

.cadastro-chave__bola {
  position: relative;
  flex: 0 0 auto;
  width: 30px;
  height: 17px;
  border-radius: 9px;
  background: #c2c7cc;
  transition: background 0.14s ease;
}

.cadastro-chave__bola::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--cor-branco);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  transition: transform 0.14s ease;
}

.cadastro-chave--ligada .cadastro-chave__bola { background: var(--cor-verde); }
.cadastro-chave--ligada .cadastro-chave__bola::after { transform: translateX(13px); }
.cadastro-chave--ligada .cadastro-chave__texto { color: var(--cor-verde); font-weight: 600; }

.cadastro-chave:focus-visible,
.cadastro-lixeira:focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 2px;
  border-radius: 4px;
}

.cadastro-lixeira {
  display: inline-flex;
  align-items: center;
  background: none;
  border: 0;
  padding: 3px;
  cursor: pointer;
  color: var(--cor-cinza);
  border-radius: 4px;
}

.cadastro-lixeira svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.cadastro-lixeira:hover { color: #c0392b; background: var(--cor-erro-suave); }

/* A recusa do apagar (há vínculo) precisa aparecer NA LISTA — antes só
   existia caminho pra mostrá-la na tela de detalhe. */
.cadastro-acoes__erro {
  margin: 0;
  padding: 10px 14px;
  border-top: 1px solid var(--cor-borda);
  color: #c0392b;
  font-size: 0.86rem;
}

/* Texto só pra leitor de tela (o rótulo do botão de lixeira). */
.sr-apenas {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

@media (prefers-reduced-motion: reduce) {
  .cadastro-chave__bola,
  .cadastro-chave__bola::after { transition: none; }
}

/* v27: o cabeçalho do detalhe usa a MESMA dupla de ações da lista, então
   herda `.cadastro-acoes`. Aqui elas ficam no canto do cabeçalho, não
   dentro de uma célula — só o respiro muda. */
.fluxo-detalhe__cabecalho .cadastro-acoes { gap: 16px; }

/* --- Relatório de Gestão (v27, INSTRUCAO_CC_relatorio_gestao) ----------
   Só o que o Comercial ainda não tinha. KPIs, blocos, notas, abas e selos
   são reaproveitados de `.relatorio-propostas__*` / `.relatorio-abas*` —
   os dois relatórios têm que parecer o mesmo produto, e duplicar as
   classes seria o começo de eles divergirem no detalhe. */

/* Altura FIXA em px, e não razão do <canvas>: os pares lado a lado
   precisam terminar na mesma linha, e `maintainAspectRatio:false` (que
   todos usam) exige que a altura venha do container. */
.relatorio-gestao__grafico {
  position: relative;
  height: 230px;
}

.relatorio-gestao__grafico--alto {
  height: 300px;
}

/* v27 (ajuste do Relatório de Mercado): a faixa mais alta, pra série
   MÚLTIPLA em largura inteira — volume por OCD são 13 linhas e por holder
   19. Em 300px elas se empilham e viram uma mancha: dá pra ver a tendência
   do conjunto e não dá pra seguir nenhuma. 480px é o ponto em que as linhas
   se separam sem a seção deixar de caber na tela. */
.relatorio-gestao__grafico--altissimo {
  height: 480px;
}

.relatorio-gestao__colunas {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

/* O gargalo ("de quem é a bola") pede mais largura que o vizinho — são 6
   rótulos de papel num eixo horizontal, e espremido eles quebram. */
.relatorio-gestao__colunas--assimetrica {
  grid-template-columns: 1.4fr 1fr;
}

/* v27 (ajuste do Relatório de Mercado): o par VOLUME x VARIAÇÃO.

   70/30 e não 50/50 porque os dois não pedem a mesma largura: o volume é a
   série principal, com 5 anos e várias linhas; a variação é o mesmo fato em
   taxa, com 3 barras por grupo, e a 50% sobraria espaço vazio nela e
   faltaria no vizinho. Ficam lado a lado porque se leem juntos — nível e
   taxa da mesma coisa. */
.relatorio-gestao__colunas--7030 {
  display: grid;
  grid-template-columns: 7fr 3fr;
  gap: 16px;
}

@media (max-width: 900px) {
  .relatorio-gestao__colunas--7030 {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 900px) {
  .relatorio-gestao__colunas,
  .relatorio-gestao__colunas--assimetrica {
    grid-template-columns: 1fr;
  }
}

/* Legenda do donut escrita em HTML, não pelo Chart.js: os números ficam
   selecionáveis e o leitor de tela os alcança. */
.relatorio-gestao__lista {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  font-size: 0.8rem;
  color: var(--cor-cinza);
}

.relatorio-gestao__ponto {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 2px;
  margin-right: 6px;
  vertical-align: baseline;
}

.relatorio-gestao__tabela {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
  margin-top: 12px;
}

.relatorio-gestao__tabela th {
  text-align: left;
  font-weight: 600;
  font-size: 0.72rem;
  color: var(--cor-cinza);
  padding: 5px 6px;
  border-bottom: 1px solid var(--cor-borda);
}

.relatorio-gestao__tabela td {
  padding: 6px;
  border-bottom: 1px solid var(--cor-fundo);
}

.relatorio-gestao__tabela .num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.relatorio-gestao__linha--destaque td {
  background: var(--cor-fundo);
}

/* O veredito é palavra, não número — 1.5rem de KPI o quebraria em duas
   linhas e desalinharia a fileira inteira. */
.relatorio-gestao__veredito {
  font-size: 1.05rem;
}

/* Selo MEN: a mesma pílula do SEM, em laranja, pra a cadência mensal se
   distinguir da semanal de relance sem virar um 2º componente. */
.relatorio-abas__selo--mensal {
  border-color: #f0c9b8;
  /* ★ (C6, 18/10/2026) era #e64a19: contraste 3,65 sobre o fundo do selo (#F6F7F8), abaixo
     dos 4,5 da regra das cores (texto pequeno). #BF3F12 é o MESMO laranja, mais escuro (matiz
     16°): 4,98 sobre o fundo do selo e 5,34 sobre o branco. Longe do erro (6°) e da atenção
     (37°), e não repete o hex de nenhuma cor de função. */
  color: #BF3F12;
}

.relatorio-abas__aba--ativa .relatorio-abas__selo--mensal {
  border-color: #BF3F12;
  color: #BF3F12;
}

/* O seletor de faixa mora no cabeçalho do cartão do gráfico (não na barra
   de filtros): ele recorta AQUELE gráfico, e colocá-lo lá em cima com o
   período faria os dois parecerem o mesmo controle. */
.relatorio-gestao__cabecalho-bloco {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}

.relatorio-gestao__cabecalho-bloco .relatorio-propostas__titulo-bloco {
  margin-bottom: 0;
}

.relatorio-gestao__faixa {
  font-size: 0.78rem;
  color: var(--cor-cinza);
}

.relatorio-gestao__faixa select {
  font: inherit;
  margin-left: 6px;
  padding: 4px 8px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  background: #fff;
}

/* --- Select com busca (v27, QA-002 C1) --------------------------------
   Seleção ÚNICA com filtro digitado no próprio cabeçalho. Herda a
   aparência do `.multiselect` de propósito: são o mesmo componente em
   duas cardinalidades, e parecerem diferentes confundiria mais do que
   ajudaria. */
.select-busca {
  position: relative;
}

.select-busca__cabecalho {
  width: 100%;
  font: inherit;
  padding: 6px 10px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  background: #fff;
  color: var(--cor-texto);
  cursor: pointer;
}

/* Aberto o cursor vira de texto: o cabeçalho É a caixa de busca. */
.select-busca--aberta .select-busca__cabecalho {
  cursor: text;
  border-color: var(--cor-azul);
}

.select-busca__painel {
  display: none;
  position: absolute;
  z-index: 30;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  max-height: 260px;
  overflow-y: auto;
  background: #fff;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.09);
}

.select-busca--aberta .select-busca__painel {
  display: block;
}

.select-busca__item {
  padding: 7px 10px;
  font-size: 0.85rem;
  cursor: pointer;
}

.select-busca__item:hover {
  background: var(--cor-fundo);
}

.select-busca__item[hidden] {
  display: none;
}

.select-busca__vazio {
  margin: 0;
  padding: 9px 10px;
  font-size: 0.8rem;
  color: var(--cor-cinza);
}

/* O <select> real continua no DOM (é ele quem fala com o htmx e quem a
   engrenagem do hx-confirm lê) — só não aparece. */
.select-busca__nativo {
  display: none;
}

/* --- Creatable no multiselect (v27, QA-002 C2) -----------------------
   O CHECKBOX GIGANTE, medido no navegador em vez de deduzido:

     .dados-processo__campo input, .dados-processo__campo select
       { ... width: 100%; }

   Essa regra genérica dos campos pega TAMBÉM o checkbox de dentro do
   painel. Isso sempre existiu, e nunca apareceu porque o checkbox é item
   de flex e encolhia sozinho (`flex-shrink: 1` padrão) até o tamanho
   natural. Na 1ª tentativa de conserto eu pus `flex: 0 0 auto` pra ele
   "não encolher" — e foi exatamente isso que soltou o `width: 100%`: o
   checkbox virou 246px de largura, empurrou o rótulo pra 281px (fora do
   painel de 279px) e criou a barra de rolagem horizontal. Medido:
   checkbox x=29 w=246, span x=281 w=57.

   O conserto certo é anular o `width` herdado, não desligar o shrink. */
.multiselect__item input[type="checkbox"] {
  flex: 0 0 auto;
  width: auto;
  min-width: 0;
  padding: 0;
  margin: 0;
}

/* Uma linha por item, como era. O rótulo longo TRUNCA em vez de quebrar
   ou vazar — quebrar deixava "125 / kHz" em duas linhas, e vazar dava a
   rolagem horizontal. `min-width: 0` é o que permite ao span encolher
   abaixo do conteúdo (item de flex tem `min-width: auto` por padrão, e é
   por isso que o texto empurrava o painel). */
.multiselect__item {
  white-space: nowrap;
  line-height: 1.35;
}

.multiselect__item span {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Trava final: o painel contém o conteúdo, sem rolagem lateral. A
   vertical continua (a lista pode ser longa). */
.multiselect__painel {
  overflow-x: hidden;
}

/* Valor digitado: mesma linha dos demais, marcado por um "(digitado)"
   discreto — não é uma 2ª categoria, é a mesma lista. */
.multiselect__item--livre em {
  font-style: normal;
  font-size: 0.72rem;
  color: var(--cor-cinza);
}

/* O campo de "outro valor" fecha o painel, separado por uma linha — é
   ação, não mais um item da lista. */
.multiselect__novo {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--cor-borda);
}

.multiselect__novo-campo {
  width: 100%;
  font: inherit;
  font-size: 0.8rem;
  padding: 5px 7px;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
}

.multiselect__novo-campo::placeholder {
  color: var(--cor-cinza);
  font-size: 0.76rem;
}

/* O cabeçalho lista os selecionados e cresce sem limite quando são
   muitos — trunca com reticências em vez de esticar o campo. */
.multiselect__cabecalho {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Plano de Teste: a norma selecionada em quadro verde (v27, QA-002) --
   Mesmo par de variáveis do card de combinação ESCOLHIDA
   (`.combinacao-card--escolhida`) — a borda do verde da identidade e o
   fundo suave. É o mesmo significado nas duas telas ("isto está
   escolhido"), então tem que ser a mesma cor: dois verdes diferentes pro
   mesmo estado é como uma interface começa a parecer duas. */
.plano-teste-norma--selecionada {
  border: 1px solid var(--cor-status-concluida);
  background: var(--cor-verde-suave);
  border-radius: 6px;
  padding: 6px 10px;
  margin-bottom: 6px;
}

/* O summary já tem padding próprio; dentro do quadro ele encostaria na
   borda de cima. */
.plano-teste-norma--selecionada > summary {
  padding: 2px 0;
}


/* --- Busca do Kanban (v27, QA-002 C5) --------------------------------
   Vive FORA de `#comercial-kanban` (ver comercial_lista.html): o board
   inteiro é trocado a cada ação, e o campo dentro dele perderia foco e
   cursor a cada 300ms de digitação. */
.kanban-busca {
  margin: 0 0 12px;
}

.kanban-busca__campo {
  width: 100%;
  max-width: 420px;
  font: inherit;
  font-size: 0.88rem;
  padding: 7px 11px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  background: var(--cor-branco);
}

.kanban-busca__campo:focus {
  outline: none;
  border-color: var(--cor-azul);
}


/* v27 (QA-005, Parte B3): o selo de salvamento.

   Canto inferior direito, fixo, pequeno. Ele existe para o usuário saber que
   há uma janela — sem isso, o aviso "Salvando… aguarde" ao clicar num link
   apareceria do nada. `pointer-events: none` porque ele nunca é clicável: um
   aviso que rouba clique num canto da tela é pior que aviso nenhum. */
.selo-salvamento {
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 200;
  padding: 6px 12px;
  border-radius: 14px;
  font-size: 0.76rem;
  font-weight: 600;
  pointer-events: none;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12);
}

.selo-salvamento--ativo {
  background: var(--cor-atencao-suave);
  color: var(--cor-atencao);
  border: 1px solid var(--cor-atencao);
}

.selo-salvamento--pronto {
  background: var(--cor-verde-suave);
  color: var(--cor-status-concluida);
  border: 1px solid var(--cor-status-concluida);
}

/* O erro NÃO some sozinho (ver base.html) e por isso é o único que pode
   receber clique — é dele que o usuário precisa se aproximar para ler. */
.selo-salvamento--erro {
  background: #fff;
  color: var(--cor-status-bloqueada);
  border: 1px solid var(--cor-status-bloqueada);
  pointer-events: auto;
}


/* v27 (QA-005, A4 completo): o aviso de que Custo/Fornecedor/Rastreio estão
   guardados mas não valem na coluna atual. Discreto e permanente — ele
   descreve um estado, não um evento, e some sozinho quando a coluna volta
   para a Moderacon. */
.painel-cotacoes__servico-guardado {
  font-size: 0.72rem;
  color: var(--cor-status-bloqueada);
  border: 1px dashed var(--cor-status-bloqueada);
  border-radius: 6px;
  padding: 3px 7px;
  white-space: nowrap;
  cursor: help;
}


/* v27 (QA-005, trava da contratada): o selo no topo da Composição. Não é um
   alerta — é uma etiqueta de estado, e por isso não pisca nem se fecha: ela
   descreve como a tela vai se comportar dali para baixo. */
.painel-cotacoes__selo-contratada {
  margin: 0 0 10px;
  padding: 7px 11px;
  border-left: 3px solid var(--cor-status-concluida);
  background: var(--cor-verde-suave);
  border-radius: 0 6px 6px 0;
  font-size: 0.8rem;
  color: var(--cor-texto);
}

/* A moeda de uma proposta contratada: mesma posição do toggle, sem parecer
   clicável. */
.toggle-moeda__fixa {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--cor-cinza);
  padding: 4px 10px;
  border: 1px dashed var(--cor-borda);
  border-radius: 6px;
}

/* ---------------------------------------------------------------------
   v27 (cancelamento de contratação, fatia A1)
   --------------------------------------------------------------------- */

/* A linha alcançada por um produto cancelado e ainda sem acerto. Âmbar
   porque é PENDÊNCIA, não erro: alguém precisa decidir, nada quebrou. */
.linha-fluxo--pendente > td {
  background: var(--cor-amarelo-suave);
}

/* O lançamento de cancelamento em si. Roxo, o mesmo tom que o status
   CANCELADO já usa no seletor ao lado — escala verde/âmbar/roxo já
   estabelecida no sistema. */
.linha-fluxo--cancelamento > td {
  background: var(--cor-roxo-suave);
  color: var(--cor-roxo);
}

.celula-cancelamento small {
  display: block;
  font-size: 0.75rem;
  opacity: 0.85;
}

.linha-fluxo--acerto > td {
  background: var(--cor-amarelo-suave);
  padding: 8px 10px;
}

.fluxo-acerto {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
}

.fluxo-acerto__titulo {
  width: 100%;
  font-size: 0.85rem;
}

.fluxo-acerto label {
  display: flex;
  flex-direction: column;
  font-size: 0.75rem;
  gap: 2px;
}

.fluxo-acerto__justificativa {
  flex: 1 1 240px;
}

.fluxo-acerto__justificativa input {
  width: 100%;
}

/* O modal de "Encerrar processo" da Gestão. Reaproveita as classes
   `form-encerramento*` do modal irmão do Comercial; só o que é próprio
   das três vias fica aqui. */
.form-encerramento__vias {
  display: flex;
  flex-direction: column;
  gap: 10px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  padding: 10px 12px;
  margin-bottom: 12px;
}

.form-encerramento__via {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}

.form-encerramento__via small {
  display: block;
  font-size: 0.78rem;
  opacity: 0.85;
}

.form-encerramento__via--perigo {
  border-left: 3px solid var(--cor-roxo);
  padding-left: 8px;
}

.form-encerramento__aviso {
  color: var(--cor-amarelo);
}

.form-encerramento__aviso--bloqueio {
  font-size: 0.78rem;
  border-left: 3px solid var(--cor-borda);
  padding-left: 8px;
  opacity: 0.9;
}

/* v27 (ajustes sobre 8d5955d, item 7): o [Cancelar processo], na barra
   de ações de Tarefas ao lado do [Finalizar].

   Contorno em vez de preenchimento: é uma saída anormal, e deve ler-se
   como diferente do [Finalizar] sem gritar. Roxo, o mesmo tom que o
   sistema já usa para cancelamento (status CANCELADO do Fluxo, ícone
   "Cancelar" do Kanban) — escala verde/âmbar/roxo já estabelecida. */
.botao-cancelar-processo {
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  background: transparent;
  color: var(--cor-roxo);
  border: 1px solid var(--cor-roxo);
  border-radius: 4px;
  padding: 5px 10px;
  cursor: pointer;
}

.botao-cancelar-processo:hover {
  background: var(--cor-roxo-suave);
}

/* v27 (ajustes sobre 8d5955d, item 10): o marcador de desfecho na lista
   de arquivados. Cor, e não só texto: numa lista de 128 linhas a
   diferença entre concluído e cancelado precisa saltar sem leitura. */
.marcador-desfecho {
  display: inline-block;
  font-size: 0.75rem;
  border-radius: 10px;
  padding: 2px 8px;
  white-space: nowrap;
}

.marcador-desfecho--concluido {
  background: var(--cor-status-concluida-suave);
  color: var(--cor-status-concluida);
}

.marcador-desfecho--cancelado {
  background: var(--cor-roxo-suave);
  color: var(--cor-roxo);
}

.marcador-desfecho--sem {
  border: 1px dashed var(--cor-borda);
  opacity: 0.7;
}

.marcador-desfecho__motivo {
  display: block;
  font-size: 0.7rem;
  opacity: 0.8;
}

/* v27 (acerto no Fluxo, §2): a linha que sofreu cancelamento.
   Precedente: o Desconto da Composição guarda positivo e exibe com
   sinal — mesmo tratamento aqui. */
.valor-contratado-riscado {
  opacity: 0.55;
  margin-right: 6px;
}

.valor-revisado {
  white-space: nowrap;
}

.etiqueta-cancelado {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--cor-roxo-suave);
  color: var(--cor-roxo);
  border-radius: 8px;
  padding: 1px 6px;
  margin-left: 6px;
  vertical-align: middle;
}

.linha-fluxo--tem-cancelamento > td {
  background: var(--cor-roxo-suave);
}

/* O detalhe recolhido reaproveita `.linha-detalhe`/`.conteudo-expandido`
   da lista de Gestão — só a tabela interna é própria. */
.tabela-detalhe-cancelamento {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.78rem;
}

.tabela-detalhe-cancelamento th,
.tabela-detalhe-cancelamento td {
  text-align: left;
  padding: 3px 8px 3px 0;
  vertical-align: top;
}

.tabela-detalhe-cancelamento th {
  font-weight: 600;
  opacity: 0.7;
}

.valor-cancelamento {
  color: var(--cor-roxo);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.fluxo-detalhe-cancelamento__topo {
  margin: 0 0 6px;
  font-size: 0.8rem;
}

.fluxo-acerto-envio {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 8px;
}

.fluxo-acerto-envio small {
  font-size: 0.75rem;
  opacity: 0.8;
}

/* v27 (ajuste): campo travado — "cobrado integral" fixa a redução em
   zero, e o campo mostra isso em vez de só recusar depois. */
.input-travado {
  background: var(--cor-fundo-suave, #f1f1f1);
  opacity: 0.75;
  cursor: not-allowed;
}

/* v27 (item 9): Fluxo arquivado. Marca visual discreta, SEM
   `pointer-events: none` — a leitura (o chevron do detalhe) tem de
   continuar funcionando. O que trava a edição é não renderizar campo
   editável nenhum, mais o 403 de `bloqueado_se_financeiro_arquivado`. */
.fluxo-fornecedor--arquivado {
  opacity: 0.92;
  border-left: 3px solid var(--cor-borda);
}

/* v27 (ajuste): os dois badges do menu Financeiro deixam de se
   confundir.

   ★ O ícone recolhido mostra UM dos dois, nunca a soma — a pendência
   quando houver, o não-lido quando não houver. Ver o comentário em
   base.html para o porquê. A cor separa o que o número significa:
   vermelho (`.sidebar-badge`, padrão) para "não lido", roxo para
   "pendente" — o mesmo tom que o sistema já usa para cancelamento no
   status do Fluxo, no marcador da lista de arquivados e no botão
   Cancelar processo. */
.sidebar-badge--pendencia {
  background: var(--cor-roxo);
}

.menu-badge--pendencia {
  background: var(--cor-roxo-suave);
  color: var(--cor-roxo);
  font-weight: 700;
}

/* v27 (INSTRUCAO_AVISO_FINANCEIRO): "o serviço acabou, confira o dinheiro".

   ★ VERDE, E NUNCA O ROXO. O roxo quer dizer CANCELAMENTO neste sistema
   inteiro — status do Fluxo, marcador da lista de arquivados, botão
   Cancelar processo e o ⚠ do acerto pendente. O verde já quer dizer
   CONCLUÍDO (status de tarefa, estados "confirmado"), que é exatamente o
   que este aviso anuncia: o serviço terminou.

   Usar o mesmo roxo faria a pessoa procurar um acerto de cancelamento que
   não existe — e os dois avisos NUNCA acendem na mesma proposta, por
   construção (decisão 1), então nada os desambiguaria na tela. */
.menu-badge--conferencia {
  background: var(--cor-verde-suave);
  color: var(--cor-verde);
  font-weight: 700;
}

.marcador-conferencia {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--cor-verde-suave);
  color: var(--cor-verde);
  border-radius: 8px;
  padding: 1px 7px;
  margin-left: 6px;
  vertical-align: middle;
  font-weight: 600;
}

/* v27 (lista do Fluxo): busca, filtros e os dois sinais da linha. */

.filtros-fluxo a {
  margin-right: 2px;
}

.filtro-fluxo--ativo {
  font-weight: 700;
  text-decoration: none;
  cursor: default;
}

/* ★ O marcador de pendência é PÍLULA COM PALAVRA, não peso de fonte —
   o negrito da linha já significa "não lido" (`vistos_fluxo`), e os
   dois aparecem na mesma tela. Roxo, o tom que o sistema usa para
   cancelamento no status do Fluxo, no marcador de desfecho da Gestão e
   no botão Cancelar processo. */
.marcador-pendencia {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  background: var(--cor-roxo-suave);
  color: var(--cor-roxo);
  border-radius: 8px;
  padding: 1px 7px;
  margin-left: 6px;
  vertical-align: middle;
  font-weight: 600;
}

.tabela-gestao th a.ordenavel {
  color: inherit;
  text-decoration: none;
}

.tabela-gestao th a.ordenavel:hover {
  text-decoration: underline;
}

.paginacao {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 10px;
  font-size: 0.85rem;
}

/* v27 (lista do Fluxo): larguras explícitas.

   ★ O Cliente ocupava largura demais — sem `width`, o navegador dá o
   espaço ao conteúdo mais largo, e os nomes de cliente são longos. Isso
   empurrava Contratação e Encerramento para a borda direita, longe do
   resto da informação. Agora o Cliente é o que cede: ele trunca com
   reticências e as datas ficam próximas. `table-layout: fixed` é o que
   faz as larguras valerem de verdade. */
.tabela-fluxo-lista {
  table-layout: fixed;
  width: 100%;
}

.tabela-fluxo-lista .col-codigo { width: 15%; }
.tabela-fluxo-lista .col-cliente { width: 26%; }
.tabela-fluxo-lista .col-produto { width: 22%; }
.tabela-fluxo-lista .col-data { width: 14%; }
.tabela-fluxo-lista .col-encerramento { width: 23%; }

/* O Cliente e o Produto truncam em vez de esticar a coluna. O `title`
   já carrega o valor inteiro nas duas. */
.tabela-fluxo-lista .col-cliente,
.tabela-fluxo-lista td.col-produto {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ★ v27 (QA-006 v7, item 4.2 / C10 fase A): faixa de contexto, grudada no
   topo acima das abas. `sticky` e não `fixed`: ela ocupa o seu lugar no
   fluxo (não cobre o cabeçalho ao carregar) e só gruda quando a rolagem a
   alcança. O cabeçalho completo continua rolando, como o GB-ordem pediu —
   a faixa é a versão compacta, só leitura. `flex-wrap` para caber em
   tela estreita sem rolagem lateral. */
.faixa-contexto {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 18px;
  margin-bottom: 12px;
  padding: 8px 16px;
  background: var(--cor-branco);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  font-size: 0.8rem;
  color: var(--cor-cinza);
}
.faixa-contexto__item--codigo {
  font-family: var(--fonte-titulo);
  font-weight: 700;
  color: var(--cor-azul);
}
.faixa-contexto__rotulo {
  margin-right: 4px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--cor-azul);
}
.faixa-contexto__numero {
  font-variant-numeric: tabular-nums;
  color: var(--cor-cinza);
  font-weight: 600;
}

/* ★ v27 (QA-006 v7, item 4.1 / C10 fase A): abas do processo.
   A visibilidade é decidida SÓ pelo `data-aba-ativa` do contêiner, que
   nunca é trocado por htmx — por isso a aba sobrevive a qualquer swap de
   `#dados-processo`/`#tabela-tarefas` sem JS nenhum depois dele. */
.abas-processo__barra {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  margin-bottom: 12px;
  border-bottom: 2px solid var(--cor-borda);
}
.abas-processo__aba {
  padding: 8px 16px;
  margin-bottom: -2px;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  font-family: var(--fonte-titulo);
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--cor-cinza);
  cursor: pointer;
}
.abas-processo__aba:hover {
  color: var(--cor-azul);
}
.abas-processo__aba:focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 2px;
}
/* ★ v27 (LAYOUT COMERCIAL F1, item 1): o realce sai do `aria-selected`
   (que o JS escreve) e passa a vir TAMBÉM do `data-aba-ativa` do
   contêiner, como os painéis. Motivo: na proposta a BARRA é
   re-renderizada a cada salvamento — é assim que os badges chegam
   frescos —, e um realce preso só ao atributo escrito pelo JS voltaria
   apagado depois do swap. O `aria-selected` continua, para leitor de
   tela. */
.abas-processo[data-aba-ativa="tarefas"] [data-aba-alvo="tarefas"],
.abas-processo[data-aba-ativa="empresas"] [data-aba-alvo="empresas"],
.abas-processo[data-aba-ativa="produto"] [data-aba-alvo="produto"],
.abas-processo[data-aba-ativa="plano-teste"] [data-aba-alvo="plano-teste"],
.abas-processo[data-aba-ativa="amostras"] [data-aba-alvo="amostras"],
.abas-processo[data-aba-ativa="proposta"] [data-aba-alvo="proposta"],
.abas-processo[data-aba-ativa="cotacoes"] [data-aba-alvo="cotacoes"],
.abas-processo[data-aba-ativa="regulatorio-produto"] [data-aba-alvo="regulatorio-produto"],
.abas-processo[data-aba-ativa="interfaces-rf"] [data-aba-alvo="interfaces-rf"],
.abas-processo[data-aba-ativa="vinculo"] [data-aba-alvo="vinculo"],
.abas-processo[data-aba-ativa="contratacao"] [data-aba-alvo="contratacao"],
.abas-processo__aba[aria-selected="true"] {
  color: var(--cor-azul);
  border-bottom-color: var(--cor-laranja);
}

/* O badge de pendências da aba. Zero não desenha — o template nem emite o
   elemento; "0 pendências" é ruído, e a instrução pediu que não exista. */
/* ★★ v11: o aviso de pendência da aba Tarefas, carregado sob demanda.

   ★ O bloco nasce VAZIO e sem borda — enquanto o aviso não chegou, não pode
   haver caixa vazia nem "0 pendências" na tela (condição do Guto). Por isso
   o estilo mora na `.aviso-pendencias` de dentro, não no `#aviso-pendencias`
   que envolve: sem conteúdo, não há o que desenhar. */
.aviso-pendencias {
  margin: 0 0 12px;
  padding: 10px 14px;
  border: 1px solid var(--cor-atencao);
  border-left-width: 4px;
  border-radius: 4px;
  background: var(--cor-atencao-suave);
}

.aviso-pendencias__titulo {
  margin: 0 0 6px;
  font-weight: 700;
}

.aviso-pendencias__lista {
  margin: 0;
  padding-left: 18px;
}

.aviso-pendencias__item {
  margin-bottom: 3px;
}

.aviso-pendencias__contagem {
  margin-left: 8px;
  color: var(--cor-texto-suave, #666);
  font-size: 0.85em;
}

.aviso-pendencias__link {
  margin-left: 8px;
  font-size: 0.85em;
}

/* ★ O contador de pendência de DOCUMENTO é visualmente distinto do badge de
   sempre, de propósito: eles medem coisas diferentes e chegam em momentos
   diferentes (o badge no carregamento, este depois do aviso). Cor igual faria
   parecer um número só, partido em dois. */
/* ★★★ v13: A ORDEM AQUI É A REGRA, e ela estava invertida.

   Os modificadores (`--documento`, `--contagem`) e a base têm a MESMA
   especificidade — uma classe cada. Com a base DEPOIS, era ela que ganhava, e
   os dois modificadores não pintavam nada.

   ★ Medido no navegador: o badge `--documento`, que pede `#c0392b`, desenhava
   `rgb(216, 43, 24)` — o coral da base. Estava assim desde que foi escrito, e
   só apareceu quando o contador neutro caiu na mesma armadilha.

   ★ Base primeiro, modificadores depois. Sem `!important` e sem subir
   especificidade: a ordem resolve, e é o que alguém lendo espera. */
.abas-processo__badge {
  display: inline-block;
  min-width: 18px;
  margin-left: 6px;
  padding: 0 5px;
  border-radius: 9px;
  /* ★ C1, ajuste do Guto (02/10/2026): o âmbar CHEIO com número branco pesava
     demais. Agora é o desenho do selo "sem nº" e do selo de atenção da
     variante A: fundo âmbar CLARO, número em âmbar ESCURO — 4,96 (0,72rem bold,
     texto pequeno: a régua é 4,5). O `--contagem` das listas continua neutro. */
  background: var(--cor-atencao-suave);
  color: var(--cor-atencao);
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  vertical-align: middle;
}

.abas-processo__badge--documento {
  background: var(--cor-vermelho, #c0392b);
}

/* ★★ v13 (validação do Guto): O CONTADOR QUE SÓ CONTA É NEUTRO.

   O badge de aba nasceu para PENDÊNCIA — coral, a cor que este sistema usa
   para "algo pede ação". As duas listas novas (Propostas e Processos) o
   reusaram para dizer "quantas há nesta aba", e aí o coral mente: ele promete
   ação onde não há nenhuma.

   ★ Varrido: são exatamente DOIS os contadores de contagem —
   `comercial_propostas.html` e `gestao_lista.html`. Os outros dois usos de
   `.abas-processo__badge` são alerta de verdade e ficam coral: o de pendência
   por aba (`_abas_barra.html`) e o `--documento`, que é vermelho.

   ★ Contraste medido, porque a fonte é 0,72rem (~11,5px) e a régua da casa
   pede 4,5 para texto pequeno:

     grafite #2F3943 sobre borda #E1E4E8 ....... 9,21  ✔
     cinza   #575756 sobre borda #E1E4E8 ....... 5,67  ✔  (também serviria)
     branco  #FFFFFF sobre coral #D82B18 ....... 4,91     o que estava no ar

   ★ Escolhi o grafite pelo mesmo motivo do contador de follow-up, decidido
   antes: o NÚMERO vai em grafite, e a cor fica reservada para o que informa
   estado. */
.abas-processo__badge--contagem {
  background: var(--cor-borda);
  color: var(--cor-grafite);
}


.abas-processo [data-aba-painel] {
  display: none;
}
.abas-processo[data-aba-ativa="tarefas"] [data-aba-painel="tarefas"],
.abas-processo[data-aba-ativa="empresas"] [data-aba-painel="empresas"],
.abas-processo[data-aba-ativa="produto"] [data-aba-painel="produto"],
.abas-processo[data-aba-ativa="plano-teste"] [data-aba-painel="plano-teste"],
.abas-processo[data-aba-ativa="amostras"] [data-aba-painel="amostras"],
/* ★ v27 (LAYOUT COMERCIAL F1, item 1): as abas da PROPOSTA, no mesmo
   mecanismo. Os slugs são os de `ABAS_PROPOSTA` (core/comercial.py) e os
   do `#hash` da URL — os três têm de bater, por isso nascem num lugar só,
   em Python. */
.abas-processo[data-aba-ativa="proposta"] [data-aba-painel="proposta"],
.abas-processo[data-aba-ativa="cotacoes"] [data-aba-painel="cotacoes"],
/* ★ v27 (F1, item 5): as tres abas da tela do servico. */
.abas-processo[data-aba-ativa="regulatorio-produto"] [data-aba-painel="regulatorio-produto"],
.abas-processo[data-aba-ativa="interfaces-rf"] [data-aba-painel="interfaces-rf"],
.abas-processo[data-aba-ativa="vinculo"] [data-aba-painel="vinculo"],
.abas-processo[data-aba-ativa="contratacao"] [data-aba-painel="contratacao"] {
  display: block;
}
/* Com um quadro por aba, recolher o quadro não tem mais sentido: a aba já
   é a escolha do que se vê. O cabeçalho colapsável some e o painel fica
   sempre aberto — `!important` vence o `style="display:none"` que o
   servidor (`aberto=False` na carga) e `aplicarEstadoDosQuadros` escrevem
   inline. A memória dos quadros continua existindo, só não decide mais
   nada dentro das abas. */
.abas-processo .dados-processo__cabecalho {
  display: none;
}
.abas-processo .dados-processo__painel {
  display: block !important;
  margin-top: 0;
}

/* A ação de contratar, no fim da aba Contratação (F1, item 1). */
.painel-cotacoes__acao-contratar {
  margin-top: 16px;
  text-align: right;
}

/* ★ v27 (F1, item 5): os modelos do serviço em tabela — o rótulo sai de
   cada linha e vai para o cabeçalho, uma vez só. */
.tabela-modelos {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 10px;
}
.tabela-modelos th,
.tabela-modelos td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--cor-borda);
  text-align: left;
}
.tabela-modelos th {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--cor-azul);
}
.tabela-modelos td input[type="text"] {
  width: 100%;
}
.tabela-modelos__testado {
  text-align: center;
}

/* ★★ v27 (QA-006 v10, item 1): o CABEÇALHO UNIFICADO da Gestão.
   Duas linhas num cartão só, no lugar do cartão antigo + a faixa da fase
   A. NÃO é sticky, de propósito: o GB-ordem pediu 'reverte o cabeçalho
   fixo', e essa decisão continua valendo. */
.cabecalho-gestao {
  position: relative;
  padding: 12px 20px;
}
.cabecalho-gestao__linha {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 18px;
  font-size: 0.82rem;
  color: var(--cor-cinza);
}
.cabecalho-gestao__linha--2 {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--cor-borda);
}
.cabecalho-gestao__codigo {
  font-family: var(--fonte-titulo);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--cor-azul);
}
.cabecalho-gestao__rotulo {
  margin-right: 4px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--cor-azul);
}
/* O laboratório sem número em destaque (pedido do Guto): a marca é na
   ETIQUETA, não no campo — o campo continua no mesmo lugar, para o
   clique de edição não dançar conforme o estado. */
.cabecalho-gestao__item--sem-numero .cabecalho-gestao__rotulo {
  color: var(--cor-atencao);
}
.cabecalho-gestao__item--sem-numero::after {
  content: "sem nº";
  margin-left: 4px;
  padding: 0 5px;
  border-radius: 8px;
  background: var(--cor-atencao-suave);
  color: var(--cor-atencao);
  font-size: 0.68rem;
  font-weight: 700;
}
.cabecalho-gestao__rel,
.cabecalho-gestao__siglas {
  color: var(--cor-cinza);
  font-size: 0.74rem;
}
.cabecalho-gestao__acoes {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ★ v27 (QA-006 v10, item 2): os ícones de ação do cabeçalho. Cinza =
   não feito; verde = feito. O padrão da fase: ícone, com title e
   aria-label, nunca botão de texto. */
.icone-acao {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 1.05rem;
  line-height: 1;
  padding: 2px 4px;
}
.icone-acao--cinza { color: var(--cor-status-pendente); }
.icone-acao--verde { color: var(--cor-verde); }
.icone-acao:hover { filter: brightness(0.85); }
.icone-acao:focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 2px;
}

.icone-acao--cancelar { color: var(--cor-status-bloqueada); }

/* ★★ v13 (item 5): o ícone de "outro laboratório assume", no plano de teste.

   ★ `--cor-azul` (#094C85), a institucional — contraste medido nesta casa:
   **8,81** sobre branco e **8,21** sobre o cinza de fundo, bem acima dos 4,5 da
   régua. ★ Não o coral: ele é o alerta, e transferir ensaio não é alerta. */
.icone-acao--outro-lab { color: var(--cor-azul); }

/* ★★ v13 (item 4): O CAMPO DE Nº DE RASTREIO DA FAIXA CABE ~15 CARACTERES.

   ★ Ele não tinha regra nenhuma: ficava com a largura padrão do navegador para
   `<input type="text">` — ~20 caracteres —, e a faixa do cabeçalho tem OC mais
   um item por laboratório disputando a mesma linha.

   ★★★ A MEDIÇÃO QUE AUTORIZA ISTO, e ela vem antes: o campo é
   `Cotacao.numero_proposta_fornecedor`, `max_length=120` no banco.

     | | local | homologação |
     |---|---|---|
     | cotações              |  47 |  46 |
     | com número preenchido | ★ 2 | ★ 9 |
     | MAIOR valor           |   6 |  11 |
     | acima de 15           | ★ 0 | ★ 0 |

   ★★ E a distinção que decide o conserto: **largura visual não corta dado.** O
   `<input>` rola; quem cortaria seria um atributo `maxlength` ou uma redução do
   `max_length` no banco — e esta última é migração destrutiva, que a régua da
   casa proíbe. Nenhum dos dois entra aqui.

   ★ `ch` é a unidade do "0" da fonte: `15ch` É "quinze caracteres", e continua
   sendo se a fonte mudar. Um valor em px viraria mentira na primeira troca de
   tipografia. O `+ 1.2em` cobre o padding e a borda da caixa. */
.campo-rastreio {
  width: calc(15ch + 1.2em);
  min-width: 0;
}

/* ★★ v13 (decisão do Guto): a CONDIÇÃO DE PAGAMENTO editável no Fluxo — o campo
   travado com o ✎ ao lado.

   ★ `inline-flex` para o lápis ficar na mesma linha do campo sem que o campo
   perca a largura: o cabeçalho do bloco tem três colunas fixas, e um botão que
   empurra a linha quebraria o alinhamento das outras duas.

   ★ O campo cresce e o botão não (`flex: 1 1 auto` contra `flex: 0 0 auto`):
   condição de pagamento é texto longo ("30 dias após a conclusão do serviço."),
   e é ele que precisa do espaço. */
.campo-condicao-fluxo {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  width: 100%;
}

.input-condicao-fluxo {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--fonte-texto);
  font-size: 0.85rem;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  padding: 4px 6px;
  box-sizing: border-box;
}

.campo-condicao-fluxo .icone-editar {
  flex: 0 0 auto;
}

/* ★ v27 (QA-006 v10, item 4): o lápis, irmão da lixeira. */
.icone-editar {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--cor-azul);
  font-size: 0.95rem;
  padding: 0 4px;
}
.icone-editar:hover { filter: brightness(1.2); }

/* ★★ v13 (INSTRUCAO_TRANSPORTE_PLANO, item 1): o laboratório da norma, no
   Plano de Teste. Mesma caixa da "Nota de teste" logo abaixo — o `<select>`
   usa o `.dados-processo__campo` genérico, então aqui só o espaçamento e o
   estado travado. */
.plano-teste-norma__lab {
  margin-top: 6px;
}

/* ★ Travado (proposta contratada, e a tela da Gestão): é TEXTO, não campo.
   O azul suave de TEXTO é o tom medido para texto pequeno — 4,84 sobre o
   branco —, e não o `--cor-azul-suave` de fundo/borda, que dá 2,93. */
.plano-teste-norma__lab--travado {
  color: var(--cor-azul-suave-texto);
  font-size: 0.78rem;
  font-weight: 600;
}

/* ★★ v13 (INSTRUCAO_LAB_POR_ITEM, item 2): o laboratório de cada ITEM, ao lado
   do nome dele. O nome ocupa o espaço que sobra e o seletor fica à direita, com
   largura própria — sem isto, uma norma de 15 itens viraria 15 seletores de
   larguras diferentes, um por tamanho de nome. */
.plano-teste-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.plano-teste-item > .dados-processo__checkbox,
.plano-teste-item > .plano-teste-item__nome {  /* ★ Fase B Etapa 2: o nome sem caixa (contratada) */
  flex: 1 1 auto;
  min-width: 0;
}

.plano-teste-item__lab {
  flex: 0 0 auto;
  max-width: 40%;
  font-size: 0.74rem;
}

/* ★ A2 (AJUSTES_TELA_FASE_B): o destaque da linha sob o mouse — a linha INTEIRA, até
   o seletor do laboratório —, para não marcar ou escolher na linha errada. Só nas
   linhas que têm o que marcar ou escolher (a lista de leitura da contratada fica
   como está). Listas: a revisão do plano e o plano no Comercial (`.plano-teste-item`),
   os itens de ensaio da norma (`.item-ensaio`) e os laboratórios da pergunta de
   custo (`.pergunta-custo__lab`). */
.plano-teste-item:has(input, select):hover,
.item-ensaio:hover,
.pergunta-custo__lab:hover {
  background: var(--cor-linha-sob-mouse);
  border-radius: 4px;
}

/* ★★ v13 (INSTRUCAO_LAB_POR_ITEM, item 4): "cote um laboratório primeiro" —
   uma vez por PRODUTO, no subtítulo, FORA do recolhimento da norma.
   ★ O amarelo é o mesmo da pendência do checklist (`--cor-amarelo`), porque é
   a mesma natureza: falta um dado para poder seguir. ★ Sobre o branco do painel
   ele dá 3,05 — insuficiente para texto pequeno —, então aqui vai em
   `--cor-grafite` com o fundo suave, e não em texto colorido. */
.plano-teste-sem-lab {
  margin: 0 0 10px;
  padding: 7px 10px;
  border-left: 3px solid var(--cor-amarelo);
  background: var(--cor-fundo);
  color: var(--cor-grafite);
  font-size: 0.78rem;
  border-radius: 0 4px 4px 0;
}

/* ★★★ v13 (decisão do Guto): o ATALHO da norma na LINHA DA NORMA, alinhado com
   a coluna dos seletores dos itens.
   ★ O nome ocupa o espaço que sobra; o seletor e o ✕ ficam à direita, com a
   MESMA largura que `.plano-teste-item__lab` usa nos itens — é o alinhamento
   que faz a coluna existir, e é ele que explica o campo sem precisar de rótulo. */
.plano-teste-norma__linha {
  display: flex;
  align-items: center;
  gap: 8px;
}

.plano-teste-norma__nome {
  flex: 1 1 auto;
  min-width: 0;
}

/* ★ O seletor do ATALHO e o de cada item compartilham a mesma faixa à direita.
   Sem a mesma base de largura eles ficariam escalonados, e a coluna — que é o
   que substitui o rótulo — deixaria de se ler como coluna. */
.plano-teste-norma__linha .plano-teste-item__lab {
  flex: 0 0 auto;
  max-width: 40%;
}

/* ★★ O ✕ fecha a linha da norma — e e' ELE que desalinhava a coluna: medido,
   o seletor da norma ficava 20px a esquerda do dos itens, porque os itens nao
   tem ✕ nenhum depois deles.
   ★ A largura mora numa variavel e e' usada nos DOIS lugares: aqui, como
   tamanho do botao, e nas linhas de item, como espaco reservado. Uma definicao,
   dois usos — se o botao mudar de tamanho, a coluna acompanha sozinha. */
.plano-teste-norma__linha .plano-teste-chip__remover {
  flex: 0 0 var(--largura-remover-norma);
  width: var(--largura-remover-norma);
  text-align: center;
}

/* ★ O espaco reservado na linha do ITEM, do tamanho do ✕ mais o gap da linha
   da norma — e' o que poe as duas bordas direitas na mesma vertical. */
.plano-teste-item {
  padding-right: calc(var(--largura-remover-norma) + 8px);
}

/* ★★★ v13 (validação do Guto): o seletor da NORMA precisa de PESO VISUAL maior
   que o dos itens — sem isso, subir para a linha não bastou: ele ficou idêntico
   aos dos itens, e não se lia de relance quem comanda e quem obedece.

   ★ O que muda, e o contraste de cada peça, medido:
     TEXTO   grafite #2F3943 sobre branco ....... 11,75  (limite 4,5)  ✔
             e sobre --cor-fundo #F6F7F8 ........ 10,95  (limite 4,5)  ✔
     BORDA   --cor-azul #094C85 ................. 8,81   (limite 3,0)  ✔
   ★ A cor do TEXTO não mudou — o destaque é peso, borda e fundo, não tom. Por
     isso o contraste do dígito continua o mesmo de antes do destaque. */
.plano-teste-norma__linha .plano-teste-item__lab {
  font-weight: 700;
  font-size: 0.8rem;
  color: var(--cor-grafite);
  border: 1.5px solid var(--cor-azul);
  background: var(--cor-fundo);
  border-radius: 4px;
  padding: 3px 6px;
}

/* ★ E o do ITEM fica deliberadamente mais leve: borda fina, sem fundo, fonte
   menor. A diferença é o que se lê de relance. */
.plano-teste-item > .plano-teste-item__lab {
  font-weight: 400;
  border: 1px solid var(--cor-borda);
  background: transparent;
}


/* ============================================================
   v14 — O PAINEL DE ACOMPANHAMENTO (Gestão › Pipeline)
   ============================================================

   ★★ NÃO É O KANBAN DO COMERCIAL, e por isso tem classes próprias.

   Ele empresta a FORMA (board › coluna › cabeçalho fixo › cards) e não as
   classes, por duas diferenças que mudariam o `.kanban-*` para todo mundo:

     1. ★ as colunas têm LARGURAS DIFERENTES (Andamento é a mais larga,
        decisão do Guto) — `.kanban-coluna` é `flex: 1 1 0` com `min/max`,
        que as faz iguais de propósito;
     2. ★ o cartão do painel NÃO é arrastável e não tem `data-status-url`.

   ★ SEM `overflow` no board, pelo MESMO motivo já documentado em
   `.kanban-board`: `overflow-x: auto` faz o `overflow-y` computar `auto`
   junto, o board vira o container de rolagem e o cabeçalho fixo da coluna
   passa a grudar NELE — medido lá, o cabeçalho ia a -510px ao rolar 700px.
   A rolagem lateral volta só no breakpoint estreito, onde as 4 colunas não
   cabem. */

.painel-cabecalho {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 14px;
  /* ★ COLUNA, e não `space-between` numa linha só: é a lição do cabeçalho do
     Fluxo (v13) — um layout que muda de forma conforme o tamanho do dado é o
     defeito, não o sintoma. Aqui o dado que cresce é o nome do responsável. */
}

.painel-cabecalho__titulo {
  margin: 0;
  font-size: 1.15rem;
  color: var(--cor-azul);
}

.painel-cabecalho__filtros {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.painel-cabecalho__rotulo {
  font-size: 0.8rem;
  color: var(--cor-texto-suave);
}

.painel-busca {
  font: inherit;
  font-size: 0.88rem;
  width: 320px;
  max-width: 100%;
  padding: 6px 11px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  background: var(--cor-branco);
}

.painel-busca:focus,
.painel-select:focus {
  outline: none;
  border-color: var(--cor-azul);
}

.painel-select {
  font: inherit;
  font-size: 0.85rem;
  padding: 5px 8px;
  border: 1px solid var(--cor-borda);
  border-radius: 6px;
  background: var(--cor-branco);
}

.painel-cabecalho__botao {
  font: inherit;
  font-size: 0.82rem;
  padding: 6px 12px;
  border: 1px solid var(--cor-azul);
  border-radius: 6px;
  background: var(--cor-branco);
  color: var(--cor-azul);
  cursor: pointer;
}

.painel-cabecalho__estado {
  margin: 0;
  font-size: 0.8rem;
  color: var(--cor-texto-suave);
}

.painel-board {
  display: grid;
  /* ★ Andamento é a mais larga (decisão do Guto). Os pesos 1/2/1/1 são os
     mesmos de `COLUNAS` em `core/painel.py`, e o smoke compara os dois — se um
     mudar sem o outro, a coluna larga deixa de ser a que o Python diz. */
  grid-template-columns: 1fr 2fr 1fr 1fr;
  gap: 12px;
  align-items: start;
  padding-bottom: 8px;
}

/* 1+2+1+1 pesos ≈ 5 faixas de 200px + 3 gaps ≈ 1036px. */
@media (max-width: 1080px) {
  .painel-board {
    overflow-x: auto;
  }
}

.painel-coluna {
  min-width: 0;
  background: var(--cor-fundo);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
}

.painel-coluna__cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--cor-branco);
  border-top: 3px solid var(--cor-azul);
  border-bottom: 1px solid var(--cor-borda);
  border-top-left-radius: var(--raio);
  border-top-right-radius: var(--raio);
  padding: 8px 10px;
  /* ★ gruda no topo ao rolar, como no Kanban — sem isto o nome da etapa sai de
     vista e não se sabe mais em que coluna se está. */
  position: sticky;
  top: 0;
  z-index: 2;
}

.painel-coluna__titulo {
  font-size: 0.85rem;
  font-weight: 600;
}

.painel-coluna__contador {
  font-size: 0.78rem;
  padding: 1px 8px;
  border-radius: 9px;
  background: var(--cor-fundo);
  color: var(--cor-texto-suave);
}

.painel-coluna__cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
}

.painel-coluna__vazia {
  margin: 0;
  padding: 10px 2px;
  font-size: 0.78rem;
  color: var(--cor-texto-suave);
}

.painel-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 9px 10px;
  background: var(--cor-branco);
  border: 1px solid var(--cor-borda);
  border-radius: var(--raio);
  /* ★★ v14 (validação do Guto): TODOS OS CARTÕES COM A MESMA ALTURA, como no
     mockup — que usa 132px.

     ★ MEDIDO ANTES, e por isso a altura precisou ser fixada: os ajustes 3 e 5
     (a devolução no rodapé e só o primeiro modelo) encurtaram os cartões, mas
     NÃO os igualaram — **101 / 113 / 122 / 126** px, por etapa. ★★ E a
     Publicação variava com a LARGURA (126 a 1280px, 122 a partir de 1600),
     porque a nota da devolução quebra na coluna estreita.

     ★★★ `min-height` E NÃO `height`, e a diferença é o controle do par: um
     `height` fixo CORTA quando o conteúdo passa, e o par exige "nada é
     cortado em nenhuma etapa". Com `min-height` todos ficam em 132 na prática
     (o mais alto medido é 126) e, se um dia um nome longo passar disso, o
     cartão CRESCE em vez de esconder. ★ O preço é que nesse dia aquele
     cartão fica mais alto — e um cartão mais alto se vê; um cortado, não. */
  min-height: 132px;
  box-sizing: border-box;
}

.painel-card__linha1 {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}

.painel-card__espaco {
  flex-grow: 1;
}

.painel-card__inicial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 11px;
  background: var(--cor-fundo);
  font-size: 0.7rem;
  color: var(--cor-texto-suave);
}

.painel-card__codigo {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--cor-azul);
  text-decoration: none;
  flex-shrink: 0;
}

.painel-card__codigo:hover {
  text-decoration: underline;
}

.painel-card__cliente,
.painel-card__meta {
  font-size: 0.78rem;
  color: var(--cor-texto-suave);
  /* ★ o nome do cliente e o do serviço são texto livre e longos (medido: 60
     caracteres no maior `str(cliente)` da base, e "Manutenção da homologação
     com transferência com teste" no serviço). Cortar com reticências é o que
     mantém o cartão com a mesma altura em toda a coluna. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.painel-card__terceiro {
  font-size: 0.78rem;
  color: var(--cor-texto);
}

.painel-card__rotulo {
  font-size: 0.72rem;
  color: var(--cor-texto-suave);
}

.painel-card__aviso {
  font-size: 0.75rem;
  /* ★ NÃO é `--cor-amarelo`: sobre o branco do cartão ele não passa de 4,5 como
     texto pequeno. `--cor-coral-texto` é a variação medida (5,18 no branco,
     4,56 no rosa) — a regra da cor de marca, no CLAUDE.md. */
  color: var(--cor-atencao);
}

.painel-card__faixa {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  background: var(--cor-fundo);
  border-radius: 4px;
  min-width: 0;
}

.painel-card__testes,
.painel-card__docs {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.painel-card__docs {
  flex-grow: 1;
}

.painel-card__divisor {
  width: 1px;
  height: 16px;
  background: var(--cor-borda);
  flex-shrink: 0;
}

.painel-card__farol {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: 0.72rem;
  /* ★ v14 (validação do Guto): as letras E / C / R em NEGRITO.
     ★★ E a cor subiu de `--cor-texto-suave` para `--cor-texto` junto, por
     medição: negrito num tom suave fica mais pesado sem ficar mais legível, e
     o cinza suave num dígito de 0,72rem é justamente o caso em que a régua de
     contraste deste projeto morde (ver `--cor-coral-texto` no CLAUDE.md). */
  font-weight: 700;
  color: var(--cor-texto);
}

.painel-card__bolha {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 5px;
}

/* ★ As MESMAS quatro cores da escala do contador, e de propósito: o farol e o
   calendário respondem à mesma pergunta ("isto está no prazo?"), e dois jogos
   de cor na mesma tela fariam o usuário aprender duas. */
.painel-card__bolha--verde { background: var(--cor-followup-folgado); }
.painel-card__bolha--azul { background: var(--cor-followup-proximo); }
.painel-card__bolha--amarelo { background: var(--cor-followup-hoje); }
.painel-card__bolha--vermelho { background: var(--cor-followup-vencido); }

.painel-card__docs-numero {
  font-size: 0.78rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

.painel-card__barra {
  display: flex;
  flex-grow: 1;
  min-width: 40px;
  height: 7px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--cor-borda);
}

.painel-card__barra-parte--feito { background: var(--cor-followup-folgado); }
.painel-card__barra-parte--prazo { background: var(--cor-followup-proximo); }
.painel-card__barra-parte--vencido { background: var(--cor-followup-vencido); }

.painel-card__vencidos {
  font-size: 0.72rem;
  color: var(--cor-coral-texto);
  flex-shrink: 0;
}

.painel-card__rodape {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.painel-card__sem-contador {
  font-size: 0.85rem;
  color: var(--cor-texto-suave);
}

/* ---- o contador: o calendário com o número dentro -----------------------
   ★ Mesmo desenho e mesmas cores do follow-up do Comercial
   (`.followup-calendario`), sem o overlay do Flatpickr — aqui não há data a
   reagendar. ★ "Número em grafite, cor no ícone", decisão do Guto: o contorno,
   a faixa e as argolas usam `currentColor`; o número, não. */
.painel-contador {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.painel-contador__corpo {
  fill: var(--cor-branco);
  stroke: currentColor;
  stroke-width: 1.3px;
}

.painel-contador__faixa {
  fill: currentColor;
}

.painel-contador__argola {
  stroke: currentColor;
  stroke-width: 1.6px;
  stroke-linecap: round;
}

.painel-contador__numero {
  position: absolute;
  left: 0;
  right: 0;
  top: 44%;
  text-align: center;
  font-size: 0.7rem;
  font-weight: 800;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  /* ★ GRAFITE: 11,75 sobre o branco do corpo. Os tons da escala reprovam como
     texto pequeno (o amarelo dá 2,37 e o azul suave 2,93) — a medição está no
     comentário de `.followup-calendario__numero`. */
  color: var(--cor-grafite);
  pointer-events: none;
}

.painel-contador--vermelho { color: var(--cor-followup-vencido); }
.painel-contador--amarelo { color: var(--cor-followup-hoje); }
.painel-contador--azul { color: var(--cor-followup-proximo); }
.painel-contador--verde { color: var(--cor-followup-folgado); }

/* ★★★ C1 (Fase C) — a BASE dos campos, para o que NENHUMA classe estiliza.

   Até aqui o sistema não tinha regra de campo comum: cada formulário
   estilizava o seu, e o resto ficava com a borda do navegador (escura, 2px,
   em relevo — os números do OC e dos labs no cabeçalho da Gestão, por exemplo).

   ★ `:where()` tem especificidade ZERO. Qualquer regra de classe que já exista
   (inclusive as que tiram a borda de propósito, nos editores em linha) vence
   esta; ela só alcança o campo que hoje está no padrão do navegador. Sem o
   `:where`, um `input[type=text]` (0,1,1) venceria `.classe { border: none }`
   (0,1,0) em silêncio. */
:where(input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="file"], [type="color"], [type="range"], [type="submit"], [type="button"], [type="image"]), select, textarea) {
  border: 1px solid var(--cor-borda-campo);
  border-radius: 6px;
  background-color: var(--cor-branco);
  color: var(--cor-grafite);
  font-family: inherit;
}
:where(input:not([type="checkbox"], [type="radio"], [type="hidden"], [type="file"], [type="color"], [type="range"], [type="submit"], [type="button"], [type="image"]), select, textarea):disabled {
  background-color: var(--cor-fundo);
}
:where(input, select, textarea, button):focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 1px;
}

/* ★ C1 — a linha sob o mouse nas listas de tarefa e do Fluxo (a da Gestão já
   tinha). Mesmo tom das listas de item (A2 da fase B). */
.tabela-tarefas tbody tr:hover > td,
table.tabela-fluxo tbody tr:hover > td {
  background-color: var(--cor-linha-sob-mouse);
}

/* ★★★ FASE C, C2 — a GESTÃO com o visual do C10 (docs/C10), só aparência.

   ★ ESCOPO: tudo aqui começa por `#abas-processo` (o contêiner das abas do
   processo, que SÓ a Gestão tem — o Comercial usa `#abas-proposta` e
   `#abas-produto` com as mesmas classes) ou por `.cabecalho-gestao`. O
   Comercial e os relatórios ficam para a C4.

   ★ Nenhuma função sai, nenhuma muda de lugar: o inventário dos controles
   (botões, campos, links, htmx) é o MESMO antes e depois — medido, ver
   ENTREGA_FASE_C2.md. O chip "Requerente" do C10 não volta ao cabeçalho. */

/* -- 1. as abas em PASTA: a ativa é branca e se cola ao painel; a linha coral
      no topo é o destaque da marca (o coral não é mais cor de alerta) -- */
#abas-processo > .abas-processo__barra {
  gap: 4px;
  margin-bottom: 0;
  border-bottom: none;
  position: relative;
  z-index: 1;
}
#abas-processo .abas-processo__aba {
  margin-bottom: -1px;
  padding: 9px 16px 10px;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--cor-cinza);
}
#abas-processo .abas-processo__aba:hover {
  color: var(--cor-azul);
}
#abas-processo[data-aba-ativa="tarefas"] [data-aba-alvo="tarefas"],
#abas-processo[data-aba-ativa="empresas"] [data-aba-alvo="empresas"],
#abas-processo[data-aba-ativa="produto"] [data-aba-alvo="produto"],
#abas-processo[data-aba-ativa="plano-teste"] [data-aba-alvo="plano-teste"],
#abas-processo[data-aba-ativa="amostras"] [data-aba-alvo="amostras"],   /* C3, V2: faltava (a aba Amostras perdia o realce depois de gravar) */
#abas-processo .abas-processo__aba[aria-selected="true"] {
  background: var(--cor-branco);
  border-color: var(--cor-borda);
  border-top: 3px solid var(--cor-laranja);
  padding-top: 7px;
  color: var(--cor-grafite);
}
/* o cartão do painel: borda fina em vez de sombra (como o C10), e o canto de
   cima à esquerda reto, onde a aba encosta */
#abas-processo [data-aba-painel].cartao,
#abas-processo [data-aba-painel="tarefas"] > .cartao {
  margin-top: 0;
  border: 1px solid var(--cor-borda);
  border-radius: 0 8px 8px 8px;
  box-shadow: none;
}

/* -- 2. o cabeçalho do processo: o código como título, os rótulos discretos.
      ★ Os RÓTULOS ficam (decisão do Guto na v11, item 1a); o C10 os troca por um
      título sem rótulo — ver "Para decidir" na entrega. -- */
.cabecalho-gestao {
  border: 1px solid var(--cor-borda);
  box-shadow: none;
  border-radius: 8px;
  margin-bottom: 14px;
}
.cabecalho-gestao__codigo {
  font-size: 1.3rem;
  color: var(--cor-grafite);
}
.cabecalho-gestao__rotulo {
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--cor-cinza);
}

/* -- 3. as caixas (Empresas, Produto, Plano de teste): título de seção em azul,
      rótulo pequeno e cinza ACIMA do campo, o campo em tamanho de leitura -- */
#abas-processo .dados-processo__secao h4 {
  font-family: var(--fonte-titulo);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--cor-azul);
}
#abas-processo .dados-processo__subtitulo {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--cor-grafite);
}
#abas-processo .dados-processo__campo {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--cor-cinza);
}
#abas-processo .dados-processo__campo :is(input, select, textarea) {
  font-size: 0.85rem;
  font-weight: 400;
}
/* a tabela de modelos do Produto: o cabeçalho leve das tabelas de lista */
#abas-processo .tabela-modelos th {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 500;
  color: var(--cor-cinza);
  background: var(--cor-fundo);
}

/* -- 4. Plano de teste: os ciclos em FITA sublinhada (como as abas de ciclo da
      tabela de tarefas e o C10), não em abas de caixa -- */
#abas-processo .fita-ciclos__aba {
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  background: none;
  color: var(--cor-cinza);
  margin-bottom: -1px;
}
#abas-processo .fita-ciclos__aba--ativa {
  background: none;
  color: var(--cor-azul);
  font-weight: 600;
  border-bottom-color: var(--cor-azul);
}

/* -- 5. Tarefas: os blocos ("Etapa inicial", "Laboratório: …") como as FAIXAS
      de bloco do C10 — fundo azul-claro, Montserrat pequena em caixa alta.
      ★ Só a aparência do que já existe; o AGRUPAMENTO por bloco do C10 é da C3. -- */
#abas-processo .etapa-inicial__cabecalho,
#abas-processo .bloco-laboratorio__cabecalho {
  padding: 6px 10px;
  border-radius: 4px;
  background: #EEF3F8;
}
#abas-processo .etapa-inicial__titulo,
#abas-processo .bloco-laboratorio__cabecalho h4 {
  font-family: var(--fonte-titulo);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--cor-azul);
}
#abas-processo .bloco-laboratorio {
  border-left: none;
  padding-left: 0;
  margin-left: 0;
}

/* ★★★ FASE C, C3 (DECISOES_C3_BLOCOS.md) — as tarefas por BLOCO, e os FILTROS.

   ★ Os filtros só ESCONDEM: `filtro-oculta` some com o bloco ou a linha;
   `filtro-mostra` traz a concluída recolhida quando o Status é "Concluídas".
   O recolher das concluídas (estilo em linha de cada grupo) não é tocado.
   ★ C3, V3 (validação do Guto, 04/10/2026): o botão "x/y concluída(s)" fica
   SEMPRE — clicado com "Em aberto", o filtro passa a respeitar aquele bloco
   (`gruposComConcluidas`, gestao_detalhe.html). Antes ele sumia nos dois
   filtros. */
.filtro-oculta {
  display: none !important;
}
.filtro-status-concluidas tbody.filtro-mostra {
  display: table-row-group !important;
}
.filtro-status-concluidas [id^="painel-grupo-"] {
  display: block !important;
}
#abas-processo .filtros-tarefas {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  /* dentro do cartão da tabela, uma linha simples, como no C10 */
  margin: 4px 0 16px;
}
#abas-processo .filtros-tarefas label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--cor-cinza);
}
#abas-processo .filtros-tarefas select {
  height: 30px;
  padding: 0 8px;
  font-size: 0.85rem;
}
#abas-processo .filtros-tarefas__contagem {
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--cor-cinza);
}
/* a faixa do bloco simples, no mesmo desenho das faixas de laboratório (C2) */
#abas-processo .bloco-tarefas__cabecalho {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 10px;
  border-radius: 4px;
  background: #EEF3F8;
}
#abas-processo .bloco-tarefas__cabecalho h3 {
  font-family: var(--fonte-titulo);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--cor-azul);
}
#abas-processo .bloco-tarefas__cabecalho .botao-nova-tarefa {
  margin-left: auto;
}

/* ★★★ FASE C, C3 — AJUSTES_C3_MOTIVO_2 (M3, validação do Guto, 03/10/2026).
   ★ A coluna de status mostra SÓ o estado real (o selo); o MOTIVO vai numa NOTA
   minimalista de UMA linha, que aparece ao passar o mouse sobre o selo e ao
   tocar nele (o toque dá foco ao select: `:focus-within`, sem JavaScript).
   ★ Fora do fluxo (`position: absolute`): a linha mantém a altura das outras e
   a coluna, a largura do select. Texto longo é cortado com "…".
   ★ Saíram (decisão do Guto): o selo "Aguarda" em contorno escrito na linha
   (D5.1), o ⓘ e a caixa do toque (M2), e a lista do aviso de campo vazio (M1). */
.status-com-motivo {
  position: relative;
  display: inline-block;
}
.nota-motivo {
  display: none;
  position: absolute;
  top: calc(100% + 3px);
  left: 0;
  z-index: 30;           /* acima da coluna presa de Ações */
  width: max-content;
  max-width: 460px;
  padding: 3px 8px;
  border: 1px solid var(--cor-borda-campo);
  border-radius: 4px;
  background: var(--cor-branco);
  color: var(--cor-grafite);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.4;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}
.status-com-motivo:hover .nota-motivo:has(.nota-motivo__parte:not(:empty)),
.status-com-motivo:focus-within .nota-motivo:has(.nota-motivo__parte:not(:empty)) {
  display: block;
}
/* o separador " · " entre as partes que têm texto (a falta chega depois, por OOB,
   e pode vir vazia) */
.nota-motivo__parte:not(:empty) ~ .nota-motivo__parte:not(:empty)::before {
  content: " · ";
}

/* ★★ FASE C, C3 (D5.4) — a aba Amostras: a tabela do que o sistema guarda
   (nº, modelo, onde está, enviada, devolvida, tarefa vinculada). Usa a
   `tabela-gestao` da base; aqui só o espaço e as notas. */
.caixa-amostras__procedimento {
  margin: 0 0 10px;
  font-size: 0.85rem;
  color: var(--cor-grafite);
}
.caixa-amostras__rolagem {
  overflow-x: auto;
}
.tabela-amostras {
  width: 100%;
}
.caixa-amostras__nota {
  color: var(--cor-status-pendente);
  font-size: 0.75rem;
}
.caixa-amostras__vazio {
  margin: 4px 0 0;
  padding: 8px 12px;
  border: 1px solid var(--cor-atencao);
  border-left-width: 4px;
  border-radius: 4px;
  background: var(--cor-atencao-suave);
  font-size: 0.85rem;
  color: var(--cor-grafite);
}
/* ★ C3 (decisão do Guto): o "+ registrar amostra" na própria aba. */
.caixa-amostras__registro {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px 14px;
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--cor-borda);
  font-size: 0.82rem;
}
.caixa-amostras__registro label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  color: var(--cor-grafite);
}
.caixa-amostras__rotulo {
  align-self: center;
  font-weight: 600;
  color: var(--cor-azul);
}
.caixa-amostras__erro {
  margin: 10px 0 0;
  padding: 6px 10px;
  border: 1px solid var(--cor-erro);
  border-left-width: 4px;
  border-radius: 4px;
  font-size: 0.82rem;
  color: var(--cor-erro);
}

/* ★★ FASE C, C3 (D5.3) — o resultado por item no Plano de teste: os itens de
   uma norma abrem dentro da linha do laboratório na fita, ocupando a linha
   inteira (a linha é uma grade de 2 colunas); em Tarefas, o resumo da norma. */
.fita-ciclos__itens {
  grid-column: 1 / -1;
  margin: 4px 0 6px;
  padding: 8px 12px;
  border-left: 3px solid var(--cor-azul-suave);
  background: var(--cor-fundo);
}
.contagem-norma {
  color: var(--cor-status-pendente);
  font-variant-numeric: tabular-nums;
}
.norma-relatorio-item__sigla {
  font-weight: 600;
}

/* ★★ FASE C, C3, V5 (validação do Guto, 04/10/2026) — a BARRA DE ABAS fixa no
   topo ao rolar, em qualquer aba; o cabeçalho do processo rola normalmente.
   `sticky` (não `fixed`): ocupa o seu lugar no fluxo e só gruda quando a rolagem
   a alcança. Fundo próprio, para o conteúdo passar POR BAIXO dela sem
   transparecer; acima da coluna presa de Ações. */
#abas-processo .abas-processo__barra {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--cor-fundo);
}
/* ★ e o que se leva ao topo (um link, uma âncora, `scrollIntoView`) para ABAIXO
   da barra, não por baixo dela: os filtros, os blocos e as linhas de tarefa.
   ★ 48px: a altura da barra (38px, medida) com folga. */
#abas-processo .filtros-tarefas,
#abas-processo [data-bloco],
#abas-processo tbody[id^="tbody-tarefa-"],
#abas-processo tr.linha-tarefa,   /* ★ C3, V4: a linha também (é ela que se leva à vista) */
#abas-processo [data-aba-painel] {
  scroll-margin-top: 48px;
}

/* ★ C3, V6: a revisão do plano — "Normas fora do plano (n)", recolhida, abaixo
   das normas que estão no plano. */
.revisao-plano__fora {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--cor-borda);
}
.revisao-plano__fora-resumo {
  cursor: pointer;
  font-weight: 600;
  color: var(--cor-azul);
  margin-bottom: 8px;
}

/* ★ C3, V4: as ações de amostra na aba (destravar, vincular, corrigir) e o link
   que substitui os subitens na linha da tarefa — este só ao passar o mouse
   (ou com o foco dentro da linha, para quem navega pelo teclado). */
.tabela-amostras__acoes {
  white-space: nowrap;
}
.caixa-amostras__acao {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 8px;
}
.link-na-linha {
  margin-left: 8px;
  font-size: 0.78rem;
  visibility: hidden;
}
tr.linha-tarefa:hover .link-na-linha,
tr.linha-tarefa:focus-within .link-na-linha {
  visibility: visible;
}

/* ★★ FASE C, C3 — NORMA PADRÃO (aprovação do Guto, 04/10/2026): laboratório, nº do
   relatório e resultado definidos na NORMA, com exceção por item.
   ★ A exceção é um "•" discreto no azul suave — é ícone, não texto, e não é alerta
   (o coral não entra) —, com a nota de UMA linha ao passar o mouse ou com o foco
   (a `.nota-motivo` do M3). Nada mais na linha.
   ★ O "↺ seguir a norma" só aparece com o mouse sobre a linha (ou o foco dentro
   dela), como o link da linha de tarefa do V4.
   ★ A linha da NORMA abre o painel "resultados", separada dos itens por um fio. */
.campo-norma {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
.excecao-norma {
  position: relative;
  display: inline-block;
  color: var(--cor-azul-suave);
  font-weight: 700;
  line-height: 1;
  cursor: help;
}
.excecao-norma:hover .excecao-norma__nota,
.excecao-norma:focus .excecao-norma__nota {
  display: block;
}
.link-seguir-norma {
  visibility: hidden;
  font-size: 0.75rem;
}
/* ★ Nas linhas do PLANO (revisão e antes da contratação) a coluna dos seletores
   tem de continuar uma coluna (smoke_v13_lab_item_tela): a largura máxima que o
   seletor tinha (40% da linha) passa ao invólucro — dentro dele, os 40% valeriam
   sobre o próprio invólucro e o seletor encolheria (medido: 68 px) —, o seletor
   mantém o peso leve do item, e o "•" sai do fluxo, na faixa já reservada à
   direita (a do ✕ da norma). O "↺" vem ANTES do seletor no HTML: invisível, ele
   só tira espaço do nome, não empurra a coluna. */
.plano-teste-item > .campo-norma {
  flex: 0 0 auto;
  max-width: 40%;
  position: relative;
}
.plano-teste-item > .campo-norma > .plano-teste-item__lab {
  max-width: 100%;
  font-weight: 400;
  border: 1px solid var(--cor-borda);
  background: transparent;
}
.plano-teste-item > .campo-norma > .excecao-norma {
  position: absolute;
  left: calc(100% + 4px);
  top: 50%;
  transform: translateY(-50%);
}
.plano-teste-item > .link-seguir-norma {
  flex: 0 0 auto;
}
.item-ensaio:hover .link-seguir-norma,
.item-ensaio:focus-within .link-seguir-norma,
.plano-teste-item:hover .link-seguir-norma,
.plano-teste-item:focus-within .link-seguir-norma {
  visibility: visible;
}
.item-ensaio--norma {
  padding-bottom: 4px;
  border-bottom: 1px solid var(--cor-borda);
}
.revisao-plano__lab-norma > .plano-teste-item__lab {
  max-width: none;   /* ★ os 40% valeriam sobre o rótulo, e o seletor encolheria */
}
.revisao-plano__lab-norma {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  font-size: 0.78rem;
  color: var(--cor-grafite);
}
.aviso-norma {
  margin: 4px 0 12px;
  font-size: 0.85rem;
  color: var(--cor-grafite);
}

/* ★★★ FASE C, C4 — os DEMAIS MÓDULOS com a linguagem da C1/C2 (só aparência).
   Comercial, Fluxo/Financeiro, Vendas e relatórios, ANATEL, cadastros,
   configuração e o login. Nenhuma função sai: o inventário de controles por tela
   é o mesmo antes e depois (ENTREGA_FASE_C4.md). PDFs e "para o e-mail" ficam de
   fora (não usam este CSS de tela). */

/* -- 1. Comercial: as abas da PROPOSTA e do PRODUTO em PASTA, como as do processo
      na Gestão (C2). Aqui elas ficam DENTRO do cartão, então a pasta assenta num
      fio de base e a ativa, branca, o cobre. -- */
:is(#abas-proposta, #abas-produto) .abas-processo__barra {
  gap: 4px;
  border-bottom: 1px solid var(--cor-borda);
}
:is(#abas-proposta, #abas-produto) .abas-processo__aba {
  margin-bottom: -1px;
  padding: 9px 16px 10px;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--cor-cinza);
}
:is(#abas-proposta, #abas-produto) .abas-processo__aba:hover {
  color: var(--cor-azul);
}
#abas-proposta[data-aba-ativa="proposta"] [data-aba-alvo="proposta"],
#abas-proposta[data-aba-ativa="plano-teste"] [data-aba-alvo="plano-teste"],
#abas-proposta[data-aba-ativa="cotacoes"] [data-aba-alvo="cotacoes"],
#abas-proposta[data-aba-ativa="contratacao"] [data-aba-alvo="contratacao"],
#abas-produto[data-aba-ativa="regulatorio-produto"] [data-aba-alvo="regulatorio-produto"],
#abas-produto[data-aba-ativa="interfaces-rf"] [data-aba-alvo="interfaces-rf"],
#abas-produto[data-aba-ativa="vinculo"] [data-aba-alvo="vinculo"],
:is(#abas-proposta, #abas-produto) .abas-processo__aba[aria-selected="true"] {
  background: var(--cor-branco);
  border-color: var(--cor-borda);
  border-top: 3px solid var(--cor-laranja);
  padding-top: 7px;
  color: var(--cor-grafite);
  box-shadow: 0 1px 0 var(--cor-branco);   /* cobre o fio de base: a pasta abre para o conteúdo */
}

/* -- 2. As barras de NAVEGAÇÃO dos módulos (relatórios, ANATEL, carteira,
      cadastro, estados da proposta) na FITA sublinhada da C2 — a mesma dos ciclos
      do Plano de teste. O verde de antes vira o azul principal. -- */
.relatorio-abas__aba:hover,
nav.abas-processo__barra[aria-label^="Estados"] > a.abas-processo__aba:hover {
  color: var(--cor-azul);
}
.relatorio-abas__aba--ativa {
  color: var(--cor-azul);
  border-bottom-color: var(--cor-azul);
}
nav.abas-processo__barra[aria-label^="Estados"] {
  border-bottom-width: 1px;
}
nav.abas-processo__barra[aria-label^="Estados"] > a.abas-processo__aba {
  margin-bottom: -1px;
  font-family: var(--fonte-texto);
  font-weight: 500;
  text-decoration: none;
}
nav.abas-processo__barra[aria-label^="Estados"] > a.abas-processo__aba[aria-selected="true"] {
  color: var(--cor-azul);
  font-weight: 600;
  border-bottom-color: var(--cor-azul);
}

/* -- 3. Títulos de seção e rótulos, como na Gestão (C2) — agora em TODA tela que
      usa as caixas de dados (proposta, produto, cadastro, Fluxo, configuração). -- */
.dados-processo__secao h4 {
  font-family: var(--fonte-titulo);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--cor-azul);
}
.dados-processo__subtitulo {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--cor-grafite);
}
.dados-processo__campo {
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--cor-cinza);
}
.dados-processo__campo :is(input, select, textarea) {
  font-size: 0.85rem;
  font-weight: 400;
}

/* -- 4. Faixa de seção: no Fluxo do processo, cada FORNECEDOR é um grupo de linhas
      — o título do bloco ganha a faixa das tarefas da Gestão (fundo azul-claro,
      Montserrat pequena em caixa alta). -- */
.fluxo-fornecedor__titulo {
  padding: 6px 10px;
  border-radius: 4px;
  background: #EEF3F8;
  font-family: var(--fonte-titulo);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--cor-azul);
}

/* -- 5. A informação SECUNDÁRIA no mouse, não na linha (regra do Guto para a C4).
      O texto que EXPLICA (de onde vem o dado, o que o gráfico conta, para que serve
      o campo) sai da linha e fica numa nota que aparece ao passar o mouse — ou com
      o foco, para quem navega pelo teclado — sobre o TÍTULO que ele explica. O
      título leva um sublinhado pontilhado discreto: é o sinal de que há nota.
      ★ Aviso, pendência e bloqueio NÃO entram: continuam na linha.
      ★ A nota é a da C3 (`.nota-motivo`), em várias linhas: estes textos são longos
      demais para uma só, e cortá-los com "…" esconderia informação. -- */
.com-nota {
  position: relative;
  display: inline-block;
  cursor: help;
  text-decoration: underline dotted var(--cor-borda-campo);
  text-underline-offset: 4px;
}
.com-nota .nota-secundaria {
  display: none;
  position: absolute;
  top: 100%;   /* ★ encostada no título: com vão, o mouse sai da área antes de chegar a um link da nota */
  left: 0;
  z-index: 40;
  width: max-content;
  max-width: min(520px, 80vw);
  padding: 6px 10px;
  border: 1px solid var(--cor-borda-campo);
  border-radius: 4px;
  background: var(--cor-branco);
  color: var(--cor-grafite);
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  font-weight: 400;
  font-style: normal;
  letter-spacing: 0;
  line-height: 1.45;
  text-transform: none;
  text-align: left;
  white-space: normal;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}
.com-nota:hover .nota-secundaria,
.com-nota:focus .nota-secundaria,
.com-nota:focus-within .nota-secundaria {
  display: block;
}

/* ★★ C4 — AJUSTES_C4_VALIDACAO, A1: o cabeçalho do fornecedor no Fluxo em DUAS
   linhas. Linha 1: Tipo · Valor total · Condição. Linha 2: Razão social · CNPJ ·
   IE · IM · Endereço, com larguras pelo TAMANHO REAL do dado — CNPJ formatado tem
   18 caracteres, IE até 14, IM até 15 — mais 1ch de folga; razão social e endereço
   dividem o resto e quebram linha. `flex-wrap`: em tela estreita a linha quebra em
   duas, sem rolagem lateral. */
.fluxo-fornecedor__linha--resumo,
.fluxo-fornecedor__linha--fiscal {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 4px 20px;
}
.fluxo-fornecedor__linha--resumo > .dados-processo__campo {
  flex: 0 0 auto;
}
.fluxo-fornecedor__linha--resumo > .fluxo-fornecedor__campo-condicao {
  flex: 1 1 280px;
  max-width: 460px;
}
.fluxo-campo--cnpj { flex: 0 0 19ch; }
.fluxo-campo--ie   { flex: 0 0 15ch; }
.fluxo-campo--im   { flex: 0 0 16ch; }
.fluxo-campo--razao {
  flex: 1 1 200px;
  min-width: 0;
}
.fluxo-campo--endereco {
  flex: 2 1 260px;
  min-width: 0;
}
.fluxo-fornecedor__linha--fiscal .dados-processo__valor-fixo {
  overflow-wrap: anywhere;   /* razão social e endereço quebram; nunca empurram a linha */
}

/* ★★ C4 — NAVEGAÇÃO (INSTRUCAO_C4_NAVEGACAO): a barra das páginas de Propostas e
   Projetos — a contagem dos ativos, a chave [ Quadro | Lista ] e o acesso discreto
   ao Histórico. A chave é um par de botões colados (segmentado), a opção ativa em
   azul cheio; o Histórico é um link discreto à direita. */
.navegacao-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin: 4px 0 12px;
}
.navegacao-barra__total {
  font-size: 0.85rem;
  color: var(--cor-cinza);
  font-variant-numeric: tabular-nums;
}
.chave-visao {
  display: inline-flex;
  border: 1px solid var(--cor-azul);
  border-radius: 6px;
  overflow: hidden;
}
.chave-visao__opcao {
  padding: 5px 14px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--cor-azul);
  text-decoration: none;
  background: var(--cor-branco);
}
.chave-visao__opcao + .chave-visao__opcao {
  border-left: 1px solid var(--cor-azul);
}
.chave-visao__opcao--ativa {
  background: var(--cor-azul);
  color: var(--cor-branco);
}
.chave-visao__opcao:focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 2px;
}
.navegacao-barra__filtro {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.78rem;
  color: var(--cor-cinza);
}
.navegacao-barra__historico {
  margin-left: auto;
  font-size: 0.82rem;
  color: var(--cor-cinza);
}
/* o "não visto" (decisão do Guto): saiu do menu e virou MARCA no cartão e na
   linha — o coral, que é o destaque da marca para "não visto" (C1) */
.marca-nao-visto {
  margin-right: 4px;
  color: var(--cor-laranja);
  font-weight: 700;
}
/* a data de follow-up na visão Lista, na cor do quadradinho do Quadro (texto
   escuro o bastante: as variantes de texto, não as de fundo) */
.followup-texto--vermelho { color: var(--cor-erro); font-weight: 600; }
.followup-texto--amarelo  { color: var(--cor-atencao); font-weight: 600; }
.followup-texto--azul     { color: var(--cor-azul); }
.followup-texto--verde    { color: var(--cor-status-concluida, #237A47); }
.kanban-coluna__legado {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
}

/* ★★ N2: o envoltório da página de quem não pode editar — só MARCA a região
   (`data-somente-leitura`, lida pelo `_somente_leitura_script.html`); não desenha
   nada: `display: contents` o tira do layout. */
.somente-leitura {
  display: contents;
}

/* ★★ D6 (QA-006 plus, etapa 3, 08/10/2026) — MODELOS POR NORMA E POR ITEM no plano de
   teste (mockup do Guto, `MOCKUP_D6_PLANO_DE_TESTE.html`). A letra é um selo pequeno;
   azul cheio = ligado na norma (testa todos os itens); vazio = desligado; o ponto =
   está em algum item; tracejado = só aquele item. Contraste: branco sobre o azul e o
   cinza de texto sobre o branco passam de 4,5. */
.plano-modelos__letra {
  display: inline-block; min-width: 22px; padding: 2px 6px; line-height: 16px;
  font: inherit; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.03em; text-align: center;
  border: 1px solid var(--cor-borda-campo); border-radius: 10px;
  background: #fff; color: var(--cor-cinza);
}
.plano-modelos__letra--legenda { background: #EAF1F8; color: var(--cor-azul); border-color: var(--cor-azul); }
.plano-modelos__legenda { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; }
.plano-modelos__legenda-item { display: inline-flex; align-items: center; gap: 6px; }
.plano-modelos__legenda-item--fora { color: var(--cor-cinza); font-weight: 400; }
.plano-modelos__legenda-item--fora .plano-modelos__letra { background: #fff; color: var(--cor-cinza); border-color: var(--cor-borda-campo); }
.plano-modelos__servico { font-weight: 400; }
.plano-modelos__chips { display: inline-flex; gap: 5px; margin-left: auto; margin-right: 6px; }
.plano-modelos__chip { position: relative; }
button.plano-modelos__chip { cursor: pointer; }
.plano-modelos__chip--ligado { background: var(--cor-azul); color: #fff; border-color: var(--cor-azul); }
.plano-modelos__chip--parcial::after {
  content: ""; position: absolute; top: -3px; right: -3px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--cor-azul); border: 1px solid #fff;
}
.plano-modelos__chip--trava { animation: plano-modelos-treme 0.3s; }
@keyframes plano-modelos-treme { 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
.plano-modelos__item { display: inline-flex; align-items: center; gap: 5px; margin-left: 8px; }
.plano-modelos__extra { color: var(--cor-azul); border: 1px dashed var(--cor-azul); }
button.plano-modelos__extra { cursor: pointer; }
/* ★ "+ modelo" aparece ao passar o mouse sobre o item OU ao chegar pelo Tab — por
   opacidade, e não `visibility: hidden`: escondido assim ele não receberia o foco */
.plano-modelos__mais { position: relative; opacity: 0; }
.plano-teste-item:hover .plano-modelos__mais,
.plano-teste-item:focus-within .plano-modelos__mais,
.plano-modelos__mais[open] { opacity: 1; }
.plano-modelos__mais-botao { cursor: pointer; color: var(--cor-azul); font-size: 0.8rem; list-style: none; padding: 2px 4px; }
.plano-modelos__mais-botao::-webkit-details-marker { display: none; }
.plano-modelos__menu {
  position: absolute; right: 0; top: 100%; z-index: 5; display: flex; gap: 6px; padding: 6px;
  background: #fff; border: 1px solid var(--cor-borda); border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
button.plano-modelos__letra--legenda { cursor: pointer; }
.plano-modelos__letra:focus-visible, .plano-modelos__mais-botao:focus-visible {
  outline: 2px solid var(--cor-azul); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) { .plano-modelos__chip--trava { animation: none; } }
/* ★★ D6 — no formulário da revisão do plano (Gestão): a letra com a caixa de marcar */
.revisao-plano__modelos { gap: 8px; }
.revisao-plano__modelo { display: inline-flex; align-items: center; gap: 3px; cursor: pointer; }
.revisao-plano__modelo input { accent-color: var(--cor-azul); margin: 0; }
.revisao-plano__modelos-rotulo { font-size: 0.75rem; color: var(--cor-cinza); }
/* ★ D6: a coluna das letras do item tem largura fixa e fica ANTES do laboratório — sem
   isso, o item com letra empurrava o seletor para fora da coluna dos outros */
.plano-teste-item .plano-modelos__item { margin-left: auto; min-width: 96px; justify-content: flex-end; }

/* ★★ (pós-D6, push 1) UM SÓ FILTRO DE RESPONSÁVEL: o texto "Mostrando … · ver todos" mora
   na linha do Quadro | Lista (Propostas e Projetos), no lugar do seletor que saiu */
.navegacao-barra__estado {
  margin: 0;
  font-size: 0.82rem;
  color: var(--cor-cinza);
}
.navegacao-barra__estado strong { color: var(--cor-grafite); }

/* ★★ (pós-D6, push 1, D1) A MARGEM INTERNA DOS BLOCOS DOS CADASTROS (Cliente, Fabricante,
   Fornecedor). Os blocos de lá são `cartao dados-processo__secao`: o `.cartao` dá 24 px dos
   lados, mas `.dados-processo__secao { padding: 12px 0 }` vem depois no arquivo, com a mesma
   especificidade, e zerava a lateral — os campos encostavam na borda (medido: 0 px dos dois
   lados; assim desde 29/08, não foi o D2). Só a COMBINAÇÃO: a seção solta, DENTRO de caixa
   (Gestão, Comercial), continua com o 0 de que precisa. */
.cartao.dados-processo__secao {
  padding: 12px 24px;
}

/* ★ (09/10/2026) Relatório de Mercado — a subaba REQUERENTE. Visual da marca (azul e grafite;
   o âmbar só no ponto da troca), minimalista, o secundário no mouse (`.com-nota`). */
.mercado-req__busca { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.mercado-req__busca input[type="search"] {
  flex: 1; min-width: 260px; padding: 8px 12px;
  border: 1px solid var(--cor-borda); border-radius: 6px; font: inherit;
}
.mercado-req__botao {
  padding: 7px 14px; border: 1px solid var(--cor-azul); border-radius: 6px;
  background: #fff; color: var(--cor-azul); font: inherit; cursor: pointer;
}
.mercado-req__sugestoes {
  list-style: none; margin: 4px 0 12px; padding: 0; max-width: 720px;
  border: 1px solid var(--cor-borda); border-radius: 6px; background: #fff;
}
.mercado-req__sugestoes li a {
  display: block; padding: 7px 12px; color: var(--cor-grafite); text-decoration: none;
  border-bottom: 1px solid var(--cor-borda);
}
.mercado-req__sugestoes li:last-child a { border-bottom: 0; }
.mercado-req__sugestoes li a:hover, .mercado-req__sugestoes li a:focus { background: #EAF1F8; }
.mercado-req__vazio { color: var(--cor-cinza); padding: 28px 0; text-align: center; }
.mercado-req__cabecalho { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin: 16px 0 4px; }
.mercado-req__cabecalho h2 { margin: 0; font-size: 1.15rem; color: var(--cor-grafite); }
.mercado-req__cnpj { color: var(--cor-cinza); font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.mercado-req__cliente {
  font-size: 0.75rem; border: 1px solid var(--cor-azul); color: var(--cor-azul);
  border-radius: 12px; padding: 2px 10px;
}
.mercado-req__variacoes { font-size: 0.8rem; color: var(--cor-cinza); }
.mercado-req__tabela { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.mercado-req__tabela th { text-align: left; font-weight: 600; color: var(--cor-cinza); border-bottom: 1px solid var(--cor-borda); padding: 6px; }
.mercado-req__tabela td { padding: 7px 6px; border-bottom: 1px solid var(--cor-borda); }
.mercado-req__tabela .n { text-align: right; font-variant-numeric: tabular-nums; }
.mercado-req__nao-identificado td { color: var(--cor-cinza); }
.mercado-req__barra { height: 6px; background: #EAF1F8; border-radius: 3px; margin-top: 3px; }
.mercado-req__barra i { display: block; height: 6px; border-radius: 3px; background: var(--cor-azul); }
.mercado-req__tag {
  font-size: 0.7rem; color: var(--cor-azul); border: 1px solid var(--cor-azul);
  border-radius: 10px; padding: 0 7px; margin-left: 6px;
}
.mercado-req__ponto-troca {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  background: var(--cor-atencao); margin-right: 4px; vertical-align: 0;
}

/* ★★★ (10/10/2026) Relatório de Mercado — subaba RECEITA DIRECIONADA. O seletor de camada
   (Tudo / Via Moderacon / Pago direto) e a barra em duas camadas. Azul da marca para "via
   Moderacon", o azul suave para "pago direto" (fundo de barra, não texto). */
.mercado-rec__camadas { display: inline-flex; border: 1px solid var(--cor-azul, #094C85); border-radius: 16px; overflow: hidden; }
/* ★ o seletor mora dentro de `.filtros`, e `.filtros button` (classe + elemento) pinta todo botão
   de azul cheio — medido no print: os três apareciam "ativos". Daí o prefixo `.mercado-rec__camadas`. */
.mercado-rec__camadas .mercado-rec__camada { border: 0; border-radius: 0; background: #fff; color: var(--cor-azul, #094C85); padding: 5px 12px; font-size: 0.85rem; cursor: pointer; }
.mercado-rec__camadas .mercado-rec__camada + .mercado-rec__camada { border-left: 1px solid var(--cor-azul, #094C85); }
.mercado-rec__camadas .mercado-rec__camada--ativa { background: var(--cor-azul, #094C85); color: #fff; }
.mercado-req__tabela + .relatorio-propostas__titulo-bloco { margin-top: 22px; }
.mercado-rec__camada:focus-visible { outline: 2px solid var(--cor-azul, #094C85); outline-offset: 2px; }
.mercado-rec__barra { display: flex; height: 6px; background: #EAF1F8; border-radius: 3px; overflow: hidden; margin-top: 4px; max-width: 260px; }
.mercado-rec__barra i { display: block; height: 6px; }
.mercado-rec__via { background: #094C85; }
.mercado-rec__direto { background: #7FA7CC; }
.mercado-rec__legenda { font-size: 0.8rem; color: var(--cor-cinza); display: flex; gap: 14px; align-items: center; margin: 8px 0 0; }
.mercado-rec__legenda i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; }
.mercado-rec__nada { color: var(--cor-cinza); font-style: italic; }

/* ★ (12/10/2026) Atribuições da carteira: seleção por pessoa, e a confirmação da Manutenção
   (mockup aprovado pelo Guto). */
/* ★ (validação do Guto) as cinco colunas de seleção com a MESMA largura, estreita: o rótulo
   longo é cortado com "…" (o nome inteiro está no mouse) e a tabela cabe sem rolagem lateral. */
.atrib-sel { font: inherit; font-size: .85rem; padding: 3px 6px; width: 8.5rem; max-width: 8.5rem;
  text-overflow: ellipsis; white-space: nowrap; overflow: hidden;
  border: 1px solid var(--cor-borda-campo); border-radius: 4px; background: #fff; }
.atrib-sel--vazio { color: #6B7280; }
.atrib-nota { display: block; margin-top: 3px; }
.atrib-compartilhado { font-size: .85rem; color: var(--cor-atencao); }
.atrib-confirma { background: #F6F7F8; border: 1px solid var(--cor-borda-campo); border-radius: 4px;
  padding: 10px 14px; font-size: .88rem; line-height: 1.5; }
.atrib-confirma ul { margin: 6px 0 8px 18px; padding: 0; }
.atrib-confirma button { font: inherit; font-size: .85rem; padding: 4px 10px; margin-right: 6px;
  border-radius: 4px; border: 1px solid var(--cor-borda-campo); background: #fff; cursor: pointer; }
.atrib-confirma__primario { background: var(--cor-azul-suave-texto) !important; color: #fff;
  border-color: var(--cor-azul-suave-texto) !important; }

/* ★ (Drive Leva 1) o link "Abrir pasta no Drive" (mockups aprovados): três estados */
.drive-link { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: .85rem;
  padding: 4px 10px; border: 1px solid var(--cor-borda-campo); border-radius: 4px; background: #fff;
  color: var(--cor-azul-suave-texto); text-decoration: none; white-space: nowrap; cursor: pointer; }
.drive-link:hover { background: #F6F7F8; }
.drive-link--aguardando { color: var(--cor-atencao); border-color: #E0B85A; background: #FFF8E6; }
.drive-link--criar { border-style: dashed; }
.drive-link__form { display: inline; margin: 0; }

/* ★★ (Drive Leva 2, mockup aprovado) o painel da "📋 Lista de Tarefas" e o "Abrir" do documento */
.lista-tarefas-painel__ancora { position: relative; display: inline-block; }
.lista-tarefas-painel { position: absolute; z-index: 30; top: calc(100% + 4px); left: 0; width: 290px;
  background: #fff; border: 1px solid var(--cor-borda-campo); border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .12); padding: 12px 14px; font-size: .86rem; text-align: left; }
.lista-tarefas-painel[hidden] { display: none; }
.lista-tarefas-painel fieldset { border: 0; margin: 0 0 10px; padding: 0; }
.lista-tarefas-painel legend { font-weight: 600; color: var(--cor-azul-suave-texto); margin-bottom: 4px; padding: 0; }
.lista-tarefas-painel label { display: flex; gap: 6px; align-items: center; margin: 2px 0; cursor: pointer; }
.lista-tarefas-painel__dica { font-size: .76rem; color: var(--cor-azul-suave-texto); }
.lista-tarefas-painel__aviso { color: var(--cor-atencao); font-size: .8rem; margin: 0 0 8px; line-height: 1.4; }
.lista-tarefas-painel__acoes { display: flex; gap: 8px; justify-content: flex-end; }
.icone-campo--abrir { font-size: .78rem; text-decoration: none; padding: 0 4px; }
.icone-campo--abrir { display: inline-flex; align-items: center; gap: 1px; vertical-align: middle; }
.icone-campo__rotulo { font-size: .62rem; font-weight: 700; line-height: 1; }

/* ★★ (Drive Leva 3, 15/10/2026 — mockup aprovado) O bloco "Documentos gerados" no Comercial e no Fluxo */
.docs-gerados { border: 1px solid var(--cor-borda); border-radius: 6px; margin: 10px 0; background: var(--cor-branco); }
.docs-gerados__titulo { cursor: pointer; padding: 8px 12px; font-family: Montserrat, Inter, sans-serif; font-weight: 600;
  color: var(--cor-azul); font-size: .9rem; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.docs-gerados__contagem { font-weight: 400; color: var(--cor-azul-suave-texto); font-size: .8rem; }
.docs-gerados__pasta { padding: 4px 12px 10px; }
.docs-gerados__pasta-titulo { font-size: .76rem; text-transform: uppercase; letter-spacing: .04em;
  color: var(--cor-azul-suave-texto); margin: 8px 0 4px; display: flex; gap: 8px; align-items: center; }
.docs-gerados__link-pasta { text-transform: none; letter-spacing: 0; font-size: .78rem; color: var(--cor-azul-suave-texto); }
.docs-gerados__rolagem { overflow-x: auto; }
.docs-gerados__tabela { border-collapse: collapse; width: 100%; font-size: .84rem; }
.docs-gerados__tabela th { text-align: left; font-weight: 600; color: var(--cor-azul-suave-texto); font-size: .74rem;
  padding: 4px 8px; border-bottom: 1px solid var(--cor-borda); }
.docs-gerados__tabela td { padding: 5px 8px; border-bottom: 1px solid #EDF0F3; vertical-align: middle; }
.docs-gerados__nome { font-family: Consolas, "Courier New", monospace; font-size: .8rem; }
.docs-gerados__data { font-variant-numeric: tabular-nums; white-space: nowrap; }
.docs-gerados__chip { display: inline-block; font-size: .7rem; padding: 1px 7px; border-radius: 9px;
  background: #EEF3F8; color: var(--cor-azul); white-space: nowrap; }
.docs-gerados__chip--antiga { background: #EEF0F2; color: #4B5560; }   /* ★ não o --cor-cinza: ele é ESCURO (#575756), e o texto sumia */
.docs-gerados__chip--aguardando { background: #FDF3E1; color: var(--cor-atencao); }
.docs-gerados__vazio { color: #8a96a3; }
.docs-gerados__copiar { font: inherit; font-size: .76rem; color: var(--cor-azul-suave-texto); background: none;
  border: 0; padding: 0; cursor: pointer; text-decoration: underline; }
.docs-gerados__abrir { text-decoration: none; font-size: 1rem; }
.docs-gerados__outra-pasta > summary { cursor: pointer; font-size: .78rem; color: var(--cor-azul-suave-texto); padding: 4px 12px 8px; }

/* ★ (17/10/2026, leva 3 do motor dos avisos) A ABA VIRADA de Certificação › ANATEL.
   O mockup aprovado (MOCKUP_VIRADA_MANUTENCAO.html). As cores são os tokens do sistema: a
   ATENÇÃO é o âmbar (--cor-atencao), nunca o coral (o coral não é cor de alerta desde a C1).
   O número da aba é âmbar: são linhas esperando decisão. */
.relatorio-abas__selo--virada,
.relatorio-abas__aba--ativa .relatorio-abas__selo--virada {
  background: var(--cor-amarelo-suave);
  border-color: #EDDCB4;
  color: var(--cor-atencao);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.virada-texto { font-size: 0.86rem; line-height: 1.5; margin: 0 0 8px; max-width: 72ch; }
.virada-texto--sub { font-size: 0.8rem; color: var(--cor-cinza); }
.virada-contagem { font-size: 0.82rem; color: var(--cor-cinza); margin: 4px 0 8px; }
.virada-contagem__decididas { color: var(--cor-cinza); }
.virada-falta { color: var(--cor-atencao); font-weight: 600; }
.virada-sub { color: var(--cor-cinza); font-size: 0.76rem; }
.virada-tabela-rolagem { overflow-x: auto; }
.virada-tabela td { vertical-align: top; }
.virada-numero { font-family: Consolas, "Courier New", monospace; font-size: 0.78rem; white-space: nowrap; }
.virada-chip {
  display: inline-block;
  font-size: 0.7rem;
  padding: 1px 7px;
  border-radius: 9px;
  background: var(--cor-azul-claro, #EEF3F8);
  color: var(--cor-azul);
  white-space: nowrap;
}
.virada-chip--3 { background: var(--cor-amarelo-suave); color: var(--cor-atencao); }
.virada-chip--en { background: var(--cor-fundo); color: var(--cor-cinza); border: 1px solid var(--cor-borda); }
.virada-decisao { font-size: 0.78rem; line-height: 1.4; }
.virada-decisao__acoes { display: flex; gap: 6px; flex-wrap: wrap; }
.virada-botao {
  font-family: var(--fonte-texto);
  font-size: 0.78rem;
  padding: 4px 10px;
  border: 1px solid var(--cor-borda);
  border-radius: 4px;
  background: var(--cor-branco);
  color: var(--cor-azul);
  cursor: pointer;
  white-space: nowrap;
}
.virada-botao--primario { background: var(--cor-azul); border-color: var(--cor-azul); color: var(--cor-branco); }
.virada-botao:focus-visible { outline: 2px solid var(--cor-azul); outline-offset: 2px; }
.virada-decisao__avisar { color: var(--cor-verde); }
.virada-decisao__nao { color: var(--cor-cinza); }
.virada-decisao__sub { color: var(--cor-cinza); }
.virada-decisao__leitura { color: var(--cor-cinza); font-style: italic; }
.virada-decisao__erro { color: var(--cor-erro); font-weight: 600; margin: 0 0 4px; }

/* ★ (18/10/2026, ajuste da Etapa A) as linhas que o "Criar tarefas que faltam" acabou de criar */
.linha-tarefa--nova > td { background: var(--cor-amarelo-suave); }
.botao-gerar-tarefas:disabled { opacity: 0.55; cursor: not-allowed; }

/* ★ (18/10/2026, INSTRUCAO_ETAPA_B_E_AJUSTES, seção 2) o SUCESSO de gerar se confirma no bloco
   "Documentos gerados": a linha nova fica destacada (âmbar suave) e o destaque APAGA sozinho em alguns
   segundos. Sem animação para quem pediu menos movimento: aí o destaque fica, sem piscar. */
@keyframes docs-gerados-destaque {
  0%, 60% { background-color: var(--cor-amarelo-suave); }
  100% { background-color: transparent; }
}
.docs-gerados__linha--nova > td { animation: docs-gerados-destaque 5s ease-out forwards; }
@media (prefers-reduced-motion: reduce) {
  .docs-gerados__linha--nova > td { animation: none; background-color: var(--cor-amarelo-suave); }
}

/* ★ (18/10/2026, decisão 2 do Guto) o MOTIVO de um botão desativado, em TEXTO ao lado dele (não só no
   mouse). Âmbar de atenção — o coral não é mais cor de alerta (C1). */
.botao-motivo { font-size: .78rem; color: var(--cor-atencao); margin-left: 6px; align-self: center; }

/* ★★ (22/10/2026, a régua dos avisos do Guto — mockup aprovado) a MARCA no campo a resolver: âmbar (a atenção, nunca o
   coral), a faixa à esquerda e o fundo claro. O texto do que falta vai no mouse (`title`) e no número da aba. */
.marca-falta { box-shadow: inset 3px 0 0 var(--cor-atencao); background: var(--cor-atencao-suave) !important; }
th.marca-falta { color: var(--cor-atencao); }
/* ★★★ (22/10/2026) o envelope do Fluxo na LISTA: só indicador (o clique fica dentro do Fluxo) */
.tabela-fluxo-lista .col-envelope { width: 28px; text-align: center; }
.fluxo-lista-envelope { font-size: 1rem; cursor: default; display: inline-flex; vertical-align: middle; }
/* ★★ (22/10/2026, ajuste do Guto) o desenho do envelope (`_icone_envelope.html`): do tamanho dos vizinhos */
.icone-envelope { width: 24px; height: 24px; display: block; }
.icone-acao:has(> .icone-envelope) { padding: 0 2px; display: inline-flex; align-items: center; }
/* ★ e o <span> que o envolve (Gestão e Fluxo) é caixa flexível: em linha, o botão alinhava pela linha de base do
   texto e descia 4 px em relação aos vizinhos (smoke_v13_cabecalho_fluxo: tops 268 e 272) */
.envio-contratante { display: inline-flex; align-items: center; }
/* ★★ (23/10/2026, Prospecção leva 1a) o marcador Lead / Cliente e o "não contatar" */
.marcador-lc { display: inline-block; font-size: 0.7rem; font-weight: 600; padding: 1px 8px; border-radius: 9px;
  white-space: nowrap; vertical-align: middle; }
.marcador-lc--lead { background: #E8EFF5; color: var(--cor-azul); }   /* 7,59 (o azul suave dava 4,17) */
.marcador-lc--cliente { background: var(--cor-verde-suave); color: var(--cor-verde); }
.marcador-lc--nao { background: #EEEEEE; color: #555555; border: 1px solid #CCCCCC; }
/* ★ no cabeçalho do Fluxo os vizinhos são botões de texto com `margin-top: 4px` (.botao-adicionar-linha): com o
   alinhamento central, o envelope sem a mesma margem ficava 2 px acima (medido: 231 contra 233) */
.fluxo-detalhe__acoes .envio-contratante { margin-top: 4px; }
.fluxo-lista-envelope--cinza { color: var(--cor-status-pendente); }   /* as cores do envelope da Gestão */
.fluxo-lista-envelope--verde { color: var(--cor-verde); }
/* ★★ (22/10/2026, mockup parte 2) o " · falta" ao lado do rótulo, como no mockup aprovado — só no que é FALTA (a
   revisão aberta e o item fora de ciclo são estado a resolver, não campo vazio); e a borda âmbar no controle.
   ★ (medido: smoke_v13_lab_item_tela) e não no laboratório do item: ali o select não tem rótulo, e o sufixo o tirava
   da coluna (35 px) — a borda e o fundo âmbar bastam */
[data-pendencia].marca-falta:not(input):not(select):not(textarea):not([data-pendencia="revisao-aberta"]):not([data-pendencia="fora-de-ciclo"]):not([data-pendencia="lab-item"])::after {
  content: " · falta"; color: var(--cor-atencao); font-weight: 600; font-size: 0.74rem;
}
.marca-falta input, .marca-falta select, input.marca-falta { border-color: var(--cor-atencao); }
/* ★★ (22/10/2026, a régua dos avisos — mockup aprovado) a LISTA do que falta, aberta pelo clique no número da aba */
.abas-processo__badge { cursor: pointer; }
.abas-lista {
  position: absolute; z-index: 60; background: var(--cor-branco); border: 1px solid var(--cor-borda);
  border-radius: 6px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); padding: 8px 12px; width: min(440px, 90vw);
  font-size: 0.82rem;
}
.abas-lista ul { margin: 0; padding-left: 16px; line-height: 1.55; }
.abas-lista a { color: var(--cor-azul); }

/* ★★★ (23/10/2026, Prospecção leva 3a) a Abordagem: o funil, as abas, as etapas do alvo e os formulários */
.abordagem-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 10px; }
/* ★★ (27/10/2026, QA-02 pacote 3) o "Próximo da fila" do INBOUND e a janela "+ Registrar contato" */
.fila-inbound { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; margin: 0 0 10px; font-size: 0.82rem; }
.fila-inbound__titulo { font-weight: 600; color: var(--cor-azul); }
.fila-inbound__item { white-space: nowrap; }
.registrar-contato { max-width: 640px; }
.registrar-contato form { display: flex; flex-direction: column; gap: 10px; }
.registrar-contato label { display: flex; flex-direction: column; gap: 3px; font-size: 0.85rem; }
.registrar-contato__canal { display: flex; gap: 14px; border: 0; padding: 0; margin: 0; }
.registrar-contato__canal label { flex-direction: row; align-items: center; gap: 4px; }
.registrar-contato__par { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.registrar-contato__botoes { display: flex; justify-content: flex-end; gap: 8px; }
.abordagem-funil { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 14px; }
.abordagem-funil__etapa { display: flex; flex-direction: column; min-width: 96px; padding: 6px 12px; border: 1px solid var(--cor-borda);
  border-radius: 6px; background: var(--cor-branco); font-size: 0.75rem; color: var(--cor-cinza); }
.abordagem-funil__etapa b { font-size: 1.15rem; color: var(--cor-grafite); font-variant-numeric: tabular-nums; }
.abordagem-abas { margin-bottom: 12px; }
.abordagem-abas__desligada { color: var(--cor-cinza); cursor: not-allowed; font-style: italic; }
.abordagem-etapa { display: inline-block; font-size: 0.72rem; font-weight: 600; padding: 1px 8px; border-radius: 9px; white-space: nowrap;
  background: var(--cor-neutro-suave); color: var(--cor-grafite); }
.abordagem-etapa--contatado { background: var(--cor-status-avaliado-suave); color: var(--cor-azul); }
.abordagem-etapa--em_contato { background: var(--cor-roxo-suave); color: var(--cor-roxo); }
.abordagem-etapa--qualificado { background: var(--cor-verde-suave); color: var(--cor-verde); }
.abordagem-etapa--encerrado, .abordagem-etapa--descartado { background: var(--cor-neutro-suave); color: var(--cor-cinza); }
.abordagem-vencida { color: var(--cor-erro); font-weight: 700; }
.abordagem-falta { color: var(--cor-atencao); font-weight: 600; }
.abordagem-acoes { display: flex; flex-wrap: wrap; gap: 6px; align-items: flex-start; }
.abordagem-inline { display: inline; margin: 0; }
.abordagem-registro > summary { list-style: none; cursor: pointer; }
.abordagem-registro > summary::-webkit-details-marker { display: none; }
.abordagem-form { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.abordagem-form label { display: flex; flex-direction: column; gap: 3px; font-size: 0.82rem; color: var(--cor-grafite); }
.abordagem-form label.abordagem-check { flex-direction: row; align-items: center; gap: 6px; }
.abordagem-form textarea { font: inherit; }
.abordagem-obrigatorio { color: var(--cor-erro); }
.abordagem-nova { margin-top: 12px; }
.abordagem-nova > summary { cursor: pointer; display: inline-block; margin-bottom: 8px; }
.abordagem-textos { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 12px; }
.abordagem-ficha { margin-bottom: 12px; }
.abordagem-dados { display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin: 0; }
.abordagem-dados dt { color: var(--cor-cinza); font-size: 0.82rem; }
.abordagem-dados dd { margin: 0; }
.abordagem-historico { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.abordagem-avisos { margin: 8px 0; }
.abordagem-aviso { margin: 0 0 6px; padding: 6px 10px; border-radius: 6px; background: var(--cor-neutro-suave); color: var(--cor-grafite); }
.abordagem-aviso--error { background: var(--cor-erro-suave); color: var(--cor-erro); }
.abordagem-aviso--success { background: var(--cor-verde-suave); color: var(--cor-verde); }
/* ★ (leva 3a.1) o número de pendências na aba Alvos: o desenho do número das abas, sem a lista do clique */
.abordagem-badge { cursor: default; }

/* ★★ (24/10/2026, Prospecção leva 3b) a aba Seleção: os filtros e a linha "Não contatar" (apagada pela COR — cinza
   #575756 sobre #ECEEF0 dá 6,22 —, e não por opacidade, que reprova no contraste) */
.abordagem-filtros { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: flex-end; margin-bottom: 10px; }
.abordagem-filtros label { display: flex; flex-direction: column; gap: 3px; font-size: 0.8rem; color: var(--cor-grafite); }
.abordagem-linha-apagada td { color: var(--cor-cinza); background: var(--cor-neutro-suave); }

/* ★★ (24/10/2026, Prospecção leva 3c) o atalho "Adicionar à campanha" nos relatórios Requerente e Mercado: o nome da
   campanha nova só aparece com "+ Nova campanha" escolhida */
.atalho-campanha { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 8px 0; }
.atalho-campanha__nova { display: none; }
/* (3c) o intervalo do volume na Seleção: dois números curtos */
.abordagem-filtros__numero { width: 5em; }
.atalho-campanha:has(select[name="campanha"] option[value="nova"]:checked) .atalho-campanha__nova { display: inline-flex; gap: 6px; align-items: center; }

/* ★★ (25/10/2026, Manutenção INMETRO, leva M3) a tabela do INMETRO reaproveita o congelamento da ANATEL
   (`.anatel-tabela--manutencao`: as 3 primeiras colunas sticky) com as larguras dela: Tipo (com o "›"), Modelo e
   Solicitante. */
.anatel-tabela--manutencao.inmetro-tabela { --congelada-1: 132px; --congelada-2: 180px; --congelada-3: 200px; min-width: 1500px; }
.inmetro-abrir { border: 0; background: none; color: var(--cor-azul); font-weight: 600; cursor: pointer; padding: 0 4px 0 0; }
.inmetro-abrir:focus-visible { outline: 2px solid var(--cor-azul); outline-offset: 2px; }
.inmetro-detalhe td { background: var(--cor-fundo); white-space: normal; }
.inmetro-form { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px 12px; margin: 8px 0; }
.inmetro-form label { display: flex; flex-direction: column; gap: 2px; font-size: .82rem; }
.inmetro-form__largo { grid-column: 1 / -1; }
.inmetro-form__erro input, .inmetro-form__erro select { border-color: var(--cor-erro); }
.inmetro-form__msg { color: var(--cor-erro); font-size: .78rem; }
.inmetro-novo > summary { display: inline-block; cursor: pointer; list-style: none; }
.inmetro-historico { margin: 0 0 8px; padding-left: 18px; font-size: .8rem; }
@media (max-width: 760px) { .inmetro-form { grid-template-columns: 1fr 1fr; } }

/* ★★★ (26/10/2026) as cláusulas contratuais: o editor (só negrito e itálico), as marcas de estado (âmbar, e não coral:
   coral não é cor de alerta desde a C1) e a lista por cláusula */
.clausulas-estado { display: inline-block; font-size: .72rem; font-weight: 600; padding: 1px 8px; border-radius: 9px;
  background: var(--cor-atencao-suave); color: var(--cor-atencao); cursor: help; border-bottom: 1px dotted var(--cor-atencao); }
.clausulas-cabecalho { display: inline-flex; gap: 8px; align-items: center; margin-left: 8px; }
.aviso-clausulas { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin: 8px 0; padding: 8px 12px;
  border: 1px solid #E0B85A; background: #FFF4D6; color: #5C3D00; border-radius: 4px; font-size: .85rem; }
.aviso-clausulas form { margin: 0; }
.clausulas-bloco { margin-bottom: 12px; }
.clausulas-titulo { margin: 0 0 6px; text-transform: uppercase; letter-spacing: .03em; font-size: .82rem; }
.clausulas-item { display: grid; grid-template-columns: 90px 1fr auto; gap: 10px; align-items: start; padding: 8px 0;
  border-bottom: 1px solid var(--cor-borda); font-size: .84rem; line-height: 1.5; }
.clausulas-item--alterada { border-left: 3px solid var(--cor-atencao); padding-left: 8px; background: var(--cor-atencao-suave); }
.clausulas-item--incluida { border-left: 3px solid var(--cor-verde); padding-left: 8px; background: var(--cor-verde-suave); }
.clausulas-item--suprimida, .clausulas-item--falta { border-left: 3px solid #9AA4AE; padding-left: 8px; color: #5B6670; }
.clausulas-item__numero { font-weight: 700; font-variant-numeric: tabular-nums; }
.clausulas-item__acoes { display: flex; gap: 6px; align-items: start; flex-wrap: wrap; }
.clausulas-item__acoes form { margin: 0; }
.clausulas-tag { display: inline-block; font-size: .66rem; font-weight: 700; padding: 0 6px; border-radius: 8px;
  background: #F1F3F5; color: #5B6670; }
.clausulas-tag--alterada { background: var(--cor-atencao-suave); color: var(--cor-atencao); }
.clausulas-tag--incluida { background: var(--cor-verde-suave); color: var(--cor-verde); }
.clausulas-padrao { margin-top: 4px; }
.clausulas-editar > summary { list-style: none; cursor: pointer; }
.clausulas-editar[open] { grid-column: 1 / -1; }
.clausula-editor { display: flex; flex-direction: column; gap: 6px; margin: 6px 0; min-width: min(640px, 80vw); }
.clausula-editor__barra { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.clausula-editor__campo { min-height: 80px; padding: 6px 8px; border: 1px solid #C9D2DC; border-radius: 4px; background: #fff;
  line-height: 1.5; }
.clausula-editor__campo:focus-visible { outline: 2px solid var(--cor-azul, #094C85); outline-offset: 2px; }
.clausulas-historico { margin: 0; padding-left: 18px; font-size: .8rem; line-height: 1.6; }
/* ★★★ (26/10/2026, estrutura RL) o Local Representative Agreement na linha de Representação Local */
/* ★ (27/10/2026, ajuste do Guto) na LINHA do produto: à direita, antes da lixeira (a margem automática a empurra) */
.agreement-linha { display: inline-flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-left: auto;
  font-size: .8rem; }
.agreement-linha .marca-falta { max-width: 32em; }
.signatario-form { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin: 0; }
.signatario-form input[type="text"], .signatario-form input[type="email"] { min-width: 12em; }
.agreement-linha__form { margin: 0; }

/* ★★★ (28/10/2026, Amostras v3) o quadro da aba Amostras (Vendas: um por serviço; Gestão: o do processo). Uma linha
   por tipo de amostra, uma coluna por modelo. ★ A rolagem de lado é DENTRO do quadro (a página não rola), e a coluna
   Tipo fica parada (`position: sticky`, com fundo próprio para os modelos passarem por baixo). */
.amostras-quadro__origem { margin: 0 0 10px; padding: 8px 12px; border-radius: 6px; background: var(--cor-fundo); color: var(--cor-cinza); font-size: 0.85rem; }
.amostras-quadro__servico + .amostras-quadro__servico { margin-top: 18px; }
.amostras-quadro__rolagem { overflow-x: auto; border: 1px solid var(--cor-borda); border-radius: 6px; }
.amostras-quadro__tabela { border-collapse: separate; border-spacing: 0; width: 100%; font-size: 0.85rem; }
.amostras-quadro__tabela th, .amostras-quadro__tabela td { padding: 6px 10px; border-bottom: 1px solid var(--cor-borda); text-align: left; vertical-align: middle; white-space: nowrap; background: var(--cor-branco); }
.amostras-quadro__tabela thead th { background: var(--cor-fundo); color: var(--cor-cinza); font-weight: 600; }
.amostras-quadro__fixa { position: sticky; left: 0; z-index: 1; min-width: 13em; box-shadow: 6px 0 6px -6px rgba(47, 57, 67, 0.25); }
.amostras-quadro__tabela thead .amostras-quadro__fixa { z-index: 2; }
.amostras-quadro__tipo { font-weight: 600; color: var(--cor-azul); }
.amostras-quadro__teste { white-space: normal; min-width: 9em; color: var(--cor-cinza); }
.amostras-quadro__modelo .plano-modelos__letra { margin-right: 5px; }
.amostras-quadro__nao { color: var(--cor-cinza); font-style: italic; }
.amostras-quadro__par { display: inline-flex; align-items: center; gap: 5px; margin: 0; flex-wrap: wrap; }
.amostras-quadro__numero { width: 4.5em; }
.amostras-quadro__a { color: var(--cor-cinza); }
.amostras-quadro__aviso { color: var(--cor-erro); font-size: 0.8rem; white-space: normal; }
.amostras-quadro__aviso:empty { display: none; }
.amostras-quadro__outras { margin-top: 10px; display: grid; gap: 6px; }
.amostras-quadro__outras-titulo { margin: 0; }
.amostras-quadro__outra { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.amostras-quadro__incluir { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0; }
.amostras-quadro__nota { color: var(--cor-cinza); font-size: 0.85rem; font-weight: 400; }
/* ★ (v3.1) o incluir de "outra amostra" atrás de um link discreto, no fim do quadro */
.amostras-quadro__mais { margin-top: 10px; display: grid; gap: 6px; justify-items: start; }
.amostras-quadro__mais > summary { list-style: none; }
.amostras-quadro__mais > summary::-webkit-details-marker { display: none; }
.amostras-quadro__mais > .amostras-quadro__nota { margin: 0; }

/* ★★★ (29/10/2026) ETAPA C, EC1 — os padrões globais (decisões do Guto sobre o MOCKUP_ETAPA_C_EC1.html). Um bloco só,
   no fim, de propósito: tudo o que o EC1 muda de aparência está aqui, e as regras antigas ficam onde estavam, com a
   história delas. ★ Nenhuma função sai: o inventário de controles das telas é o mesmo antes e depois (ENTREGA_EC1.md). */

:root {
  /* ★ o vermelho da lixeira sob o mouse: era um hex solto na "Remover tarefa"; agora as duas lixeiras (Gestão e
     Vendas) leem o MESMO token */
  --cor-remover-mouse: #990000;
}

/* -- 1. As abas da CAMPANHA (Alvos · Textos · Seleção) na pasta da Vendas e da Gestão. A aba aberta vem do servidor
      (`aria-selected`), porque cada aba é uma página (`?aba=`). -- */
.abordagem-abas.abas-processo__barra {
  gap: 4px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--cor-borda);
}
.abordagem-abas .abas-processo__aba {
  margin-bottom: -1px;
  padding: 9px 16px 10px;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--cor-cinza);
  text-decoration: none;
}
.abordagem-abas .abas-processo__aba:hover {
  color: var(--cor-azul);
}
.abordagem-abas .abas-processo__aba[aria-selected="true"] {
  background: var(--cor-branco);
  border-color: var(--cor-borda);
  border-top: 3px solid var(--cor-laranja);
  padding-top: 7px;
  color: var(--cor-grafite);
  box-shadow: 0 1px 0 var(--cor-branco);
}

/* -- 2. Os filtros do Fluxo, no grupo de botões (`chave-visao`), como o INBOUND -- */
.filtros-fluxo-linha {
  margin: 0 0 8px;
}

/* -- 3. "+ novo" em VERDE: só quem cria um REGISTRO NOVO (Registrar contato, Nova campanha, Incluir empresa à mão,
      Novo cliente/fornecedor, Nova tarefa, Adicionar serviço/produto, Nova combinação, Novo certificado). Os "+" que
      acrescentam uma linha dentro de um formulário continuam tracejados.
      ★ `.filtros .botao-novo`: dentro de `.filtros`, a regra `.filtros button` pintava de azul cheio.
      ★★ (29/10/2026, Leva A — decisão do Guto) CONTORNO, não cheio: borda e texto verdes, fundo transparente; com o
      mouse, o verde claro. O verde como texto: 5,3 sobre o branco, 4,9 sobre o cinza do cartão e 4,7 sobre o verde
      claro do hover. -- */
.botao-novo,
.filtros .botao-novo {
  font-family: var(--fonte-texto);
  font-size: 0.8rem;
  font-weight: 600;
  border: 1px solid var(--cor-verde);
  border-radius: 4px;
  padding: 4px 12px;
  background: transparent;
  color: var(--cor-verde);
  cursor: pointer;
  transition: background-color 0.15s;
}
.botao-novo:hover,
.filtros .botao-novo:hover {
  background: var(--cor-verde-suave);
}
.botao-novo:focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 2px;
}
.botao-novo:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  filter: none;
}
summary.botao-novo {
  display: inline-block;
  list-style: none;
}
summary.botao-novo::-webkit-details-marker {
  display: none;
}

/* -- 4. SEM / TRI / MEN: um desenho só — o MEN deixa de ter o laranja próprio (o selo da aba ativa continua azul) -- */
.relatorio-abas__selo--mensal {
  border-color: var(--cor-borda);
  color: var(--cor-cinza);
}
.relatorio-abas__aba--ativa .relatorio-abas__selo--mensal {
  border-color: var(--cor-azul);
  color: var(--cor-azul);
}

/* -- 5. A lixeira da Vendas ("Remover do funil") com o desenho e a cor da "Remover tarefa" da Gestão: o cinza a 50%
      (`--cor-cinza`, como o `.icone-campo`) e o vermelho no mouse, pelo mesmo token -- */
.icone-remover-tarefa:hover {
  color: var(--cor-remover-mouse);
}
.icone-decisao--cancelar {
  color: var(--cor-cinza);
  opacity: 0.5;
  transition: color 0.15s, opacity 0.15s;
}
.icone-decisao--cancelar:hover {
  color: var(--cor-remover-mouse);
  opacity: 1;
}
/* ★ "Editar cláusulas", logo depois da lixeira: o mesmo tamanho e o mesmo cinza */
.icone-clausulas {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  color: var(--cor-cinza);
  opacity: 0.5;
  transition: color 0.15s, opacity 0.15s;
}
.icone-clausulas:hover {
  color: var(--cor-azul);
  opacity: 1;
}
.icone-clausulas:focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 2px;
  opacity: 1;
}
/* ★ o "Cancelar processo" da Gestão no roxo do "Perder" (era o 🚫 vermelho) */
.icone-acao--cancelar {
  color: var(--cor-roxo);
}
.icone-acao--cancelar .icone-traco {
  display: block;
}

/* -- 6. O cabeçalho do Fluxo: os botões À DIREITA, na linha do título, como na Vendas e na Gestão. ★ O título
      quebra DENTRO da sua coluna (`min-width: 0`); o grupo de botões não encolhe nem se parte em volta dele — o
      defeito que a regra da v13 consertava (os botões quebrando um a um) continua impossível. -- */
.fluxo-detalhe__cabecalho {
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: space-between;
  align-items: baseline;   /* os botões na linha de base da 1ª linha do título */
  gap: 10px 24px;
}
.fluxo-detalhe__cabecalho > h1 {
  flex: 1 1 auto;
  min-width: 0;
}
.fluxo-detalhe__acoes {
  flex: 0 0 auto;
  justify-content: flex-end;
}

/* -- 7. O logo na barra do topo -- */
.topbar .marca__logo {
  display: block;
  height: 24px;
  width: auto;
}

/* -- 8. A delegação: na barra, só o selo "Delegando" (um link para a aba); o botão em Configuração › Sistema -- */
a.topbar-delegacao {
  display: inline-block;
  text-decoration: none;
}
.config-delegacao__estado {
  margin: 12px 0 8px;
}

/* -- 9. (acréscimo do Guto) o título de um serviço na aba Amostras e no Plano de teste: o MODELO na etiqueta do cartão
      do Orçamento (`--cor-azul-suave-texto` com branco: 4,84) e o serviço em texto normal ao lado -- */
.titulo-modelo-servico {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
}
.modelo-etiqueta {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 12px;
  background: var(--cor-azul-suave-texto);
  color: var(--cor-branco);
  font-weight: 700;
  font-size: 0.78rem;
}
.modelo-etiqueta__servico {
  font-weight: 400;
  color: var(--cor-grafite);
}


/* ★★★ (29/10/2026) LEVA A — EC5 (Seleção), EC2 (formulários) e o "modelo testado" (decisões do Guto sobre o
   MOCKUP_LEVA_A.html). Um bloco só, no fim, como o do EC1. ★ Nenhuma função sai: o inventário de controles das telas
   é o mesmo antes e depois (ENTREGA_LEVA_A.md). */

:root {
  /* ★ o cinza do "pouco histórico" (3,2 sobre o branco do cartão: ícone, não texto) */
  --cor-tendencia-pouco: #8A9199;
}

/* -- EC5. A Seleção: o filtro de certificados num rótulo só; o CNPJ e a troca numa linha; a tendência em ícone -- */
.abordagem-filtros__faixa {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.selecao__cnpj,
.selecao__troca {
  white-space: nowrap;
}
th.selecao__tendencia,
td.selecao__tendencia {
  width: 1%;
  text-align: center;
}
.icone-tendencia {
  display: inline-flex;
  vertical-align: middle;
}
.icone-tendencia svg {
  display: block;
}
.icone-tendencia--nova { color: var(--cor-azul); }
.icone-tendencia--crescendo { color: var(--cor-verde); }
.icone-tendencia--estavel { color: var(--cor-grafite); }
.icone-tendencia--caindo { color: var(--cor-atencao); }
.icone-tendencia--parou { color: var(--cor-erro); }
.icone-tendencia--pouco { color: var(--cor-tendencia-pouco); }

/* -- EC2. "+ Nova campanha" e "+ Incluir empresa à mão": os campos numa linha (quebram abaixo de ~900 px) -- */
.abordagem-nova .abordagem-form {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px 10px;
  max-width: none;
}
.abordagem-nova .abordagem-form > p {
  flex: 1 1 100%;
  margin: 0;
}
.abordagem-nova .abordagem-form > label {
  flex: 1 1 140px;
  min-width: 0;
}
.abordagem-nova .abordagem-form > label.abordagem-form__largo { flex: 2 1 200px; }
.abordagem-nova .abordagem-form > label.abordagem-form__idioma { flex: 0 0 7.5em; }
.abordagem-nova .abordagem-form > label.abordagem-form__dono { flex: 0 0 11em; }
.abordagem-nova .abordagem-form > label.abordagem-form__textos { flex: 0 0 14em; }
.abordagem-nova .abordagem-form > label.abordagem-form__cnpj { flex: 0 0 13em; }
.abordagem-nova .abordagem-form > label > input,
.abordagem-nova .abordagem-form > label > select {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

/* -- EC2. Configuração › Amostras e o controle físico: cada campo SOB A SUA COLUNA (o `form=` liga o campo ao
      formulário da linha, que mora na célula das ações) -- */
.tabela-tipos-amostra input[form],
.tabela-tipos-amostra textarea[form],
.tabela-amostras input[form],
.tabela-amostras select[form] {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
.tabela-tipos-amostra textarea[form] {
  font: inherit;
  font-size: 0.82rem;
}
.tabela-tipos-amostra__acoes {
  white-space: nowrap;
}
.tabela-tipos-amostra__acoes form {
  display: inline;
  margin: 0;
}

/* -- EC2. O editor de cláusulas aberto ocupa a LINHA INTEIRA do item (o `grid-column` do EC0 ficava no <details>,
      que não é filho da grade: a regra nunca pegou) -- */
.clausulas-item:has(> .clausulas-item__acoes > .clausulas-editar[open]) > .clausulas-item__acoes {
  grid-column: 1 / -1;
}
.clausulas-item__acoes > .clausulas-editar[open] {
  flex: 1 1 100%;
}
.clausulas-item__acoes > .clausulas-editar[open] .clausula-editor {
  min-width: 0;
}

/* -- EC2. "+ Nova tarefa" nos 5 tópicos: o formulário logo abaixo do título -- */
.bloco-tarefas > .form-nova-tarefa,
.bloco-laboratorio > .form-nova-tarefa {
  margin: 0 0 10px;
}
.bloco-laboratorio__cabecalho .botao-nova-tarefa {
  margin-left: auto;
}
.form-nova-tarefa__nota {
  font-size: 0.78rem;
  color: var(--cor-cinza);
}
.form-nova-tarefa__responsavel-travado {
  font-size: 0.82rem;
  color: var(--cor-grafite);
  cursor: help;
}

/* -- EC2. As caixas da família EMPILHADAS, largura total, a mesma altura; o "traduzir" na linha do título, à
      direita, fora do fluxo (não empurra a caixa) -- */
.dados-processo__grade--familia {
  grid-template-columns: 1fr;
}
.dados-processo__grade--familia > label {
  position: relative;
}
.dados-processo__grade--familia > label > .botao-traduzir {
  position: absolute;
  top: -3px;
  right: 0;
}

/* -- "Modelo testado": a caixa na legenda do Plano de teste; a coluna só leitura na tela Produto -- */
.plano-modelos__legenda-item input[type="checkbox"] {
  margin: 0 4px 0 0;
  vertical-align: middle;
}
.plano-modelos__legenda-item--travado {
  cursor: not-allowed;
}
.testado-so-leitura {
  font-size: 0.78rem;
  color: var(--cor-cinza);
  white-space: nowrap;
}

/* =====================================================================================================================
   LEVA B (29/10/2026, decisões do Guto sobre o MOCKUP_LEVA_B)
   ===================================================================================================================== */

/* -- EC3 ⚑ 1. A Vendas em TRÊS CAIXAS, como a Gestão: o `#comercial-proposta` (o alvo dos swaps) fica sem fundo, e o
      cabeçalho e as abas viram caixas com a borda do cabeçalho da Gestão. Os Documentos gerados já são caixa. -- */
.cartao.comercial-proposta--caixas {
  background: transparent;
  box-shadow: none;
  padding: 0;
}
.cartao.comercial-proposta__caixa {
  border: 1px solid var(--cor-borda);
  box-shadow: none;
  border-radius: 8px;
  margin-bottom: 14px;
}
.cartao.comercial-proposta__caixa--cabecalho {
  padding: 12px 20px;
}
.cartao.comercial-proposta__caixa--abas {
  padding: 14px 24px;
}

/* -- EC3 ⚑ 3. O vínculo da Gestão com o desenho da Vendas: as classes são as mesmas (`.vinculo-bloco`, `--vinculo`).
      ★ Na Gestão o `#abas-processo .dados-processo__subtitulo` (grafite) vence pela especificidade: o azul volta aqui.
      ⚑ 4. O link da proposta no cabeçalho da Gestão, como texto de link. -- */
#abas-processo .dados-processo__subtitulo.dados-processo__subtitulo--vinculo {
  color: var(--cor-azul);
}
.cabecalho-gestao__proposta {
  font-size: 0.82rem;
  color: var(--cor-azul);
  text-decoration: none;
  white-space: nowrap;
}
.cabecalho-gestao__proposta:hover,
.cabecalho-gestao__proposta:focus-visible {
  text-decoration: underline;
}

/* -- EC6 (⚑ 5, opção B). A ficha do contato do INBOUND: "+ Criar proposta" à esquerda, as outras à direita; os dados
      em três colunas (Contato · Empresa · Dono e follow-up). O formulário de um <details> aberto desce para a linha de
      baixo, inteiro, e não empurra os botões para os lados. -- */
.abordagem-acoes--ficha {
  align-items: flex-start;
  gap: 8px 12px;
}
.abordagem-acoes__outras {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 6px 10px;
  margin-left: auto;
}
.abordagem-acoes__outras > .abordagem-registro[open] {
  flex-basis: 100%;
  order: 1;
}
.abordagem-acoes__outras > .abordagem-registro[open] > .abordagem-form {
  margin: 8px 0 0 auto;
}
.abordagem-ficha__grade {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px 28px;
}
.abordagem-ficha__grade > .abordagem-dados {
  align-content: start;
}
.abordagem-ficha__grade dd {
  overflow-wrap: anywhere;
}
@media (max-width: 900px) {
  .abordagem-ficha__grade { grid-template-columns: 1fr; }
}

/* -- EC4. Os textos da campanha em 2 x 2 (A e B em cima, C e D embaixo); cada corpo com a proporção de uma caixa de
      e-mail e a letra da cópia (Verdana, o "Normal" do Gmail). A barra estendida: sublinhado, listas e as cores. -- */
.abordagem-textos {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 900px) {
  .abordagem-textos { grid-template-columns: 1fr; }
}
.abordagem-form__corpo {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 0.82rem;
  color: var(--cor-grafite);
}
.clausula-editor--campanha {
  min-width: 0;
  margin: 0;
}
.clausula-editor__campo--campanha {
  min-height: 300px;
  max-height: 520px;
  overflow-y: auto;
  font-family: Verdana, Geneva, sans-serif;
  font-size: 13px;
  color: var(--cor-grafite);
}
.clausula-editor__campo--campanha p { margin: 0 0 1em; }
.clausula-editor__campo--campanha ul,
.clausula-editor__campo--campanha ol { margin: 0 0 1em; padding-left: 24px; }
.clausula-editor__separador {
  width: 1px;
  align-self: stretch;
  background: var(--cor-borda);
}
.clausula-editor__cor {
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--cor-borda-campo);
  border-radius: 4px;
  background: var(--cor-amostra, var(--cor-grafite));
  cursor: pointer;
}
.clausula-editor__cor--realce {
  width: auto;
  padding: 0 6px;
  background: #FFF2CC;
  color: var(--cor-grafite);
  font-size: 0.75rem;
}
.clausula-editor__cor:focus-visible {
  outline: 2px solid var(--cor-azul);
  outline-offset: 2px;
}

/* -- Fluxo, o PC/OC numa linha só: rótulo, o campo (~15 caracteres), a TAG (o que sobra) e "Copiar TAG" no fim. -- */
.fluxo-tag-faturamento__linha--unica {
  margin-top: 0;
  flex-wrap: nowrap;
}
.fluxo-tag-faturamento__rotulo {
  font-size: 0.82rem;
  color: var(--cor-grafite);
  white-space: nowrap;
}
.fluxo-tag-faturamento__pc-oc {
  flex: 0 0 auto;
  width: calc(15ch + 18px);
  box-sizing: border-box;
}
.fluxo-tag-faturamento__linha--unica code {
  min-width: 0;
  overflow-wrap: anywhere;
}
.fluxo-tag-faturamento__linha--unica > .botao-adicionar-linha {
  flex: 0 0 auto;
  white-space: nowrap;
}
@media (max-width: 760px) {
  .fluxo-tag-faturamento__linha--unica { flex-wrap: wrap; }
}
