/*
 * Paleta do univercheck, tema CLARO e só claro.
 *
 * `color-scheme: light` trava o tema: sem isso o navegador escurece campos e
 * barras de rolagem por conta própria quando o aparelho está no modo escuro, e
 * a tela sai meio clara meio escura.
 *
 * O contraste é alto de propósito — esta tela vive sob luz de galpão, muitas
 * vezes numa tela suja, olhada de longe e com pressa.
 */
:root {
  color-scheme: light;

  --fundo: #f4f6f8;
  --superficie: #ffffff;
  --borda: #dfe4ea;
  --borda-forte: #c3ccd6;

  --tinta: #12171d;
  --tinta-suave: #4d5866;
  --tinta-fraca: #7d8894;

  --ok: #0a7f4f;
  --ok-fundo: #e7f5ee;
  --parcial: #9a5b00;
  --parcial-fundo: #fdf1de;
  --erro: #c02626;
  --erro-fundo: #fdeaea;
  --realce: #0b5fa5;
  --realce-fundo: #e8f1fa;

  --sombra: 0 1px 2px rgba(16, 24, 40, .04);
  --sombra-alta: 0 1px 2px rgba(16, 24, 40, .06), 0 8px 24px rgba(16, 24, 40, .08);
  --raio: .875rem;
  --rapido: 140ms cubic-bezier(.2, .8, .3, 1);
}

* { box-sizing: border-box; }

/*
 * `hidden` precisa vencer o `display` das classes.
 *
 * O padrão do navegador é `[hidden] { display: none }`, que perde para qualquer
 * regra de classe com `display`. Sem esta linha, `.folha` e `.conexao`
 * continuam ocupando a tela mesmo escondidas — e a folha, que cobre tudo,
 * engole cada clique da página sem aparecer.
 */
[hidden] { display: none !important; }

html, body { height: 100%; }
body {
  margin: 0;
  background: var(--fundo);
  color: var(--tinta);
  font: 16px/1.5 -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
  padding-bottom: env(safe-area-inset-bottom);
  /*
   * Palavra comprida quebra em vez de empurrar a tela.
   *
   * O texto aqui vem do Bling, e lá existe nome de produto sem um espaço
   * sequer, código de barras de vinte dígitos e SKU colado com dois-pontos. Um
   * desses numa tela de 320px empurraria tudo para o lado — e ninguém vai
   * revisar cada nome do catálogo antes de cadastrar.
   */
  overflow-wrap: break-word;
}
button, input { font: inherit; color: inherit; }
.numeros { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum'; }

/* ── Porta: PIN e nome ──────────────────────────────────────────────────── */
.tela--centro { min-height: 100dvh; display: grid; place-items: center; padding: 1.5rem; }
.cartao {
  background: var(--superficie); border: 1px solid var(--borda);
  border-radius: var(--raio); box-shadow: var(--sombra);
}
.cartao--porta { width: min(23rem, 100%); padding: 2rem 1.75rem; text-align: center; }
.rotulo-porta {
  font-size: .72rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .16em; color: var(--tinta-fraca); margin: 0;
}
.marca { font-size: 2rem; line-height: 1; margin-bottom: .75rem; }

/* O PIN grande e espaçado: dá para conferir de longe o que foi digitado. */
.pin {
  width: 100%; margin: 1.25rem 0 0; padding: 0; background: transparent;
  border: none; outline: none; text-align: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 2.5rem; letter-spacing: .3em; text-indent: .3em;
  color: var(--tinta);
}
.pin::placeholder { color: var(--borda-forte); }

.campo { display: block; text-align: left; margin-top: 1.25rem; }
.campo span {
  display: block; font-size: .72rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .14em; color: var(--tinta-fraca); margin-bottom: .4rem;
}
/*
 * O <select> entra aqui junto com o <input>, e não é capricho.
 *
 * Sem estilo ele vira o controle nativo do sistema: um retângulo de 130px,
 * fonte menor, alinhado fora da coluna dos outros campos. No meio de uma folha
 * de formulário parece um pedaço que ficou faltando — e é justamente onde se
 * escolhe de qual depósito a mercadoria sai.
 */
.campo input, .campo select {
  width: 100%; padding: .8rem 1rem; background: var(--fundo);
  border: 1px solid var(--borda); border-radius: .75rem;
  font: inherit; color: inherit;
  transition: border-color var(--rapido), background var(--rapido);
}
/*
 * A seta é desenhada por nós porque `appearance: none` apaga a nativa. Sem
 * ela o campo vira um texto solto e ninguém sabe que dá para tocar.
 */
.campo select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--tinta-fraca) 50%),
    linear-gradient(135deg, var(--tinta-fraca) 50%, transparent 50%);
  background-position: calc(100% - 1.1rem) 55%, calc(100% - .75rem) 55%;
  background-size: .35rem .35rem, .35rem .35rem;
  background-repeat: no-repeat;
  padding-right: 2.2rem;
}
.campo input::placeholder { color: var(--tinta-fraca); }
.campo input:focus, .campo select:focus { outline: none; border-color: var(--realce); background-color: var(--superficie); }

/* ── Escolha do papel ───────────────────────────────────────────────────── */
.papeis { border: none; margin: 1.25rem 0 0; padding: 0; text-align: left; }
.papeis legend {
  font-size: .72rem; font-weight: 600; text-transform: uppercase; letter-spacing: .14em;
  color: var(--tinta-fraca); padding: 0; margin-bottom: .5rem;
}
.papel {
  display: flex; align-items: center; gap: .7rem; padding: .7rem .85rem; cursor: pointer;
  border: 1px solid var(--borda); border-radius: .75rem; margin-bottom: .5rem;
  transition: border-color var(--rapido), background var(--rapido);
}
.papel:has(input:checked) { border-color: var(--ok); background: var(--ok-fundo); }
.papel input { width: 1.1rem; height: 1.1rem; accent-color: var(--ok); flex: none; }
.papel span { display: flex; flex-direction: column; }
.papel small { color: var(--tinta-fraca); font-size: .8rem; }

/* ── Exportar ───────────────────────────────────────────────────────────── */
.exportar { display: flex; gap: .5rem; margin: 1.25rem 0 0; }
.exportar .botao { flex: 1; text-align: center; text-decoration: none; }

/* ── Estrutura ──────────────────────────────────────────────────────────── */
.topo {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: .75rem;
  padding: .8rem 1rem; padding-top: calc(.8rem + env(safe-area-inset-top));
  background: var(--superficie); border-bottom: 1px solid var(--borda);
}
.topo__titulo { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/*
 * Título e subtítulo em UMA linha cada, com reticências.
 *
 * A barra é fixa no topo, e num celular de 320px um subtítulo como "Geral ·
 * aguardando revisão" quebrava em três linhas: a barra crescia, empurrava o
 * conteúdo para baixo e a altura do topo mudava de tela para tela. Barra de
 * app não muda de tamanho — é isso que faz a navegação parecer firme.
 */
.topo__titulo span,
.topo__titulo small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topo__titulo span { font-weight: 650; letter-spacing: -.01em; }
.topo__titulo small { color: var(--tinta-fraca); font-size: .78rem; }
.tela { max-width: 46rem; margin: 0 auto; padding: 1rem 1rem 6rem; }
.secao {
  font-size: .72rem; font-weight: 600; text-transform: uppercase; letter-spacing: .14em;
  color: var(--tinta-fraca); margin: 1.75rem 0 .6rem;
}

/* ── Botões ─────────────────────────────────────────────────────────────── */
.botao {
  border: 1px solid var(--borda); background: var(--superficie); color: var(--tinta-suave);
  border-radius: .75rem; padding: .7rem 1.05rem; cursor: pointer; font-weight: 600;
  transition: transform var(--rapido), background var(--rapido), border-color var(--rapido);
}
.botao:hover:not(:disabled) { border-color: var(--borda-forte); color: var(--tinta); }
.botao:active:not(:disabled) { transform: scale(.98); }
.botao:disabled { background: var(--fundo); color: var(--tinta-fraca); cursor: not-allowed; transform: none; }
.botao--principal { background: var(--ok); color: #fff; border-color: transparent; }
.botao--principal:hover:not(:disabled) { background: #0c6f47; color: #fff; }
.botao--perigo { background: var(--erro-fundo); color: var(--erro); border-color: transparent; }
.botao--fantasma { background: transparent; border-color: transparent; color: var(--tinta-fraca); }
.botao--grande { width: 100%; padding: .9rem; font-size: 1rem; }
.botao--icone { padding: .45rem .65rem; background: transparent; border-color: transparent; font-size: 1.15rem; }

/* ── Estado do sistema ──────────────────────────────────────────────────── */
.estado {
  display: flex; gap: .9rem; align-items: center;
  padding: 1rem 1.1rem; border-radius: var(--raio); margin-bottom: 1.25rem;
  border: 1px solid transparent; animation: surgir .22s ease-out both;
}
.estado--livre { background: var(--ok-fundo); border-color: #bfe3d1; }
.estado--ocupado { background: var(--parcial-fundo); border-color: #f0d9ac; }
.estado__icone {
  font-size: 1.2rem; width: 2.3rem; height: 2.3rem; flex: none;
  display: grid; place-items: center; border-radius: 50%; background: #fff;
}
.estado--livre .estado__icone { color: var(--ok); }
.estado--ocupado .estado__icone { color: var(--parcial); }
.estado__texto { display: flex; flex-direction: column; min-width: 0; }
.estado__texto span { color: var(--tinta-suave); font-size: .88rem; }

/* ── Ações ──────────────────────────────────────────────────────────────── */
.acoes { display: grid; gap: .65rem; }
.acao {
  display: flex; align-items: center; gap: .9rem; text-align: left; width: 100%;
  padding: 1rem 1.1rem; background: var(--superficie);
  border: 1px solid var(--borda); border-radius: var(--raio);
  cursor: pointer; box-shadow: var(--sombra); color: var(--tinta);
  transition: border-color var(--rapido), transform var(--rapido);
}
.acao:hover:not(:disabled) { border-color: var(--borda-forte); }
.acao:active:not(:disabled) { transform: scale(.995); }
.acao:disabled { opacity: .55; cursor: not-allowed; }
.acao__icone { font-size: 1.4rem; flex: none; }
.acao__texto { display: flex; flex-direction: column; min-width: 0; }
.acao__texto small { color: var(--tinta-fraca); font-size: .85rem; }
.acao--destaque { border-color: var(--realce); }
.acao--assistir { border-style: dashed; }

/* ── Bipe ───────────────────────────────────────────────────────────────── */
/*
 * `minmax(0, 1fr)` e não `1fr`.
 *
 * Um `1fr` cru é `minmax(auto, 1fr)`, e o `auto` de um <input> é a largura
 * intrínseca dele — uns 170px, venha de onde vier. Somada aos 5rem da
 * quantidade e ao botão, a barra pedia 451px numa tela de 375: o "Adicionar"
 * ficava metade fora e a tela inteira rolava para o lado. É a tela mais usada
 * do sistema, e era a mais quebrada.
 */
.bipe { display: grid; grid-template-columns: minmax(0, 1fr) 4.5rem auto; gap: .5rem; margin-bottom: .5rem; }
.bipe__codigo, .bipe__qtd {
  padding: .9rem 1rem; background: var(--superficie); border: 2px solid var(--borda);
  border-radius: .75rem; font-variant-numeric: tabular-nums;
  transition: border-color var(--rapido);
}
.bipe__codigo { font-size: 1.05rem; font-weight: 600; letter-spacing: .02em; }
.bipe__codigo::placeholder { color: var(--tinta-fraca); font-weight: 400; }
.bipe__codigo:focus, .bipe__qtd:focus { outline: none; border-color: var(--realce); }
.bipe--erro .bipe__codigo { border-color: var(--erro); animation: tremer .3s; }
.dica { color: var(--tinta-fraca); font-size: .84rem; margin: 0 0 1rem; }

/* ── Sugestões da busca ─────────────────────────────────────────────────── */

/*
 * Aparecem embaixo do campo, sem tapar a fila do que já foi contado.
 *
 * Altura limitada de propósito: a lista inteira empurraria os itens contados
 * para fora da tela justamente quando a pessoa quer conferir se acabou de
 * somar no lugar certo.
 */
.sugestoes {
  display: grid; gap: .4rem; margin-bottom: 1rem;
  max-height: 17rem; overflow-y: auto;
  animation: surgir .18s ease-out both;
}
.sugestoes .linha { padding: .6rem .75rem; }
.sugestoes .linha__nome { font-weight: 600; }

/* ── Apoio do bipe e progresso ──────────────────────────────────────────── */
.bipe-apoio { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: 1rem; }
.bipe-apoio .dica { margin: 0; flex: 1; }

.progresso {
  position: fixed; left: 0; right: 0; bottom: 4.5rem; z-index: 16;
  padding: .8rem 1rem; background: var(--superficie); border-top: 1px solid var(--borda);
}
.progresso__barra { height: .5rem; border-radius: 999px; background: var(--fundo); overflow: hidden; }
.progresso__barra span {
  display: block; height: 100%; width: 0; border-radius: 999px; background: var(--ok);
  transition: width 240ms cubic-bezier(.2, .8, .3, 1);
}

/* ── Resumo ─────────────────────────────────────────────────────────────── */
/*
 * Três colunas que podem encolher de verdade.
 *
 * `repeat(3, 1fr)` é `minmax(auto, 1fr)`: cada coluna se recusa a ficar menor
 * que a palavra mais longa de dentro. "ITENS DIVERGENTES" em caixa alta com
 * espaçamento de letra estourava a terceira coluna para fora da tela num
 * aparelho de 320px.
 */
.resumo { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .5rem; margin-bottom: 1rem; }
.resumo__bloco {
  background: var(--superficie); border: 1px solid var(--borda); border-radius: .75rem;
  padding: .7rem; text-align: center; display: flex; flex-direction: column;
}
.resumo__bloco strong { font-size: 1.5rem; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.resumo__bloco small {
  color: var(--tinta-fraca); font-size: .68rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  /*
   * Quebra entre PALAVRAS, nunca dentro delas.
   *
   * Com a coluna já podendo encolher, "ITENS DIVERGENTES" cabe em duas
   * linhas. O `break-word` que o body aplica partiria no meio — "DIVERGEN /
   * TES" — e em caixa alta com espaçamento de letra isso vira sopa.
   */
  overflow-wrap: normal;
}
.resumo__bloco--sobra strong { color: var(--ok); }
.resumo__bloco--falta strong { color: var(--erro); }

/* ── Alerta de venda durante a contagem ─────────────────────────────────── */
.alerta {
  display: flex; align-items: center; gap: .8rem; width: 100%; text-align: left;
  background: var(--parcial-fundo); border: 1px solid #f0d9ac; border-left: 4px solid var(--parcial);
  border-radius: .75rem; padding: .75rem .95rem; color: var(--tinta);
  cursor: pointer; animation: surgir .25s ease-out both;
}
.alerta__icone { font-size: 1.3rem; flex: none; animation: pulsar 2s ease-in-out infinite; }
.alerta__corpo { flex: 1; min-width: 0; }
.alerta__titulo { font-weight: 600; letter-spacing: -.01em; }
.alerta__texto { color: var(--parcial); font-size: .84rem; font-weight: 600; }
.alerta__num { font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums; flex: none; }

/* ── Roteiro do inventário ──────────────────────────────────────────────── */
.roteiro {
  background: var(--superficie); border: 1px solid var(--borda);
  border-radius: .75rem; padding: .8rem .95rem; margin-bottom: 1rem;
}
.roteiro__cabeca { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: .6rem; }
.roteiro__cabeca .dica { display: block; margin: 0; }
.roteiro .progresso__barra span { background: var(--realce); }

/* ── Listas ─────────────────────────────────────────────────────────────── */
/*
 * `minmax(0, 1fr)` em vez da coluna `auto` implícita.
 *
 * Uma coluna `auto` num grid é larga o bastante para o CONTEÚDO caber sem
 * encolher, e o nome do produto tem `white-space: nowrap` — então o conteúdo
 * mínimo é a frase inteira. Medido em 28/09/2026 num celular de 375px: a
 * coluna virava 1087px e a tela inteira rolava para o lado, com metade de cada
 * cartão fora de vista. O `0` do minmax é o que autoriza a coluna a ser menor
 * que o conteúdo, e é ele que faz o `text-overflow: ellipsis` finalmente ter
 * onde acontecer.
 */
.lista { display: grid; grid-template-columns: minmax(0, 1fr); gap: .5rem; }
.linha {
  display: flex; align-items: center; gap: .8rem; width: 100%; text-align: left;
  /* Mesmo motivo do `minmax(0, …)` acima, para quando a linha estiver dentro
     de um flex: sem isto ela se recusa a ficar menor que o próprio texto. */
  min-width: 0;
  background: var(--superficie); border: 1px solid var(--borda);
  border-radius: .75rem; padding: .75rem .95rem; color: var(--tinta);
}
button.linha { cursor: pointer; transition: border-color var(--rapido); }
button.linha:hover { border-color: var(--borda-forte); }
.linha--nova { animation: surgir .25s ease-out both; }
.linha--destaque { border-color: var(--ok); background: var(--ok-fundo); }
/*
 * Mercadoria pendurada: saiu de um depósito e não chegou no outro. Fica em
 * vermelho e pulsando porque um erro desses, quando some da vista, vira saldo
 * errado para sempre — ninguém volta para procurá-lo depois.
 */
.linha--alerta { border-color: var(--erro); background: var(--erro-fundo); animation: pulsarBorda 2.4s ease-in-out infinite; }
/*
 * A BORDA pisca, o texto não.
 *
 * O nome é `pulsarBorda` e não `pulsar` porque já existe um `@keyframes pulsar`
 * mais abaixo que baixa a OPACIDADE a 30%. Ele ganhava por vir depois no
 * arquivo, e o aviso mais urgente da tela virava o mais difícil de ler.
 */
@keyframes pulsarBorda { 0%, 100% { border-color: var(--erro); } 50% { border-color: transparent; } }
.linha__corpo { flex: 1; min-width: 0; }
.linha__nome { font-weight: 600; letter-spacing: -.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.linha__meta { color: var(--tinta-fraca); font-size: .8rem; font-variant-numeric: tabular-nums; }
.linha__num {
  font-size: 1.3rem; font-weight: 700; font-variant-numeric: tabular-nums;
  min-width: 2.4rem; text-align: right; letter-spacing: -.02em; flex: none;
}
.linha__num--piscar { animation: contagem .34s ease-out; }
.pilula {
  font-size: .7rem; font-weight: 700; padding: .2rem .5rem; border-radius: 999px;
  text-transform: uppercase; letter-spacing: .04em; flex: none;
}
.pilula--ok { background: var(--ok-fundo); color: var(--ok); }
.pilula--sobra { background: var(--ok-fundo); color: var(--ok); }
.pilula--falta { background: var(--erro-fundo); color: var(--erro); }
.pilula--aviso { background: var(--parcial-fundo); color: var(--parcial); }
.vazio { text-align: center; color: var(--tinta-fraca); padding: 2.5rem 1rem; }

/* ── Imagem do produto ──────────────────────────────────────────────────── */

/*
 * A miniatura tem tamanho FIXO e reserva o espaço antes de a imagem chegar.
 * Sem isso a lista inteira pula para baixo conforme cada foto carrega, e quem
 * está bipando perde a linha que estava olhando.
 */
.miniatura {
  /*
   * 3,5rem e não 3: o público reconhece o produto pela EMBALAGEM, não pelo
   * nome. Numa prateleira com quarenta frascos parecidos, meio centímetro a
   * mais de foto decide se a pessoa confere ou chuta.
   */
  width: 3.5rem; height: 3.5rem; flex: none; border-radius: .6rem;
  background: var(--fundo); border: 1px solid var(--borda);
  object-fit: cover; display: grid; place-items: center;
  color: var(--tinta-fraca); font-size: 1.1rem; overflow: hidden;
}
.miniatura img { width: 100%; height: 100%; object-fit: cover; display: block; }

.capa {
  width: 100%; max-height: 14rem; object-fit: contain;
  background: var(--fundo); border: 1px solid var(--borda);
  border-radius: .75rem; margin-bottom: 1rem; animation: surgir .25s ease-out both;
}

.fichas { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: .5rem; margin-bottom: 1rem; }
.ficha {
  background: var(--fundo); border: 1px solid var(--borda); border-radius: .6rem; padding: .6rem .7rem;
}
.ficha dt {
  font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em;
  color: var(--tinta-fraca); margin: 0 0 .15rem;
}
.ficha dd {
  margin: 0; font-weight: 600; font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere; font-size: .95rem;
}
.ficha--forte dd { font-size: 1.35rem; letter-spacing: -.02em; }

.etiqueta {
  display: inline-flex; align-items: center; gap: .3rem; font-size: .7rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; padding: .2rem .5rem; border-radius: 999px;
  background: var(--realce-fundo); color: var(--realce);
}

/* ── Faixas ─────────────────────────────────────────────────────────────── */
.faixa { padding: .8rem 1rem; border-radius: .75rem; margin-bottom: 1rem; font-size: .9rem; }
.faixa--aviso { background: var(--parcial-fundo); color: var(--parcial); }
.faixa--info { background: var(--realce-fundo); color: var(--realce); }

/* ── Rodapé fixo ────────────────────────────────────────────────────────── */
.rodape {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 15;
  display: flex; gap: .6rem; padding: .8rem 1rem;
  padding-bottom: calc(.8rem + env(safe-area-inset-bottom));
  background: var(--superficie); border-top: 1px solid var(--borda);
}
/*
 * `min-width: 0` é o que deixa o botão ser menor que o próprio texto.
 *
 * Sem ele, "Enviar para revisão" impõe a largura mínima do rodapé inteiro, e
 * dois botões lado a lado não cabem em 375px — o rodapé passava de 451 e o
 * botão principal saía pela direita da tela.
 */
.rodape .botao { flex: 1; min-width: 0; }
.rodape .botao--principal { flex: 2; }

/* ── Busca ──────────────────────────────────────────────────────────────── */
.busca { margin-bottom: 1rem; }
.busca input {
  width: 100%; padding: .85rem 1rem; background: var(--superficie);
  border: 1px solid var(--borda); border-radius: .75rem;
}
.busca input:focus { outline: none; border-color: var(--realce); }

/* ── Avisos flutuantes ──────────────────────────────────────────────────── */
.brindes {
  position: fixed; left: 50%; bottom: 5.5rem; transform: translateX(-50%); z-index: 40;
  display: grid; gap: .4rem; width: min(24rem, calc(100% - 2rem));
}
.brinde {
  padding: .7rem 1rem; border-radius: .75rem; box-shadow: var(--sombra-alta);
  background: var(--superficie); border: 1px solid var(--borda);
  font-size: .9rem; animation: surgir .22s ease-out both;
}
.brinde--ok { background: var(--ok-fundo); color: var(--ok); border-color: #bfe3d1; }
.brinde--erro { background: var(--erro-fundo); color: var(--erro); border-color: #f2c9c9; }
.brinde--saindo { animation: sumir .18s ease-in both; }

/* ── Folha ──────────────────────────────────────────────────────────────── */
.folha { position: fixed; inset: 0; z-index: 50; background: rgba(18, 23, 29, .35); display: grid; align-items: end; }
.folha__corpo {
  background: var(--superficie); border-radius: 1rem 1rem 0 0; padding: 1.25rem 1rem 2rem;
  max-height: 85dvh; overflow-y: auto; animation: subirFolha .26s cubic-bezier(.2, .9, .3, 1) both;
}
.folha__corpo h2 { margin: 0 0 .25rem; font-size: 1.1rem; }
@media (min-width: 40rem) {
  .folha { align-items: center; justify-items: center; }
  .folha__corpo { border-radius: 1rem; width: min(30rem, 90%); }
}

/* ── Quem está operando ─────────────────────────────────────────────────── */
.quem {
  display: flex; align-items: center; gap: .5rem; padding: .3rem .6rem .3rem .3rem;
  background: var(--fundo); border: 1px solid var(--borda); border-radius: 999px;
  cursor: pointer; color: var(--tinta-suave); font-size: .85rem; font-weight: 600;
  transition: border-color var(--rapido);
  user-select: none; -webkit-user-select: none;
}
.quem:hover { border-color: var(--borda-forte); }
.quem__inicial {
  width: 1.6rem; height: 1.6rem; border-radius: 50%; background: var(--realce); color: #fff;
  display: grid; place-items: center; font-size: .78rem; font-weight: 700;
}
.quem__nome { max-width: 8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 26rem) { .quem__nome { display: none; } }

/* ── Assinatura ─────────────────────────────────────────────────────────── */

/*
 * Tela BRANCA e inteira, de propósito.
 *
 * Assinar é o momento de parar. Uma caixinha por cima da lista continuaria
 * mostrando o trabalho e convidaria a assinar no automático; a tela vazia
 * obriga a olhar o que está sendo confirmado.
 */
.assinatura {
  position: fixed; inset: 0; z-index: 70; background: #fff;
  display: flex; flex-direction: column; padding: 1.5rem 1.25rem;
  padding-bottom: calc(1.5rem + env(safe-area-inset-bottom));
  animation: surgir .2s ease-out both;
}
.assinatura__cabeca { text-align: center; }
.assinatura__cabeca h2 { margin: .5rem 0 .25rem; font-size: 1.15rem; letter-spacing: -.01em; }
.assinatura__cabeca .dica { margin: 0; }

.assinatura__area {
  flex: 1; position: relative; margin: 1.25rem 0;
  border: 2px dashed var(--borda-forte); border-radius: .75rem; overflow: hidden;
  background: #fff;
}
.assinatura__area canvas { width: 100%; height: 100%; display: block; touch-action: none; cursor: crosshair; }
.assinatura__linha {
  position: absolute; left: 0; right: 0; bottom: 1.25rem; margin: 0; text-align: center;
  color: var(--tinta-fraca); font-size: .85rem; pointer-events: none;
}
.assinatura__acoes { display: flex; gap: .6rem; }
.assinatura__acoes .botao { flex: 1; padding: .95rem; }
.assinatura__acoes .botao--principal { flex: 2; }

/* ── Conexão ────────────────────────────────────────────────────────────── */
.conexao {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  background: var(--parcial-fundo); color: var(--parcial);
  font-size: .8rem; padding: .3rem;
}
.ponto { width: .45rem; height: .45rem; border-radius: 50%; background: currentColor; animation: pulsar 1.2s ease-in-out infinite; }

.erro { color: var(--erro); font-size: .88rem; margin: .9rem 0 0; }

@keyframes surgir { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: none } }
@keyframes subirFolha { from { transform: translateY(16px); opacity: .7 } to { transform: none; opacity: 1 } }
@keyframes sumir { to { opacity: 0; transform: translateY(5px) } }
@keyframes contagem { 0% { transform: scale(1) } 35% { transform: scale(1.24) } 100% { transform: scale(1) } }
@keyframes pulsar { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }
@keyframes tremer { 25% { transform: translateX(-5px) } 75% { transform: translateX(5px) } }

/* ── Dedo, não ponteiro ───────────────────────────────────────────────────
 *
 * O sistema é operado em pé, na frente da prateleira, com uma mão segurando o
 * produto. Um alvo de 34px passa num mouse e erra num polegar — e errar aqui
 * não é só incômodo: "Remover" fica a poucos pixels do que a pessoa queria
 * tocar.
 *
 * A regra vale por `pointer: coarse`, que pergunta pelo DEDO, e não por
 * largura de tela: um tablet largo continua sendo tocado com o polegar, e um
 * navegador estreito no desktop continua tendo mouse.
 */
@media (pointer: coarse) {
  /* Os chips do catálogo (ordem e grade/lista) e os botões de linha dos
     alertas nasceram com a altura do texto; aqui ganham a do dedo. */
  .botao--chip,
  .linha .alerta-toggle,
  .linha .alerta-remover,
  .linha .alerta-trava-remover {
    min-height: 2.75rem;
  }
  /* Voltar e o chip de quem está operando ficavam a um fio dos 44px: no
     cabeçalho, que é onde a mão alcança primeiro, não vale arriscar. */
  #voltar.botao--icone { min-height: 2.75rem; min-width: 2.75rem; }
  .quem { min-height: 2.75rem; }
}

/*
 * O campo de bipe sozinho na primeira linha.
 *
 * Em 375px os três controles lado a lado deixavam 148px para o campo — menos
 * de 40% da tela para o campo MAIS usado do sistema, enquanto "Adicionar"
 * levava 107px. Quem digita nome de produto via só uns quinze caracteres do
 * que escreveu.
 *
 * Empilhado, o nome ocupa a largura inteira e a quantidade segue ao lado do
 * botão, que é o par que anda junto.
 */
@media (max-width: 30rem) {
  .bipe { grid-template-columns: 4.5rem minmax(0, 1fr); }
  .bipe__codigo { grid-column: 1 / -1; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ── Painel ─────────────────────────────────────────────────────────────── */
.periodo { display: flex; gap: .5rem; margin-bottom: 1rem; }
.botao--periodo { flex: 1; }
/* O período em uso precisa se distinguir sem cor forte: é escolha, não alerta. */
.botao--periodo.em-uso { background: var(--tinta); color: var(--superficie); border-color: transparent; }
.cartoes { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; margin-bottom: 1.25rem; }
.cartao-num {
  background: var(--superficie); border: 1px solid var(--borda); border-radius: .75rem;
  padding: .9rem .5rem; text-align: center;
}
.cartao-num strong { display: block; font-size: 1.6rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.cartao-num small { display: block; color: var(--tinta-fraca); font-size: .72rem; margin-top: .2rem; }
.cartao-num--erro { border-color: var(--erro); background: var(--erro-fundo); }
.cartao-num--erro strong { color: var(--erro); }

/* ── Linha do tempo ─────────────────────────────────────────────────────── */
.linha-tempo { display: grid; gap: .1rem; }
.evento { display: flex; gap: .8rem; }
/* O traço que liga um evento ao seguinte: é ele que faz virar linha do tempo
   em vez de lista solta. O último não tem para onde continuar. */
.evento__marca {
  flex: none; width: 2rem; height: 2rem; display: grid; place-items: center;
  border-radius: 50%; background: var(--superficie); border: 1px solid var(--borda);
  position: relative; font-size: .9rem;
}
.evento:not(:last-child) .evento__marca::after {
  content: ''; position: absolute; top: 2rem; left: 50%; width: 1px;
  height: calc(100% + .1rem); background: var(--borda);
}
.evento__corpo { flex: 1; min-width: 0; padding-bottom: 1rem; }
.evento__topo { display: flex; align-items: baseline; gap: .5rem; }
.evento__qtd { font-variant-numeric: tabular-nums; font-weight: 700; }
.evento__qtd--entra { color: var(--ok); }
.evento__qtd--sai { color: var(--erro); }
.evento__texto { margin: .2rem 0; font-size: .85rem; line-height: 1.45; }
.evento__pe { color: var(--tinta-fraca); font-size: .75rem; }

/* ── Escolher o que fazer: saída, entrada ou balanço ────────────────────── */
/*
 * Três botões grandes em vez de um campo "saldo correto".
 *
 * Quem está na bancada pensa em "saiu 2", não em "o saldo passa a ser 688".
 * Obrigar a fazer a subtração de cabeça é como se erra o número.
 */
.modos { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; margin: 1rem 0 .25rem; }
.modo {
  display: flex; flex-direction: column; align-items: center; gap: .1rem;
  padding: .75rem .4rem; cursor: pointer; text-align: center;
  background: var(--superficie); border: 1px solid var(--borda); border-radius: .75rem;
  color: var(--tinta-suave); transition: border-color var(--rapido), background var(--rapido);
}
.modo:hover { border-color: var(--borda-forte); }
.modo__sinal { font-size: 1.3rem; font-weight: 700; line-height: 1; }
.modo__nome { font-weight: 650; font-size: .9rem; }
.modo small { font-size: .68rem; color: var(--tinta-fraca); line-height: 1.2; }
.modo--ativo { border-color: var(--tinta); background: var(--tinta); color: var(--superficie); }
.modo--ativo small { color: rgba(255,255,255,.72); }

/* A prévia do resultado: "690 → 688" é conferível de cabeça antes de mandar. */
.previa { margin: .5rem 0 0; font-size: .9rem; font-weight: 650; font-variant-numeric: tabular-nums; min-height: 1.3rem; }
.previa--sobe { color: var(--ok); }
.previa--desce { color: var(--parcial); }
.previa--erro { color: var(--erro); }

/* ── A fila indo para o Bling ───────────────────────────────────────────── */
.fila__lado { display: flex; flex-direction: column; align-items: flex-end; gap: .25rem; }
.linha__erro { color: var(--erro); font-size: .78rem; margin-top: .2rem; }
.fila--fazendo { border-color: var(--realce); background: var(--realce-fundo); }
.fila--espera { border-style: dashed; }
.fila--feito { border-color: #bfe3d1; }
.fila--falhou, .fila--duvida { border-color: var(--erro); background: var(--erro-fundo); }

.etiqueta--fazendo { background: var(--realce-fundo); color: var(--realce); }
.etiqueta--espera { background: var(--fundo); color: var(--tinta-fraca); }
.etiqueta--feito { background: var(--ok-fundo); color: var(--ok); }
.etiqueta--falhou, .etiqueta--duvida { background: var(--erro-fundo); color: var(--erro); }

/* "enviando…" precisa PARECER que está andando, senão é igual a travado. */
.fila--fazendo .linha__nome::after {
  content: ''; display: inline-block; width: .5rem; height: .5rem; margin-left: .4rem;
  border-radius: 50%; background: var(--realce); animation: pulsar 1s ease-in-out infinite;
}

/* "Todos os depósitos": o atalho de zerar um produto de uma vez. */
.linha--todos { border-style: dashed; border-color: var(--borda-forte); }
.previa--lista { display: grid; gap: .15rem; font-weight: 500; }
.previa__linha { display: flex; justify-content: space-between; gap: 1rem; font-size: .85rem; }
.previa__linha span { color: var(--tinta-fraca); }
.previa__linha strong { font-variant-numeric: tabular-nums; }

/* O cabeçalho da fila, com o botão de limpar do lado do título. */
.fila__cabecalho { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: .6rem; }
.botao--pequeno { padding: .35rem .7rem; font-size: .8rem; }

/* A peça que trava o kit: o saldo do kit é o dela, e só dela. */
.linha--gargalo { border-color: var(--erro); background: var(--erro-fundo); }

/*
 * Abas da ficha do produto.
 *
 * O histórico existia desde sempre, mas como um botão no PÉ da ficha — depois
 * dos sete depósitos e do "mover entre depósitos". Quem abria um produto não
 * rolava até lá, e concluía que o sistema não guardava a história. Aqui em
 * cima ele deixa de ser um achado e vira uma das duas metades do produto.
 */
.abas {
  display: flex; gap: .25rem; margin: 0 0 1rem;
  border-bottom: 1px solid var(--borda);
}
.aba {
  flex: 1; padding: .6rem .5rem; border: 0; background: none; cursor: pointer;
  font: inherit; font-weight: 600; color: var(--tinta-fraca);
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.aba--ativa { color: var(--tinta); border-bottom-color: var(--realce); }
.aba:disabled { cursor: default; }

/* ── Catálogo de um depósito ──────────────────────────────────────────────
 *
 * Grade de fotos em vez de lista de linhas. A pergunta aqui é "o que tem
 * guardado nesta prateleira?", e essa pergunta se responde com o olho: a
 * pessoa reconhece o frasco antes de ler o nome.
 *
 * `auto-fill` com mínimo de 8rem cresce sozinho: duas colunas no celular,
 * mais no computador, sem nenhuma media query.
 *
 * O 8rem é medido, não escolhido a esmo. Com 9rem, um aparelho de 320px não
 * cabia duas colunas (2 × 144 + 12 de vão = 300 contra 288 disponíveis) e
 * caía para UMA — um cartão gigante por fileira, rolagem infinita e metade da
 * tela vazia.
 *
 * O `min(…, 100%)` protege o caso extremo de uma tela mais estreita que o
 * próprio mínimo, onde o cartão passaria da borda.
 */
.catalogo {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(8rem, 100%), 1fr));
  gap: .75rem;
}
.cartao-prod {
  display: flex; flex-direction: column; text-align: left; padding: 0; overflow: hidden;
  background: var(--superficie); border: 1px solid var(--borda); border-radius: .9rem;
  cursor: pointer; font: inherit; color: var(--tinta);
  transition: border-color var(--rapido), transform var(--rapido);
}
.cartao-prod:hover { border-color: var(--borda-forte); }
.cartao-prod:active { transform: scale(.98); }
/* Quadrado fixo: foto de proporção diferente não desalinha a grade inteira. */
.cartao-prod__foto {
  aspect-ratio: 1; width: 100%; object-fit: cover; background: var(--fundo);
  display: block;
}
.cartao-prod__semfoto {
  aspect-ratio: 1; display: grid; place-items: center; font-size: 2rem;
  background: var(--fundo); color: var(--tinta-fraca);
}
.cartao-prod__corpo { padding: .55rem .65rem .65rem; display: flex; flex-direction: column; gap: .15rem; }
/*
 * Nome em duas linhas no máximo, com reticências.
 *
 * Os nomes aqui passam de cem caracteres ("Emulsão Oxidante Express 900ml
 * Selecione Volumes e Quantidade…"): soltos, um cartão ficaria quatro vezes
 * mais alto que o vizinho e a grade viraria escada.
 */
.cartao-prod__nome {
  font-size: .82rem; font-weight: 600; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  /* Reserva as duas linhas mesmo quando o nome ocupa uma: numa grade, um
     cartão mais baixo que o vizinho desalinha a fileira inteira. */
  min-height: 2.05em;
}
/*
 * SKU em UMA linha, com reticências.
 *
 * "SKUCO15122025-9.21 · kit" quebrava em duas e deixava aquele cartão mais
 * alto que os vizinhos — numa grade, um cartão fora de medida desalinha a
 * fileira inteira.
 */
.cartao-prod__sku {
  font-size: .68rem; color: var(--tinta-fraca); font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cartao-prod__qtd {
  margin-top: .3rem; font-size: 1.35rem; font-weight: 700; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.cartao-prod__qtd small { font-size: .7rem; font-weight: 600; color: var(--tinta-fraca); margin-left: .2rem; }
/* Barra do catálogo: ordem à esquerda, grade/lista à direita. */
.catalogo-barra {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin: 0 0 .7rem; flex-wrap: wrap;
}
.catalogo-visao { display: flex; gap: .25rem; }
.botao--chip { padding: .4rem .7rem; font-size: .82rem; border-radius: 999px; }
/* Em uso fica com o contraste invertido: num par de chips, cor de borda sozinha
   não diz qual está valendo. */
.botao--chip.em-uso { background: var(--tinta); color: var(--superficie); border-color: transparent; }
/*
 * A sentinela ocupa altura.
 *
 * Com altura zero ela pode nunca cruzar a viewport em telas altas, e a rolagem
 * infinita simplesmente não dispararia.
 */
.catalogo-fim {
  min-height: 3rem; display: grid; place-items: center;
  color: var(--tinta-fraca); font-size: .8rem;
}
/* O mesmo vermelho do cartão, na visão em lista. Sem a borda pulsante de
   `.linha--alerta`: ali o pulso é para mercadoria pendurada, que é urgência de
   outra natureza. */
.linha--negativo { border-color: var(--erro); background: var(--erro-fundo); }
.linha--negativo .linha__num { color: var(--erro); }
.linha__num small { font-size: .7rem; font-weight: 600; color: var(--tinta-fraca); margin-left: .15rem; }

/* Negativo é impossível na prateleira: fica vermelho para ser investigado. */
.cartao-prod--negativo { border-color: var(--erro); background: var(--erro-fundo); }
.cartao-prod--negativo .cartao-prod__qtd { color: var(--erro); }

/* Alertas de estoque: cada número tem caixa de seleção e os botões de pausar e
   remover. Os botões não encolhem o texto do número; a caixa fica alinhada. */
.alerta-check { display: flex; align-items: center; flex: 0 0 auto; }
.alerta-check input { width: 1.15rem; height: 1.15rem; }
.linha .alerta-toggle, .linha .alerta-remover, .linha .alerta-trava-remover { flex: 0 0 auto; padding: .4rem .65rem; font-size: .8rem; }

/* A conexão com o WAHA: um bloco que fica recolhido quando já está configurado
   e aberto quando falta configurar (o `open` vem do HTML). */
.alerta-conexao {
  border: 1px solid var(--borda); border-radius: .75rem;
  padding: .5rem .95rem .95rem; margin-bottom: 1rem; background: var(--superficie);
}
.alerta-conexao summary { cursor: pointer; font-weight: 600; padding: .4rem 0; }
.alerta-conexao .campo { margin-top: .75rem; }
