/* ===========================================================================
   COMPONENTES — o vocabulário visual reaproveitado em todas as telas.

   Regra de ouro do alvo de toque: **44 px**. Quem usa isto está de pé, com o
   celular numa mão e um cliente na frente. Botão de 32 px é botão que erra.
   =========================================================================== */

/* ── Casca ───────────────────────────────────────────────────────────────── */

.casca { display: flex; min-height: 100vh; min-height: 100dvh; }

.lateral {
  width: var(--lateral);
  flex: 0 0 var(--lateral);
  background: var(--cartao);
  border-right: 1px solid var(--linha);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; height: 100dvh;
}
.lateral .topo-marca {
  padding: 18px 18px 14px;
  border-bottom: 1px solid var(--linha);
  display: flex; align-items: center; gap: 10px;
}
.lateral .topo-marca .marca-nome { font-size: 1.05rem; color: var(--acento); }
.lateral .topo-marca small { display: block; font-size: .7rem; color: var(--tinta-3); letter-spacing: .04em; text-transform: uppercase; }

.menu { flex: 1; overflow-y: auto; padding: 10px 10px 20px; }
.menu-grupo { margin-top: 14px; }
.menu-grupo > span {
  display: block; padding: 6px 10px; font-size: .68rem; font-weight: 650;
  letter-spacing: .08em; text-transform: uppercase; color: var(--tinta-3);
}
.menu a {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--raio-p);
  color: var(--tinta-2); font-weight: 500; text-decoration: none;
  min-height: 42px;
}
.menu a:hover { background: var(--cartao-2); color: var(--tinta); text-decoration: none; }
.menu a.ativo { background: var(--acento-fraco); color: var(--acento); font-weight: 620; }
.menu a .icone { width: 20px; text-align: center; flex: 0 0 20px; }
.menu a .selo {
  margin-left: auto; background: var(--acento); color: var(--acento-tinta);
  border-radius: 999px; padding: 1px 7px; font-size: .7rem; font-weight: 650;
}

.rodape-lateral { border-top: 1px solid var(--linha); padding: 10px; }

.principal { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.barra {
  /* Altura MÍNIMA, e não fixa.
     Era `height`, e o conteúdo que não coubesse não empurrava a barra: ficava
     centralizado e vazava para os dois lados. O que vaza para cima some — a
     barra está grudada no topo — e o resultado foi meia dúzia de ícones
     cortados pela metade num Galaxy de 360 px. Com min-height a barra cresce
     em vez de cortar, que é o pior dos dois males. */
  min-height: var(--topo); flex: 0 0 auto;
  border-bottom: 1px solid var(--linha);
  background: color-mix(in srgb, var(--papel) 88%, transparent);
  backdrop-filter: blur(8px);
  display: flex; align-items: center; gap: 12px; padding: 0 16px;
  position: sticky; top: 0; z-index: 30;
}
/* O TÍTULO pode quebrar em duas linhas; a LEGENDA, não.

   Não é capricho: quem aumenta a fonte do Android para 150% precisa ler, e num
   telefone de 320 px "Espelho de vendas" não cabe numa linha nem espremido.
   Cortar o nome da tela para "Espelh…" justamente para quem pediu letra maior
   é o contrário do que se quer — melhor a barra crescer dois dedos.

   A legenda é secundária (repete o que o menu já disse) e ganha reticências:
   ela sozinha dobrava a altura da barra em tela estreita, sem acrescentar
   nada que a pessoa não soubesse. */
.barra h1 { font-size: 1.05rem; overflow-wrap: anywhere; }
.barra .sub {
  color: var(--tinta-3); font-size: .8rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Os botões nunca quebram linha nem encolhem: quem cede espaço é o bloco do
   título, que sabe quebrar. `.fileira` quebra linha por padrão, e era daí que
   vinha a segunda fileira de ícones vazando para fora da barra. */
.barra .empurra {
  margin-left: auto;
  flex: 0 0 auto;
  flex-wrap: nowrap;
}
.barra .empurra .etiq { white-space: nowrap; }

/* ── "Sem conexão": faixa PENDURADA na barra, e não etiqueta dentro dela ────
   Dentro, ela entrava na mesma fileira dos ícones e cobrava uns 110 px de quem
   podia cedê-los: o bloco do título, o único que encolhe. O nome da tela então
   quebrava em duas ou três linhas, a barra crescia junto (ela tem min-height,
   não height) e os ícones se espremiam contra a borda — a tela inteira parecia
   se desmontar por causa de um aviso que some sozinho.

   Fora do fluxo e ancorada logo abaixo da barra, ela cobre uma tira do
   conteúdo enquanto dura e não move um pixel do que está em volta. Não recebe
   toque: nada nela é clicável, e ela paira sobre o começo do conteúdo. */
.barra .faixa-conexao {
  position: absolute;
  top: 100%; left: 0; right: 0;
  padding: 3px 12px;
  text-align: center;
  font-size: .74rem; font-weight: 620; line-height: 1.35;
  color: var(--vermelho);
  background: var(--vermelho-fraco);
  border-bottom: 1px solid color-mix(in srgb, var(--vermelho) 30%, transparent);
  pointer-events: none;
}

.conteudo { padding: 18px 16px 30px; flex: 1; }
.conteudo.largo { max-width: none; }
.limite { max-width: 1180px; margin: 0 auto; }

/* ── Navegação de celular ────────────────────────────────────────────────── */

.nav-celular {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--cartao); border-top: 1px solid var(--linha);
  padding-bottom: env(safe-area-inset-bottom);
}
.nav-celular ul { display: flex; list-style: none; padding: 0; }
.nav-celular li { flex: 1; }
.nav-celular a {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; height: var(--rodape); font-size: .68rem; color: var(--tinta-3);
  text-decoration: none; font-weight: 550;
}
.nav-celular a.ativo { color: var(--acento); }
.nav-celular a .icone { font-size: 1.15rem; line-height: 1; }

/* ── Botões ──────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 44px; padding: 0 16px; border-radius: var(--raio-p);
  border: 1px solid var(--linha-forte); background: var(--cartao);
  color: var(--tinta); font-weight: 560; white-space: nowrap;
  transition: background .12s, border-color .12s, transform .06s;
}
.btn:hover { background: var(--cartao-2); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .45; cursor: not-allowed; }
/* `<a>` não aceita `disabled`, e um link-botão sem `href` continua com cara de
   botão vivo. Onde a ação está travada (contrato ainda não salvo, cadastro com
   problema), a classe faz o que o atributo faria. */
.btn.desligado { opacity: .45; cursor: not-allowed; }
.btn.desligado:hover { background: var(--cartao); }
.btn.primario { background: var(--acento); border-color: var(--acento); color: var(--acento-tinta); }
.btn.primario:hover { filter: brightness(1.07); background: var(--acento); }
.btn.perigo { color: var(--vermelho); border-color: color-mix(in srgb, var(--vermelho) 40%, transparent); }
.btn.perigo:hover { background: var(--vermelho-fraco); }
.btn.fantasma { border-color: transparent; background: transparent; }
.btn.fantasma:hover { background: var(--cartao-2); }
.btn.p { min-height: 34px; padding: 0 10px; font-size: .85rem; border-radius: 6px; }
.btn.g { min-height: 52px; padding: 0 22px; font-size: 1.02rem; }
.btn.bloco { width: 100%; }

.botoes { display: flex; gap: 8px; flex-wrap: wrap; }

/* Nome + contato do cabecalho de uma ficha. Cresce com o espaco que sobra e
   pode encolher — mas nao abaixo de um piso no celular: era o unico bloco
   encolhivel da fileira, entao levava todo o aperto. "Ricardo Salles" saia em
   duas linhas e o telefone em tres, ao lado de dois botoes folgados. */
.identidade { flex: 1; min-width: 0; }
.botoes.fim { justify-content: flex-end; }

/* ── Cartões ─────────────────────────────────────────────────────────────── */

.cartao {
  background: var(--cartao); border: 1px solid var(--linha);
  border-radius: var(--raio); box-shadow: var(--sombra);
}
.cartao > header {
  padding: 14px 16px; border-bottom: 1px solid var(--linha);
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.cartao > header h2 { font-size: 1rem; }
.cartao > header .empurra { margin-left: auto; }
.cartao .corpo { padding: 16px; }
.cartao .corpo.justo { padding: 0; }

.grade { display: grid; gap: 14px; }
.grade.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grade.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grade.c4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grade.auto { grid-template-columns: repeat(auto-fit, minmax(186px, 1fr)); }

/* ── Indicadores ─────────────────────────────────────────────────────────── */

/* ── O NÚMERO CABE NO CARTÃO ────────────────────────────────────

   O número era 1,85 rem fixo. Numa fileira de quatro cartões dentro do modal
   da unidade cada um fica com ~200 px, e "R$ 1.945.102" transbordava a borda
   direita — o Fabio mandou o print.

   ⚠️ **Ele não quebra linha por causa de um espaço INSEPARÁVEL**: o
   `Intl.NumberFormat('pt-BR')` põe U+00A0 entre "R$" e os dígitos, então
   "R$ 1.945.102" é uma palavra só. Com espaço comum ele quebraria e caberia —
   é por isso que o defeito não aparece em quem testa com um número digitado à
   mão, e por isso `testes\cartao-cabe.js` usa o caractere de verdade.

   `cqi` é 1% da largura DO CARTÃO: o número passa a encolher junto com ele e
   volta ao tamanho cheio onde há espaço. O piso de 1,05 rem existe para o
   número não virar legenda num cartão espremido; o teto de 1,85 rem é o que
   sempre foi.

   O 14 foi MEDIDO, e não escolhido: com 16 dois números ainda estouram, com 15
   nenhum estoura — e 14 fica uma casa abaixo do limite, para um rótulo novo ou
   uma fonte diferente não quebrarem isto de novo. Num cartão de 200 px dá uns
   23 px, contra os 29,6 px de antes.

   ⚠️ Encolher o valor é melhor do que cortar: dinheiro pela metade
   ("R$ 1.945.1") é um número errado na tela, e não um número apertado. */
.indicador {
  background: var(--cartao); border: 1px solid var(--linha);
  border-radius: var(--raio); padding: 14px 16px;
  border-left: 3px solid var(--acento);
  container-type: inline-size;
}
.indicador .rotulo { font-size: .74rem; color: var(--tinta-3); text-transform: uppercase; letter-spacing: .05em; font-weight: 600; }
.indicador .numero {
  font-size: clamp(1.05rem, 14cqi, 1.85rem);
  font-weight: 660; line-height: 1.15; font-variant-numeric: tabular-nums;
}
.indicador .nota { font-size: .78rem; color: var(--tinta-3); }
.indicador.verde { border-left-color: var(--verde); }
.indicador.ambar { border-left-color: var(--ambar); }
.indicador.azul  { border-left-color: var(--azul); }
.indicador.roxo  { border-left-color: var(--roxo); }
.indicador.vermelho { border-left-color: var(--vermelho); }
.indicador.cinza { border-left-color: var(--cinza); }

/* ── Etiquetas ───────────────────────────────────────────────────────────── */

.etiq {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  font-size: .74rem; font-weight: 620; letter-spacing: .01em;
  background: var(--cinza-fraco); color: var(--cinza); white-space: nowrap;
}
.etiq.verde { background: var(--verde-fraco); color: var(--verde); }
.etiq.ambar { background: var(--ambar-fraco); color: var(--ambar); }
.etiq.azul  { background: var(--azul-fraco); color: var(--azul); }
.etiq.roxo  { background: var(--roxo-fraco); color: var(--roxo); }
.etiq.vermelho { background: var(--vermelho-fraco); color: var(--vermelho); }
.etiq.ocre  { background: var(--acento-fraco); color: var(--acento); }
.etiq .ponto { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* ── Formulários ─────────────────────────────────────────────────────────── */

.campo { display: block; margin-bottom: 14px; }
.campo > span {
  display: block; margin-bottom: 5px; font-size: .82rem;
  font-weight: 600; color: var(--tinta-2);
}
.campo > span .exig { color: var(--vermelho); }
.campo .ajuda { font-size: .76rem; color: var(--tinta-3); margin-top: 4px; display: block; }

input[type="text"], input[type="email"], input[type="tel"], input[type="number"],
input[type="date"], input[type="datetime-local"], input[type="time"], input[type="search"],
input[type="password"], select, textarea {
  width: 100%; min-height: 44px; padding: 9px 12px;
  border: 1px solid var(--linha-forte); border-radius: var(--raio-p);
  background: var(--cartao); color: var(--tinta);
}
textarea { min-height: 84px; resize: vertical; line-height: 1.45; }
input:focus, select:focus, textarea:focus { border-color: var(--acento); outline: none; box-shadow: 0 0 0 3px var(--acento-fraco); }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color: var(--vermelho); }
input::placeholder, textarea::placeholder { color: var(--tinta-3); }
select { appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; }


/* ── Seletor com busca ─────────────────────────────────────────────────────
   O campo que entra no lugar do <select> quando a lista pode crescer. A lista
   abre NO FLUXO (empurrando o que vem abaixo) e não flutuando: o corpo do
   modal rola, e camada flutuante seria cortada na borda. Ver `seletorBusca`
   em `ui.js`. */

.seletor-caixa { position: relative; }

.seletor-gatilho {
  width: 100%; min-height: 44px; padding: 8px 34px 8px 12px;
  border: 1px solid var(--linha-forte); border-radius: var(--raio-p);
  background: var(--cartao); color: var(--tinta); font: inherit;
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  text-align: left; cursor: pointer;
  /* Mesma setinha do <select>, pelo mesmo truque: o campo tem que continuar
     se lendo como campo de escolha, e não como botão. */
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.seletor-gatilho:focus-visible {
  border-color: var(--acento); outline: none; box-shadow: 0 0 0 3px var(--acento-fraco);
}
.seletor-gatilho[disabled] { opacity: .55; cursor: not-allowed; }
.seletor-gatilho .seletor-texto { font-size: .95rem; line-height: 1.3; }
.seletor-gatilho .seletor-texto.vago { color: var(--tinta-3); }
.seletor-gatilho .seletor-sub { color: var(--tinta-3); font-size: .74rem; line-height: 1.25; }

.seletor-lista {
  margin-top: 6px; border: 1px solid var(--linha); border-radius: var(--raio-p);
  background: var(--cartao); box-shadow: var(--sombra); overflow: hidden;
}

/* ⚠️ Na barra de filtros a lista FLUTUA; no formulário ela empurra.
   São os dois lugares, e cada um quebra do jeito oposto:

   - A `.filtros` é uma fileira `align-items: flex-end`. Abrindo no fluxo, o
     campo de corretor ficava três vezes mais alto que os vizinhos, e "De" e
     "Até" desciam para o rodapé da fileira — a barra inteira parecia
     desmontada só porque alguém abriu uma lista.
   - No modal é o contrário: o corpo rola (`overflow-y: auto`), e camada
     flutuante seria cortada na borda de baixo justamente nos campos do fim do
     formulário, que é onde o corretor mora.

   Daí a exceção morar aqui, e não no componente. */
.filtros .seletor-lista {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 30;
  min-width: 260px; margin-top: 4px;
}
/* Escolhido, o filtro volta a ter uma linha só: a segunda (CRECI,
   imobiliária) fazia o campo crescer e desalinhava "De" e "Até" ao lado. Ela
   serve para escolher entre dois "Marcelo", e isso acontece na lista aberta,
   que continua mostrando as duas linhas. */
.filtros .seletor-gatilho .seletor-sub { display: none; }
.filtros .seletor-gatilho { justify-content: center; }
/* Especificidade maior que a regra geral de input[type=search], para o filtro
   virar a primeira linha da caixa em vez de um campo dentro de outro campo. */
.seletor-lista input[type="search"] {
  border: 0; border-bottom: 1px solid var(--linha); border-radius: 0;
  background: var(--cartao-2); min-height: 42px;
}
.seletor-lista input[type="search"]:focus { box-shadow: none; border-color: var(--linha); }

.seletor-rolagem { max-height: 46vh; overflow-y: auto; }

.seletor-opcao {
  display: block; width: 100%; text-align: left; padding: 10px 12px;
  background: none; border: 0; border-top: 1px solid var(--linha);
  color: var(--tinta); font: inherit; cursor: pointer;
}
.seletor-rolagem > .seletor-opcao:first-child { border-top: 0; }
.seletor-opcao:hover, .seletor-opcao.marcado { background: var(--cartao-2); }
.seletor-opcao[aria-selected="true"] { background: var(--acento-fraco); }
.seletor-opcao .nome { display: block; font-size: .92rem; line-height: 1.3; }
.seletor-opcao .sub { display: block; color: var(--tinta-3); font-size: .74rem; line-height: 1.25; }

.seletor-grupo {
  padding: 7px 12px 5px; border-top: 1px solid var(--linha);
  background: var(--cartao-2); color: var(--tinta-3);
  font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 600;
}
.seletor-mais, .seletor-nada {
  padding: 9px 12px; border-top: 1px solid var(--linha);
  color: var(--tinta-3); font-size: .78rem;
}
/* A última linha da lista, quando o campo aceita cadastrar o que falta. Tem a
   cor do acento para não se confundir com as opções que já existem — é uma
   ação, e não mais um item para escolher. */
.seletor-criar {
  display: block; width: 100%; text-align: left; padding: 10px 12px;
  background: none; border: 0; border-top: 1px solid var(--linha);
  color: var(--acento); font: inherit; font-weight: 600; font-size: .85rem;
  cursor: pointer;
}
.seletor-criar:hover, .seletor-criar.marcado { background: var(--acento-fraco); }

.linha-campos { display: grid; gap: 0 12px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

.marcador { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0; cursor: pointer; }
.marcador input { width: 20px; height: 20px; margin-top: 2px; flex: 0 0 20px; accent-color: var(--acento); }
.marcador span { font-size: .9rem; }

/* Grupo de opções em pílula — mais rápido que um <select> no celular. */
.pilulas { display: flex; flex-wrap: wrap; gap: 7px; }
.pilulas button {
  min-height: 40px; padding: 0 14px; border-radius: 999px;
  border: 1px solid var(--linha-forte); background: var(--cartao);
  font-weight: 550; font-size: .88rem;
}
.pilulas button[aria-pressed="true"] { background: var(--acento); border-color: var(--acento); color: var(--acento-tinta); }


/* ── Tabelas ─────────────────────────────────────────────────────────────── */

.rolagem { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table.tab { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.tab th, table.tab td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--linha); vertical-align: middle; }
table.tab th {
  font-size: .74rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--tinta-3); font-weight: 650; white-space: nowrap;
  position: sticky; top: 0; background: var(--cartao); z-index: 1;
}
table.tab tbody tr:hover { background: var(--cartao-2); }
table.tab td.num, table.tab th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.tab tr:last-child td { border-bottom: none; }

/* ── TABELA COM AÇÃO NA LINHA: a última coluna gruda na direita ───────

   O cronograma de uma unidade ganhou as colunas do caixa em 09/09/2026 e
   passou de cinco para sete. A rolagem lateral continua morando DENTRO da
   `.rolagem`, que é o combinado — a página inteira não anda de lado —, mas a
   barra dela fica no PÉ da tabela, e 34 parcelas põem esse pé longe: para
   alcançar "Dar baixa" era preciso rolar até o fim, andar de lado e voltar.

   Grudando a ação na borda direita, o botão está sempre na altura da linha, e
   a rolagem lateral vira detalhe em vez de caminho obrigatório. O cabeçalho
   já fazia o mesmo em cima, e por isso o `th` da ponta gruda nos DOIS eixos.

   As células também apertam: com sete colunas, o respiro de 12 px custava
   168 px de largura — mais do que uma coluna inteira. */
/* `compacta` é só o aperto; `caixa` é o aperto MAIS a ação grudada. Nem toda
   tabela larga tem botão na linha — a de unidades e a de meses não têm. */
table.tab.compacta, table.tab.caixa { font-size: .86rem; }
table.tab.compacta th, table.tab.compacta td,
table.tab.caixa th, table.tab.caixa td { padding: 8px; }
table.tab.caixa th:last-child,
table.tab.caixa td:last-child {
  position: sticky; right: 0; background: var(--cartao);
  border-left: 1px solid var(--linha);
}
table.tab.caixa th:last-child { z-index: 2; }
/* Sem isto a linha sob o cursor acende inteira menos a ponta grudada. */
table.tab.caixa tbody tr:hover td:last-child { background: var(--cartao-2); }

/* ── Vazio, carregando, erro ─────────────────────────────────────────────── */

.vazio { padding: 40px 20px; text-align: center; color: var(--tinta-3); }
.vazio .simbolo { font-size: 2rem; opacity: .5; display: block; margin-bottom: 8px; }
.vazio h3 { color: var(--tinta-2); margin-bottom: 4px; }

.carregando { padding: 30px; text-align: center; color: var(--tinta-3); }
.girando {
  display: inline-block; width: 18px; height: 18px;
  border: 2px solid var(--linha-forte); border-top-color: var(--acento);
  border-radius: 50%; animation: girar .7s linear infinite; vertical-align: -3px;
}
@keyframes girar { to { transform: rotate(360deg); } }

.aviso {
  padding: 11px 14px; border-radius: var(--raio-p); font-size: .88rem;
  background: var(--ambar-fraco); color: var(--ambar);
  border: 1px solid color-mix(in srgb, var(--ambar) 26%, transparent);
}
.aviso.erro { background: var(--vermelho-fraco); color: var(--vermelho); border-color: color-mix(in srgb, var(--vermelho) 26%, transparent); }
.aviso.ok { background: var(--verde-fraco); color: var(--verde); border-color: color-mix(in srgb, var(--verde) 26%, transparent); }
.aviso.info { background: var(--azul-fraco); color: var(--azul); border-color: color-mix(in srgb, var(--azul) 26%, transparent); }

/* ── Modal ───────────────────────────────────────────────────────────────── */

.fundo-modal {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(20, 14, 10, .5);
  display: flex; align-items: center; justify-content: center; padding: 16px;
  animation: aparecer .12s ease-out;
}
@keyframes aparecer { from { opacity: 0; } }
.modal {
  background: var(--cartao); border-radius: var(--raio);
  box-shadow: var(--sombra-alta); width: min(560px, 100%);
  max-height: 90vh; max-height: 90dvh; display: flex; flex-direction: column;
  border: 1px solid var(--linha);
}
.modal.largo { width: min(880px, 100%); }
.modal > header { padding: 16px 18px; border-bottom: 1px solid var(--linha); display: flex; align-items: center; gap: 10px; }
.modal > header h2 { flex: 1; font-size: 1.05rem; }
/* O respiro vale para todo `.corpo` dentro do modal — inclusive os cartões
   que as telas montam lá dentro, que já se acertam com `.justo`. */
.modal .corpo { padding: 18px; }

/* ⚠️ **Quem ROLA é só o corpo do PRÓPRIO modal — o filho direto.**

   `.modal .corpo` é seletor de descendente, e pega também os `.corpo` que as
   telas põem DENTRO do modal: o cartão de "Todas as telas" do menu "Mais", a
   lista de clientes parecidos, o checklist. Nenhum deles precisa rolar —
   quem rola é o corpo de fora, e eles são justamente o conteúdo que
   transborda dele.

   Fazer deles contêineres de rolagem que nunca rolam não é inofensivo: no
   dedo, o gesto é entregue ao contêiner mais interno sob o toque, e um
   contêiner que não tem para onde rolar **engole o gesto** em vez de passá-lo
   ao pai. Como o dedo sempre pousa dentro do cartão, a lista inteira parava
   de rolar no celular. `overscroll-behavior: contain` — que existe para o fim
   da rolagem não arrastar a página atrás do modal — piora isso, porque manda
   explicitamente não encadear.

   Não aparece no computador: a roda do mouse desce por outro caminho e rola
   normalmente. É um defeito só de quem usa o dedo — que é todo mundo no
   stand. */
.modal > .corpo { overflow-y: auto; overscroll-behavior: contain; flex: 1; }
.modal > footer { padding: 14px 18px; border-top: 1px solid var(--linha); display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; }

/* ── Avisos flutuantes ───────────────────────────────────────────────────── */

/* Canto inferior direito, e não centralizado: no meio da tela o aviso caía
   exatamente em cima das linhas 2 e 3 da fila — que é onde a recepção olha
   para conferir se a fila girou. */
#torradas {
  position: fixed; z-index: 200; right: 18px; left: auto;
  bottom: 18px; display: flex; flex-direction: column;
  gap: 8px; align-items: flex-end; pointer-events: none; width: min(420px, calc(100% - 24px));
}
.torrada {
  pointer-events: auto; background: var(--tinta); color: var(--papel);
  padding: 11px 16px; border-radius: 999px; font-size: .9rem; font-weight: 550;
  box-shadow: var(--sombra-alta); animation: subir .18s ease-out;
  display: flex; align-items: center; gap: 9px; max-width: 100%;
}
.torrada.erro { background: var(--vermelho); color: #fff; }
.torrada.ok { background: var(--verde); color: #fff; }
@keyframes subir { from { opacity: 0; transform: translateY(10px); } }

/* ── Diversos ────────────────────────────────────────────────────────────── */

.pilha { display: flex; flex-direction: column; gap: 14px; }
.fileira { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.fileira.entre { justify-content: space-between; }
.mudo { color: var(--tinta-3); }
.mini { font-size: .8rem; }
/* Endereço longo tem que quebrar: sem isto a URL do balcão estoura a largura
   do modal no celular e empurra o botão de fechar para fora da tela. */
.quebra { word-break: break-all; }

/* ── O QR na tela ────────────────────────────────────────────────────────────
   Fundo branco e respiro próprios, independentes do tema: leitor de QR espera
   escuro sobre claro, e no tema escuro o código ficaria ilegível. */
.qr-caixa {
  display: inline-block; padding: 12px; background: #FFFFFF;
  border: 1px solid var(--linha); border-radius: var(--raio-p);
}
.qr-caixa svg { display: block; }

/* Na impressão sobra o QR e o endereço: cabeçalho, menu e botões não ajudam
   ninguém no papel do balcão. */
@media print {
  body > *:not(.fundo-modal) { display: none !important; }
  .fundo-modal { position: static; background: none; padding: 0; }
  .modal { box-shadow: none; border: 0; max-height: none; width: 100%; }
  .modal > header button, .modal > footer { display: none !important; }
}
.forte { font-weight: 650; }
.centro { text-align: center; }
.direita { text-align: right; }

.filtros {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;
  padding: 12px 14px; background: var(--cartao); border: 1px solid var(--linha);
  border-radius: var(--raio); margin-bottom: 14px;
}
.filtros .campo { margin: 0; min-width: 148px; }
/* Campo de busca precisa caber o próprio texto de ajuda: com 148 px o
   "nome, telefone ou e-mail" saía cortado no meio da palavra. */
.filtros .campo:has(input[type="search"]) { min-width: 260px; flex: 1 1 260px; }

.avatar {
  width: 36px; height: 36px; border-radius: 50%; flex: 0 0 36px;
  background: var(--acento-fraco); color: var(--acento);
  display: flex; align-items: center; justify-content: center;
  font-weight: 680; font-size: .85rem;
}
.avatar.g { width: 46px; height: 46px; flex-basis: 46px; font-size: 1rem; }

.barra-progresso { height: 7px; border-radius: 999px; background: var(--cartao-2); overflow: hidden; }
.barra-progresso i { display: block; height: 100%; background: var(--acento); border-radius: 999px; }
/* A parte JÁ RECEBIDA, dentro da barra do mês (09/09/2026). A barra diz o
   tamanho do mês; a cabeça verde diz quanto dele já entrou — uma coluna a
   menos, e a leitura fica de relance em vez de comparar dois números. */
.barra-progresso i b { display: block; height: 100%; background: var(--verde); border-radius: 999px; }

/* ── Adaptação a telas pequenas ──────────────────────────────────────────── */

/* O que decide o tamanho do alvo e o DEDO, e nao a largura da tela.

   O iPad deitado tem 1180 px: nao entra na regra de 900 px acima, e ali o
   botao pequeno continuava com 34 px de altura para ser acertado com o
   polegar. A largura respondia "e um celular?"; a pergunta certa e "tem
   mouse?" — e o CSS sabe responder essa.

   Fica num bloco proprio, e nao junto do de cima, de proposito: la dentro
   moram a barra lateral e a navegacao de rodape, e no iPad deitado as duas
   estao certas como estao. So o tamanho do alvo muda. */
@media (pointer: coarse) {
  .btn.p { min-height: 44px; padding: 0 14px; font-size: .9rem; }
  .barra .btn.fantasma.p { min-width: 44px; }
}

@media (max-width: 900px) {
  /* 44 px é o mínimo para quem está de pé, com o celular numa mão e um cliente
     na frente. No desktop 34 px basta (há mouse); no celular "Pular" e
     "Pausar" a 3 px um do outro é erro na certa — e pular consome a vez de
     alguém. */
  .btn.p { min-height: 44px; padding: 0 14px; font-size: .9rem; }
  .fila .acoes { gap: 10px; }
  .fila .acoes .btn { flex: 1 1 auto; }
  .barra .btn.fantasma.p { min-width: 44px; }

  .lateral { display: none; }
  .nav-celular { display: block; }

  /* -- Casca de aplicativo: a PAGINA nao rola, o CONTEUDO rola --------------
     Duas coisas quebravam enquanto a pagina inteira rolava, e as duas vinham
     do mesmo lugar: no Chrome do Android a regua do "position: fixed" e a
     tela SEM a barra de endereco, mesmo com a barra de endereco a mostra.
     Medido no Galaxy do stand: regua 853 px, area visivel 694 px.

     1. A barra de navegacao de baixo era desenhada de 790 a 853 -- 159 px
        abaixo da tela. Sumia sozinha, sem ninguem rolar nada.
     2. Reposiciona-la por JavaScript a cada quadro consertava a posicao e
        criava um quique: o calculo chega sempre um quadro depois do dedo.

     Com o conteudo rolando por dentro, a pagina nao rola; sem rolagem de
     pagina, o Chrome nao esconde a barra de endereco; sem isso as duas reguas
     nunca divergem. A barra de navegacao sai do "fixed" e volta ao fluxo, no
     fim da coluna -- nao tem como sumir nem quicar, porque nao depende de
     medida nenhuma.

     O preco e a barra de endereco ficar sempre a vista. Num aplicativo de
     trabalho, layout que nao pula vale mais que 56 px que aparecem e somem. */
  .casca {
    flex-direction: column;
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
  }
  .principal { min-height: 0; }
  /* overscroll-behavior impede que a rolagem, ao chegar no fim da lista,
     "vaze" para a pagina e traga de volta o puxar-para-recarregar. */
  .conteudo { overflow-y: auto; overscroll-behavior: contain; }
  .nav-celular { position: static; flex: 0 0 auto; }

  /* -- Sobreposicoes: ancorar no ALTO e medir com dvh ----------------------
     Tudo que e "position: fixed" continua medindo pela regua da PAGINA (853
     px no aparelho do stand), e nao pela area visivel (694). Entao "bottom:
     0" nao e o pe da tela: e 159 px abaixo dele.

     Consequencias que estavam de pe: a torrada de erro aparecia fora da tela
     (a mensagem que explica por que a gravacao falhou), o aviso de versao nova
     idem, e o modal, centralizado em 853, tinha o rodape com os botoes cortado
     -- justamente "Salvar" e "Cancelar".

     A saida e ancorar no alto (top: 0) e dar a altura em dvh, que e a area
     visivel de verdade. Como a pagina nao rola mais, esse valor e estavel. */
  .fundo-modal { inset: auto; top: 0; left: 0; right: 0; height: 100dvh; }
  #torradas {
    top: 0; bottom: auto; height: 100dvh;
    justify-content: flex-end; padding-bottom: 14px;
  }

  .conteudo { padding: 14px 12px calc(var(--rodape) + 24px); }
  /* 300 px, e não 150.
     Com 150 cabiam DUAS colunas num celular de 360 px — e um cartão de 170 px
     não comporta o conteúdo que vai nele: o título ia para duas linhas, os
     rótulos viravam "Portais (ZAP/Vi…", e a barra de mídia (nome + trilho +
     dois números, uns 226 px de largura mínima) simplesmente vazava para fora
     do cartão, cortando os números na borda da tela.

     Com 300 o celular cai para UMA coluna e o tablet mantém duas — a conta é
     do conteúdo, não do aparelho: 300 px é o que a barra de mídia precisa para
     mostrar o nome inteiro. */
  .grade.c2, .grade.c3, .grade.c4 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
  #torradas { right: 12px; left: 12px; align-items: stretch; width: auto; }
  .barra { padding: 0 12px; }
  .modal { width: 100%; max-height: 94dvh; }
  .fundo-modal { padding: 8px; align-items: flex-end; }
}

@media (max-width: 560px) {
  .grade.c3, .grade.c4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .indicador .numero { font-size: 1.5rem; }
}

/* ── Ver como outra pessoa ──────────────────────────────────────────────────
   Uma linha, rente. Isto é um andaime de quem desenvolve, não um recurso do
   stand: tomava duas fileiras e mais de 200 px num celular com a fonte do
   Android aumentada — mais que o cabeçalho inteiro. Agora diz o essencial (de
   quem é a pele) e o resto é ícone.

   Continua grudada no topo, acima da barra (z-index 31 contra os 30 dela), e
   sem botão de esconder: quem esquece que trocou de pele abre uma tela, não
   acha o que procurava e conclui que o sistema quebrou.

   Tamanhos em px, e não em rem, de propósito — é a única parte do aplicativo
   que faz isso. A escala de fonte do Android existe para o corretor ler o nome
   do cliente, não para engordar o andaime.                                   */
.tarja-pele {
  position: sticky;
  top: 0;
  z-index: 31;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 8px;
  min-height: 26px;
  background: var(--ambar-fraco);
  color: var(--ambar);
  border-bottom: 1px solid var(--linha);
  font-size: 12px;
  line-height: 1.3;
}
.tarja-pele svg { flex: 0 0 auto; }
.tarja-pele .quem {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tarja-pele b { color: inherit; font-weight: 650; }
.tarja-pele .btn-pele {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Largura folgada e altura da faixa inteira: dá uma área de toque decente
     sem custar um pixel de altura. */
  align-self: stretch;
  width: 32px;
  /* A margem negativa come o respiro da faixa: o alvo passa a ocupar a altura
     inteira dela, sem que a faixa cresça. */
  margin: -3px 0;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  font-size: 13px;
  cursor: pointer;
}
.tarja-pele .btn-pele:hover { background: color-mix(in srgb, var(--ambar) 18%, transparent); }
/* A barra também é grudenta, e no topo: com a tarja presente ela precisa
   parar embaixo. A altura vem medida em JS — um valor de tabela erraria assim
   que a tarja mudasse de tamanho. */
.casca.com-pele .barra { top: var(--tarja, 26px); }
/* Com a tarja de ambiente em cima, a da pele gruda embaixo dela. */
.casca.com-pele .tarja-pele { top: var(--tarja-ambiente, 0px); }

/* ── Ambiente de testes ────────────────────────────────────────────────────
   Listrada e vermelha de propósito: não pode parecer parte do aplicativo, nem
   sumir no tema escuro. Mesma altura da tarja de pele, mesma regra de px. */
.tarja-ambiente {
  position: sticky;
  top: 0;
  z-index: 32;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  min-height: 26px;
  color: #fff;
  background: repeating-linear-gradient(135deg, #A83232 0 14px, #7E2323 14px 28px);
  font-size: 12px;
  line-height: 1.3;
  letter-spacing: .02em;
}
.tarja-ambiente .quem {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tarja-ambiente b { color: inherit; font-weight: 750; }

.secao-pele {
  text-transform: uppercase;
  letter-spacing: .06em;
  margin: .7rem 0 .15rem;
}
.linha-pele {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  text-align: left;
  width: 100%;
}
.linha-pele .mudo { margin-left: auto; }
.linha-pele .etiq { margin-left: .4rem; }


/* ── "Saiu uma versão nova" ─────────────────────────────────────────────────
   Embaixo, e não em cima: em cima já moram a barra do título e a tarja de
   "ver como", e um terceiro andar empurraria o conteúdo para fora da tela do
   celular. Fica acima da navegação de baixo para não cobrir os atalhos.

   Não some sozinha. Um aviso que desaparece em cinco segundos é um aviso que
   ninguém leu — e este é justamente o que a pessoa precisa ver quando voltar
   a olhar o telefone.                                                       */
.barra-versao {
  position: fixed;
  z-index: 60;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--rodape) + 12px);
  display: flex;
  align-items: center;
  gap: .7rem;
  max-width: calc(100vw - 24px);
  padding: .55rem .6rem .55rem 1rem;
  border-radius: var(--raio);
  border: 1px solid var(--linha-forte);
  background: var(--cartao);
  box-shadow: var(--sombra-alta);
  font-size: .88rem;
}
@media (min-width: 900px) {
  /* No computador não existe navegação de baixo: a barra desce até o pé. */
  .barra-versao { bottom: 16px; left: auto; right: 18px; transform: none; }
}

/* A barra de "versao nova" e declarada acima, fora de media query. O ajuste de
   celular precisa vir DEPOIS dela: mesma especificidade, quem vem por ultimo
   ganha — e o ajuste dentro do bloco de 900 px, escrito antes, era desfeito
   pela regra base sem nenhum aviso. */
@media (max-width: 900px) {
  .barra-versao {
    top: calc(100dvh - 14px);
    bottom: auto;
    transform: translate(-50%, -100%);
  }
}

/* ── Lista de anexos ───────────────────────────────────────────────────────

   O que vai junto do contrato para assinatura. Cada linha diz sim ou nao com
   simbolo E cor: quem nao distingue verde de vermelho continua lendo o ✓ e o
   ✗, e quem le rapido pega a cor. So a cor seria uma lista que o daltonico
   nao consegue conferir antes de mandar contrato para o cliente. */
.anexos { list-style: none; margin: 8px 0; padding: 0; font-size: .9rem; }
.anexos li { padding: 3px 0; }
.anexos li.ok b { color: var(--verde); }
.anexos li.falta { color: var(--vermelho); }
.anexos li.falta b { color: var(--vermelho); }

/* ── Ações de linha e menu de "mais" ────────────────────────────────────────
   O contrário da parede de botões. Ver o cabeçalho de `acoes()` em `ui.js`
   para a conta que motivou tudo isto (56 botões numa fila de 14 pessoas).

   O gatilho é o botão MAIS discreto do aplicativo de propósito: ele repete
   linha a linha, e o que repete linha a linha não pode chamar atenção. Três
   pontos de tinta, sem borda, sem fundo — a borda só aparece com o dedo ou o
   mouse em cima, que é quando ela vira alvo em vez de enfeite. */

.btn.so-icone {
  min-width: 40px;
  padding: 0 8px;
  color: var(--tinta-3);
}
.btn.so-icone:hover { color: var(--tinta); }
/* No dedo o alvo volta aos 44 px de sempre: um menu que abre por engano na
   linha errada pula a vez de um corretor. */
@media (pointer: coarse) {
  .btn.so-icone { min-width: 44px; }
}

.painel-acoes {
  position: fixed;
  /* 150: acima do modal (100) — a ficha da unidade É um modal e tem linhas de
     contrato com menu —, abaixo da torrada de erro (200), que nunca pode
     ficar atrás de nada. */
  z-index: 150;
  min-width: 200px;
  max-width: min(320px, calc(100vw - 16px));
  overflow-y: auto;
  overscroll-behavior: contain;   /* rolar o menu não rola a lista atrás */
  padding: 6px;
  background: var(--cartao);
  border: 1px solid var(--linha-forte);
  border-radius: var(--raio-p);
  box-shadow: var(--sombra-alta);
}

.item-acao {
  display: flex; align-items: center; gap: 10px;
  width: 100%; min-height: 42px; padding: 8px 10px;
  border: none; border-radius: 6px; background: none;
  color: var(--tinta); font-weight: 500; text-align: left;
  text-decoration: none;
}
.item-acao:hover, .item-acao:focus-visible { background: var(--cartao-2); text-decoration: none; }
.item-acao .rot { display: flex; flex-direction: column; line-height: 1.25; }
/* A nota explica a ação em meia linha — é aqui que cabe o "cria um segundo
   envelope" que antes vivia num parágrafo cinza embaixo do grupo. */
.item-acao .rot small { color: var(--tinta-3); font-size: .76rem; font-weight: 400; }
.item-acao .icone { color: var(--tinta-3); flex: 0 0 auto; }
.item-acao.perigo { color: var(--vermelho); }
.item-acao.perigo:hover, .item-acao.perigo:focus-visible { background: var(--vermelho-fraco); }
.item-acao.perigo .icone { color: inherit; }
.item-acao[disabled], .item-acao.desligado { opacity: .45; cursor: not-allowed; }
.item-acao[disabled]:hover, .item-acao.desligado:hover { background: none; }

.divisor-acoes { border: none; border-top: 1px solid var(--linha); margin: 5px 4px; }

/* No celular a linha da lista quebra, e as ações vão para uma fileira própria
   embaixo. Ali o gatilho não pode esticar junto com os botões (a regra
   `.fila .acoes .btn { flex: 1 1 auto }` faria isso): três pontos numa caixa
   de meia largura de tela é um alvo que mente sobre o que tem dentro. */
@media (max-width: 900px) {
  .acoes .btn.so-icone, .fila .acoes .btn.so-icone { flex: 0 0 auto; }
}

/* ── Barra de ações de formulário ───────────────────────────────────────────
   O grupo de botões que conclui um passo, com a explicação dentro. Ver o
   cabeçalho de `barraAcoes()` em `ui.js`.

   O fundo é `--cartao-2` sobre `--cartao`: um degrau de superfície basta para
   dizer "isto é um bloco de comando", sem gastar uma borda colorida que
   competiria com os avisos que vivem logo acima dela. */

.barra-acoes {
  background: var(--cartao-2);
  border: 1px solid var(--linha);
  border-radius: var(--raio-p);
  padding: 12px;
  margin-top: 12px;
}
.barra-acoes .linha-acoes {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.barra-acoes .lado-secundario { display: flex; gap: 8px; flex-wrap: wrap; }
/* `margin-left: auto` e não `justify-content: space-between`: sem ação
   secundária, a principal ficaria encostada à esquerda, no lugar onde o olho
   procura o que é secundário. */
.barra-acoes .lado-principal { margin-left: auto; display: flex; gap: 8px; }
.barra-acoes .nota-acoes {
  margin: 10px 2px 0;
  color: var(--tinta-3); font-size: .8rem; line-height: 1.45;
}
.barra-acoes .btn { background: var(--cartao); }
.barra-acoes .btn.primario { background: var(--acento); }
.barra-acoes .btn.fantasma { background: transparent; }

/* Celular: a ação que conclui ocupa a largura toda e fica EM CIMA das
   secundárias. Quem chegou até aqui vai clicar nela; as outras são desvios. */
@media (max-width: 700px) {
  .barra-acoes .linha-acoes { flex-direction: column-reverse; align-items: stretch; }
  .barra-acoes .lado-principal { margin-left: 0; }
  .barra-acoes .lado-principal .btn { width: 100%; }
  .barra-acoes .lado-secundario .btn { flex: 1 1 auto; }
}

/* ── Lista de peças do envelope ─────────────────────────────────────────────
   O que vai para a assinatura, em forma de lista com marcação — e não de
   `<input type=checkbox>` cru colado num texto.

   O cru desalinhava (a caixa nasce na linha de base do texto, não no meio),
   media 13 px no Windows e não tinha estado nenhum ao ser desmarcado: a peça
   fora do envelope ficava exatamente igual à que ia dentro, só com um
   quadradinho vazio de 13 px separando as duas. Num envelope que vai para
   assinatura de contrato, essa é a diferença que mais importa da tela. */

.lista-pecas { list-style: none; margin: 10px 0; padding: 0; display: grid; gap: 6px; }
.lista-pecas > li { margin: 0; }

.peca {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 10px 12px; width: 100%;
  border: 1px solid var(--linha);
  border-radius: var(--raio-p);
  background: var(--cartao);
  text-align: left;
}
.peca:hover { border-color: var(--linha-forte); }

/* Checkbox de verdade, repintado — e não uma `div` fingindo de caixa.

   O componente falso teria de reimplementar foco, tecla de espaço, leitor de
   tela e o `for` do rótulo, e erraria em algum deles. `appearance: none`
   guarda tudo isso e só troca o desenho. O certo é feito com duas bordas
   giradas: um `::after` não carrega SVG, e o traço tem de mudar de cor com o
   estado da peça.

   O rótulo se liga por `for`, e não envolvendo o campo: a linha da peça tem
   botões dentro ("tirar", "N mudança(s)"), e `<label>` com descendente
   interativo é a armadilha que já custou o grupo de pílulas — o WebKit
   repassa a ativação para o primeiro controle do rótulo, e só no iPhone, que
   é justamente o aparelho do balcão. */
.peca > input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  flex: 0 0 20px; width: 20px; height: 20px; margin: 2px 0 0;
  border: 1.5px solid var(--linha-forte); border-radius: 5px;
  background: var(--cartao); cursor: pointer; position: relative;
}
.peca > input[type="checkbox"]::after {
  content: ''; position: absolute; left: 5.5px; top: 2px;
  width: 5px; height: 9px; opacity: 0;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(42deg);
}
.peca > input[type="checkbox"]:checked::after { opacity: 1; }
.peca > input[type="checkbox"]:disabled { cursor: default; }
.peca > label { cursor: pointer; }
.peca > input[type="checkbox"]:disabled + label { cursor: default; }
.peca .corpo-peca { min-width: 0; flex: 1; }
.peca .corpo-peca b { display: block; font-weight: 600; line-height: 1.3; }
.peca .corpo-peca small { display: block; color: var(--tinta-3); font-size: .78rem; line-height: 1.35; }
.peca .tam { color: var(--tinta-3); font-size: .78rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

.peca.dentro { border-color: color-mix(in srgb, var(--verde) 42%, transparent); background: var(--verde-fraco); }
.peca.dentro > input[type="checkbox"] { background: var(--verde); border-color: var(--verde); }
.peca.dentro .corpo-peca b { color: var(--verde); }
.peca.dentro .corpo-peca small, .peca.dentro .tam { color: color-mix(in srgb, var(--verde) 74%, var(--tinta-2)); }

/* FORA do envelope: cinza e apagado, para a diferença ser visível de longe.
   Não é erro — é escolha —, e por isso não é vermelho. */
.peca.fora { background: var(--cartao-2); }
.peca.fora .corpo-peca b { color: var(--tinta-3); font-weight: 500; text-decoration: line-through; }

/* A peça que não se pode tirar (o contrato) não finge ser clicável. */
.peca.travada { cursor: default; }
.peca.travada > input[type="checkbox"] { background: var(--cinza); border-color: var(--cinza); }
.peca.travada:hover { border-color: var(--linha); }

/* ── Ordem de assinatura ────────────────────────────────────────────────────
   Uma fila de nomes é uma sequência, e sequência se lê melhor numerada e
   ligada do que como três itens soltos de lista. */

.ordem-assinatura { list-style: none; margin: 6px 0 0; padding: 0; counter-reset: passo; }
.ordem-assinatura li {
  position: relative; counter-increment: passo;
  padding: 7px 0 7px 34px; line-height: 1.35;
}
.ordem-assinatura li::before {
  content: counter(passo);
  position: absolute; left: 0; top: 6px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--cartao-2); border: 1px solid var(--linha-forte);
  color: var(--tinta-2); font-size: .74rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums;
}
/* O fio que liga um passo ao seguinte — para de descer no último. */
.ordem-assinatura li:not(:last-child)::after {
  content: ''; position: absolute; left: 11px; top: 30px; bottom: -1px;
  border-left: 1px dashed var(--linha-forte);
}
.ordem-assinatura li b { font-weight: 600; }
.ordem-assinatura li .papel { color: var(--tinta-3); }
/* ── UMA PESSOA POR LINHA, COM O ESTADO NA FRENTE ─────────────────────

   Depois do envio, a etapa deixa de ser "Fulano, Beltrano" e passa a ter
   estado por pessoa — e estado não cabe numa lista separada por vírgula.

   A marca é ✓ ou ○, e não só a cor: quem imprime a tela, quem enxerga mal e
   quem olha de longe precisam distinguir "assinou" de "falta" sem depender
   do verde. */
.ordem-assinatura li .assinante { display: flex; align-items: baseline; gap: 6px; }
.ordem-assinatura li .assinante .marca { font-weight: 700; min-width: 1em; }

/* ── Passo dentro de um cartão ──────────────────────────────────────────────
   O subtítulo que divide uma seção comprida nas perguntas que ela responde.

   Nasceu na Assinatura do contrato: uma coluna de vinte centímetros com
   lista, botões, quatro avisos, outra lista e mais botões, sem um único
   descanso — e nada dizendo onde uma coisa acabava e a outra começava, num
   lugar onde o clique errado manda o contrato ao comprador.

   O primeiro não ganha o fio de cima: o cabeçalho do cartão já está logo
   acima dele, e duas linhas juntas seriam uma moldura dupla. */
.passo-secao {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 22px 0 8px;
  padding-top: 16px;
  border-top: 1px solid var(--linha);
  font-size: .78rem; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--tinta-2);
}
.passo-secao:first-child { margin-top: 2px; padding-top: 0; border-top: none; }
/* A contagem ao lado do título — "3 documento(s)". Minúscula e sem espaçar as
   letras: é dado, não rótulo. */
.passo-secao span {
  font-size: .78rem; font-weight: 400; letter-spacing: 0;
  text-transform: none; color: var(--tinta-3);
}
