/* ==========================================================================
   RASTREIO — componentes. Depende de tokens.css.
   Nada de valor cru aqui: se precisou de um hex, faltou um token.
   ========================================================================== */

@layer base {
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--fonte-ui);
  font-size: var(--t-md);
  line-height: var(--altura-normal);
  color: var(--tinta);
  background: var(--fundo);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-numeric: tabular-nums;
  /* Trama. Duas diagonais finíssimas em ângulo de tecido — some no fundo, mas
     tira o "branco de app" e dá matéria à página.

     H.2, calibrada contra celular real (Android, tema escuro). Duas coisas
     estavam erradas e as duas se viam só com pixel na frente:

     1. O passo era de **7px**. Duas diagonais cruzadas nessa densidade batem
        com a grade física da tela e produzem MOIRÉ — a página parecia vibrar ao
        rolar. Passou para 14px: a trama continua legível de perto e para de
        brigar com o subpixel.
     2. `--borda-sutil` é branco a 8%; com as duas camadas se cruzando, a
        interseção somava para perto de 16% — o triplo da atmosfera pretendida.
        Agora é latão a 3,5%, que dá o mesmo sopro de calor sem peso.

     E saiu o `background-attachment: fixed`. No Chrome/Android ele força
     repintura da camada de fundo a cada quadro de scroll e é a origem
     conhecida de fantasmas de composição — era o "header duplicado no meio da
     rolagem" que apareceu no print. A trama agora rola com a página, o que de
     quebra elimina a sensação de conteúdo deslizando sobre uma grade parada. */
  background-image:
    repeating-linear-gradient(58deg,
      oklch(70% 0.06 75 / .035) 0 1px, transparent 1px 14px),
    repeating-linear-gradient(-58deg,
      oklch(70% 0.06 75 / .035) 0 1px, transparent 1px 14px);
}

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--fonte-display);
  font-weight: var(--peso-display);
  line-height: var(--altura-densa);
  letter-spacing: -0.011em;
  font-optical-sizing: auto;
  font-variation-settings: "SOFT" 0, "WONK" 1;
  text-wrap: balance;
}
p { margin: 0; text-wrap: pretty; }

a { color: var(--marca); text-decoration-color: var(--marca-contorno);
    text-underline-offset: 2px; transition: color var(--t-rapida); }
@media (hover: hover) { a:hover { color: var(--marca-forte); text-decoration-color: currentColor; } }

button, input, select, textarea { font: inherit; color: inherit; }

::selection { background: var(--marca-fraca); color: var(--tinta); }

:focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.mono { font-family: var(--fonte-mono); font-variant-numeric: tabular-nums; }
.num  { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

}  /* @layer base */

@layer app {
/* --------------------------------------------------------------------------
   Faixa de honestidade — fina, escura, discreta. Informa sem tomar a tela.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Topo
   -------------------------------------------------------------------------- */
/* H.2 — duas correções vistas só no aparelho:

   `top` passou a somar `env(safe-area-inset-top)`. O `viewport-fit=cover` do
   `<meta viewport>` faz o app ocupar a tela inteira, inclusive por baixo da
   barra de status; os 32px de `--faixa-h` bastavam num Android sem recorte e
   deixavam relógio e bateria por cima do header em qualquer aparelho com barra
   sólida mais alta. Com `env()` o header desce o quanto o aparelho pedir, e em
   desktop o valor é zero — nada muda.

   `isolation: isolate` dá ao header um contexto de empilhamento próprio. Junto
   com a remoção do `background-attachment: fixed` do body, é o que fecha o
   fantasma de composição: o `backdrop-filter` deixa de recompor a pilha inteira
   a cada quadro de scroll. */
/* DUAS PERSONALIDADES, uma por contexto — rodada I.

   No DESKTOP o header flutua: os 32px de `--faixa-h` deixam o fundo aparecer
   por cima dele, os cantos são arredondados e a sombra o descola da página.
   Sobra espaço de tela e o gesto é do ponteiro, então a barra pode ser um
   objeto pousado sobre o conteúdo.

   No CELULAR ele COLA no topo. Tela pequena não tem 32px para gastar com ar
   acima de uma barra fixa, e barra flutuante encostada na área da câmera vira
   ruído junto com o relógio e a bateria do sistema. Colado, com borda inferior
   sólida, ele se comporta como a barra do próprio aparelho — que é a leitura
   certa para algo que fica ali o tempo todo. Ver a media query mais abaixo. */
.topo {
  position: fixed; z-index: 50; isolation: isolate;
  top: calc(var(--faixa-h) + env(safe-area-inset-top, 0px));
  left: max(var(--e-4), env(safe-area-inset-left, 0px));
  right: max(var(--e-4), env(safe-area-inset-right, 0px));
  border-radius: var(--r-lg);
  height: var(--topo-h);
  display: flex; align-items: center; gap: var(--e-4);
  padding: 0 clamp(var(--e-4), 4vw, var(--e-8));
  background: color-mix(in oklab, var(--superficie) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(14px);
  -webkit-backdrop-filter: saturate(1.6) blur(14px);
  border: 1px solid var(--borda);
  box-shadow: var(--elev-2);
  max-width: var(--largura); margin: 0 auto;
}

/* --- o header colado, no celular ---------------------------------------- */
@media (max-width: 900px) {
  .topo {
    top: 0; left: 0; right: 0;
    padding-top: env(safe-area-inset-top, 0px);
    height: calc(var(--topo-h) + env(safe-area-inset-top, 0px));
    border-radius: 0; border-left: 0; border-right: 0; border-top: 0;
    box-shadow: none;
    /* colado, o vidro precisa ser mais opaco: com 88% o texto da página passava
       por baixo e competia com o nome do app ao rolar */
    background: color-mix(in oklab, var(--superficie) 94%, transparent);
  }
  /* D1.4 (17/09): o menu suspenso e o `.nav-tema` saíram com o hambúrguer — o
     Tema mora no Mais. O botão de tema do topo segue só no desktop. */
  .topo-acoes #btTema { display: none; }
}


.marca { display: flex; align-items: center; gap: var(--e-3);
         text-decoration: none; color: inherit; }
@media (hover: hover) { .marca:hover { color: inherit; } }
/* O selo da marca — rodada I.
   O símbolo (fio + nó) vive no `index.html` como SVG inline e herda a cor por
   `currentColor`, então o mesmo desenho serve ao selo colorido, ao P&B da
   impressão e a qualquer tema, sem uma segunda cópia para manter.

   Saiu o gradiente que o placeholder tinha: o brief da marca exige que ela
   sobreviva à impressão em preto sobre branco, e gradiente não sobrevive. Índigo
   chapado, latão no traço — a mesma gramática do resto do app. */
.marca-sig {
  position: relative;
  width: 34px; height: 34px; flex: none;
  border-radius: var(--r-md);
  background: var(--indigo-700);
  box-shadow: var(--elev-1);
  display: grid; place-items: center;
  color: var(--latao-300);
  transition: background var(--t-rapida), color var(--t-rapida);
}
.marca-sig svg { width: 26px; height: 26px; display: block; }
@media (hover: hover) { .marca:hover .marca-sig { background: var(--indigo-600); color: var(--latao-200); } }

/* Na impressão o selo é só o símbolo, em preto: fundo colorido em folha A4 é
   cartucho gasto, e a OS vai assinada na mão de quem está na facção. */
@media print {
  .marca-sig { background: none; box-shadow: none; color: #000; }
}
.marca-txt { display: flex; flex-direction: column; line-height: 1.15; }
.marca-txt b {
  font-family: var(--fonte-display); font-size: var(--t-lg);
  font-weight: var(--peso-display); letter-spacing: -.015em;
}
.marca-txt em {
  font-style: normal; font-size: var(--t-3xs); color: var(--tinta-3);
  letter-spacing: .13em; text-transform: uppercase; font-weight: var(--peso-medio);
}

.nav { display: flex; gap: var(--e-1); margin-left: auto; align-items: center; }
.nav a {
  position: relative;
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-md);
  color: var(--tinta-2); font-size: var(--t-sm); font-weight: var(--peso-medio);
  text-decoration: none; white-space: nowrap;
  transition: color var(--t-rapida), background var(--t-rapida);
}
@media (hover: hover) { .nav a:hover { background: var(--neutro-bg); color: var(--tinta); } }
.nav a[aria-current="page"] { color: var(--marca-forte); }
/* Sublinhado de latão: o item ativo é costurado à página. */
.nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: var(--e-3); right: var(--e-3);
  bottom: -2px; height: 2px; border-radius: 2px;
  background: var(--acento);
}

/* --- "Mais" no topo do desktop — 07/09 ---------------------------------
   Ate aqui o topo despejava as 13 rotas numa linha e o que nao cabia SUMIA
   (o `.topo` e fixed: o que transborda nao rola). Agora sao 5 ou 6 primarios
   e este botao, que abre a mesma folha agrupada do celular.

   Ele e um `button`, nao um link: abre um dialogo, nao navega. E responde a
   clique, nao a hover — hover esconde a navegacao de quem usa toque num
   laptop hibrido e nao existe para quem navega por teclado. */
.nav-mais {
  display: inline-flex; align-items: center; gap: 4px;
  padding: var(--e-2) var(--e-3);
  border: 0; border-radius: var(--r-md);
  background: none; color: var(--tinta-2);
  font-family: inherit; font-size: var(--t-sm); font-weight: var(--peso-medio);
  white-space: nowrap; cursor: pointer;
  transition: color var(--t-rapida), background var(--t-rapida);
}
.nav-mais:focus-visible { background: var(--neutro-bg); color: var(--tinta); }
@media (hover: hover) { .nav-mais:hover { background: var(--neutro-bg); color: var(--tinta); } }
.nav-mais-seta { font-size: .7em; opacity: .7; }


@media (max-width: 900px) {
    .nav-mais { display: none; }   /* a barra inferior ja tem o "Mais" dela */
}

.topo-acoes { display: flex; align-items: center; gap: var(--e-2); margin-left: var(--e-2); }
/* H.2 — a borda sólida de 1px em volta destes dois controles os deixava com
   cara de painel administrativo. Agora a borda é latão bem diluído (some no
   repouso, aparece no toque), o ícone é latão em vez de cinza, e o alvo subiu
   de 38 para 44px — o mínimo de acessibilidade para quem toca com o dedo. */
.bt-icone {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  border: 1px solid oklch(75% 0.06 75 / .18); border-radius: var(--r-md);
  background: transparent; color: var(--acento);
  cursor: pointer;
  transition: background var(--t-rapida), border-color var(--t-rapida),
              color var(--t-rapida);
}
.bt-icone:focus-visible {
  border-color: var(--acento); color: var(--acento);
  background: var(--acento-tenue);
}
@media (hover: hover) { .bt-icone:hover {
  border-color: var(--acento); color: var(--acento);
  background: var(--acento-tenue);
} }

@media (max-width: 900px) {

  .nav {
    position: absolute; top: var(--topo-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--e-2);
    background: var(--superficie);
    border-bottom: 1px solid var(--borda);
    box-shadow: var(--elev-2);
    display: none;
  }
  .nav.aberto { display: flex; animation: desce var(--t-media) both; }
  .nav a { padding: var(--e-3) var(--e-4); border-radius: var(--r-md); }
  .nav a[aria-current="page"] { background: var(--marca-tenue); }
  .nav a[aria-current="page"]::after { left: 0; right: auto; top: 25%; bottom: 25%;
                                       width: 2px; height: auto; }
}
@keyframes desce { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

/* --------------------------------------------------------------------------
   Estrutura
   -------------------------------------------------------------------------- */
.app {
  max-width: var(--largura);
  margin: 0 auto;
  padding: calc(var(--faixa-h) + env(safe-area-inset-top, 0px) + var(--topo-h) + var(--e-8))
           max(var(--e-5), env(safe-area-inset-right, 0px)) var(--e-16)
           max(var(--e-5), env(safe-area-inset-left, 0px));
}
@media (max-width: 900px) {
  .app { padding-top: calc(env(safe-area-inset-top, 0px) + var(--topo-h) + var(--e-6)); }
  .app.limpo { padding-top: calc(env(safe-area-inset-top, 0px) + var(--e-6)); }
}
/* Frente D: aqui havia `outline: none` e `animation: entra` soltos dentro do
   @media, sem seletor — CSS inválido, que o navegador descarta em silêncio. A
   intenção (a tela entra com um sopro de movimento) agora mora em `.pagina`, que
   o shell recria a cada troca de rota; no `.app`, que nunca é recriado, a
   animação só rodaria uma vez na vida da aba. O `outline` some porque o `.app`
   recebe foco por programa (tabindex=-1), não por teclado. */
.app:focus { outline: none; }
@keyframes entra { from { opacity: 0; transform: translateY(6px); } }
.pagina { animation: entra var(--dur-lenta) var(--curva-entra) both; }

.app.limpo { padding-top: calc(var(--faixa-h) + env(safe-area-inset-top, 0px) + var(--e-8)); }

.rodape {
  border-top: 1px solid var(--borda);
  padding: var(--e-6) clamp(var(--e-4), 4vw, var(--e-8)) var(--e-10);
  color: var(--tinta-3); font-size: var(--t-xs);
}
.rodape-int { max-width: var(--largura); margin: 0 auto;
              display: flex; gap: var(--e-4); flex-wrap: wrap; align-items: center; }
.rodape a { color: var(--tinta-2); }
.rodape .sep { color: var(--borda-forte); }
/* H.3 — a versao em uso, no menor tipo da escala. Existe por um motivo pratico:
   o service worker serve a casca do cache, entao "publiquei" e "o aparelho dele
   ja tem" sao coisas diferentes. Com isto, a pergunta "voce esta na versao nova?"
   se responde rolando ate o rodape. */
.rodape-versao {
  margin-left: auto; font-family: var(--fonte-mono); font-size: var(--t-2xs);
  color: var(--tinta-3); opacity: .6; letter-spacing: .02em;
  font-variant-numeric: tabular-nums;
}
@media (max-width: 520px) { .rodape-versao { margin-left: 0; width: 100%; } }

/* --------------------------------------------------------------------------
   Cabeçalho de página — "eyebrow" em latão, título em serifa
   -------------------------------------------------------------------------- */
.cabeca { margin-bottom: var(--e-8); max-width: 68ch; }
.cabeca .olho {
  display: inline-flex; align-items: center; gap: var(--e-2);
  font-size: var(--t-3xs); font-weight: var(--peso-forte);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--acento); margin-bottom: var(--e-3);
}
.cabeca .olho::before {
  content: ""; width: 18px; height: 1.5px; background: var(--acento);
}
.cabeca h1 { font-size: clamp(var(--t-2xl), 4.5vw, var(--t-4xl)); }
.cabeca p { color: var(--tinta-2); margin-top: var(--e-3); font-size: var(--t-md); }

.sec-titulo {
  display: flex; align-items: baseline; gap: var(--e-3);
  margin: var(--e-10) 0 var(--e-4); flex-wrap: wrap;
}
.sec-titulo:first-child { margin-top: 0; }
.sec-titulo h2 { font-size: var(--t-xl); }
.sec-titulo .nota { font-size: var(--t-xs); color: var(--tinta-3); }
.sec-titulo .linha { flex: 1; height: 1px; background: var(--borda); min-width: var(--e-6); }

/* --------------------------------------------------------------------------
   Superfícies
   -------------------------------------------------------------------------- */
.cartao {
  background: var(--superficie);
  border-radius: var(--r-lg);
  box-shadow: var(--elev-1);
  transition: box-shadow var(--t-media);
}
.cartao-p { padding: var(--e-5); }
.cartao.alto { box-shadow: var(--elev-2); }

.grade { display: grid; gap: var(--e-4); }
.g2 { grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.g3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.g4 { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
/* A grade de CARTÕES tem de vencer o bloco `.grade` da contagem por tamanho do
   Registrar (mais abaixo, v9.05), que redefine `.grade` como coluna e vem depois:
   desde 07/09 os cartões do Início e dos Relatórios saíam empilhados no desktop.
   A combinação é mais específica que o nome solto (11/09, ver armadilhas). */
.grade.g2, .grade.g3, .grade.g4 { display: grid; }

/* --------------------------------------------------------------------------
   Entrada em cascata — Rodada H
   --------------------------------------------------------------------------
   Os cartões de uma linha aparecem com 60 ms entre eles. O efeito é curto e só
   acontece no primeiro paint da rota: dá a leitura de "isto foi montado agora,
   com dado de agora" em vez de a tela surgir pronta como uma imagem.

   Em CSS puro, por `nth-child`, e não em JavaScript — de propósito. O `h()`
   monta DOM e nada mais; animação que depende de JS teria de rodar depois do
   render, e a única coisa que garantidamente roda depois do render aqui é o
   próprio navegador. Sete posições cobrem toda grade que existe hoje.
   -------------------------------------------------------------------------- */
@keyframes sobe {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.grade > *, .acoes > *, .adiante-lista > a {
  animation: sobe var(--t-saida) both;
}
.grade > *:nth-child(1), .acoes > *:nth-child(1), .adiante-lista > a:nth-child(1) { animation-delay: 0ms; }
.grade > *:nth-child(2), .acoes > *:nth-child(2), .adiante-lista > a:nth-child(2) { animation-delay: 60ms; }
.grade > *:nth-child(3), .acoes > *:nth-child(3), .adiante-lista > a:nth-child(3) { animation-delay: 120ms; }
.grade > *:nth-child(4), .acoes > *:nth-child(4), .adiante-lista > a:nth-child(4) { animation-delay: 180ms; }
.grade > *:nth-child(5), .acoes > *:nth-child(5), .adiante-lista > a:nth-child(5) { animation-delay: 240ms; }
.grade > *:nth-child(6), .acoes > *:nth-child(6), .adiante-lista > a:nth-child(6) { animation-delay: 300ms; }
.grade > *:nth-child(n+7), .acoes > *:nth-child(n+7), .adiante-lista > a:nth-child(n+7) { animation-delay: 360ms; }

/* O painel de primeiro passo entra sozinho, um pouco antes de tudo. */
.primeiro { animation: sobe var(--t-saida) both; }

/* Quem pediu menos movimento recebe a tela pronta, sem meio-termo. */
@media (prefers-reduced-motion: reduce) {
  .grade > *, .acoes > *, .adiante-lista > a, .primeiro {
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   Primeiro passo — o painel que ocupa a tela enquanto a operação não existe
   --------------------------------------------------------------------------
   Rodada H. Antes daqui, a inicial com base vazia mostrava quatro indicadores
   zerados e cinco cartões grandes, e quatro daqueles caminhos estavam trancados
   por falta de cadastro. Zero não é informação: ocupava o lugar nobre da tela
   para dizer que nada aconteceu.

   O painel é deliberadamente o único elemento com peso visual quando aparece —
   índigo profundo, o mesmo tratamento que `.acao.destaque` já usava para a ação
   principal do coletor. Latão entra só na trilha de progresso e no botão, que é
   a regra da casa: latão é hierarquia, não decoração.
   -------------------------------------------------------------------------- */
/* H.2: contorno de latão diluído. No tema escuro o índigo profundo do card e o
   fundo da página se aproximam demais, e a borda do cartão simplesmente sumia —
   era parte do que dava a sensação de "encostado na tela". */
.primeiro {
  position: relative; overflow: hidden;
  border: 1px solid oklch(75% 0.06 75 / .16);
  padding: var(--e-8) var(--e-6) var(--e-6);
  margin-bottom: var(--e-8);
  border-radius: var(--r-lg);
  background: linear-gradient(160deg, var(--indigo-700), var(--indigo-900));
  color: var(--tinta-inversa);
  box-shadow: var(--elev-2);
}
/* fio de latão no topo: a mesma marca de hierarquia dos cartões de indicador */
.primeiro::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(90deg, var(--latao-500), var(--latao-300) 40%, transparent);
}
.primeiro-cima {
  display: flex; align-items: center; gap: var(--e-4);
  margin-bottom: var(--e-5); flex-wrap: wrap;
}
/* H.2 — no aparelho, estes traços eram o MENOR elemento da tela, e são a única
   prova visual de onde a pessoa está no fluxo. Ganharam corpo: 3px -> 5px, e os
   passos ainda não feitos saíram de branco a 16% (quase invisível sobre índigo)
   para latão a 28% — a leitura passa a ser "faltam três", não "a barra está
   vazia". O ativo é latão sólido e mais largo, para o olho pousar nele. */
.primeiro-selo {
  font-size: var(--t-2xs); text-transform: uppercase; letter-spacing: .16em;
  font-weight: 700; color: var(--latao-200);
}
.primeiro-trilha { display: flex; gap: 5px; align-items: center; }
.primeiro-trilha span {
  width: 26px; height: 5px; border-radius: var(--r-pilula);
  background: oklch(75% 0.06 75 / .28);
}
.primeiro-trilha span.feito { background: var(--latao-400); }
.primeiro-trilha span.agora {
  background: var(--latao-200); width: 44px;
  box-shadow: 0 0 0 1px oklch(85% 0.09 75 / .35);
}
.primeiro h2 {
  font-family: var(--fonte-display); font-size: var(--t-2xl);
  font-weight: var(--peso-display); letter-spacing: -.015em;
  margin: 0 0 var(--e-3);
}
.primeiro p {
  color: oklch(88% 0.055 264); font-size: var(--t-md);
  line-height: var(--altura-normal); max-width: 58ch; margin: 0 0 var(--e-6);
}
.primeiro .bt { width: auto; min-width: 260px; }
.primeiro-dica {
  display: block; margin-top: var(--e-3);
  font-size: var(--t-xs); color: oklch(78% 0.090 264);
}

/* "O que vem depois" — os outros destinos, sem disputar com o passo atual */
.adiante { margin-bottom: var(--e-8); }
.adiante-rot {
  display: block; font-size: var(--t-3xs); text-transform: uppercase;
  letter-spacing: .12em; color: var(--tinta-3); font-weight: var(--peso-forte);
  margin-bottom: var(--e-3);
}
.adiante-lista { display: flex; flex-wrap: wrap; gap: var(--e-2); }
.adiante-lista a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: var(--e-2) var(--e-4); flex: 0 1 auto;
  border: 1px solid var(--borda); border-radius: var(--r-pilula);
  font-size: var(--t-sm); color: var(--tinta-2); text-decoration: none;
  transition: border-color var(--t-rapida), color var(--t-rapida),
              background var(--t-rapida);
}
@media (hover: hover) { .adiante-lista a:hover {
  border-color: var(--acento); color: var(--tinta);
  background: var(--acento-tenue); text-decoration: none;
} }

/* H.2 — o destino que ainda não abre precisa parecer TRANCADO, não esquecido.
   No aparelho, o contorno cinza sobre fundo escuro sumia: não lia como link nem
   como desabilitado. Agora tem cadeado, contorno de latão diluído e um `title`
   que diz o que destrava. A opacidade fica em 0,55 e não em 0,4 porque abaixo
   disso, sobre índigo escuro, o texto deixa de ser legível — e a intenção aqui
   é justamente que ele SEJA lido. */
.adiante-lista .chip-travado {
  display: inline-flex; align-items: center; gap: var(--e-2);
  min-height: 44px; padding: var(--e-2) var(--e-4);
  border: 1px dashed oklch(75% 0.06 75 / .30); border-radius: var(--r-pilula);
  font-size: var(--t-sm); color: var(--tinta-3);
  opacity: .55; cursor: not-allowed; user-select: none;
}
.adiante-lista .chip-travado .ic-svg { opacity: .8; }
@media (max-width: 860px) { .adiante-lista .chip-travado { min-height: var(--toque); } }

/* --------------------------------------------------------------------------
   Mobile das telas de gestor — Rodada H
   --------------------------------------------------------------------------
   O gestor também abre isto fora do escritório. Em 375px o `.app` deixa 343px
   úteis (padding lateral de 16px de cada lado); dentro do `.primeiro`, com
   24px de padding, sobram 295px. O botão com `min-width: 260px` cabia por 35px
   e estourava em qualquer aparelho de 320px — passa a ocupar a linha inteira.

   E as pílulas de "o que vem depois" sobem para o alvo de 56px: no celular são
   tocadas com o dedo, e a regra da casa (`--toque`) vale para elas como para
   qualquer outro alvo. No desktop, onde o alvo é o ponteiro, 40px basta e
   mantém a lista compacta.
   -------------------------------------------------------------------------- */
@media (max-width: 860px) {
  .primeiro { padding: var(--e-6) var(--e-5) var(--e-5); }
  .primeiro h2 { font-size: var(--t-xl); }
  .primeiro p { font-size: var(--t-sm); margin-bottom: var(--e-5); }
  .primeiro .bt { width: 100%; min-width: 0; }
  .adiante-lista a { min-height: var(--toque); }
  /* Os chips de especialidade são o alvo mais tocado do cadastro de facção —
     é neles que se diz "esta oficina faz costura e barra". No desktop 44px é o
     padrão de acessibilidade e basta para o ponteiro; no celular sobem para o
     mesmo 56px do resto, porque aqui quem escolhe é o dedo. */
  .cad-chip { min-height: var(--toque); }
  .cad-item .bt.compacto { min-height: 48px; }
}

/* --------------------------------------------------------------------------
   Ações da inicial — cartão com faixa de latão que acende no hover
   -------------------------------------------------------------------------- */
.acoes { display: grid; gap: var(--e-4);
         grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); }
.acao {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: var(--e-3);
  padding: var(--e-6); min-height: 172px;
  background: var(--superficie);
  border-radius: var(--r-lg);
  box-shadow: var(--elev-1);
  color: var(--tinta); text-decoration: none; text-align: left; cursor: pointer;
  transition: transform var(--t-media), box-shadow var(--t-media);
}
.acao::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--acento);
  transform: scaleY(0); transform-origin: bottom;
  transition: transform var(--t-saida);
}
/* Meia-luz: um brilho que desce do topo, em vez do cartão saltar.
   Rodada H — `translateY(-3px)` no hover fazia a grade inteira tremer quando o
   ponteiro atravessava, e num app de trabalho isso é ruído. O gradiente sugere
   o foco sem mover nada de lugar; a faixa de latão continua sendo a afirmação. */
.acao::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, var(--acento-tenue), transparent 62%);
  opacity: 0; transition: opacity var(--t-media);
}
@media (hover: hover) { .acao:hover { box-shadow: var(--elev-2); text-decoration: none; color: var(--tinta); } }
@media (hover: hover) { .acao:hover::after { opacity: 1; } }
@media (hover: hover) { .acao:hover::before { transform: scaleY(1); transform-origin: top; } }
.acao:active { box-shadow: var(--elev-1); }
.acao > * { position: relative; z-index: 1; }
@media (hover: hover) { .acao.destaque:hover::after {
  background: linear-gradient(180deg, oklch(100% 0 0 / .08), transparent 62%);
} }
.acao .ic {
  width: 44px; height: 44px; border-radius: var(--r-md);
  background: var(--marca-tenue); color: var(--marca);
  display: grid; place-items: center; font-size: 1.35rem;
  transition: background var(--t-media);
}
@media (hover: hover) { .acao:hover .ic { background: var(--marca-fraca); } }
.acao b { font-family: var(--fonte-display); font-size: var(--t-lg);
          font-weight: var(--peso-display); letter-spacing: -.01em; }
.acao span { color: var(--tinta-2); font-size: var(--t-sm);
             line-height: var(--altura-normal); }
.acao.destaque { background: linear-gradient(160deg, var(--indigo-700), var(--indigo-900));
                 color: var(--tinta-inversa); }
.acao.destaque .ic { background: oklch(100% 0 0 / .12); color: var(--latao-200); }
.acao.destaque span { color: oklch(88% 0.055 264); }
@media (hover: hover) { .acao.destaque:hover { color: var(--tinta-inversa); } }

/* --------------------------------------------------------------------------
   Indicadores — número em serifa, grande, com rótulo miúdo em caixa alta
   -------------------------------------------------------------------------- */
/* Rodada H: fio de latão no topo (hierarquia, não enfeite) e o número em mono.
   O valor era `--fonte-display` com `tabular-nums` — declaração INERTE, porque a
   Fraunces não tem a feature `tnum` (medido com fontTools; ver `fonts.css`).
   Numa linha de quatro indicadores lado a lado o desalinhamento era discreto,
   mas o número aqui é o conteúdo da tela: merece ser tabular de verdade. */
.kpi { padding: var(--e-5); position: relative; overflow: hidden; }
.kpi::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: var(--acento); opacity: .5;
  transition: opacity var(--t-media);
}
.kpi::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, var(--acento-tenue), transparent 58%);
  opacity: 0; transition: opacity var(--t-media);
}
@media (hover: hover) { .kpi:hover::before { opacity: 1; } }
@media (hover: hover) { .kpi:hover::after { opacity: 1; } }
.kpi > * { position: relative; z-index: 1; }
.kpi .rot {
  font-size: var(--t-3xs); text-transform: uppercase; letter-spacing: .12em;
  color: var(--tinta-3); font-weight: var(--peso-forte);
}
.kpi .val {
  font-family: var(--fonte-mono);
  font-size: var(--t-2xl); font-weight: 600;
  letter-spacing: -.02em; line-height: 1.15; margin-top: var(--e-2);
  font-variant-numeric: tabular-nums;
}
.kpi .sub { font-size: var(--t-xs); color: var(--tinta-2); margin-top: var(--e-1); }
.kpi.t-grave .val { color: var(--grave); }
.kpi.t-atencao .val { color: var(--atencao); }
/* A inicial pede `t-erro` e `t-alerta`, e só `t-grave` e `t-atencao` existiam:
   "Passaram do prazo" e "Peças a menos na volta" saíam na cor neutra mesmo com
   atraso (Frente D). Apelidos, e não troca no inicio.js — outra frente mexe lá. */
.kpi.t-erro .val { color: var(--grave); }
.kpi.t-alerta .val { color: var(--atencao); }
.kpi.t-ok .val { color: var(--ok); }
.kpi.destaque { background: var(--marca-tenue); box-shadow: var(--elev-1); }
.kpi.destaque .val { color: var(--marca-forte); }

/* --------------------------------------------------------------------------
   Etiquetas
   -------------------------------------------------------------------------- */
.tag {
  display: inline-flex; align-items: center; gap: var(--e-1);
  padding: 2px var(--e-2); border-radius: var(--r-pilula);
  font-size: var(--t-2xs); font-weight: var(--peso-forte); white-space: nowrap;
  background: var(--neutro-bg); color: var(--neutro);
  line-height: 1.5;
}
.tag::before { content: ""; width: 5px; height: 5px; border-radius: 50%;
               background: currentColor; flex: none; }
.tag.ok      { background: var(--ok-bg);      color: var(--ok); }
.tag.atencao { background: var(--atencao-bg); color: var(--atencao); }
.tag.grave   { background: var(--grave-bg);   color: var(--grave); }
.tag.info    { background: var(--marca-fraca);color: var(--marca-forte); }
.tag.outro   { background: var(--outro-bg);   color: var(--outro); }
/* o laranja da inteireza (RN-12): a palavra vem antes da cor — a tag diz "buscada em parte" */
.tag.laranja { background: var(--laranja-bg); color: var(--laranja); }
.kb-lin.parcial { box-shadow: inset 4px 0 0 var(--laranja); }
.tag.acento  { background: var(--acento-fraco); color: var(--acento); }
.tag.simples { border: 1px solid var(--borda); background: transparent;
               color: var(--tinta-2); font-weight: var(--peso-medio); }
.tag.simples::before { display: none; }

/* --------------------------------------------------------------------------
   Avisos
   -------------------------------------------------------------------------- */
.aviso {
  display: flex; gap: var(--e-3); padding: var(--e-4);
  border-radius: var(--r-md); font-size: var(--t-sm);
  line-height: var(--altura-normal); align-items: flex-start;
  border-left: 3px solid currentColor;
}
/* `min-width: 0` e `overflow-wrap`: filho de flex não encolhe abaixo do próprio
   conteúdo, e um texto sem espaço (um endereço, um código) vazava da caixa —
   visto a 390 e a 1280 no aviso do Financeiro (11/09). */
.aviso > div { color: var(--tinta); min-width: 0; overflow-wrap: anywhere; }
.aviso.info    { background: var(--marca-tenue);  color: var(--marca-forte); }
.aviso.atencao { background: var(--atencao-bg);   color: var(--atencao); }
.aviso.grave   { background: var(--grave-bg);     color: var(--grave); }
.aviso.ok      { background: var(--ok-bg);        color: var(--ok); }
/* o tamanho do icone vem do `tam` de icone(); aqui so o alinhamento */
.aviso .em { line-height: 1.3; flex: none; display: inline-flex; align-items: center; }

/* --------------------------------------------------------------------------
   Agenda — a cor por dia é navegação, não enfeite
   -------------------------------------------------------------------------- */
/* Rodada H: um fio de latao a esquerda de todo bloco de dia. Os blocos ficam
   quase encostados, entao os fios se leem como um EIXO VERTICAL continuo — a
   linha do tempo descendo pela tela. No dia de hoje o mesmo fio fica opaco: e'
   a unica coisa que o gestor procura quando abre esta tela. */
.dia { border-radius: var(--r-lg); overflow: hidden;
       box-shadow: var(--elev-1); margin-bottom: var(--e-3);
       border-left: 2px solid oklch(55% 0.135 72 / .20); }
.dia.hoje { border-left-color: var(--acento); }
.dia-topo {
  display: flex; align-items: baseline; gap: var(--e-3); flex-wrap: wrap;
  padding: var(--e-3) var(--e-5);
  border-bottom: 1px solid var(--borda-sutil);
}
.dia-topo b { font-family: var(--fonte-display); font-size: var(--t-md);
              font-weight: var(--peso-display); }
.dia-topo .semana { font-size: var(--t-xs); color: var(--tinta-2);
                    text-transform: capitalize; }
.dia-topo .cont { margin-left: auto; font-size: var(--t-2xs);
                  color: var(--tinta-2); font-weight: var(--peso-medio); }
.dia-corpo { background: var(--superficie); }
.dia.hoje .dia-topo b::after {
  content: "hoje"; margin-left: var(--e-2);
  font-family: var(--fonte-ui); font-size: var(--t-3xs); font-weight: 700;
  background: var(--acento); color: var(--indigo-950);
  padding: 1px var(--e-2); border-radius: var(--r-pilula);
  text-transform: uppercase; letter-spacing: .08em; vertical-align: 2px;
}
.dia.vazio { box-shadow: var(--elev-0); }
.dia.vazio .dia-corpo { padding: var(--e-4) var(--e-5); color: var(--tinta-3);
                        font-size: var(--t-xs); letter-spacing: .01em; }

.reg { display: grid; grid-template-columns: auto 1fr auto; gap: var(--e-4);
       padding: var(--e-4) var(--e-5); align-items: start;
       border-bottom: 1px solid var(--borda-sutil);
       transition: background var(--t-rapida); }
.reg:last-child { border-bottom: 0; }
@media (hover: hover) { .reg:hover { background: var(--superficie-2); } }
.reg-hora { font-family: var(--fonte-mono); font-size: var(--t-2xs);
            color: var(--tinta-3); padding-top: 3px; }
.reg-corpo b { font-size: var(--t-sm); font-weight: var(--peso-forte); display: block; }
.reg-corpo .meta { font-size: var(--t-xs); color: var(--tinta-2); margin-top: 1px; }
.reg-corpo .obs { font-size: var(--t-xs); color: var(--tinta-2); margin-top: var(--e-2);
                  padding-left: var(--e-3); border-left: 2px solid var(--borda-forte);
                  font-style: italic; }
.reg-qtd { text-align: right; }
/* G.2: era --fonte-display, e ali `tabular-nums` nao fazia nada (a Fraunces nao
   tem `tnum`). Como e' uma COLUNA — uma linha por remessa — o desalinhamento
   aparecia a cada mudanca de digito. Plex Mono e' tabular por construcao (600/600) — a mesma que resolveu o contador. */
.reg-qtd .n { font-family: var(--fonte-mono); font-size: var(--t-lg);
              font-weight: 600; font-variant-numeric: tabular-nums; }
.reg-qtd .u { font-size: var(--t-3xs); color: var(--tinta-3); display: block;
              text-transform: uppercase; letter-spacing: .08em; }
.reg-qtd .dif { font-size: var(--t-2xs); color: var(--grave);
                font-weight: var(--peso-forte); display: block; }

/* --------------------------------------------------------------------------
   Tabela — régua de ledger: linha fina, cabeçalho miúdo, número alinhado
   -------------------------------------------------------------------------- */
.tab-rolo { overflow-x: auto; -webkit-overflow-scrolling: touch;
            border-radius: var(--r-lg); }
table { width: 100%; border-collapse: collapse; font-size: var(--t-sm);
        min-width: 540px; background: var(--superficie); }
th, td { padding: var(--e-3) var(--e-4); text-align: left;
         border-bottom: 1px solid var(--borda-sutil); }
th {
  font-size: var(--t-3xs); text-transform: uppercase; letter-spacing: .1em;
  color: var(--tinta-3); font-weight: var(--peso-forte);
  background: var(--superficie-2); position: sticky; top: 0; z-index: 1;
  border-bottom: 1px solid var(--borda);
}
/* zebra de 1,5%: quase invisivel isolada, decisiva numa tabela de 20 linhas
   para o olho nao pular de linha ao atravessar da esquerda para a direita */
tbody tr:nth-child(even) { background: oklch(50% 0.014 66 / .015); }
tbody tr { transition: background var(--t-rapida); }
@media (hover: hover) { tbody tr:hover { background: var(--acento-tenue); } }
tbody tr:last-child td { border-bottom: 0; }

/* Rodada H: coluna numerica em Plex Mono. E' o caso de coluna empilhada por
   excelencia — vinte valores em R$ um sobre o outro, e a virgula precisa cair
   sempre no mesmo lugar. Inter tem `tnum`, entao ja alinhava; a mono alinha E
   diz "isto e' numero, nao texto", que e' o tom de sala de operacoes. */
td.num { text-align: right; font-family: var(--fonte-mono);
         font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
th.num { text-align: right; }
.total-linha td { font-weight: 600; background: var(--superficie-2);
                  border-top: 2px solid var(--acento); }

/* --------------------------------------------------------------------------
   Formulário
   -------------------------------------------------------------------------- */
.campo { margin-bottom: var(--e-5); }
.campo > label { display: block; font-size: var(--t-xs); font-weight: var(--peso-forte);
                 margin-bottom: var(--e-2); color: var(--tinta);
                 letter-spacing: .01em; }
.campo .ajuda { font-size: var(--t-xs); color: var(--tinta-2); margin-bottom: var(--e-2); }

select, input[type="text"], input[type="date"], input[type="email"],
input[type="password"], input[type="tel"], textarea {
  width: 100%; padding: var(--e-3) var(--e-4);
  font-size: var(--t-md);
  border: 1px solid var(--borda-forte); border-radius: var(--r-md);
  background: var(--superficie); color: var(--tinta);
  min-height: var(--toque);
  transition: border-color var(--t-rapida), box-shadow var(--t-rapida);
}
input::placeholder, textarea::placeholder { color: var(--tinta-3); }
/* Rodada H: o anel de foco passou de indigo para LATAO. No sistema desta casa
   o latao marca o que importa agora — e o campo em foco e' exatamente isso. O
   indigo e' a base; usar a base para destacar diluia a propria hierarquia.
   Vale para o app inteiro de proposito: foco que muda de cor por tela ensina a
   pessoa duas vezes a mesma coisa. */
select:focus, input:focus, textarea:focus {
  outline: none; border-color: var(--acento);
  box-shadow: 0 0 0 3px oklch(55% 0.135 72 / .26);
}
textarea { min-height: 96px; resize: vertical; line-height: var(--altura-normal); }

/* --------------------------------------------------------------------------
   Botões
   -------------------------------------------------------------------------- */
.bt {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--e-2);
  min-height: var(--toque); padding: var(--e-3) var(--e-6);
  border: 1px solid transparent; border-radius: var(--r-md);
  font-size: var(--t-md); font-weight: var(--peso-forte);
  cursor: pointer; width: 100%;
  /* H.3 — LATÃO É AÇÃO, no app inteiro. Até aqui o primário era índigo, e o
     índigo é a cor da superfície: cartão de ação, painel do primeiro passo,
     selo da marca. Usar a mesma cor para "isto é um lugar" e para "isto faz
     algo" obrigava a aprender a gramática duas vezes.

     Uma regra num lugar só atinge os 28 botões primários de uma vez — inclusive
     os 12 do coletor —, o que é a diferença entre uma gramática e uma lista de
     correções que alguém vai esquecer de continuar. Quem precisar de índigo
     pede: `.bt.marca`.

     Contraste — CORRIGIDO na Frente D (16/09). Este comentário dizia "~7:1"
     para índigo-950 sobre latão-600; medido, eram 3,80:1, abaixo do AA. O fundo
     passou para `--acao` (latão a 73%): 7,7:1, AAA. Ver tokens.css e o guard
     `contraste`. No galpão o par escuro-sobre-claro continua o certo. */
  background: var(--acao); color: var(--acao-tinta);
  border-color: var(--acao-borda);
  /* `a.bt` herdava o sublinhado do link: sobre o latão escuro de antes ele
     sumia; sobre o latão claro, aparecia cortando o rótulo */
  text-decoration: none;
  font-size: var(--t-acao); font-weight: var(--peso-acao);
  box-shadow: var(--elev-1), var(--luz-interna);
  transition: background var(--t-rapida), transform var(--t-rapida),
              box-shadow var(--t-rapida), border-color var(--t-rapida);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
@media (hover: hover) { .bt:hover { background: var(--acao-hover); box-shadow: var(--elev-2); color: var(--acao-tinta); } }
/* Índigo continua disponível para quando a ação for de superfície, não de
   comando — hoje ninguém usa, e isso é sinal de que a inversão estava certa. */
.bt.marca { background: var(--marca); color: var(--tinta-inversa); border-color: transparent; }
@media (hover: hover) { .bt.marca:hover { background: var(--marca-forte); } }
/* O toque se CONFIRMA no próprio botão: afunda 2% e perde a sombra, em 120 ms.
   Na rua, com luva ou dedo suado, é essa resposta que diz "pegou" antes de a
   tela seguinte chegar — e evita o segundo toque que registraria duas vezes. */
.bt:active { transform: scale(.98); background: var(--acao-ativo); box-shadow: var(--elev-0); }
/* H.3 — desabilitado guarda a COR BASE e varia a opacidade, a mesma lógica dos
   chips travados: o botão continua dizendo que é a ação primária, só que ainda
   não. Pintar de cinza fazia parecer outro componente. */
.bt[disabled] { background: var(--acao); color: var(--acao-tinta);
                opacity: .45; cursor: not-allowed; box-shadow: none; transform: none; }
@media (hover: hover) { .bt[disabled]:hover { background: var(--acao); } }
.bt.sec { background: var(--superficie); color: var(--tinta);
          border-color: var(--borda-forte); font-weight: var(--peso-forte); }
@media (hover: hover) { .bt.sec:hover { background: var(--superficie-2); border-color: var(--tinta-3); } }
.bt.sec:active { background: var(--superficie-2); }
/* `.bt.acento` virou redundante em H.3 (o `.bt` já é latão) e fica como apelido
   para não quebrar quem o escreve por hábito. */
.bt.acento { background: var(--acao); color: var(--acao-tinta); }
@media (hover: hover) { .bt.acento:hover { background: var(--acao-hover); } }
.bt.fantasma { background: transparent; color: var(--tinta-2); box-shadow: none;
               border-color: transparent; font-weight: var(--peso-medio); }
@media (hover: hover) { .bt.fantasma:hover { background: var(--neutro-bg); color: var(--tinta); } }
/* Ação que destrói ou descarta (Descartar este registro, Cancelar a conta):
   contorno grave, nunca fundo grave — o vermelho cheio chamaria o dedo para o
   botão que menos se quer tocar por engano. */
.bt.perigo { background: var(--superficie); color: var(--grave); border-color: var(--grave); }
@media (hover: hover) { .bt.perigo:hover { background: var(--grave-bg); } }
/* C-03 (13/09): 44px e o piso de toque (F21). Com 38, "Mudar a rota", "Imprimir so
   esta" e os demais compactos mediam 40px no E2E — abaixo do dedo de quem esta de pe. */
.bt.compacto { min-height: 44px; padding: var(--e-2) var(--e-4);
               font-size: var(--t-sm); width: auto; }
.bt-linha { display: flex; gap: var(--e-3); margin-top: var(--e-5); }
.bt-linha .bt { width: auto; flex: 1; }

/* --------------------------------------------------------------------------
   Fluxo do coletor — o contador É o projeto
   -------------------------------------------------------------------------- */
.passos { display: flex; gap: var(--e-2); margin-bottom: var(--e-6); }
.passo { flex: 1; height: 3px; border-radius: 2px; background: var(--borda);
         transition: background var(--t-media); }
.passo.feito { background: var(--acento); }
.passo.atual { background: var(--marca); }

.contador {
  background: var(--superficie); border-radius: var(--r-lg);
  box-shadow: var(--elev-2); padding: var(--e-6); text-align: center;
  position: relative; overflow: hidden;
}
.contador::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: linear-gradient(90deg, var(--marca), var(--acento));
}
.contador-rot { font-size: var(--t-2xs); color: var(--tinta-3);
                text-transform: uppercase; letter-spacing: .14em;
                font-weight: var(--peso-forte); }
/* O número que o coletor lê enquanto conta peça.
   06/09 (rodada G): era `--fonte-display` (Fraunces) com `tabular-nums` — e o
   `tabular-nums` era INERTE. Medido com fontTools no arquivo que servimos: a
   Fraunces tem dígitos proporcionais (o "1" mede 1024 e o "0" mede 1461 upm, uma
   diferença de 30%) e **não possui a feature `tnum`** — só `liga` e `rvrn`. Não
   há alternativa tabular na fonte; a declaração não tinha como funcionar.
   Resultado: o número saltava a cada mudança de dígito (9→10, 19→20), na maior
   tipografia da tela, justamente enquanto alguém conta em voz alta.
   Isso contradizia a decisão mais explícita do tokens.css — "números SEMPRE
   tabulares" — e era anterior ao self-host: acontecia igual com o Google Fonts.

   Plex Mono resolve por construção (todo dígito mede 600/600) e é a escolha
   coerente com o desenho que já existia: os botões `+1/+10/−1/−10` logo abaixo
   (`.bt-cont`) já usam `--fonte-mono`, e o tokens.css já a descreve como a fonte
   do "teclado do contador". O valor agora pertence à mesma família dos botões
   que o alteram. `tabular-nums` fica declarado por intenção, embora redundante
   numa monoespaçada. */
.contador-valor {
  font-family: var(--fonte-mono);
  font-size: clamp(3.2rem, 16vw, 4.8rem); font-weight: var(--peso-display);
  line-height: 1; letter-spacing: -.03em; font-variant-numeric: tabular-nums;
  margin-top: var(--e-2);
}
.contador-dif { margin-top: var(--e-2); font-size: var(--t-sm);
                font-weight: var(--peso-forte); min-height: 1.5em; }
.contador-dif.neg { color: var(--grave); }
.contador-dif.zero { color: var(--ok); }
.contador-botoes { display: grid; grid-template-columns: repeat(4, 1fr);
                   gap: var(--e-2); margin-top: var(--e-5); }
.bt-cont {
  min-height: 66px; border-radius: var(--r-md);
  border: 1px solid var(--borda-forte); background: var(--superficie-2);
  font-family: var(--fonte-mono); font-size: var(--t-lg); font-weight: 600;
  cursor: pointer; transition: background-color var(--t-rapida), border-color var(--t-rapida), color var(--t-rapida), box-shadow var(--t-rapida), transform var(--t-rapida);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
@media (hover: hover) { .bt-cont:hover { background: var(--superficie); border-color: var(--tinta-3); } }
.bt-cont:active { transform: scale(.96); background: var(--marca-fraca);
                  border-color: var(--marca); }
.bt-cont.mais { color: var(--ok); }
.bt-cont.menos { color: var(--grave); }

.foto-alvo {
  border: 1.5px dashed var(--borda-forte); border-radius: var(--r-lg);
  padding: var(--e-8) var(--e-4); text-align: center; color: var(--tinta-2);
  background: var(--superficie); cursor: pointer; min-height: 156px;
  display: grid; place-content: center; gap: var(--e-2);
  transition: background-color var(--t-media), border-color var(--t-media), color var(--t-media), box-shadow var(--t-media), transform var(--t-media);
}
@media (hover: hover) { .foto-alvo:hover { border-color: var(--marca); background: var(--marca-tenue); } }
.foto-alvo .big { font-size: 2rem; }
.foto-alvo b { color: var(--tinta); font-weight: var(--peso-forte); }
.foto-alvo.ok { border-style: solid; border-color: var(--ok);
                background: var(--ok-bg); }

/* --------------------------------------------------------------------------
   Login — página inteira, não caixinha
   -------------------------------------------------------------------------- */
.login-tela {
  min-height: 100svh;
  display: grid; grid-template-columns: 1fr;
  padding-top: var(--faixa-h);
}
@media (min-width: 940px) { .login-tela { grid-template-columns: 1.05fr .95fr; } }

.login-arte {
  display: none;
  position: relative; overflow: hidden;
  background: linear-gradient(150deg, var(--indigo-800), var(--indigo-950) 60%);
  color: oklch(96% 0.02 264);
  padding: var(--e-12) clamp(var(--e-6), 5vw, var(--e-16));
  flex-direction: column; justify-content: space-between;
}
@media (min-width: 940px) { .login-arte { display: flex; } }
/* Trama de tecido em escala grande — a peça vista de perto. */
.login-arte::before {
  content: ""; position: absolute; inset: -20%;
  background:
    repeating-linear-gradient(58deg, oklch(100% 0 0 / .05) 0 1px, transparent 1px 11px),
    repeating-linear-gradient(-58deg, oklch(100% 0 0 / .05) 0 1px, transparent 1px 11px);
  transform: rotate(-4deg);
}
.login-arte::after {
  content: ""; position: absolute; width: 420px; height: 420px;
  right: -140px; top: 12%;
  background: radial-gradient(circle, oklch(70% 0.14 75 / .22), transparent 65%);
  filter: blur(10px);
}
.login-arte > * { position: relative; z-index: 1; }
.login-arte h2 {
  font-size: clamp(var(--t-2xl), 3.4vw, var(--t-4xl));
  color: oklch(99% 0.01 264); max-width: 16ch;
}
.login-arte .lede { color: oklch(86% 0.045 264); margin-top: var(--e-4);
                    max-width: 44ch; font-size: var(--t-md); }
.login-arte ul { list-style: none; padding: 0; margin: var(--e-8) 0 0;
                 display: grid; gap: var(--e-4); }
.login-arte li { display: flex; gap: var(--e-3); align-items: flex-start;
                 font-size: var(--t-sm); color: oklch(88% 0.04 264); max-width: 42ch; }
.login-arte li b { color: oklch(99% 0.01 264); font-weight: var(--peso-forte); }
.login-arte li .m { color: var(--latao-300); flex: none; font-size: 1.05rem;
                    line-height: 1.4; }
.login-arte .rodape-arte { font-size: var(--t-2xs); color: oklch(72% 0.04 264); }

.login-form {
  display: flex; flex-direction: column; justify-content: center;
  padding: var(--e-10) clamp(var(--e-4), 5vw, var(--e-12));
  background: var(--superficie);
}
.login-caixa { width: 100%; max-width: 400px; margin: 0 auto; }
.login-caixa > .marca { margin-bottom: var(--e-8); }
.login-caixa h1 { font-size: var(--t-2xl); }
.login-caixa .sub { color: var(--tinta-2); margin-top: var(--e-2);
                    margin-bottom: var(--e-8); font-size: var(--t-sm); }

.abas { display: flex; gap: var(--e-1); padding: var(--e-1);
        background: var(--fundo-fundo); border-radius: var(--r-md);
        margin-bottom: var(--e-6); }
.aba {
  flex: 1; min-height: 44px; /* C-03: as abas da Conferencia e do login tambem sao alvo de dedo */
  padding: var(--e-2) var(--e-3); border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--tinta-2);
  font-size: var(--t-sm); font-weight: var(--peso-medio); cursor: pointer;
  transition: background-color var(--t-rapida), border-color var(--t-rapida), color var(--t-rapida), box-shadow var(--t-rapida), transform var(--t-rapida);
}
.aba[aria-selected="true"] { background: var(--superficie); color: var(--tinta);
                             font-weight: var(--peso-forte); box-shadow: var(--elev-1); }

.bt-google {
  display: flex; align-items: center; justify-content: center; gap: var(--e-3);
  width: 100%; min-height: var(--toque); padding: var(--e-3) var(--e-4);
  background: var(--superficie); color: var(--tinta);
  border: 1px solid var(--borda-forte); border-radius: var(--r-md);
  font-size: var(--t-md); font-weight: var(--peso-medio); cursor: pointer;
  transition: background-color var(--t-rapida), border-color var(--t-rapida), color var(--t-rapida), box-shadow var(--t-rapida), transform var(--t-rapida);
}
@media (hover: hover) { .bt-google:hover { background: var(--superficie-2); border-color: var(--tinta-3);
                   box-shadow: var(--elev-1); } }
.bt-google svg { width: 19px; height: 19px; flex: none; }

.divisor { display: flex; align-items: center; gap: var(--e-3);
           margin: var(--e-6) 0; color: var(--tinta-3); font-size: var(--t-2xs);
           text-transform: uppercase; letter-spacing: .1em; }
.divisor::before, .divisor::after { content: ""; flex: 1; height: 1px;
                                    background: var(--borda); }

.login-erro { color: var(--grave); font-size: var(--t-xs); min-height: 1.3em;
              margin-top: var(--e-2); }
.login-legal { margin-top: var(--e-8); font-size: var(--t-2xs);
               color: var(--tinta-3); line-height: var(--altura-normal); }

/* --------------------------------------------------------------------------
   Páginas legais — coluna de leitura, não de painel
   -------------------------------------------------------------------------- */
.legal { max-width: 74ch; }
.legal h2 { font-size: var(--t-xl); margin-top: var(--e-10); }
.legal h3 { font-size: var(--t-md); margin-top: var(--e-6);
            font-family: var(--fonte-ui); font-weight: var(--peso-forte); }
.legal p, .legal li { color: var(--tinta-2); margin-top: var(--e-3);
                      line-height: var(--altura-solta); }
.legal ul { padding-left: var(--e-5); margin: 0; }
.legal li { margin-top: var(--e-2); }
.legal strong { color: var(--tinta); font-weight: var(--peso-forte); }
.legal .selo {
  display: inline-flex; align-items: center; gap: var(--e-2);
  padding: var(--e-2) var(--e-4); border-radius: var(--r-md);
  background: var(--acento-tenue); color: var(--acento);
  font-size: var(--t-xs); font-weight: var(--peso-forte); margin-bottom: var(--e-6);
}
.legal .indice { display: grid; gap: var(--e-2); padding: var(--e-5);
                 background: var(--superficie-2); border-radius: var(--r-md);
                 margin: var(--e-6) 0; }
.legal .indice a { font-size: var(--t-sm); }

/* --------------------------------------------------------------------------
   Diversos
   -------------------------------------------------------------------------- */
.rota { display: flex; flex-wrap: wrap; gap: var(--e-1); align-items: center; }
.rota-item { font-size: var(--t-2xs); padding: 2px var(--e-2);
             border-radius: var(--r-sm); background: var(--neutro-bg);
             color: var(--tinta-2); font-weight: var(--peso-medio); }
.rota-seta { color: var(--borda-forte); font-size: var(--t-3xs); }

.carregando { display: flex; align-items: center; justify-content: center;
              gap: var(--e-3); color: var(--tinta-3); padding: var(--e-16) 0; }
.spin { width: 16px; height: 16px; border: 2px solid var(--borda-forte);
        border-top-color: var(--marca); border-radius: 50%;
        animation: gira .7s linear infinite; }
@keyframes gira { to { transform: rotate(360deg); } }

.vazio-msg { padding: var(--e-10) var(--e-4); text-align: center;
             color: var(--tinta-3); font-size: var(--t-sm); }

.nota-rodape { margin-top: var(--e-10); padding-top: var(--e-5);
               border-top: 1px solid var(--borda); font-size: var(--t-xs);
               color: var(--tinta-2); line-height: var(--altura-solta); }
.nota-rodape b { color: var(--tinta); }
code { font-family: var(--fonte-mono); font-size: .9em;
       background: var(--neutro-bg); padding: 1px var(--e-1);
       border-radius: var(--r-sm); }

/* --- kanban ---------------------------------------------------------------
   POR QUE TRILHO HORIZONTAL COM SNAP, E NÃO COLUNAS EMPILHADAS NO CELULAR

   O valor do kanban está na COMPARAÇÃO: "por que a costura tem tanta peça?" só
   existe como pergunta quando a costura está ao lado do silk. Empilhar troca
   comparação por memória — o gestor rola, esquece o número de cima e compara
   errado. O trilho preserva a metáfora espacial e o polegar já sabe usá-la.

   Duas defesas: a coluna mede `min(82vw, …)`, então a próxima sempre aparece
   pela beirada — é o que diz "tem mais à direita" sem barra de rolagem; e o
   `overflow-x` fica no trilho, com `overscroll-behavior-x: contain`, para o
   BODY nunca rolar de lado. Os totais de cada etapa também estão nos quatro
   indicadores do topo, que não exigem arrastar nada.
   -------------------------------------------------------------------------- */

.kb-filtro { display: flex; flex-wrap: wrap; align-items: center;
             gap: var(--e-2); margin-bottom: var(--e-5); }
.kb-filtro .rot { font-size: var(--t-2xs); text-transform: uppercase;
                  letter-spacing: .08em; color: var(--tinta-3);
                  margin-right: var(--e-1); }
.kb-chip {
  min-height: 44px; padding: var(--e-2) var(--e-4);
  border: 1px solid var(--borda); border-radius: var(--r-pilula);
  background: var(--superficie); color: var(--tinta-2);
  font-size: var(--t-sm); font-weight: var(--peso-medio); cursor: pointer;
  transition: background-color var(--t-rapida), border-color var(--t-rapida), color var(--t-rapida), box-shadow var(--t-rapida), transform var(--t-rapida);
}
@media (hover: hover) { .kb-chip:hover { border-color: var(--borda-forte); color: var(--tinta); } }
.kb-chip[aria-pressed="true"] { background: var(--marca-tenue);
                                border-color: var(--marca);
                                color: var(--marca-forte);
                                font-weight: var(--peso-forte); }

.kb-dica { display: none; }
@media (max-width: 760px) {
  .kb-dica { display: block; font-size: var(--t-2xs); color: var(--tinta-3);
             margin-bottom: var(--e-2); }
}

.kb-trilho {
  display: flex; gap: var(--e-4); align-items: stretch;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-bottom: var(--e-4);
  -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.kb-col {
  flex: 0 0 min(82vw, 300px); scroll-snap-align: start;
  display: flex; flex-direction: column;
  background: var(--superficie); border-radius: var(--r-lg);
  box-shadow: var(--elev-1); overflow: hidden;
}
@media (min-width: 900px) { .kb-col { flex: 0 0 268px; } }

.kb-topo { padding: var(--e-4); background: var(--superficie-2);
           border-top: 3px solid var(--borda-forte);
           border-bottom: 1px solid var(--borda); }
.kb-cab { display: flex; align-items: center; justify-content: space-between;
          gap: var(--e-2); margin-bottom: var(--e-3); }
.kb-cab h3 { font-size: var(--t-md); }
/* H.3 — o número da coluna aparecia "cortado no meio" no celular, e a causa não
   era a fonte: era a MÉTRICA. A Fraunces é uma serifa com ascendente e
   descendente generosos, e a soma passa de 1em; com `line-height: 1` a caixa de
   linha fica menor que o próprio glifo, e o `overflow: hidden` do `.kb-col`
   (necessário para o cantinho arredondado da coluna) fatiava o que sobrava.

   `line-height: 1.15` devolve a caixa ao tamanho do glifo, e o `letter-spacing`
   negativo sai: aperto de -0.02em ajuda título em caixa alta, e atrapalha
   dígito grande isolado, que precisa da própria largura para ler.

   A fonte fica em Fraunces de propósito. Este número é DISPLAY — um por coluna,
   sem nada com que alinhar verticalmente — e a serifa dá a presença que o
   Kanban quer. É por isso que ele segue na lista dos `tabular-nums` inertes
   (documentada em `fonts.css`): aqui a declaração é inofensiva, e trocar para
   mono custaria o peso visual sem ganhar alinhamento nenhum. */
.kb-n { font-family: var(--fonte-display); font-size: var(--t-3xl);
        line-height: 1.15; font-variant-numeric: tabular-nums;
        letter-spacing: 0; }
.kb-u { font-size: var(--t-3xs); color: var(--tinta-3);
        text-transform: uppercase; letter-spacing: .1em; margin-top: 2px; }
.kb-sub { font-size: var(--t-xs); color: var(--tinta-2); margin-top: var(--e-2); }

.kb-corpo { display: flex; flex-direction: column; flex: 1; }
.kb-lin { padding: var(--e-3) var(--e-4); min-height: 44px;
          border-bottom: 1px solid var(--borda-sutil); }
.kb-lin:last-child { border-bottom: 0; }
.kb-lin b { display: flex; align-items: baseline; justify-content: space-between;
            gap: var(--e-3); font-size: var(--t-sm);
            font-weight: var(--peso-forte); }
.kb-lin .meta { font-size: var(--t-2xs); color: var(--tinta-2); margin-top: 2px; }
.kb-lin.kb-sep { background: var(--superficie-2); color: var(--tinta-2);
                 border-top: 1px solid var(--borda); }
.kb-vazio { padding: var(--e-6) var(--e-4); text-align: center;
            color: var(--tinta-3); font-size: var(--t-xs); }

/* Gargalo é o único latão da tela — e latão, aqui, quer dizer "olhe para isto". */
.kb-col.gargalo { box-shadow: var(--elev-2); }
.kb-col.gargalo .kb-topo { background: var(--acento-tenue); }

/* Contorno tracejado: a coluna das perdidas não é uma etapa do processo, é a
   ausência de uma. A borda diz isso antes de qualquer rótulo. */
.kb-col.perdidas { background: var(--fundo-fundo);
                   outline: 1px dashed var(--borda-forte); outline-offset: -1px; }
.kb-col.perdidas .kb-topo { background: transparent; border-top-color: var(--acento); }

.kb-honesto { margin-top: auto; padding: var(--e-4);
              border-top: 1px solid var(--borda); background: var(--superficie-2);
              font-size: var(--t-2xs); color: var(--tinta-2);
              line-height: var(--altura-normal); }
.kb-honesto b { color: var(--tinta); }

/* ==========================================================================
   Barra inferior (tabbar) — navegação de polegar
   --------------------------------------------------------------------------
   Padrão de app de rede social, e a razão é ergonômica, não estética: o
   coletor usa isto de pé, na rua, com UMA mão. O topo da tela de um celular
   moderno está fora do alcance do polegar; a base, não.

   Só existe no celular. No desktop o menu do topo já resolve, e uma barra
   flutuante ali seria enfeite ocupando altura útil.
   ========================================================================== */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
  display: none; align-items: flex-end; justify-content: space-around;
  background: var(--superficie);
  border-top: 1px solid var(--borda);
  /* respeita a barra de gestos do iPhone — sem isto o último item fica
     debaixo do risquinho do sistema e não recebe toque */
  padding: var(--e-1) var(--e-1) calc(var(--e-1) + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -1px 12px oklch(0% 0 0 / .06);
}
.tabbar-item {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; padding: var(--e-2) var(--e-1);
  /* 56px: o alvo de toque que a spec do coletor exige (T5.6) */
  min-height: 56px;
  color: var(--tinta-3); text-decoration: none;
  font-size: var(--t-3xs); font-weight: var(--peso-medio);
  border-radius: var(--r-md); background: none; border: 0;
  -webkit-tap-highlight-color: transparent;
}
.tabbar-item .ic { font-size: 1.25rem; line-height: 1; }
.tabbar-item[aria-current="page"] { color: var(--marca); }
.tabbar-item[aria-current="page"] .ic { transform: translateY(-1px); }
.tabbar-item:active { background: var(--neutro-bg); }
.tabbar-rot { max-width: 100%; overflow: hidden; text-overflow: ellipsis;
              white-space: nowrap; }

/* O botão do meio: a câmera. Maior e em latão porque é a ação que o app
   existe para receber — fotografar o romaneio. */
.tabbar-cam {
  flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  background: none; border: 0; padding: 0 var(--e-2);
  color: var(--tinta-3); font-size: var(--t-3xs);
  font-weight: var(--peso-medio); font-family: inherit;
  -webkit-tap-highlight-color: transparent;
}
.tabbar-cam .bolha {
  width: 58px; height: 58px; margin-top: -22px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--marca); color: var(--papel-50);
  font-size: 1.6rem; line-height: 1;
  border: 4px solid var(--superficie);
  box-shadow: 0 4px 14px oklch(0% 0 0 / .22);
  transition: transform var(--t-rapida);
}
.tabbar-cam:active .bolha { transform: scale(.94); }

/* Contador de itens esperando rede. Só aparece quando há o que esperar —
   badge com zero é ruído que ensina a ignorar badge. */
.tabbar-badge {
  position: absolute; top: 4px; margin-left: 22px;
  min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center;
  background: var(--acento); color: var(--papel-900);
  border-radius: 9px; font-size: var(--t-3xs);
  font-weight: var(--peso-forte); font-variant-numeric: tabular-nums;
}

/* Folha de "Mais" — o resto da navegação, que não cabe em cinco slots. */
.folha-fundo { position: fixed; inset: 0; z-index: 70;
               background: oklch(0% 0 0 / .45); }
.folha {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 71;
  background: var(--superficie);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  border-top: 1px solid var(--borda);
  padding: var(--e-3) var(--e-4)
           calc(var(--e-6) + env(safe-area-inset-bottom, 0px));
  max-height: 76vh; overflow-y: auto;
  animation: folha-sobe var(--dur-lenta) var(--curva-entra);
}
/* Nome próprio desde a Frente D. Esta regra se chamava `sobe` — o mesmo nome da
   entrada em cascata dos cartões, declarada 900 linhas acima. Com dois
   `@keyframes` de mesmo nome o último vence os dois (a armadilha das duas
   classes com um nome só, agora em animação): todo cartão de toda grade entrava
   deslizando 100% da PRÓPRIA altura, em vez dos 6px desenhados. */
@keyframes folha-sobe { from { transform: translateY(100%); } to { transform: none; } }
@keyframes folha-fundo-entra { from { opacity: 0; } }
.folha-fundo:not([hidden]) { animation: folha-fundo-entra var(--dur-media) var(--curva-padrao); }

/* No desktop a folha deixa de subir do chao e vira painel ancorado ao topo,
   perto do botao que a abriu. Bottom sheet e gramatica de polegar; com ponteiro
   ela obriga o olho a atravessar a tela inteira ate o rodape para ler um menu
   que nasceu no cabecalho. Continua sendo o MESMO dialogo, com o mesmo
   conteudo — so o lugar muda. E nao cobre a tela: o contexto atras fica
   visivel, que e o que a diretriz de menu pede. */
@media (min-width: 901px) {
  .folha {
    left: auto; bottom: auto;
    top: calc(var(--faixa-h) + var(--topo-h) + var(--e-3));
    right: max(var(--e-4), env(safe-area-inset-right, 0px));
    width: min(360px, calc(100vw - var(--e-8)));
    border-radius: var(--r-lg);
    border: 1px solid var(--borda);
    box-shadow: var(--elev-2);
    max-height: min(70vh, 620px);
    padding: var(--e-3) var(--e-4) var(--e-4);
    animation: desce var(--t-saida);
  }
  .folha-puxador { display: none; }   /* nao ha o que arrastar com o ponteiro */
  .folha-fundo { background: oklch(0% 0 0 / .28); }
}
/* `desce` tinha duas declarações (a outra junto do menu suspenso, com -6px);
   ficou uma só, lá em cima. E a regra de movimento reduzido estava escrita duas
   vezes seguidas — a segunda, sem `!important`, não fazia nada. */
@media (prefers-reduced-motion: reduce) { .folha, .folha-fundo, .pagina { animation: none !important; } }
.folha-puxador { width: 44px; height: 4px; border-radius: 2px;
                 background: var(--acento); opacity: .55;
                 margin: 0 auto var(--e-4); }

/* H.2 — título de grupo do menu "Mais". Fraunces em itálico, latão, caixa alta:
   a mesma voz dos rótulos de seção do resto do app, num tamanho que separa sem
   competir com os itens. A regra fina acima repete a marca de seção do
   formulário de cadastros — uma linguagem só para "aqui começa outra coisa". */
.folha-grupo {
  font-family: var(--fonte-display); font-style: italic;
  font-size: var(--t-2xs); text-transform: uppercase; letter-spacing: .14em;
  color: var(--acento); font-weight: 600;
  margin: var(--e-4) 0 var(--e-1); padding-top: var(--e-3);
  border-top: 1px solid oklch(75% 0.06 75 / .15);
}
/* O primeiro grupo nao leva a regra de separacao acima dele — nao ha nada
   antes para separar. Era `.folha-grupo:first-of-type`, e essa regra NUNCA
   pegou: `:first-of-type` olha o tipo do elemento, e o `.folha-puxador` tambem
   e um `div`, entao o "primeiro div" do menu sempre foi ele. O primeiro grupo
   ficava com margem, padding e uma linha de latao orfa no topo — em celular e
   desktop, desde que os grupos existem. Ancorar no puxador, que esta sempre no
   DOM (so escondido no desktop), casa nos dois casos. */
.folha-puxador + .folha-grupo { margin-top: var(--e-1); padding-top: 0; border-top: 0; }

/* a barra inferior sai enquanto o diálogo está aberto — ver `abrirMais()` */
body.modal-aberto .tabbar { display: none; }
/* `:not(.bt)` desde 11/09 (F18): esta regra desenha os ITENS do menu, e pegava
   todo link dentro de uma folha. O `.folha a` (0,1,1) vencia o `.bt` (0,1,0):
   o botao "Enviar no WhatsApp" do recibo do Mover — e o "Cadastrar etapas" da
   folha sem destino, desde 10/09 — perdiam fundo e borda e viravam linha de menu. */
.folha a:not(.bt), .folha button.folha-item {
  display: flex; align-items: center; gap: var(--e-3);
  min-height: 52px; padding: var(--e-2) var(--e-2);
  color: var(--tinta); text-decoration: none;
  font-size: var(--t-md); font-weight: var(--peso-medio);
  border-bottom: 1px solid var(--borda);
  background: none; border-left: 0; border-right: 0; border-top: 0;
  width: 100%; font-family: inherit; text-align: left; cursor: pointer;
}
.folha a:not(.bt):last-of-type { border-bottom: 0; }
.folha .ic { font-size: 1.15rem; width: 1.5rem; text-align: center; }

/* 900px, e não 860px — alinhado em 07/09.
   A barra inferior aparecia até 860px e o topo só virava barra horizontal
   acima de 900px: entre 861 e 900 o app ficava sem barra E sem menu aberto,
   com a navegação inteira atrás do botão hambúrguer. Ninguém escolheu essa
   faixa; ela nasceu de dois números escritos em momentos diferentes para a
   mesma virada. Um tablet em retrato (768–900) cai exatamente ali.

   Agora há um ponto de virada só, e ele é o mesmo que o JS lê em `CELULAR` —
   o guard `menu` do smoke confere que os dois números continuam iguais. */
@media (max-width: 900px) {
  .tabbar { display: flex; }
  /* a barra flutua sobre o conteúdo: sem esta folga o último cartão da lista
     fica permanentemente escondido atrás dela */
  body { padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
  .app.limpo ~ .tabbar { display: none; }   /* tela de entrada é imersiva */
}
@media print { .tabbar, .folha, .folha-fundo { display: none !important; } }

/* --------------------------------------------------------------------------
   Ordem de serviço — desenhada para o PAPEL

   Esta é a única tela do sistema cujo leitor final não está no navegador: está
   na facção, com uma caneta na mão. Por isso o bloco `@media print` no fim não
   é acabamento — é o alvo, e o que aparece na tela é o rascunho dele.

   Duas armadilhas resolvidas aqui, e as duas só aparecem na impressora:

   1. **Tema escuro imprime escuro.** Os tokens viram tinta clara sobre fundo
      escuro; mandar isso para a impressora gasta um cartucho e sai ilegível. No
      print, a folha força preto sobre branco, independentemente do tema.
   2. **Uma OS por página.** `break-after: page` em cada folha, menos na última —
      sem isso, imprimir seis ordens dá seis folhas cortadas ao meio.
   -------------------------------------------------------------------------- */

.os-barra { display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-4);
            margin-bottom: var(--e-6); }
.os-barra .bt { width: auto; }
.os-aviso { font-size: var(--t-xs); color: var(--tinta-3); max-width: 46ch;
            line-height: var(--altura-normal); }

.os-folha {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--r-lg);
  box-shadow: var(--elev-1);
  padding: var(--e-8);
  max-width: 210mm;                 /* A4: a tela já mostra a largura da folha */
  margin: 0 auto var(--e-8);
}

.os-topo { display: flex; flex-wrap: wrap; gap: var(--e-4);
           justify-content: space-between; align-items: flex-start;
           padding-bottom: var(--e-4); border-bottom: 2px solid var(--tinta); }
.os-emissor b { display: block; font-family: var(--fonte-display);
                font-size: var(--t-lg); }
.os-emissor span { font-size: var(--t-2xs); color: var(--tinta-3);
                   letter-spacing: .06em; text-transform: uppercase; }
.os-id { text-align: right; }
.os-id .rot { display: block; font-size: var(--t-2xs); letter-spacing: .12em;
              text-transform: uppercase; color: var(--tinta-3); }
/* G.2: `OS-0009` -> `OS-0010` deslocava a coluna numa lista de ordens. Aqui a
   escolha e' mono e nao Inter: e' um CODIGO, e a OS ja usa mono em `.os-mini`. */
.os-codigo { display: block; font-family: var(--fonte-mono);
             font-size: var(--t-3xl); line-height: 1.05; font-weight: 600;
             font-variant-numeric: tabular-nums; }
.os-id .sub { font-size: var(--t-2xs); color: var(--tinta-2); }

.os-linha-status { display: flex; align-items: center; gap: var(--e-3);
                   flex-wrap: wrap; margin-top: var(--e-4); }
/* F18: sem telefone da faccao, o lugar do botao vira o recado de como cadastrar —
   ele desce para a linha de baixo em vez de espremer a etiqueta e o Imprimir */
.os-linha-status .wa-sem { flex-basis: 100%; margin: 0; }
/* No celular o botao do WhatsApp desce inteiro para a linha de baixo: ao lado da
   etiqueta e do Imprimir ele quebrava em tres linhas e empurrava a pagina para o
   lado (E2E de 11/09, gestor a 390px em Ordens de servico). */
@media (max-width: 900px) {
  .os-linha-status .bt-wa { flex-basis: 100%; margin-left: 0; }
}
.os-linha-status .bt { width: auto; margin-left: auto; }

.os-partes { display: grid; gap: var(--e-5);
             grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
             margin-top: var(--e-6); }
.os-campo .rot { display: block; font-size: var(--t-2xs); letter-spacing: .08em;
                 text-transform: uppercase; color: var(--tinta-3);
                 margin-bottom: 2px; }
.os-campo strong { font-size: var(--t-md); }
.os-campo .sub { display: block; font-size: var(--t-xs); color: var(--tinta-2); }

.os-quadro { display: grid; gap: var(--e-4); margin-top: var(--e-6);
             grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.os-cifra { border: 1px solid var(--borda); border-radius: var(--r-md);
            padding: var(--e-4); }
.os-cifra.destaque { border-width: 2px; border-color: var(--tinta);
                     background: var(--superficie-2); }
.os-cifra .rot { display: block; font-size: var(--t-2xs); letter-spacing: .08em;
                 text-transform: uppercase; color: var(--tinta-3); }
/* G.2: o caso mais forte dos quatro — esta cifra SAI DA TELA e vira papel na mao
   de quem assina na faccao. Duas cifras empilhadas (destaque + normal) que nao
   alinhavam, porque `tabular-nums` sobre a Fraunces e' inerte. */
.os-cifra strong { display: block; font-family: var(--fonte-mono);
                   font-size: var(--t-2xl); line-height: 1.1; font-weight: 600;
                   font-variant-numeric: tabular-nums; margin: 2px 0; }
.os-cifra.destaque strong { font-size: var(--t-3xl); }
.os-cifra .sub { font-size: var(--t-2xs); color: var(--tinta-2); }

.os-aceite { display: flex; gap: var(--e-4); align-items: flex-start;
             margin-top: var(--e-6); padding: var(--e-4);
             border: 1px solid var(--borda); border-radius: var(--r-md);
             background: var(--superficie-2); }
.os-check { flex: none; width: 34px; height: 34px; border: 2px solid var(--tinta);
            border-radius: var(--r-sm); display: flex; align-items: center;
            justify-content: center; font-size: var(--t-xl); line-height: 1;
            font-weight: var(--peso-forte); }
.os-aceite b { font-size: var(--t-sm); }
.os-aceite p { font-size: var(--t-xs); color: var(--tinta-2); margin-top: 2px; }

.os-devolucao { margin-top: var(--e-6); padding-top: var(--e-5);
                border-top: 1px dashed var(--borda-forte); }
.os-sec-rot { font-size: var(--t-2xs); letter-spacing: .12em;
              text-transform: uppercase; color: var(--tinta-3);
              margin-bottom: var(--e-4); }
.os-branco { display: grid; gap: var(--e-5);
             grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); }
.os-linha-campo { display: block; margin-bottom: var(--e-5); }
.os-linha-campo > span { display: block; font-size: var(--t-2xs);
                         color: var(--tinta-3); margin-bottom: var(--e-4); }
/* A linha para escrever à mão. Alta o bastante para caber caneta grossa em
   prancheta apoiada no joelho — que é onde isto vai ser preenchido. */
.os-linha { display: block; height: 0; border-bottom: 1px solid var(--tinta-3);
            margin-bottom: var(--e-6); }
.os-linha-campo.alta .os-linha:last-child { margin-bottom: var(--e-4); }
.os-assinaturas { display: grid; gap: var(--e-8);
                  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                  margin-top: var(--e-8); }
.os-assinaturas .os-linha { margin-bottom: var(--e-1); }
.os-assinaturas span { font-size: var(--t-2xs); color: var(--tinta-3); }

.os-anotacao { margin-top: var(--e-4); }
.os-anotacao .rot { display: block; font-size: var(--t-2xs); letter-spacing: .08em;
                    text-transform: uppercase; color: var(--tinta-3); }
.os-anotacao p { font-size: var(--t-sm); color: var(--tinta); margin-top: 2px; }

.os-rodape { margin-top: var(--e-6); padding-top: var(--e-4);
             border-top: 1px solid var(--borda); }
.os-rodape p { font-size: var(--t-2xs); color: var(--tinta-2);
               line-height: var(--altura-normal); }
.os-mini { font-family: var(--fonte-mono); font-size: var(--t-3xs);
           color: var(--tinta-3); margin-top: var(--e-2); }

@media print {
  @page { size: A4 portrait; margin: 14mm; }

  /* o cromo do app não vai para o papel */
  .topo, .nav, .rodape, .tabbar, .os-tela { display: none !important; }

  html, body {
    background: #fff !important;
    background-image: none !important;
  }
  body, .app, .app.limpo {
    margin: 0 !important; padding: 0 !important; max-width: none !important;
  }

  /* Preto sobre branco à força: sem isto, quem estiver no tema escuro imprime
     uma folha preta — e a impressora obedece. */
  .os-folha, .os-folha * {
    color: #000 !important;
    background: transparent !important;
    box-shadow: none !important;
  }
  .os-folha {
    border: none !important; border-radius: 0 !important;
    padding: 0 !important; margin: 0 !important; max-width: none !important;
    break-after: page; page-break-after: always;
  }
  .os-folha:last-child { break-after: auto; page-break-after: auto; }

  /* uma seção nunca deve começar no fim de uma página e terminar na seguinte */
  .os-quadro, .os-aceite, .os-devolucao, .os-assinaturas {
    break-inside: avoid; page-break-inside: avoid;
  }

  .os-topo { border-bottom: 2px solid #000 !important; }
  .os-cifra { border: 1px solid #555 !important; }
  .os-cifra.destaque { border: 2px solid #000 !important; }
  .os-aceite { border: 1px solid #555 !important; }
  .os-check { border: 2px solid #000 !important; }
  .os-devolucao { border-top: 1px dashed #555 !important; }
  .os-linha { border-bottom: 1px solid #000 !important; }
  .os-rodape { border-top: 1px solid #555 !important; }

  /* "Imprimir só esta": as demais folhas somem do trabalho de impressão */
  .os-raiz.imprimir-uma .os-folha:not(.so-esta) { display: none !important; }
}

/* --------------------------------------------------------------------------
   pedido novo — o cadastro que faltava
   --------------------------------------------------------------------------
   Duas exigências mandam neste bloco: a rota precisa ser LEGÍVEL enquanto é
   montada (é ela que carrega a decisão de modelagem), e todo alvo de toque
   passa de 44px, porque o gestor também abre isto no celular.
   -------------------------------------------------------------------------- */
.pn-peca {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--r-lg);
  padding: var(--e-5);
  margin-bottom: var(--e-4);
}
.pn-peca-topo {
  display: flex; align-items: center; gap: var(--e-3);
  flex-wrap: wrap; margin-bottom: var(--e-4);
}
.pn-peca-n { font-family: var(--fonte-display); font-size: var(--t-lg); }
.pn-peca-sub { font-size: var(--t-xs); color: var(--tinta-2); }
.pn-peca-topo .bt { margin-left: auto; }

.pn-grade {
  display: grid; gap: var(--e-3);
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}
/* dentro da grade o espaçamento é da própria grade — o do campo empilharia */
.pn-grade .campo { margin-bottom: 0; }

/* A grade do item (11/09, F12): um campo por tamanho, o tamanho em cima do
   número — como a grade se lê no papel. Quatro por linha a 390px. */
.pn-tams {
  display: grid; gap: var(--e-2);
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
}
.pn-tam { display: flex; flex-direction: column; gap: var(--e-1); margin: 0; }
.pn-tam > b {
  font-family: var(--fonte-mono); font-size: var(--t-sm); font-weight: var(--peso-forte);
  color: var(--tinta-2); text-align: center;
}
.pn-tam > input { text-align: center; font-variant-numeric: tabular-nums; }
/* a prévia da grade no cadastro do produto: os tamanhos como etiquetas */
.prd-grade-previa {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--e-1);
  margin-top: var(--e-2);
}
.prd-grade-n { font-size: var(--t-xs); color: var(--tinta-2); }

/* O fechamento por facção (F05 · SF-20, 11/09): os quatro filtros numa linha no
   desktop, dois por linha no celular — período, facção e etapa à vista. */
.fin-filtros {
  display: grid; gap: var(--e-3); margin-bottom: var(--e-4);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.fin-filtros .campo { margin-bottom: 0; }

.pn-rota {
  margin-top: var(--e-5); padding-top: var(--e-4);
  border-top: 1px dashed var(--borda-forte);
}
.pn-rot {
  font-size: var(--t-2xs); letter-spacing: .12em; text-transform: uppercase;
  color: var(--tinta-3); margin-bottom: var(--e-2);
}

.pn-trilha { display: flex; flex-wrap: wrap; gap: var(--e-2); margin: var(--e-3) 0; }
/* A borda esquerda leva a cor da etapa: a trilha se lê de relance, sem contar
   posição. Cor sem número seria enfeite — o número da ordem vem junto. */
.pn-passo {
  display: inline-flex; align-items: center; gap: var(--e-1);
  min-height: var(--toque); padding: var(--e-1) var(--e-2) var(--e-1) var(--e-3);
  border: 1px solid var(--borda-forte); border-left-width: 4px;
  border-radius: var(--r-md);
  background: var(--superficie-2);
}
.pn-ord {
  font-family: var(--fonte-mono); font-size: var(--t-2xs); color: var(--tinta-3);
  min-width: 1.2em; text-align: right;
}
.pn-nome { font-size: var(--t-sm); font-weight: var(--peso-medio); margin-right: var(--e-1); }

.pn-mini {
  min-width: 44px; min-height: 44px; padding: 0;
  border: none; background: transparent; cursor: pointer;
  color: var(--tinta-2); font-size: var(--t-lg); line-height: 1;
  border-radius: var(--r-sm);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
@media (hover: hover) { .pn-mini:hover { background: var(--neutro-bg); color: var(--tinta); } }
.pn-mini[disabled] { color: var(--borda-forte); cursor: not-allowed; }
.pn-mini.tirar { font-size: var(--t-md); }
@media (hover: hover) { .pn-mini.tirar:hover { color: var(--grave); } }

.pn-chips { display: flex; flex-wrap: wrap; gap: var(--e-2); }
.pn-chip {
  min-height: 44px; padding: var(--e-2) var(--e-4);
  border: 1px dashed var(--borda-forte); border-radius: var(--r-pilula);
  background: transparent; color: var(--tinta-2);
  font-size: var(--t-sm); font-weight: var(--peso-medio); cursor: pointer;
  transition: background-color var(--t-rapida), border-color var(--t-rapida), color var(--t-rapida), box-shadow var(--t-rapida), transform var(--t-rapida);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
@media (hover: hover) { .pn-chip:hover { border-style: solid; border-color: var(--marca);
                 color: var(--marca-forte); background: var(--marca-tenue); } }

.pn-rota-vazia {
  font-size: var(--t-sm); color: var(--tinta-2);
  padding: var(--e-3) var(--e-4); margin: var(--e-3) 0;
  border: 1px dashed var(--borda-forte); border-radius: var(--r-md);
  line-height: var(--altura-normal);
}

.pn-copia {
  display: flex; align-items: flex-end; gap: var(--e-3);
  flex-wrap: wrap; margin-top: var(--e-4);
}
.pn-copia-de { flex: 1 1 200px; }
.pn-copia-de > span {
  display: block; font-size: var(--t-2xs); color: var(--tinta-3);
  margin-bottom: var(--e-1);
}
.pn-copia .bt { width: auto; }

/* O sufixo "· peça 2" que desambigua cada rótulo repetido. Ele é informação de
   segunda ordem: precisa estar lá, e não pode competir com o nome do campo. */
.pn-de-quem { color: var(--tinta-3); font-weight: var(--peso-normal); }

/* A conta da peça, que anda enquanto se digita. Fica colada na grade de campos
   — o total longe dos números que o formam não é conferível de relance. */
.pn-total-item {
  display: flex; justify-content: space-between; align-items: baseline;
  flex-wrap: wrap; gap: var(--e-2) var(--e-4);
  margin-top: var(--e-4); padding-top: var(--e-3);
  border-top: 1px solid var(--borda);
  font-size: var(--t-sm); color: var(--tinta-2);
}
.pn-total-item > strong {
  color: var(--tinta); font-variant-numeric: tabular-nums;
}

/* O botão de acrescentar e o teto na mesma linha: o limite se lê no lugar em
   que a decisão de acrescentar é tomada, não num rodapé. */
.pn-acrescentar {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--e-2) var(--e-4);
}
.pn-acrescentar .bt { width: auto; }
.pn-limite { font-size: var(--t-xs); color: var(--tinta-2); }
.pn-limite > strong { color: var(--tinta); font-variant-numeric: tabular-nums; }
.pn-limite.perto > strong { color: var(--atencao); }
.pn-limite.cheio > strong { color: var(--grave); }

/* Os botões compactos do cartão de peça ("Remover peça 2", "Usar a rota da peça
   2 em todas") nasciam com os 38px da variante compacta — abaixo do piso da
   casa. Medido no Chromium a 390px: eram os únicos alvos da tela sob 44px, e
   "Remover" errado por dedo grosso apaga trabalho já digitado. */
.pn-peca .bt.compacto { min-height: 44px; }

.pn-linha {
  display: flex; justify-content: space-between; gap: var(--e-4);
  padding: var(--e-2) 0; border-bottom: 1px solid var(--borda);
}
.pn-linha:last-child { border-bottom: none; }
.pn-linha > span { color: var(--tinta-2); font-size: var(--t-sm); }
.pn-linha > strong { text-align: right; font-variant-numeric: tabular-nums; }

/* --------------------------------------------------------------------------
   --- lote novo ---
   Tela do GESTOR: uma página, sentado, com o pedido na frente. Por isso ela
   pode ter campo numérico e lista densa — coisas que o fluxo do coletor recusa
   de propósito. O que ela herda do coletor é só o alvo grande: o Kaio também
   abre lote do celular, entre uma coisa e outra.
   -------------------------------------------------------------------------- */
.ln-saldo {
  display: flex; flex-wrap: wrap; gap: var(--e-2) var(--e-5);
  padding-top: var(--e-3); border-top: 1px solid var(--borda);
  font-size: var(--t-xs); color: var(--tinta-2);
}
.ln-saldo strong { font-family: var(--fonte-mono); color: var(--tinta);
                   font-variant-numeric: tabular-nums; }

.ln-var {
  display: flex; align-items: center; gap: var(--e-3);
  padding: var(--e-3) var(--e-4);
  border-bottom: 1px solid var(--borda);
  /* a linha inteira é o alvo: marcar peça com o polegar não pode exigir
     acertar um quadradinho de 16px */
  min-height: var(--toque);
}
.ln-var:last-child { border-bottom: none; }
.ln-var.on { background: var(--marca-tenue); }

.ln-var-alvo { display: flex; align-items: center; gap: var(--e-3);
               flex: 1; min-width: 0; cursor: pointer; padding: var(--e-2) 0; }
.ln-var-alvo input[type="checkbox"] {
  width: 22px; height: 22px; flex: none; accent-color: var(--marca); cursor: pointer;
}
.ln-var-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ln-var-txt strong { font-size: var(--t-sm); }
.ln-var-txt span { font-size: var(--t-xs); color: var(--tinta-2); }
.ln-var-txt .rota { margin-top: 2px; }

.ln-var-qtd { display: flex; flex-direction: column; align-items: flex-end;
              gap: 2px; flex: none; }
.ln-qtd {
  width: 96px; min-height: 44px; padding: var(--e-2) var(--e-3);
  text-align: right;
  font-family: var(--fonte-mono); font-size: var(--t-md);
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--borda-forte); border-radius: var(--r-md);
  background: var(--superficie); color: var(--tinta);
}
.ln-qtd:disabled { background: var(--superficie-2); color: var(--tinta-3); }
.ln-var-de { font-size: var(--t-3xs); color: var(--tinta-3);
             font-variant-numeric: tabular-nums; }

.ln-total {
  margin-top: var(--e-4); padding: var(--e-5);
  border: 1px solid var(--borda-forte); border-radius: var(--r-lg);
  background: var(--superficie); text-align: center;
}
.ln-total-rot { font-size: var(--t-2xs); letter-spacing: .08em;
                text-transform: uppercase; color: var(--tinta-3); }
.ln-total-n {
  font-family: var(--fonte-display); font-weight: var(--peso-display);
  font-size: var(--t-3xl); line-height: 1.1; color: var(--tinta);
  font-variant-numeric: tabular-nums;
}
.ln-total-nota { font-size: var(--t-xs); color: var(--tinta-2); }
.ln-total-nota.alerta { color: var(--atencao); font-weight: var(--peso-forte); }

.ln-erro:empty { display: none; }
.ln-erro { font-size: var(--t-xs); color: var(--tinta-2); margin-bottom: var(--e-2); }
.ln-erro.api { color: var(--grave); font-weight: var(--peso-forte); }

.ln-codigo {
  font-family: var(--fonte-mono); font-size: var(--t-xl);
  letter-spacing: .04em; color: var(--marca-forte);
  margin-top: var(--e-3);
}

/* --------------------------------------------------------------------------
   --- cadastros ---
   Ambiente de CONFIGURAÇÃO, não de operação de todo dia (ADR-032, Decisão 4:
   "cadastro é operação rara, vive dentro de configuração"). Por isso pode ter
   lista densa e formulário longo — o que não pode ter é alvo pequeno: o Kaio
   também abre isto do celular, entre uma facção e outra.
   -------------------------------------------------------------------------- */
.cad-abas {
  display: flex; gap: var(--e-2);
  margin-bottom: var(--e-6);
  border-bottom: 1px solid var(--borda);
  /* as abas têm de caber em qualquer tela (com quatro, desde 11/09, só cabem a
     390px pelo bloco de 520px abaixo); o rolo é a rede para quando não couberem
     — aba cortada pela margem é aba que ninguém descobre que existe */
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.cad-abas::-webkit-scrollbar { display: none; }

.cad-aba {
  display: inline-flex; align-items: center; gap: var(--e-2);
  min-height: 48px; padding: var(--e-2) var(--e-4);
  border: none; border-bottom: 2px solid transparent;
  background: transparent; cursor: pointer; white-space: nowrap;
  color: var(--tinta-2); font-size: var(--t-md); font-weight: var(--peso-medio);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: color var(--t-rapida), border-color var(--t-rapida);
}
@media (hover: hover) { .cad-aba:hover { color: var(--tinta); } }
.cad-aba.on { color: var(--marca-forte); border-bottom-color: var(--marca);
              font-weight: var(--peso-forte); }
.cad-aba-n {
  font-family: var(--fonte-mono); font-size: var(--t-2xs);
  font-variant-numeric: tabular-nums;
  padding: 1px var(--e-2); border-radius: var(--r-pilula);
  background: var(--neutro-bg); color: var(--tinta-3);
}
.cad-aba.on .cad-aba-n { background: var(--marca-fraca); color: var(--marca-forte); }
/* 11/09: a aba Clientes fez quatro. A 390px as quatro somavam ~500px, "Preços"
   saía cortada e "Etapas" sumia atrás da margem — visto na tela, não no smoke.
   No celular elas dividem a largura em partes iguais, a contagem sob o nome. */
/* 16/09 (Frente 7): "Quem leva as peças" fez seis, e seis em partes iguais dão
   ~55px a 390 — a de nome mais longo transbordaria a própria aba e o rolo
   voltaria a esconder alguma. Três por linha, em duas linhas, com o nome
   quebrando dentro da aba: nenhuma fica atrás da margem. */
@media (max-width: 520px) {
  .cad-abas { gap: 0; flex-wrap: wrap; overflow-x: visible; }
  .cad-aba { flex: 1 1 33%; min-width: 0; flex-direction: column; justify-content: center;
             gap: 2px; padding: var(--e-2) var(--e-1); font-size: var(--t-sm);
             white-space: normal; text-align: center; line-height: 1.15; }
}

/* --- formulário em cartão ------------------------------------------------- */
/* Rodada H: mais respiro. Esta e' a tela onde o cliente cadastra as primeiras
   facoes — se ela parecer apertada, ele para no meio. O fio de latao sob o
   rotulo separa as secoes sem precisar de mais uma borda. */
.cad-form {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--r-lg);
  padding: var(--e-6);
  margin-bottom: var(--e-6);
  box-shadow: var(--elev-1);
}
.cad-rot {
  font-size: var(--t-2xs); letter-spacing: .12em; text-transform: uppercase;
  color: var(--tinta-3); margin-bottom: var(--e-5);
  padding-bottom: var(--e-3);
  border-bottom: 1px solid var(--borda-sutil);
  position: relative;
}
.cad-rot::after {
  content: ""; position: absolute; left: 0; bottom: -1px;
  width: 34px; height: 1px; background: var(--acento);
}
.cad-grade {
  display: grid; gap: var(--e-5);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
/* dentro da grade o espaçamento é da própria grade — o do campo empilharia */
.cad-grade .campo { margin-bottom: 0; }

/* O seletor de cor do navegador ignora padding e vem minúsculo por padrão;
   sem altura explícita ele é o único alvo da tela abaixo dos 44px. */
.cad-cor {
  width: 100%; min-height: var(--toque); padding: var(--e-1);
  border: 1px solid var(--borda-forte); border-radius: var(--r-md);
  background: var(--superficie); cursor: pointer;
}

.cad-troca {
  display: flex; align-items: center; gap: var(--e-3);
  min-height: var(--toque); cursor: pointer;
  font-size: var(--t-sm); color: var(--tinta-2);
  line-height: var(--altura-normal);
}
.cad-troca input[type="checkbox"] {
  width: 22px; height: 22px; flex: none; accent-color: var(--marca); cursor: pointer;
}

/* --- chips de especialidade ----------------------------------------------- */
.cad-chips { display: flex; flex-wrap: wrap; gap: var(--e-2); }
.cad-chip {
  min-height: 44px; padding: var(--e-2) var(--e-4);
  border: 1px dashed var(--borda-forte); border-radius: var(--r-pilula);
  background: transparent; color: var(--tinta-2);
  font-size: var(--t-sm); font-weight: var(--peso-medio); cursor: pointer;
  transition: background-color var(--t-rapida), border-color var(--t-rapida), color var(--t-rapida), box-shadow var(--t-rapida), transform var(--t-rapida);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
@media (hover: hover) { .cad-chip:hover { border-style: solid; border-color: var(--marca); color: var(--marca-forte); } }
/* marcado é sólido e não só colorido: cor sozinha não se lê no sol do galpão,
   nem por quem não distingue as duas */
.cad-chip.on {
  border-style: solid; border-color: var(--marca);
  background: var(--marca); color: var(--tinta-inversa);
  font-weight: var(--peso-forte);
}

/* --- itens da lista -------------------------------------------------------- */
/* Rodada H: hover sutilíssimo — borda que esquenta para latão, nada de sombra
   nem deslocamento. A lista de facções é onde o cliente confere o que acabou de
   cadastrar; ela precisa responder ao ponteiro sem parecer que vai sair do lugar. */
.cad-item {
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-radius: var(--r-md);
  padding: var(--e-5);
  margin-bottom: var(--e-3);
  transition: border-color var(--t-rapida), background var(--t-rapida);
}
@media (hover: hover) { .cad-item:hover { border-color: var(--acento-fraco); background: var(--acento-tenue); } }
@media (hover: hover) { .cad-item.off:hover { background: var(--superficie-2); border-color: var(--borda-forte); } }
/* inativa continua legível, só recua: ela ainda explica o histórico */
.cad-item.off { background: var(--superficie-2); border-style: dashed; }
.cad-item.off .cad-item-n { color: var(--tinta-2); }

.cad-item-topo {
  display: flex; align-items: center; gap: var(--e-3);
  flex-wrap: wrap;
}
.cad-item-n { font-family: var(--fonte-display); font-size: var(--t-lg);
              font-weight: var(--peso-display); }
.cad-item-ord { font-size: var(--t-2xs); color: var(--tinta-3);
                font-variant-numeric: tabular-nums; }
.cad-item-topo .bt { margin-left: auto; }
.cad-item-sub { font-size: var(--t-xs); color: var(--tinta-2); margin-top: var(--e-1); }
.cad-item-sub.fraco { color: var(--tinta-3); }
.cad-esp { display: flex; flex-wrap: wrap; gap: var(--e-1); margin-top: var(--e-2); }

.cad-etapa-cor {
  width: 14px; height: 14px; flex: none; border-radius: var(--r-sm);
  border: 1px solid var(--borda-forte);
}

/* --- preços ---------------------------------------------------------------- */
.cad-preco {
  display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap;
  background: var(--superficie);
  border: 1px solid var(--borda);
  border-left: 4px solid var(--ok);
  border-radius: var(--r-md);
  padding: var(--e-3) var(--e-4);
  margin-bottom: var(--e-2);
  min-height: var(--toque);
}
/* a vigência encerrada NÃO é apagada nem escondida: ela é a prova de que o
   relatório do mês passado usou o número daquele mês (RF-09) */
.cad-preco.off { border-left-color: var(--borda-forte); background: var(--superficie-2); }

.cad-preco-quem { display: flex; flex-direction: column; gap: 1px;
                  flex: 1 1 160px; min-width: 0; }
.cad-preco-quem strong { font-size: var(--t-sm); }
.cad-preco-quem span { font-size: var(--t-xs); color: var(--tinta-2); }
/* G.2: dinheiro numa lista de precos por faccao — empilhado, precisa alinhar.
   Plex Mono, pelo mesmo motivo de `.reg-qtd .n`. */
.cad-preco-val {
  font-family: var(--fonte-mono); font-size: var(--t-lg); font-weight: 600;
  font-variant-numeric: tabular-nums; flex: none;
}
.cad-preco.off .cad-preco-val { color: var(--tinta-2); }
.cad-preco-vig { display: flex; align-items: center; gap: var(--e-2);
                 flex: 1 1 180px; justify-content: flex-end; }
.cad-preco-vig span { font-size: var(--t-xs); color: var(--tinta-3);
                      font-variant-numeric: tabular-nums; }

/* --- linha rótulo/valor e estado vazio ------------------------------------ */
.cad-linha {
  display: flex; justify-content: space-between; gap: var(--e-4);
  padding: var(--e-2) 0; border-bottom: 1px solid var(--borda);
}
.cad-linha:last-child { border-bottom: none; }
.cad-linha > span { color: var(--tinta-2); font-size: var(--t-sm); }
.cad-linha > strong { text-align: right; font-variant-numeric: tabular-nums; }

.cad-vazio {
  font-size: var(--t-sm); color: var(--tinta-2);
  padding: var(--e-4); margin-bottom: var(--e-4);
  border: 1px dashed var(--borda-forte); border-radius: var(--r-md);
  line-height: var(--altura-normal);
}

@media (max-width: 520px) {
  /* no celular a vigência desce para a linha de baixo em vez de espremer o
     valor: preço cortado ao meio é o único número desta tela que não pode
     ficar ambíguo */
  .cad-preco-vig { justify-content: flex-start; flex-basis: 100%; }
}

/* ==========================================================================
   Ícones — SVG de traço, no lugar do emoji
   --------------------------------------------------------------------------
   `vertical-align` e não flex solto: o ícone aparece dentro de linha de texto
   em botão, aviso e item de menu, e sem isto ele senta na linha de base e
   empurra a linha inteira alguns pixels para cima.

   `flex: none` porque em `.aviso` o ícone divide espaço com um parágrafo que
   cresce — sem isso ele é o primeiro a ser espremido, e vira um risco.
   ========================================================================== */
.ic-svg { display: inline-block; vertical-align: -0.15em; flex: none; }
.aviso .em, .aviso .ic-svg { margin-top: 1px; }
.tabbar-item .ic, .tabbar-cam .bolha, .folha .ic {
  display: inline-flex; align-items: center; justify-content: center;
}
/* o ícone do tema é montado em runtime; o botão precisa de altura antes disso */
#btTema { display: inline-flex; align-items: center; justify-content: center; }

/* Contextos onde o ícone entrou no lugar do emoji e precisa de alinhamento
   próprio: o emoji ocupava a caixa toda da linha; o SVG não. */
.acao .ic, .login-arte li .m { display: inline-flex; align-items: center;
                              justify-content: center; }
.legal .selo { display: flex; align-items: center; gap: var(--e-2); }


/* --------------------------------------------------------------------------
   A GRADE POR TAMANHO — 07/09
   --------------------------------------------------------------------------
   Uma linha por tamanho, com a mesma gramatica do contador unico: botao
   grande, sem teclado, alvo de 44px. O cliente foi explicito sobre por que o
   contador unico nao servia — "como eu sei se e no P, no M, no G?" — e sobre a
   grade ser dinamica: camiseta traz P/M/G, calca traz 38/40/42.

   O numero e mono e tabular: numa coluna de tamanhos, digito que dança faz
   parecer que o valor mudou quando so mudou a largura do algarismo.
   -------------------------------------------------------------------------- */
.grade { display: flex; flex-direction: column; gap: var(--e-2); }
.grade-linha {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e-3); flex-wrap: wrap;
  padding: var(--e-3);
  border: 1px solid var(--borda); border-radius: var(--r-md);
  background: var(--superficie);
}
.grade-rot { display: flex; align-items: baseline; gap: var(--e-2); min-width: 5.5rem; }
.grade-rot b { font-size: var(--t-lg); font-weight: var(--peso-medio); }
.grade-esperado { font-size: var(--t-2xs); color: var(--tinta-3);
                  font-family: var(--fonte-mono); font-variant-numeric: tabular-nums; }
.grade-cont { display: flex; align-items: center; gap: var(--e-2); margin-left: auto; }
.grade-n {
  min-width: 3.6rem; text-align: center;
  font-family: var(--fonte-mono); font-variant-numeric: tabular-nums;
  font-size: var(--t-lg); font-weight: var(--peso-medio); color: var(--tinta);
}
.grade-n.neg { color: var(--grave); }
/* `--alerta` nunca existiu (Frente D): o tamanho contado A MAIS saía na cor do
   texto, igual ao que confere. É o laranja da sobra (RN-09). */
.grade-n.mais { color: var(--laranja); }

.grade-total {
  display: flex; align-items: baseline; gap: var(--e-3); flex-wrap: wrap;
  margin-top: var(--e-2); padding-top: var(--e-3);
  border-top: 1px solid oklch(75% 0.06 75 / .25);
}
.grade-total-rot { font-size: var(--t-xs); color: var(--tinta-2);
                   text-transform: uppercase; letter-spacing: .1em; }
.grade-total-n { font-family: var(--fonte-mono); font-variant-numeric: tabular-nums;
                 font-size: var(--t-2xl); font-weight: var(--peso-medio); }
.grade-total-dif { font-size: var(--t-xs); color: var(--tinta-2); margin-left: auto; }
.grade-total-dif.zero { color: var(--ok); }
.grade-total-dif.neg { color: var(--grave); }

/* No celular o rotulo fica em cima e os botoes ocupam a linha inteira: com
   cinco alvos de 44px numa linha de 360px, nao cabe o nome do tamanho junto. */
@media (max-width: 420px) {
  .grade-linha { flex-direction: column; align-items: stretch; gap: var(--e-2); }
  .grade-cont { margin-left: 0; justify-content: space-between; }
  .grade-n { flex: 1; }
}


/* Lote que esta na etapa mas cuja saida nao foi registrada — 08/09.
   Borda tracejada em latao: presente no quadro, e visivelmente incompleto.
   O cliente procurou o lote dele "no corte" e nao encontrou nada, porque o
   quadro so lia `remessas`. Agora ele aparece, e diz o que falta. */
.kb-lin.kb-sem-saida {
  border-style: dashed;
  border-color: oklch(75% 0.09 75 / .55);
  background: oklch(97% 0.02 75 / .5);
}
.kb-aviso { display: flex; align-items: center; gap: var(--e-2);
            flex-wrap: wrap; margin-top: var(--e-2); }
.kb-atalho { font-size: var(--t-2xs); color: var(--acento);
             text-decoration: underline; text-underline-offset: 2px; }


/* --------------------------------------------------------------------------
   ARRASTAR entre etapas no kanban — 08/09, escolhido pelo cliente
   -------------------------------------------------------------------------- */
.kb-lin.kb-movivel { cursor: grab; }
.kb-lin.kb-movivel:active { cursor: grabbing; }
.kb-lin.arrastando { opacity: .45; }
.kb-col.kb-alvo {
  outline: 2px dashed var(--acento);
  outline-offset: -4px;
  background: var(--acento-tenue);
}
/* O botao "mover" e o caminho de quem nao arrasta: dedo no celular, teclado no
   desktop. Discreto no repouso, visivel ao passar e SEMPRE presente ao foco —
   controle que so aparece no hover nao existe para quem navega por Tab.
   `.kb-em-casa` (a etapa feita em casa, DT-21) tem o mesmo desenho e classe própria. */
.kb-mover, .kb-em-casa {
  /* C-03 (13/09): 44px em toda largura, nao so no celular — media 29px no desktop */
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-height: 44px; min-width: 44px;
  margin-top: var(--e-2); padding: 4px var(--e-3);
  border: 1px solid var(--borda); border-radius: var(--r-sm);
  background: transparent; color: var(--tinta-2);
  font-family: inherit; font-size: var(--t-2xs); cursor: pointer;
  opacity: .75; transition: opacity var(--t-rapida), border-color var(--t-rapida);
}
.kb-mover:focus-visible, .kb-em-casa:focus-visible {
  opacity: 1; border-color: var(--acento); color: var(--acento);
}
@media (hover: hover) { .kb-lin:hover .kb-mover, .kb-lin:hover .kb-em-casa {
  opacity: 1; border-color: var(--acento); color: var(--acento);
} }
@media (max-width: 900px) { .kb-mover, .kb-em-casa { opacity: 1; min-height: var(--toque); } }

.kb-folha-tit { font-family: var(--fonte-display); font-size: var(--t-xl); margin: 0 0 var(--e-1); }

/* C-05 (13/09): a faixa da versao nova. Embaixo, onde o polegar alcanca, e acima da
   barra inferior do celular — nunca por cima dela. */
.versao-nova {
  position: fixed; z-index: 70; left: 50%; transform: translateX(-50%);
  bottom: var(--e-5); width: min(560px, calc(100% - 2 * var(--e-4)));
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-3);
  padding: var(--e-3) var(--e-4); border-radius: var(--r-md);
  background: var(--superficie); color: var(--tinta);
  border: 1px solid var(--acento); box-shadow: var(--elev-2, var(--elev-1));
  font-size: var(--t-sm);
}
.versao-nova .bt { flex: 0 0 auto; }
@media (max-width: 900px) {
  .versao-nova { bottom: calc(76px + env(safe-area-inset-bottom, 0px)); flex-wrap: wrap; }
}
.kb-folha-sub { color: var(--tinta-2); font-size: var(--t-sm); margin: 0 0 var(--e-4); }
.kb-qtd { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.kb-qtd-n {
  flex: 1; min-width: 4.5rem; text-align: center;
  font-family: var(--fonte-mono); font-variant-numeric: tabular-nums;
  font-size: var(--t-2xl); font-weight: var(--peso-medio);
}

/* --------------------------------------------------------------------------
   O PRAZO EM PALAVRAS — Vencido · Vence hoje · No prazo · Sem prazo (RNF-07)

   Aqui a cor virou o que sempre deveria ter sido: reforço. A etiqueta continua
   com o tom e com o pontinho colorido, mas quem carrega o recado é o texto —
   que funciona para quem não separa as cores, para quem lê no sol e para o
   papel preto e branco da OS.

   O detalhe ("há 5 dias", "faltam 3 dias") fica FORA da etiqueta de propósito:
   `.tag` não quebra linha, e a coluna do kanban no celular é estreita. Assim a
   palavra sobrevive inteira e o detalhe desce para a linha seguinte.
   -------------------------------------------------------------------------- */
.selo-prazo { display: inline-flex; align-items: center; gap: var(--e-1);
              flex-wrap: wrap; }
.selo-det { font-size: var(--t-2xs); color: var(--tinta-2); }
.kb-prazo { display: flex; flex-wrap: wrap; gap: var(--e-1);
            margin-top: var(--e-2); }

/* --------------------------------------------------------------------------
   Campo de sugestão — a lista que aceita o que não está nela (RF-03 / B3)

   A lista fica NO FLUXO, e não `position: absolute`. Flutuar seria mais bonito
   no desktop e é exatamente o defeito que já custou uma sessão aqui: o que
   transborda de um contêiner com recorte não rola — some. Este campo nasceu
   para viver dentro de folha, cartão e modal, todos com recorte próprio. Em
   fluxo ele empurra o formulário para baixo, o que é feio e sempre visível;
   flutuando, ele desapareceria em algumas telas e em outras não.
   -------------------------------------------------------------------------- */
.sug { position: relative; }

.sug-lista {
  list-style: none;
  margin: var(--e-2) 0 0;
  padding: var(--e-1);
  border: 1px solid var(--borda-forte);
  border-radius: var(--r-md);
  background: var(--superficie);
  box-shadow: var(--elev-2);
  /* Teto em altura, rolagem DENTRO da própria caixa: a página nunca rola na
     horizontal nem estica sem fim por causa de um campo. */
  max-height: 17rem;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.sug-lista[hidden] { display: none; }

.sug-opcao {
  display: flex; align-items: center;
  min-height: var(--toque);
  padding: var(--e-2) var(--e-3);
  border-radius: var(--r-sm);
  font-size: var(--t-md); color: var(--tinta);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
/* `.ativa` é o destaque do TECLADO e `:hover` o do ponteiro — mesma pintura de
   propósito: quem alterna entre os dois não deve aprender duas linguagens. */
.sug-opcao.ativa {
  background: var(--acento-tenue); color: var(--acento);
}
@media (hover: hover) { .sug-opcao:hover {
  background: var(--acento-tenue); color: var(--acento);
} }

.sug-mais {
  padding: var(--e-2) var(--e-3);
  font-size: var(--t-2xs); color: var(--tinta-3);
}

/* O aviso reserva a própria altura mesmo vazio. Sem isto, "Nova opção…"
   aparecendo empurra o botão de salvar no instante em que o polegar já está a
   caminho dele — e a pessoa toca no que veio parar no lugar. */
.sug-aviso {
  min-height: 1.35em; margin-top: var(--e-2);
  font-size: var(--t-xs); color: var(--tinta-2);
  line-height: var(--altura-normal);
}
.sug-aviso.nova { color: var(--acento); font-weight: var(--peso-forte); }
.sug-aviso.mesma { color: var(--ok); }

/* ==========================================================================
   B8/B9 — a lista vazia diz o próximo passo; a ação diz o efeito antes
   --------------------------------------------------------------------------
   `.vazio-passo` é o estado vazio que não é beco: o motivo numa frase, o que
   vem depois e o caminho até lá. Alinhado à esquerda, e não centralizado como
   o `.vazio-msg` — duas linhas centralizadas se leem como aviso de erro, e
   isto é orientação.

   `.efeito` é a consequência dita antes do toque. Discreta de propósito: não
   é aviso nem alerta, é a linha que o cliente pôs no sistema dele perto do
   botão. Se gritasse, viraria mais uma coisa disputando a tela — que é
   exatamente a reclamação dele.
   ========================================================================== */
.vazio-passo {
  padding: var(--e-5);
  font-size: var(--t-sm); color: var(--tinta-2);
  line-height: var(--altura-normal);
}
.vazio-passo p { max-width: 62ch; }
.vazio-passo .vazio-porque { color: var(--tinta); font-weight: var(--peso-forte); }
.vazio-passo .vazio-seguinte { margin-top: var(--e-1); }
.vazio-passo .bt { width: auto; margin-top: var(--e-4); }
.vazio-passo .vazio-dono { margin-top: var(--e-3); font-size: var(--t-xs); color: var(--tinta-3); }
/* dentro de um campo de formulário: sem moldura, colado no controle vazio */
.vazio-passo.compacto { padding: var(--e-3) 0 0; font-size: var(--t-xs); }
.vazio-passo.compacto .bt { margin-top: var(--e-3); }
/* no celular o passo seguinte é a ação da tela: largura inteira, no polegar */
@media (max-width: 900px) {
  .vazio-passo .bt { width: 100%; }
}

/* célula ou trilha sem item: "sem rota definida", "nenhuma marcada" */
.vazio-curto { font-size: var(--t-xs); color: var(--tinta-3); }

.efeito {
  display: flex; gap: var(--e-2); align-items: flex-start;
  margin-top: var(--e-4); max-width: 68ch;
  font-size: var(--t-xs); color: var(--tinta-2);
  line-height: var(--altura-normal);
}
.efeito .ic-svg { margin-top: 2px; color: var(--tinta-3); }
/* logo abaixo de um título de seção, a linha fala da lista que vem: cola nela */
.sec-titulo + .efeito { margin: calc(-1 * var(--e-2)) 0 var(--e-3); }
/* dentro do campo, a ajuda que vem DEPOIS do controle troca o respiro de lado */
.campo .ajuda.depois { display: block; margin: var(--e-2) 0 0; }

/* ==========================================================================
   FRENTE D — o sistema de componentes (16/09)
   --------------------------------------------------------------------------
   Cada bloco abaixo tem um dono em `assets/js/componentes.js`, com o mesmo
   nome. A regra da casa continua: nenhum valor cru — se precisou de número,
   faltou token. E nenhum nome reusado: antes de criar, o nome foi procurado no
   CSS inteiro (a armadilha do `.grade` de 11/09, e a do `@keyframes sobe`
   consertada acima).
   ========================================================================== */

/* --- olho da página: em que parte do app a pessoa está --------------------
   O shell escreve, acima de toda tela, o GRUPO do menu a que ela pertence
   ("Produção", "Pedidos", "Conferência"). É o mesmo nome que a pessoa tocou no
   menu, e responde "onde estou?" sem breadcrumb. Fica fora da view de
   propósito: as telas de passo redesenham o próprio conteúdo a cada toque, e um
   olho dentro delas sumiria no segundo passo. */
.pagina-olho {
  display: flex; align-items: center; gap: var(--e-2);
  font-size: var(--t-3xs); font-weight: var(--peso-forte);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--acento); margin: 0 0 var(--e-3);
}
.pagina-olho::before { content: ""; width: 18px; height: 1.5px; background: var(--acento); }

/* --- cabeçalho com ação principal ----------------------------------------
   `.cabeca` continua sendo o cabeçalho de página. O `cabecalho()` do
   componentes.js acrescenta só a linha de ação ao lado do título no desktop —
   e embaixo dele no celular, onde a largura não dá para os dois. */
.cabeca-linha { display: flex; align-items: flex-end; gap: var(--e-4); flex-wrap: wrap; }
.cabeca-linha > h1 { flex: 1 1 18ch; }
.cabeca-acao { flex: 0 0 auto; }
.cabeca-acao .bt { width: auto; }
@media (max-width: 900px) {
  .cabeca-acao { flex-basis: 100%; }
  .cabeca-acao .bt { width: 100%; }
}
.cabeca p { max-width: var(--medida); }

/* --- a trilha de passos, com nome -----------------------------------------
   Os traços sozinhos dizem "há quatro passos"; não dizem qual é este. A linha de
   texto acima deles diz — e é a que o leitor de tela anuncia. */
.passos-rot {
  display: flex; justify-content: space-between; gap: var(--e-3);
  font-size: var(--t-2xs); color: var(--tinta-3); font-weight: var(--peso-medio);
  margin-bottom: var(--e-2); font-variant-numeric: tabular-nums;
}
.passos-rot b { color: var(--tinta-2); font-weight: var(--peso-forte); }
.passos-rot + .passos { margin-bottom: var(--e-5); }
.passo { transition: background var(--dur-lenta) var(--curva-padrao); }
.passo.atual { height: 4px; margin-top: -0.5px; }

/* --- resumo: rótulo à esquerda, valor à direita -------------------------
   A tela de "Confira antes de registrar" do Registrar e do Buscar escrevia esta
   linha com seis estilos em linha, duas vezes. Um componente, uma regra. */
.resumo { display: grid; }
.resumo-linha {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--e-4);
  padding: var(--e-2) 0; border-bottom: 1px solid var(--borda-sutil);
}
.resumo-linha:last-child { border-bottom: 0; }
.resumo-linha > span { color: var(--tinta-2); font-size: var(--t-sm); }
.resumo-linha > strong { text-align: right; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.resumo-linha.destaque > strong { font-family: var(--fonte-mono); font-size: var(--t-lg); }

/* --- estado desenhado: gravou, guardou, falhou, recusado, vazio, sem sinal ---
   O fim de um fluxo não é um parágrafo centralizado: é um SELO (o círculo com o
   ícone na cor do fato), o título do que aconteceu, uma frase, e as ações.
   A cor vem do fato e nunca vem sozinha — o título diz a mesma coisa em palavra
   (RNF-07: funciona para quem não separa as cores, no sol e impresso). */
.estado {
  display: grid; justify-items: center; text-align: center; gap: var(--e-2);
  padding: var(--e-8) var(--e-5) var(--e-6);
}
.estado-selo {
  width: 64px; height: 64px; border-radius: 50%;
  display: grid; place-items: center; margin-bottom: var(--e-2);
  background: var(--neutro-bg); color: var(--neutro);
  box-shadow: 0 0 0 6px color-mix(in oklab, currentColor 10%, transparent);
  animation: selo-entra var(--dur-lenta) var(--curva-entra) both;
}
.estado.ok .estado-selo       { background: var(--ok-bg); color: var(--ok); }
.estado.guardado .estado-selo { background: var(--atencao-bg); color: var(--atencao); }
.estado.falhou .estado-selo,
.estado.recusado .estado-selo { background: var(--grave-bg); color: var(--grave); }
.estado.info .estado-selo     { background: var(--marca-tenue); color: var(--marca); }
.estado h2 { font-size: var(--t-xl); }
.estado > p { color: var(--tinta-2); max-width: 46ch; }
.estado-acoes {
  display: flex; gap: var(--e-3); width: 100%; max-width: 420px;
  margin-top: var(--e-4); flex-wrap: wrap;
}
.estado-acoes > .bt { flex: 1 1 160px; width: auto; }
@keyframes selo-entra { from { transform: scale(.85); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .estado-selo { animation: none; } }

/* A pilha de avisos que segue um estado: o espaço é do componente, não de um
   `marginTop` em linha repetido em cada aviso. */
.pilha { display: grid; gap: var(--e-3); margin-top: var(--e-4); }
.pilha:empty { display: none; }

/* --- carregando: o esqueleto no lugar do texto ---------------------------
   "Carregando…" numa linha diz que algo vem; três barras na forma do que vem
   dizem O QUE vem, e a tela não pula quando chega. O brilho para quem pediu
   menos movimento. */
.esqueleto { display: grid; gap: var(--e-3); padding: var(--e-5); }
.esqueleto i {
  display: block; height: 14px; border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--neutro-bg), var(--superficie-2), var(--neutro-bg));
  background-size: 200% 100%;
  animation: esqueleto-brilho 1.2s linear infinite;
}
.esqueleto i:nth-child(1) { width: 42%; height: 20px; }
.esqueleto i:nth-child(2) { width: 88%; }
.esqueleto i:nth-child(3) { width: 64%; }
@keyframes esqueleto-brilho { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .esqueleto i { animation: none; } }

/* --- o aviso efêmero (avisos.js) — D1.3 -----------------------------------
   Era um `div` reaproveitado com estilo por tom. Agora é uma pilha (`.avisos`, uma
   por app) onde cada aviso nasce, some e leva o "Desfazer". Tinta sobre papel
   invertido — o aviso é a única coisa escura na tela clara, e por isso se lê sem
   disputar com o conteúdo; no escuro, o inverso. O tom vai no ícone, nunca só na
   cor (PD-8.5), e o fio lateral saiu (V-16). Fica acima da barra inferior e, quando
   a linha de ação sticky está na tela, acima dela (`--avisos-acima`, medido no JS). */
.avisos {
  position: fixed; left: 50%; transform: translateX(-50%); z-index: var(--z-aviso);
  bottom: var(--avisos-acima, calc(var(--e-5) + env(safe-area-inset-bottom, 0px)));
  width: min(92vw, 440px); display: grid; gap: var(--e-2); pointer-events: none;
}
@media (max-width: 900px) {
  .avisos { bottom: var(--avisos-acima, calc(var(--tabbar-h) + var(--e-3) + env(safe-area-inset-bottom, 0px))); }
}
.aviso-shell {
  pointer-events: auto; display: flex; align-items: center; gap: var(--e-3);
  min-height: 52px; padding: var(--e-2) var(--e-2) var(--e-2) var(--e-4);
  border-radius: var(--r-xl); box-shadow: var(--elev-3);
  background: var(--tinta); color: var(--tinta-inversa);
  font-size: var(--t-sm); line-height: 1.35; font-weight: var(--peso-medio); text-align: left;
  transform: translateX(var(--arrasto-x, 0px));
  animation: aviso-entra var(--dur-lenta) var(--curva-entra) both;
  touch-action: pan-y;
}
.aviso-shell.saindo { animation: aviso-sai 160ms var(--curva-sai) forwards; }
@keyframes aviso-entra { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
@keyframes aviso-sai { to { opacity: 0; transform: translateY(6px); } }
.aviso-shell-ic { display: inline-flex; flex: none; }
.aviso-shell.ok .aviso-shell-ic      { color: oklch(80% 0.13 155); }
.aviso-shell.atencao .aviso-shell-ic { color: oklch(84% 0.13 75); }
.aviso-shell.grave .aviso-shell-ic   { color: oklch(78% 0.14 25); }
.aviso-shell-texto { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.aviso-shell-acao {
  flex: none; min-height: 44px; padding: 0 var(--e-3); border: 0; border-radius: var(--r-md);
  background: none; color: oklch(84% 0.10 75); font: 650 var(--t-sm)/1 var(--fonte-ui); cursor: pointer;
}
.aviso-shell-acao:active { background: oklch(100% 0 0 / .1); }
.aviso-shell-fechar {
  flex: none; width: 40px; height: 44px; border: 0; background: none; color: inherit;
  opacity: .6; font-size: 1.3rem; line-height: 1; cursor: pointer;
}
@media (prefers-reduced-motion: reduce) { .aviso-shell, .aviso-shell.saindo { animation: none; } }

/* --- a ação principal no polegar (o fluxo do coletor) --------------------
   No celular, a linha de botões dos passos de Registrar e Buscar GRUDA acima da
   barra inferior enquanto o passo rola: o "Continuar" fica onde o polegar está,
   e não depois de três campos. `sticky`, e não `fixed` — o que é fixo e
   transborda some (armadilhas: position fixed), e o sticky volta ao fluxo no
   fim do passo, sem cobrir o último campo. O véu de papel atrás dele é o que
   impede o texto que rola por baixo de competir com o rótulo. */
@media (max-width: 900px) {
  .fluxo .bt-linha {
    position: sticky; z-index: 5;
    bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
    margin-left: calc(-1 * var(--e-5)); margin-right: calc(-1 * var(--e-5));
    padding: var(--e-3) var(--e-5);
    background: color-mix(in oklab, var(--fundo) 92%, transparent);
    backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
    border-top: 1px solid var(--borda-sutil);
  }
  /* dentro do cartão do destino a linha gruda igual, com o véu da superfície:
     o `.cartao-p` tem o mesmo respiro lateral do `.app`, então a margem
     negativa encosta na borda do cartão, e não na da tela */
  .fluxo .cartao .bt-linha {
    background: color-mix(in oklab, var(--superficie) 94%, transparent);
    border-radius: 0 0 var(--r-lg) var(--r-lg);
  }
}

/* ==========================================================================
   O GUIA DA PÁGINA — "Como funciona esta página" (Frente D, fase 2)
   --------------------------------------------------------------------------
   Discreto fechado, generoso aberto. Fechado é uma faixa com a borda tracejada
   de latão — a mesma gramática de "aqui há mais" do chip de sugestão —, alta o
   bastante para o polegar (56px). Aberto, vira uma folha de papel com seções
   curtas, numeradas onde há ordem, e com os botões citados desenhados como
   botões: a pessoa lê "[Registrar remessa]" e reconhece o formato na tela.
   ========================================================================== */
.guia {
  margin-top: var(--e-10);
  border: 1px dashed color-mix(in oklab, var(--acento) 45%, transparent);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--superficie) 70%, transparent);
  transition: background var(--t-media), border-color var(--t-media), box-shadow var(--t-media);
}
.guia.aberto {
  border-style: solid; border-color: var(--borda);
  background: var(--superficie); box-shadow: var(--elev-1);
}
.guia-abrir {
  display: flex; align-items: center; gap: var(--e-3);
  width: 100%; min-height: var(--toque); padding: var(--e-3) var(--e-4);
  border: 0; border-radius: var(--r-lg); background: none; color: var(--tinta);
  text-align: left; cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
@media (hover: hover) { .guia-abrir:hover { background: var(--acento-tenue); } }
.guia-abrir:active { background: var(--acento-fraco); }
.guia-ic {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--acento-tenue); color: var(--acento);
}
.guia-titulo { flex: 1; min-width: 0; display: grid; gap: 1px; }
.guia-titulo b { font-size: var(--t-md); font-weight: var(--peso-forte); }
.guia-titulo small { font-size: var(--t-xs); color: var(--tinta-2); }
.guia-chevron { flex: none; color: var(--tinta-3); display: grid; transition: transform var(--t-media); }
.guia.aberto .guia-chevron { transform: rotate(180deg); }

.guia-corpo {
  padding: 0 var(--e-5) var(--e-5);
  border-top: 1px solid var(--borda-sutil);
  animation: entra var(--dur-lenta) var(--curva-entra) both;
}
.guia-corpo[hidden] { display: none; }
.guia-resumo {
  font-family: var(--fonte-display); font-size: var(--t-lg); line-height: var(--altura-densa);
  margin: var(--e-5) 0 0; max-width: var(--medida); text-wrap: balance;
}
.guia-secao { margin-top: var(--e-6); max-width: var(--medida); }
.guia-secao h3 {
  font-family: var(--fonte-ui); font-size: var(--t-3xs); font-weight: var(--peso-forte);
  text-transform: uppercase; letter-spacing: .14em; color: var(--acento);
  margin-bottom: var(--e-3);
}
/* O passo a passo numerado com o número em círculo: é a lista que a pessoa segue
   com o dedo, e o número grande é o que ela procura quando volta os olhos à tela. */
.guia-passos { list-style: none; padding: 0; margin: 0; counter-reset: passo; display: grid; gap: var(--e-3); }
.guia-passos li {
  counter-increment: passo; position: relative; padding-left: calc(28px + var(--e-3));
  line-height: var(--altura-normal); min-height: 28px;
}
.guia-passos li::before {
  content: counter(passo); position: absolute; left: 0; top: 0;
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: var(--fonte-mono); font-size: var(--t-xs); font-weight: 600;
  background: var(--marca-tenue); color: var(--marca-forte);
}
.guia-lista { margin: 0; padding-left: var(--e-5); display: grid; gap: var(--e-2); line-height: var(--altura-normal); }
.guia-lista li::marker { color: var(--acento); }
.guia-lista.recusa li::marker { color: var(--grave); }
.guia-els { margin: 0; display: grid; gap: var(--e-3); }
.guia-el { display: grid; grid-template-columns: minmax(0, 12rem) 1fr; gap: var(--e-2) var(--e-4); align-items: baseline; }
.guia-el dt { margin: 0; }
.guia-el dt b { font-weight: var(--peso-forte); }
.guia-el dd { margin: 0; color: var(--tinta-2); line-height: var(--altura-normal); }
@media (max-width: 520px) { .guia-el { grid-template-columns: 1fr; gap: var(--e-1); } }
/* O botão citado: a forma do `.bt`, em miniatura e sem ser clicável. */
.guia-bt {
  display: inline-flex; align-items: center; padding: 1px var(--e-2);
  border: 1px solid var(--acao-borda); border-radius: var(--r-sm);
  background: var(--acao); color: var(--acao-tinta);
  font-size: .92em; font-weight: var(--peso-forte); white-space: nowrap;
  line-height: 1.45; vertical-align: 1px;
}
.guia-depois { display: grid; gap: var(--e-2); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.guia-ir {
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-3);
  min-height: var(--toque); padding: var(--e-2) var(--e-4);
  border: 1px solid var(--borda); border-radius: var(--r-md);
  color: var(--tinta); text-decoration: none; background: var(--superficie-2);
  transition: border-color var(--t-rapida), background var(--t-rapida);
}
@media (hover: hover) { .guia-ir:hover { border-color: var(--acento); background: var(--acento-tenue); color: var(--tinta); } }
.guia-ir > span { display: grid; gap: 1px; min-width: 0; }
.guia-ir small { font-size: var(--t-xs); color: var(--tinta-2); }
.guia-seta { color: var(--acento); flex: none; }
.chip-motivo { font-size: var(--t-2xs); color: var(--tinta-3); }
@media print { .guia, .pagina-olho { display: none !important; } }
@media (prefers-reduced-motion: reduce) { .guia-corpo { animation: none; } }

/* --- A CASCA DE APP no celular — D1.4 · D1.7 · D1.9 (Design Premium, 17/09) ----
   O topo deixa de ser "site" abaixo de 900px: vira a barra de navegação de um
   app — 52px, opaca (o Safari 26 pinta as barras do sistema com o fundo do
   elemento fixo; vidro sobre conteúdo variável custa leitura no sol), com o
   VOLTAR à esquerda nas telas de fluxo, a marca só no Início, o TÍTULO COMPACTO
   ao centro quando o grande rola para fora, e a sincronia à direita. O hambúrguer
   e o rodapé de site saem (o "Mais" tem tudo, inclusive "Sobre o app"). No
   desktop nada disto se aplica: o topo flutuante continua. */
.barra-voltar, .barra-titulo { display: none; }
.barra-sentinela { height: 1px; margin-top: -1px; }
@media (max-width: 900px) {
  .topo {
    height: calc(var(--barra-h) + env(safe-area-inset-top, 0px));
    padding: env(safe-area-inset-top, 0px) max(var(--e-2), env(safe-area-inset-right, 0px)) 0 max(var(--e-2), env(safe-area-inset-left, 0px));
    background: var(--superficie);
    backdrop-filter: none; -webkit-backdrop-filter: none;
    border-bottom-color: transparent;
    transition: border-color var(--dur-rapida) var(--curva-padrao);
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: var(--e-2);
  }
  .topo.com-titulo { border-bottom-color: var(--borda); }
  .nav { display: none; }                       /* o menu suspenso saiu com o hambúrguer */
  .topo-acoes { justify-self: end; margin-left: 0; }
  /* a marca só no Início; nas outras telas o canto esquerdo é do voltar (ou fica vazio) */
  .topo:not([data-raiz]) .marca { display: none; }
  .topo .marca { justify-self: start; min-height: var(--toque-min); padding-left: var(--e-1); }
  .topo .marca-txt em { display: none; }        /* "PRIVATELAB" em caixa alta miúda: cabe no desktop, não na barra */
  .barra-voltar {
    display: inline-flex; align-items: center; gap: 2px; justify-self: start;
    min-height: var(--toque-min); min-width: var(--toque-min);
    padding: 0 var(--e-2) 0 var(--e-1); border-radius: var(--r-md);
    color: var(--marca); text-decoration: none;
    font-size: var(--t-acao); font-weight: var(--peso-medio); line-height: 1;
  }
  .barra-voltar[hidden] { display: none; }
  .barra-voltar:active { background: var(--marca-tenue); }
  .barra-chevron { font-size: 1.9rem; line-height: .7; margin-top: -3px; }
  .barra-titulo {
    display: block; grid-column: 2; text-align: center;
    font-size: var(--t-acao); font-weight: var(--peso-forte); color: var(--tinta);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 52vw;
    opacity: 0; transform: translateY(4px);
    transition: opacity var(--dur-rapida) var(--curva-sai), transform var(--dur-rapida) var(--curva-sai);
  }
  .topo.com-titulo .barra-titulo { opacity: 1; transform: none; }
  /* a página começa logo abaixo da barra de 52px, e não dos 64px do topo do desktop */
  .app { padding-top: calc(env(safe-area-inset-top, 0px) + var(--barra-h) + var(--e-5)); }
  /* D1.7: o rodapé de site sai da rolagem das telas de trabalho (os links e a versão estão no Mais) */
  .rodape { display: none; }
  /* D1.9: o fundo com diagonais só na tela de entrada; nas telas de trabalho, papel liso */
  body { background-image: none; }
  body:has(.app.limpo) {
    background-image:
      repeating-linear-gradient(58deg, oklch(70% 0.06 75 / .035) 0 1px, transparent 1px 14px),
      repeating-linear-gradient(-58deg, oklch(70% 0.06 75 / .035) 0 1px, transparent 1px 14px);
  }
}
/* D1.9: o acabamento nativo, em qualquer largura — sem o flash cinza do toque, sem
   seleção de texto em controle, sem o zoom do toque duplo, e a rolagem interna que
   não arrasta a página inteira (o body do app instalado não "estica"). */
a, button, .tabbar, .folha, .aba, .cad-aba { -webkit-tap-highlight-color: transparent; }
button, .bt, .tabbar-item, .tabbar-cam, .aba, .cad-aba, .kb-chip, .folha-item, .barra-voltar { user-select: none; -webkit-user-select: none; touch-action: manipulation; }
.folha, .tab-rolo, .kb-trilho, .sug-lista, .guia-corpo { overscroll-behavior: contain; }
@media (max-width: 900px) and (display-mode: standalone) { body { overscroll-behavior-y: none; } }
/* o "Sobre o app" do Mais: a linha da versão não é botão — mas veste a mesma linha
   de item (a regra da folha só alcança `a` e `button`) */
.folha .folha-item.folha-info {
  display: flex; align-items: center; gap: var(--e-3);
  min-height: 52px; padding: var(--e-2) var(--e-2);
  font-size: var(--t-md); font-weight: var(--peso-medio); color: var(--tinta-2);
  border-bottom: 1px solid var(--borda); cursor: default;
}
.folha .folha-dir { margin-left: auto; font-family: var(--fonte-mono); font-size: var(--t-xs); color: var(--tinta-3); }
/* o item logo antes de um título de grupo perde o fio de baixo: o grupo já traz o seu */
.folha a:not(.bt):has(+ .folha-grupo), .folha .folha-item:has(+ .folha-grupo) { border-bottom: 0; }

/* --- a pergunta dentro da folha (folha.js `sujo()`, D1.1 · U-26) --------------
   No topo da própria folha, e não num diálogo empilhado: quem vai perder a grade
   digitada continua vendo a grade enquanto decide. O tom é o do `.aviso.atencao`;
   os dois botões são compactos e o de descartar é `.perigo` (contorno, nunca
   fundo vermelho — o botão que menos se quer tocar por engano). */
.folha-pergunta {
  margin: 0 0 var(--e-4); padding: var(--e-4);
  border-radius: var(--r-md); background: var(--atencao-bg); color: var(--tinta);
  animation: entra var(--dur-lenta) var(--curva-entra) both;
}
.folha-pergunta-titulo { font-weight: var(--peso-forte); font-size: var(--t-md); }
.folha-pergunta-texto { font-size: var(--t-sm); color: var(--tinta-2); margin-top: var(--e-1); }
.folha-pergunta .bt-linha { margin-top: var(--e-3); }
.folha-pergunta .bt-linha .bt { width: auto; flex: 1; }
@media (prefers-reduced-motion: reduce) { .folha-pergunta { animation: none; } }

}  /* @layer app */

@layer ajustes {
/* ==========================================================================
   FRENTE D, FASE 4 — silêncio visual, folha nativa e o estado do aparelho
   --------------------------------------------------------------------------
   Sobreposições, e não edição de cada regra antiga: cada bloco abaixo diz o que
   vence e por quê, num lugar só, e a regra de origem continua lendo como foi
   escrita (com o comentário da decisão de então). Quando a spec Design Premium
   organizar o CSS em camadas (D0.4), estes blocos migram para `componentes`.
   ========================================================================== */

/* --- o acabamento de app (PD-1.5) ---------------------------------------
   Toque sem o clarão do navegador, sem seleção de texto ao segurar um botão, e
   a rolagem de dentro (quadro, folha, lista) que não arrasta a página junto. */
button, .bt, .tabbar-item, .tabbar-cam, .aba, .cad-aba, .kb-chip, .folha-item, .guia-abrir, .sinc, .bt-cont {
  -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none;
}
.kb-trilho, .folha, .sug-lista, .tab-rolo, .cad-abas { overscroll-behavior: contain; }

/* --- U-03 residual: o botão desabilitado que carrega a INSTRUÇÃO ----------
   "Escolha lote, etapa e facção", "Confirme o prazo para registrar": é a frase
   que diz o que fazer, e a opacidade de 45% a deixava em ~1,6:1. O botão guarda
   a forma do primário (borda de latão, tracejada = "ainda não") e o texto fica
   em `--tinta-2` sobre `--superficie-2` — o guard `contraste` mede o par. */
.bt[disabled], .bt.acento[disabled] {
  background: var(--superficie-2); color: var(--tinta-2);
  border: 1px dashed var(--acao-borda); opacity: 1; box-shadow: none;
}
@media (hover: hover) { .bt[disabled]:hover {
  background: var(--superficie-2); color: var(--tinta-2);
  border: 1px dashed var(--acao-borda); opacity: 1; box-shadow: none;
} }
.bt.sec[disabled] { border-style: dashed; border-color: var(--borda-forte); }

/* --- silêncio visual: menos caixa alta, menos fio, menos gradiente ---------
   A spec Design Premium (V-14, V-16) mediu o que faz o app parecer "site de
   sistema": rótulo em caixa alta espaçada em todo canto, fio colorido à esquerda
   de toda caixa, gradiente como enfeite. A caixa alta fica onde é voz de marca
   ou de papel (o olho da página, a OS impressa); o resto fala normal. */
.kpi .rot, th, .adiante-rot, .kb-filtro .rot, .contador-rot, .kb-u, .grade-total-rot,
.pn-rot, .cad-rot, .ln-total-rot, .divisor, .guia-secao h3 {
  text-transform: none; letter-spacing: .005em; font-size: var(--t-xs);
}
.kpi .rot { color: var(--tinta-2); }
.folha-grupo {
  text-transform: none; font-style: normal; letter-spacing: 0;
  font-family: var(--fonte-ui); font-size: var(--t-xs); color: var(--tinta-3);
}
/* o aviso diz o tom pelo fundo e pelo ícone; o fio de 3px repetia os dois */
.aviso { border-left: 0; }
/* cor chapada no lugar do gradiente: o índigo fundo continua sendo a superfície
   de destaque, sem a "luz de vitrine" que o gradiente simulava */
.primeiro, .acao.destaque { background: var(--indigo-800); }
.primeiro::before { background: var(--latao-400); opacity: .7; }
.contador::before { background: var(--acento); }

/* --- U-15: os itens do topo do desktop no piso de 44px ------------------ */
@media (min-width: 901px) {
  .nav a, .nav-mais { min-height: var(--toque-min); display: inline-flex; align-items: center; }
}

/* --- U-16: o atalho "registrar" do cartão do quadro é alvo, não sublinhado -- */
.kb-atalho {
  display: inline-flex; align-items: center; min-height: var(--toque-min);
  padding: 0 var(--e-2); font-weight: var(--peso-forte);
}

/* --- U-27: no celular, os quatro indicadores cabem numa faixa 2x2 ---------
   Quatro cartões de largura inteira ocupavam a primeira tela do Kanban, e o
   quadro começava abaixo da dobra. */
@media (max-width: 520px) {
  .grade.g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--e-2); }
  .grade.g4 .kpi { padding: var(--e-3); }
  .grade.g4 .kpi .val { font-size: var(--t-xl); }
  .grade.g4 .kpi .sub { font-size: var(--t-2xs); }
}

/* --- a folha nativa (folha.js) --------------------------------------------
   Sobe com a curva de gaveta do iOS; é o único movimento acima de 200 ms
   (`--dur-espacial`, DP-3 da spec Design Premium, pendente — voltar a 200 ms é
   mudar um token). O puxador ganha área de toque sem crescer na tela, e é dele
   que o arrasto para baixo parte sem brigar com a rolagem do conteúdo. */
.folha { animation-duration: var(--dur-espacial); animation-timing-function: var(--curva-mola);
         transition: transform var(--dur-media) var(--curva-mola); }
.folha:focus { outline: none; }
.folha-puxador { position: relative; touch-action: none; cursor: grab; }
.folha-puxador::after { content: ""; position: absolute; inset: -20px -60px; }

/* --- o estado do aparelho (sincronia.js, PD-6.1) --------------------------
   Palavra + ícone, na cor do fato. "Tudo enviado" fica quieto; "guardados" e
   "Sem sinal" pedem atenção. */
/* D1.6 / V-23 (17/09): sem borda. Com o fio de 1px e a superfície branca, a pílula
   "Tudo enviado" media 264×88 na barra de 390 e pesava mais que a marca — parecia
   um botão de formulário. Agora é o fundo tênue do ESTADO (o verde do ok, o âmbar
   do guardado, o cinza do sem sinal, o índigo do enviando), o mesmo desenho do
   selo de prazo: lê-se como estado, não como ação. A palavra continua (PD-6.1). */
.sinc {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  min-height: var(--toque-min); padding: 0 var(--e-3);
  border: 0; border-radius: var(--r-pilula);
  background: var(--ok-bg); color: var(--ok);
  font-family: inherit; font-size: var(--t-xs); font-weight: var(--peso-forte);
  white-space: nowrap; cursor: pointer;
  transition: background-color var(--t-rapida), color var(--t-rapida), transform var(--t-rapida);
}
.sinc:active { transform: scale(.97); }
/* V-22: `:hover` só onde há ponteiro — em tela de toque ele fica preso depois do tap */
@media (hover: hover) { .sinc:hover { filter: brightness(.96); } }
.sinc.guardados { background: var(--atencao-bg); color: var(--atencao); }
.sinc.sem-sinal { background: var(--neutro-bg); color: var(--tinta-2); }
.sinc.enviando  { background: var(--marca-tenue); color: var(--marca-forte); }
.sinc.enviando .ic-svg { animation: sinc-sobe 1s var(--curva-padrao) infinite; }
@keyframes sinc-sobe { 50% { transform: translateY(-2px); } }
@media (prefers-reduced-motion: reduce) { .sinc.enviando .ic-svg { animation: none; } }
@media (max-width: 900px) { .topo-acoes { margin-left: auto; } }
@media (max-width: 380px) { .sinc { padding: 0 var(--e-2); } .sinc-txt { display: none; } }

/* --- a miniatura da foto (U-20) ------------------------------------------ */
.foto-miniatura {
  width: 96px; height: 96px; object-fit: cover; border-radius: var(--r-md);
  border: 1px solid var(--borda); margin: 0 auto;
}

/* --- "Detalhes": os fatos secundários do fim de um fluxo (PD-4.2) -------- */
.detalhes { margin-top: var(--e-4); border: 1px solid var(--borda); border-radius: var(--r-lg); background: var(--superficie); }
.detalhes > summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--e-3);
  min-height: var(--toque); padding: 0 var(--e-4); cursor: pointer; list-style: none;
  font-weight: var(--peso-forte);
}
.detalhes > summary::-webkit-details-marker { display: none; }
.detalhes > summary::after { content: "+"; font-family: var(--fonte-mono); color: var(--tinta-3); }
.detalhes[open] > summary::after { content: "−"; }
.detalhes > .pilha { margin: 0; padding: 0 var(--e-4) var(--e-4); }

/* --- revisao da sessao 12 (17/09): o olho e o guia mais quietos ----------
   DV-1: o olho em caixa alta acima de todo titulo era mais uma marca de "site de
   sistema". No celular e dentro dos fluxos de passo ele sai (a trilha ja diz
   onde se esta); no desktop fica, em caixa normal.
   V-18: o guia fechado ocupava ~110 px com borda tracejada no celular — agora e
   uma linha compacta, com fio fino, que so cresce quando aberta. */
.pagina-olho { text-transform: none; letter-spacing: 0; font-size: var(--t-xs); }
.pagina-olho:has(+ .fluxo) { display: none; }
@media (max-width: 900px) {
  .pagina-olho { display: none; }
  .guia { margin-top: var(--e-6); border: 1px solid var(--borda-sutil); background: none; }
  .guia-abrir { padding: var(--e-2) var(--e-3); }
  .guia-titulo small { display: none; }
  .guia-ic { width: 28px; height: 28px; }
}

}  /* @layer ajustes */