/* ==========================================================================
   CASCA — barra lateral, barra superior, pagina, responsivo.
   FONTE: DS 4.0, secao "A CASCA".

   A v2 pintava a lateral de branco e chamava isso de "superficie, nao fundo".
   O DS 4.0 desfaz essa decisao pela LEI 2: cor precisa de AREA. Com a marca
   vivendo so em objetos de 22 px, o produto inteiro lia como cinza. A lateral
   agora e um campo grande de --inst — e e nela que a marca vira navegacao.
   ========================================================================== */

.app { display: grid; grid-template-columns: var(--lat) minmax(0, 1fr); height: 100dvh; }
.app.recolhida { grid-template-columns: var(--lat-min) minmax(0, 1fr); }

/* ======================================================= barra lateral === */
.lat {
  background: var(--inst); color: var(--inst-fg);
  display: flex; flex-direction: column; min-height: 0;
  position: relative; overflow: hidden;
}
/* No tema claro a lateral separa do conteudo por 15:1 de claridade e nao
   precisa de nada. No escuro nao ha essa folga: violeta escuro contra fundo
   quase preto mede 1.22, e um campo sem aresta some. A aresta e o que
   restabelece a moldura — nao e decoracao, e o limite do campo. */
html[data-tema="escuro"] .lat { border-right: 1px solid var(--lin2); }
/* a malha: e ESTRUTURA, nao textura — o passo e o mesmo --e5 do resto */
.lat::before {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(var(--inst-mesh) 1px, transparent 1px);
  background-size: var(--e5) var(--e5); opacity: .14; pointer-events: none;
}

.lat__marca { display: flex; align-items: center; gap: 10px; padding: 16px 16px 20px; position: relative; }
/* ⚠ A CAIXA DA MARCA NÃO É QUADRADA, e QUEM DECIDE A LARGURA É O ARQUIVO.
   O arquivo oficial (`casca.js:marca()`) tem viewBox 108×64 = 1,6875:1, contra
   os 24×24 da marca desenhada que ele substituiu. Só a ALTURA se digita aqui;
   `width: auto` deixa o navegador derivar a largura do viewBox — medido, 22 px
   de altura dão 37,125 px, exatos. Digitar a largura seria a segunda cópia da
   proporção, e ela divergiria em silêncio no dia em que o arquivo mudasse: a
   marca não quebra, ela só letterboxa dentro da caixa errada.
   22 px é a altura que mantém a presença ótica dos 22×22 anteriores — o
   conteúdo ocupa 49 dos 64 do viewBox, então há calha em cima e embaixo. E os
   37 px resultantes cabem com folga de 11 px na lateral recolhida, que mede
   `--lat-min` (60 px). */
.lat__marca .mk { width: auto; height: 22px; flex: none; }
.lat__marca b { font-size: 13px; font-weight: 600; letter-spacing: -.012em; white-space: nowrap; }
.lat__marca .rec {
  margin-left: auto; background: none; border-color: transparent;
  color: rgba(243,240,251,.5); opacity: 0; transition: opacity var(--t1) var(--ease), color var(--t1) var(--ease);
}
.lat:hover .lat__marca .rec { opacity: 1; }
.lat__marca .rec:hover { background: rgba(243,240,251,.1); color: #F3F0FB; border-color: transparent; }

/* ------------------------------------------------------------- trajeto ---
   A linha que liga os nos e a marca virada navegacao.
   TRES PECAS, UM EIXO. No, linha e indicador tem larguras diferentes (9, 1.5 e
   17 px), entao cada um precisa do seu proprio recuo para o MESMO centro. Cada
   um com um `left` chutado foi como o indicador ficou 4 px fora do no. */
.lat__nav {
  --eixo: 22.5px;
  position: relative; padding: 0 12px; flex: 1; min-height: 0; overflow-y: auto;
  align-self: stretch;
}
.lat__nav::before {
  content: ""; position: absolute; left: calc(var(--eixo) - .75px); top: 14px; bottom: 14px;
  width: 1.5px; background: rgba(243,240,251,.15);
}

/* o grupo nao cria caixa nem calha propria: os nos de todos os grupos precisam
   cair no MESMO eixo vertical, que e o da nav. */
.lat__gr { display: block; }
.lat__gr > .rot {
  position: relative; display: block; padding: 16px 0 6px 28px;
  font-family: var(--fm); font-size: 9.5px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: rgba(243,240,251,.34);
}

.lat a.nv {
  position: relative; display: flex; align-items: center; gap: 12px;
  height: 34px; padding: 0 10px 0 0; border-radius: var(--r-sm);
  font-size: 12.5px; color: rgba(243,240,251,.62);
  transition: color calc(var(--t1) * var(--mo)) var(--suave);
}
@media (hover: hover) {
  .lat a.nv:hover { color: #F3F0FB; transition-duration: calc(var(--t2) * var(--mo)); }
}

/* o NO */
.lat a.nv .no {
  width: 9px; height: 9px; border-radius: 50%; flex: none; margin-left: 6px;
  border: 1.5px solid rgba(243,240,251,.4); background: var(--inst);
  transition: background var(--t2) var(--ease), border-color var(--t2) var(--ease),
              transform var(--t2) var(--ease);
}
.lat a.nv:hover .no { border-color: var(--b300); }
.lat a.nv.on { color: #FFF; font-weight: 550; }
.lat a.nv.on .no { background: var(--b400); border-color: var(--b400); transform: scale(1.25); }

/* O ÚLTIMO NÓ DA LATERAL É LIME — portado do DS 4.0
   (`.nav a:last-of-type .no`), que eu não tinha aplicado.
   A lateral É o trajeto, e todo trajeto do sistema termina em lime: a marca, a
   arte de fundo e o ícone do app já faziam isso, e só a navegação — a peça
   MAIOR das três — ficava sem destino. `:last-of-type` sozinho acenderia o
   último de CADA grupo (dois nós lime); o destino é um só, então o seletor
   ancora no último grupo. Relatórios é o fim do trajeto de verdade: é a tela
   de onde o material sai do sistema. */
.lat__gr:last-child a.nv:last-of-type .no { border-color: color-mix(in srgb, var(--lime) 55%, transparent); }
.lat__gr:last-child a.nv:last-of-type:hover .no { border-color: var(--lime); }
.lat__gr:last-child a.nv:last-of-type.on .no { background: var(--lime); border-color: var(--lime); }

.lat a.nv .n { margin-left: auto; font-family: var(--fm); font-size: 10.5px; color: rgba(243,240,251,.4); }
.lat a.nv.on .n { color: var(--b300); }
/* o badge do Hoje: O QUE VENCE HOJE, nao o tamanho da fila. 3 e um alarme;
   120 e um acervo. Em dia calmo ele some — nao se renderiza zero. */
.lat a.nv.dest .n {
  background: var(--b600); color: #fff; font-weight: 600;
  padding: 1px 6px; border-radius: var(--pill); min-width: 20px; text-align: center;
}
.lat a.nv.dest.on .n { background: var(--b400); color: var(--inst); }
/* O LOGIN VENCIDO (05/11/2026) — a exceção de cor de `regras/interface.md`, só neste
   item. A cor não vai sozinha: o nó vira losango, que sobrevive à lateral
   recolhida, e o `!` sai com ela aberta. O vermelho é claro de propósito: o `--r1`
   do tema claro não tem contraste contra o fundo escuro da lateral. */
.lat a.nv.nv--login { color: #FF9AA8; font-weight: 550; }
.lat a.nv.nv--login .no, .lat a.nv.nv--login:hover .no, .lat a.nv.nv--login.on .no {
  background: #FF9AA8; border-color: #FF9AA8; border-radius: 2px; transform: rotate(45deg);
}
.nv__login {
  margin-left: auto; width: 16px; height: 16px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-size: 11px; font-weight: 700; line-height: 1;
  background: #FF9AA8; color: var(--inst);
}

/* o indicador que corre pelo trajeto — a marca em movimento */
.lat__ind {
  position: absolute; left: calc(var(--eixo) - 8.5px); top: 0;
  width: 17px; height: 17px; border-radius: 50%;
  background: color-mix(in srgb, var(--b400) 22%, transparent);
  pointer-events: none; opacity: 0;
  transition: transform calc(var(--t3) * var(--mo)) cubic-bezier(.34, 1.3, .5, 1),
              opacity var(--t2) var(--ease);
}
.lat__ind.on { opacity: 1; }
html[data-m="s"] .lat__ind { transition: transform var(--t1) var(--ease), opacity var(--t1) var(--ease); }

/* -------------------------------------------------------------- rodape ---
   O DESTINO da lateral: o filtro global de empresa e a prova de que o dado
   chegou. O ponto e lime porque lime e chegada — e nao verde, que pertence
   ao prazo e a mais nada. */
.lat__pe {
  position: relative; flex: none; align-self: stretch;
  display: flex; flex-direction: column; gap: 10px;
  margin: 0 12px 12px; padding: 12px; border-radius: var(--r-md);
  background: rgba(243,240,251,.06);
}

/* CONFIGURACOES NAO ENTRA NAS DUAS AREAS. Mora aqui, no rodape, acima do
   seletor de empresa: nao e trabalho nem leitura, e manutencao, e se usa uma
   vez por mes. Ficar fora dos grupos e tambem o que garante que ela NUNCA
   acende lime — o seletor do ultimo no ancora em `.lat__gr:last-child`, e lime
   e fim de trajeto, nunca item de menu. */
.lat__cfg {
  display: flex; align-items: center; gap: 10px; flex: none;
  height: 30px; padding: 0 8px; margin: -2px -4px 0; border-radius: var(--r-xs);
  font-size: 12px; color: rgba(243,240,251,.62);
  transition: color calc(var(--t1) * var(--mo)) var(--suave),
              background calc(var(--t1) * var(--mo)) var(--suave);
}
.lat__cfg .ico { flex: none; }
.lat__cfg.on { color: #FFF; font-weight: 550; background: rgba(243,240,251,.1); }

.lat__emp {
  display: block; width: 100%; position: relative; text-align: left;
  padding: 0 22px 0 0; color: inherit;
  border-radius: var(--r-xs); transition: opacity var(--t1) var(--ease);
}
.lat__emp:hover { opacity: .78; }
.lat__emp .rot { display: block; color: rgba(243,240,251,.42); font-size: 9.5px; letter-spacing: .1em; }
.lat__emp b { display: block; margin-top: 3px; font-size: 12px; font-weight: 600;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lat__emp i { display: block; font-style: normal; font-family: var(--fm);
              font-size: 10.5px; color: rgba(243,240,251,.5);
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lat__emp .lat__emp-cv { position: absolute; right: 2px; top: 50%; margin-top: -6px; color: rgba(243,240,251,.45); }
.lat__emp .lat__emp-ic { display: none; color: rgba(243,240,251,.62); }

.lat__coleta {
  display: flex; gap: 8px; padding-top: 10px; border-top: 1px solid rgba(243,240,251,.1);
  font-size: 10.5px; color: rgba(243,240,251,.5); line-height: 1.35;
}
.lat__coleta s { text-decoration: none; width: 9px; height: 9px; border-radius: 50%;
                 background: var(--lime); flex: none; margin-top: 3px; }

/* --------------------------------------------------------- recolhida ----
   `.lat a.nv span` esconderia TAMBEM o no, que e span — a lateral colapsada
   ficaria sem os pontos, que sao a assinatura do sistema. */
.app.recolhida .lat__marca b,
.app.recolhida .lat__marca .rec,
.app.recolhida .lat__gr > .rot,
.app.recolhida .lat a.nv span:not(.no),
.app.recolhida .lat__emp .rot,
.app.recolhida .lat__emp b,
.app.recolhida .lat__emp i,
.app.recolhida .lat__coleta,
.app.recolhida .lat__cfg span,
.app.recolhida .lat__emp .lat__emp-cv { display: none; }
.app.recolhida .lat__cfg { justify-content: center; padding: 0; margin: 0 0 6px; }
.app.recolhida .lat__marca { padding: 16px 0 20px; justify-content: center; }
.app.recolhida .lat__nav { --eixo: 30px; }
.app.recolhida .lat a.nv { justify-content: center; padding: 0; }
.app.recolhida .lat a.nv .no { margin-left: 0; }
.app.recolhida .lat__pe { margin: 0 8px 12px; padding: 10px 0; }
.app.recolhida .lat__emp { display: grid; place-items: center; padding: 0; }
.app.recolhida .lat__emp .lat__emp-ic { display: block; }

/* --------------------------------------------------- pular para o conteudo
   PORTADO DO DS 4.0 (`.pular`), que eu nao tinha aplicado — e o produto nao
   tinha equivalente nenhum. Sem ele, quem navega por teclado atravessa os SEIS
   links da lateral em toda troca de tela antes de chegar na tabela. Fica fora
   da tela ate receber foco, e ai aparece como o primeiro alvo do Tab. */
.pular {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  padding: 10px 14px; background: var(--acao); color: var(--acao-fg);
  border-radius: var(--r-sm); font-size: 12.5px; font-weight: 550;
}
.pular:focus { left: 8px; top: 8px; }

/* ======================================================== barra superior = */
.principal { position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.topo {
  flex: none; display: flex; align-items: center; gap: var(--e4);
  height: var(--topo); padding: 0 var(--e6);
  border-bottom: 1px solid var(--lin); background: var(--sup);
  position: relative; z-index: var(--z-fixo);
}
.topo__mig { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--fg3); min-width: 0; }
.topo__mig b { font-size: 15px; font-weight: 600; letter-spacing: -.012em; color: var(--fg); white-space: nowrap; }
.topo__mig > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topo__mig .ico { width: 13px; height: 13px; color: var(--fg4); }

/* a busca do topo e uma superficie RECUADA sobre a barra branca: ela recebe o
   --bg tingido, que agora tem degrau suficiente contra o branco para dispensar
   borda pesada. */
.topo__busca {
  display: flex; align-items: center; gap: var(--e3); height: 32px; padding: 0 10px;
  min-width: 250px; border-radius: var(--r-sm);
  background: var(--bg); border: 1px solid var(--lin); color: var(--fg3); font-size: 12.5px;
  transition: border-color var(--t1) var(--ease), background var(--t1) var(--ease);
}
.topo__busca:hover { border-color: var(--lin3); background: var(--sup); }
.topo__busca > span { flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 19px; height: 19px; padding: 0 5px; flex: none;
  border: 1px solid var(--lin2); border-bottom-width: 2px; border-radius: var(--r-xs);
  background: var(--sup); font-family: var(--fm); font-size: 10px; color: var(--fg2);
}

/* identidade de quem opera. Roxo institucional (b800) — o escritorio que opera
   o painel, nao um usuario inventado. */
.topo__id {
  display: grid; place-items: center; width: 28px; height: 28px; flex: none;
  border-radius: 50%; background: var(--b800); color: #fff;
  font-size: 11px; font-weight: 600; letter-spacing: .02em;
  transition: box-shadow var(--t1) var(--ease);
}
.topo__id:hover { box-shadow: 0 0 0 3px var(--b50); }
html[data-tema="escuro"] .topo__id { background: var(--b300); color: var(--b900); }
html[data-tema="escuro"] .topo__id:hover { box-shadow: 0 0 0 3px var(--b100); }

.hamb { display: none; }

/* -------------------------------------------------- alvo de toque ------
   O DS desenha os controles do topo em 32 px, e no desktop isso esta certo —
   ponteiro fino acerta 32 px sem esforco. Em tela de toque o minimo e 44, e
   medimos 32x32 no tema/menu e 28x28 na identidade.

   A correcao amplia a AREA, nao o desenho: um pseudo-elemento centrado de
   44x44 em `pointer:coarse`. Aumentar a altura visual empurraria a barra de
   56 px inteira e mudaria o ritmo da casca em todas as larguras — o defeito
   e de alcance, entao a correcao tem que ser de alcance.

   MEDIDO: com o gap de --e4 (12 px) o par tema/identidade fica a 42 px entre
   centros (16 + 12 + 14) e os halos de 44 se sobrepoem por 2 px — o toque na
   borda direita do tema caia na identidade. Com --e5 sao 46 px entre centros e
   os halos param de encostar. O gap so muda em toque; no desktop a barra fica
   exatamente como o DS a desenhou. */
@media (pointer: coarse) {
  .topo { gap: var(--e5); }
  .topo .bt--ico, .topo__id, .hamb { position: relative; }
  .topo .bt--ico::after, .topo__id::after, .hamb::after {
    content: ""; position: absolute; left: 50%; top: 50%;
    width: 44px; height: 44px; transform: translate(-50%, -50%);
  }
}

/* ============================================================== pagina ===
   LINGUAGEM GRAFICA — o fundo comunica, nunca compete.
   Camada 1: a grade de checkpoints, passo de --e5.
   Camada 2: o trajeto — polilinha com nos, em peso visual baixo.
   As duas vivem em `.arte`, que e irma da pagina e nao rola com ela: campo de
   pontos que rola produz costura visivel a cada quadro. */
.arte {
  position: absolute; top: var(--topo); left: 0; right: 0; bottom: 0;
  pointer-events: none; z-index: 0; overflow: hidden;
}
.arte::before {
  content: ""; position: absolute; inset: 0;
  background-image: radial-gradient(color-mix(in srgb, var(--b400) 22%, transparent) 1px, transparent 1px);
  background-size: var(--e5) var(--e5); opacity: .55;
}
.arte svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.arte .via { stroke: var(--b400); fill: none; stroke-linejoin: round; stroke-linecap: round; }
.arte .no  { fill: var(--b400); }
.arte .fim { fill: var(--lime); }

/* quem rola e ESTE elemento, e o padding lateral e dele — nunca max-width no
   elemento que rola, senao a barra de rolagem descola da borda da janela.
   scrollbar-gutter both-edges: sem o primeiro, a barra que aparece e some
   realimenta o observer de largura; sem o segundo a pagina fica assimetrica.
   ⚠ O RESPIRO DE BAIXO E `--pg-pb`, E ELE E LIDO POR QUEM GRUDA NO FIM
   *(30/09/2026)*: o `sticky; bottom` de um filho gruda no fim da CAIXA DE
   CONTEUDO do `.pg`, nao no da janela — o Chrome desconta o padding. Medido:
   a `.selbar` flutuava 64 px acima do fim da tela, cobrindo linhas. Quem
   gruda embaixo compensa com este numero (`.selbar`), e as duas faixas de
   baixo (64 e 56 px) trocam o numero, nunca o padding direto. */
.pg {
  --pg-pb: 72px;
  position: relative; z-index: 1;
  flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden;
  scrollbar-gutter: stable both-edges;
  padding: var(--e6) var(--e6) var(--pg-pb);
}
.pg__in { max-width: var(--pg-max); margin: 0 auto; display: flex; flex-direction: column; gap: var(--e6); }
/* item de flex tem `min-width:auto`: um cartao com tabela larga dentro cresce
   ate caber a tabela e leva a pagina junto, mesmo com overflow-x no .tb-rol.
   Medido em 375 px na Concentracao — a tabela de 930 px empurrava o .pg. */
.pg__in > * { min-width: 0; }

/* cabecalho de tela */
.cab { display: flex; align-items: flex-end; gap: var(--e4); flex-wrap: wrap; }
.cab .col { gap: 3px; }
/* ⚠ `flex-wrap: wrap` NAO E SIMETRIA COM `.cab`: e o que impede o conteudo de
   ser CORTADO em vez de descer. `.pg` e `overflow-x: hidden`, entao um filho
   largo demais nao rola — ele some pela direita, e a pagina continua com
   `scrollWidth` igual a largura da janela, que e o sintoma que passa verde em
   toda regua de estouro. Medido a 375 px na T5, com o par de lente ao lado do
   total do Acervo: 145 + 8 + 229 = 382 dentro de um `.cab` de 349, e o chip
   "Acervo inteiro" — a UNICA porta do estado *todos* — ficava inalcancavel. */
.cab__acoes { margin-left: auto; display: flex; align-items: center; gap: var(--e3);
              flex-wrap: wrap; }

/* barra de ferramentas */
.fer { display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap; }
/* O CAMPO QUE FILTRA A LISTA — não é a busca do acervo.
   Havia três superfícies de busca no sistema com o MESMO desenho e dois
   comportamentos: a do topo (⌘K, varre o acervo inteiro e abre o dossiê), a do
   Acervo e a da Concentração (recortam o que já está em tela). Mesma lupa,
   mesma caixa, mesma altura. Agora este leva FUNIL, cantos de pílula e rótulo
   que diz onde ele age; a lupa fica sendo só da busca global. */
.fer__busca {
  display: flex; align-items: center; gap: 7px; height: 32px; padding: 0 12px;
  border-radius: var(--pill); background: var(--sup2); border: 1px solid var(--lin2);
  /* ⚠ ELA CRESCE, e o numero antigo era o defeito: `flex: 0 1 268px` a travava
     em 268 px numa linha de 974, entao o controle MAIS USADO do produto —
     *"essa placa tem multa?"* — ocupava 27% da faixa e o resto ficava vazio,
     com o botao `Filtros` de 58 px perdido ao lado. `flex: 1 1 380px` a faz
     tomar o espaco que sobra ate um teto de leitura: linha de busca mais larga
     que ~520 px so afasta o cursor do texto que ele digitou. */
  /* ⚠ SEM TETO. Havia um `max-width: 520px` aqui com o argumento de que linha
     mais larga afasta o cursor do texto — verdadeiro para um formulario, falso
     para esta barra: o teto deixava ~400 px de vazio entre a busca e o
     `Filtros`, e vazio no meio de um agrupamento de controles le como controle
     faltando. Ela cresce e empurra o par `Filtros`/`Limpar tudo` para a borda,
     que e onde o olho ja procura acao secundaria. */
  min-width: 210px; flex: 1 1 380px;
  transition: border-color var(--t1) var(--ease), box-shadow var(--t1) var(--ease),
              background var(--t1) var(--ease);
}
.fer__busca:focus-within { background: var(--sup); border-color: var(--b400); box-shadow: var(--anel); }
.fer__busca .ico { color: var(--fg3); }
.fer__busca input { flex: 1; min-width: 0; font-size: 12.5px; }
.fer__busca input::placeholder { color: var(--fg3); }
/* o campo cheio se declara aceso: filtro ativo que parece vazio é filtro
   esquecido, e o operador jura que a lista está incompleta */
.fer__busca--on { background: var(--b50); border-color: var(--b300); }
.fer__busca--on .ico { color: var(--b600); }
html[data-tema="escuro"] .fer__busca--on .ico { color: var(--b500); }
.fer__chips { display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap; }

/* a faixa que abre com os cinco filtros do Acervo. Dentro da chapa ela já
   herda o degrau --sup2 e o fio de 1 px acima — aqui só o rótulo que a nomeia,
   para a faixa não aparecer como uma fileira de botões sem dono. */
.fer--exp .rot { margin-right: var(--e2); }
@media (max-width: 560px) { .fer--exp .rot { display: none; } }

/* faixa de constantes: o que e igual em toda a lista sobe para ca em vez de
   repetir em N linhas. le o resultado inteiro, nao a pagina. */
/* A FAIXA DE ESCOPO — DUAS CASAS, E SO UMA DELAS COLA NA TABELA.
   `.const` cru e a de Relatorios: barra solta que declara o recorte do
   documento, com icone, contagem e um botao na ponta. Ela fica como esta.
   `.const--fx` e a faixa de constantes do Acervo, que fala DA TABELA logo
   abaixo — outra pergunta, outro desenho, mesmo esqueleto. */
.const { display: flex; align-items: center; gap: var(--e4); flex-wrap: wrap;
         padding: 9px 14px; border-radius: var(--r-md); background: var(--sup2);
         font-size: 12px; color: var(--fg2); }
.const b { color: var(--fg); font-weight: 550; }

/* ---------------------------------------- a faixa de constantes do Acervo --
   QUEM SEPARA AS ENTRADAS E O ESPACO, NAO UM GLIFO — e a proporcao e o que faz
   isso funcionar: 16 px ENTRE pares contra 5 px DENTRO de cada um. Agrupamento
   por proximidade, que e o canal certo aqui porque o par ja tem contraste de cor
   e de peso proprio (--fg3 contra --fg 550).

   ⚠ O `·` FOI TENTADO E CAIU NA MEDICAO, nos dois enderecos possiveis. Como
   `<span>` no meio do flex ele levava o `gap` inteiro dos dois lados, virava uma
   entrada a mais na contagem visual e um no vazio para o leitor de tela. Movido
   para `.const__i + .const__i::before`, sai do DOM e some da leitura — mas
   MEDIDO a 375 px a faixa quebra em TRES linhas com duas entradas abrindo linha,
   e ali o `·` aparece orfao na margem esquerda, antes de qualquer palavra. CSS
   nao tem como perguntar se um item comeca uma linha. */
.const--fx { gap: var(--e2) var(--e5); }

/* A LEGENDA E SUBORDINADA, E O FILETE E O QUE A SEPARA DO CONTEUDO.
   Ela usava `.rot` — mono, caixa alta, `letter-spacing` —, que e o idioma de
   rotulo de UMA OU DUAS palavras. Com uma frase inteira virava a coisa mais
   pesada da barra, e o olho lia a legenda antes do dado que ela legenda.
   Aqui ela recua para --fg3 e para 9,5 px, e o filete faz o trabalho que o
   peso tipografico estava fazendo errado. */
.const__c {
  align-self: stretch; display: flex; align-items: center;
  padding-right: var(--e3); border-right: 1px solid var(--lin2);
  font-family: var(--fm); font-size: 9.5px; font-weight: 500;
  letter-spacing: .07em; text-transform: uppercase; color: var(--fg3);
  white-space: nowrap;
}

/* O PAR RÓTULO + VALOR LE COMO PAR, e e por isso que o rotulo desce para --fg3:
   com rotulo em --fg2 e valor em --fg a diferenca era pequena demais a 12 px, e
   "Status Aguardando decisao Origem SENATRAN" lia como uma frase corrida. */
.const__i { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.const__r { color: var(--fg3); }

/* A TAMPA DO INSTRUMENTO. Fecha os cantos de baixo e deixa o `.tb-env` seguinte
   abrir os de cima, para os dois lerem como UMA peca em vez de duas placas
   empilhadas. A sombra e a mesma do envelope — sem ela o topo do conjunto
   perderia a elevacao no meio do caminho —, e a de baixo cai ATRAS do `.tb-env`,
   que e opaco e vem depois no documento: nenhum `z-index` nasce aqui.

   ⚠ A regra do vizinho mora NESTA folha, junto da peca que a exige, e nao em
   `componentes.css` com o `.tb-env`. Ela ganha por ESPECIFICIDADE (0,2,0 contra
   os 0,1,0 de `.tb-env`), entao nao depende de ordem de arquivo — que e
   exatamente a armadilha que a lei do projeto manda evitar. */
.const--cola {
  border: 1px solid var(--lin); border-bottom: none;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: var(--sh1), var(--brilho);
  /* ⚠ O RECUO SAI DO MESMO TOKEN QUE ABRE O ESPACO, nunca de um numero
     digitado: `.pg__in` e um flex com `gap: var(--e6)`, e sem cancela-lo os dois
     ficavam 24 px afastados — a "tampa" boiando acima da tabela, que e pior do
     que o desenho anterior porque agora ela tem cantos retos virados para o
     nada. Trocar o `gap` da pagina reposiciona esta peca sozinho; um `-24px`
     escrito a mao viraria cota falsa no dia seguinte. */
  margin-bottom: calc(var(--e6) * -1);
}
.const--cola + .tb-env { border-top-left-radius: 0; border-top-right-radius: 0; }

/* rodape de proveniencia — --fg3, NUNCA --fg4.
   MEDIDO: --fg4 sobre --bg da 3,43:1, reprova AA para texto, e o proprio
   base.css declara o fg4 como token GRAFICO (piso de 3:1, para rotulo de
   grupo e marca). Esta frase e a que sustenta o numero na primeira pergunta
   do cliente — "de onde veio esse total", "quantos em quarentena". Era o
   texto menos legivel da tela justamente onde a defesa do registro mora.
   --fg3 mede 5,11:1 no mesmo par. */
.prov { padding-top: var(--e2); font-size: 11px; color: var(--fg3); line-height: 1.5; max-width: 860px; }

/* ================================================= a casca NUA (#/entrar) =
   DUAS CASCAS, NAO UMA. A rota de entrada nao tem lateral nem topo: nao ha
   para onde navegar antes de entrar, e uma casca cheia atras de um formulario
   de login promete acesso que ainda nao existe.

   Metade da tela em campo institucional — e a lei de "cor precisa de area"
   aplicada a unica tela do produto que nao tem instrumento nenhum. */
/* `.app.app--nua`, e NAO `.app--nua`: os dois blocos responsivos redeclaram
   `grid-template-columns` em `.app`, e MEDIA QUERY NAO ACRESCENTA
   ESPECIFICIDADE — com peso igual quem ganha e quem vem depois no arquivo, e
   eles vem. Medido em 14/08, em 1180 px: a casca nua caiu na calha de 64 px da
   lateral recolhida, com a marca quebrando letra a letra. E o mesmo defeito
   que a lei nomeia, uma peca adiante. `.app.recolhida` ja usava dois pesos
   pelo mesmo motivo. */
.app.app--nua { grid-template-columns: minmax(0, 1fr); }

.nua { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); height: 100dvh; }
.nua__inst {
  position: relative; overflow: hidden;
  background: var(--inst); color: var(--inst-fg);
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: flex-start; padding: var(--e7);
}
/* ⚠ O CONTEUDO SOBE ACIMA DA ARTE, e sem estas duas linhas ele fica ATRAS
   dela. `.arte` e IRMA do conteudo e carrega `z-index: 0` (bloco `.arte`, mais
   acima); um elemento POSICIONADO com z-index 0 pinta por cima de um irmao
   estatico, por mais que o numero seja o mesmo. O sintoma e mudo — a malha de
   pontos passa por cima do lockup e do trajeto e os esmaece —, e ele ja existia
   quando esta metade era so a marca. */
.nua__lock { position: relative; z-index: 1; }

/* ------------------------------------------------------------- o lockup ---
   MESMA FORMA DE `.lat__marca`: marca a esquerda, nome ao lado, na horizontal.
   Ele NAO fica mais parado no rodape com o nome embaixo — quem entra tem de
   saber onde esta na primeira fixacao, e o canto inferior esquerdo e o ultimo
   lugar para onde o olho vai numa tela sem conteudo. */
.nua__lock { display: flex; align-items: center; gap: 12px; }
/* Mesma lei da `.lat__marca .mk`: a altura se digita, a largura sai do viewBox
   (108x64 = 1,6875:1). Largura digitada seria a segunda copia da proporcao. */
.nua__lock .mk { width: auto; height: 26px; flex: none; }
.nua__lock b { font-size: 15px; font-weight: 600; letter-spacing: -.014em; }

/* ⚠ O DISCURSO SAIU EM 25/08/2026, e a decisao foi do operador vendo a tela:
   *"nao esta moderno e minimalista"*. Eram uma manchete (`.nua__cl`) e tres
   promessas num trajeto de nos (`.nua__tj`) — e o problema nao era a execucao,
   era a ESPECIE: aquilo e pagina de marketing, e uma tela de login nao vende,
   ela deixa entrar. Medido em tres referencias (Linear, Vercel e o dashboard da
   Stripe), **nenhuma tem discurso nenhum ao lado do formulario**; a Stripe e a
   Vercel nao tem sequer painel.
   ⚠ O CAMPO FICA, e ele fica por lei: *"cor precisa de area — cada tela tem pelo
   menos um campo grande de cor"*. Sem ele, `#/entrar` seria a unica tela do
   produto sem nenhuma. O que ele carrega agora e o lockup e a `.arte`, que ja e
   a linguagem grafica da marca em peso visual baixo.
   ⚠ E O QUE SAIU TEM DE SAIR DOS DOIS LADOS: `PROMESSAS` foi apagada de
   `casca.js` no mesmo commit. Regra de CSS sem consumidor e a metade 2 da lei da
   classe orfa — e em `casca.css` nenhuma varredura a cobraria. */

/* a arte de fundo aqui comeca no topo: nao ha barra superior para descontar */
.nua__inst .arte { top: 0; }
.nua__cx { display: grid; place-items: center; padding: var(--e6); overflow-y: auto; }
/* 420 px, e a conta e do CONTEUDO, nao da caixa: com o cartao de volta, o recuo
   de --e7 e as duas bordas comem 66 px, entao 420 devolve os ~354 px de linha de
   leitura que a versao sem cartao tinha em 380. Medido nas tres referencias que
   serviram de regua: Linear 288, Vercel 320, dashboard da Stripe 412.
   ⚠ Mexer no recuo do cartao sem mexer aqui ENCOLHE a linha de leitura em
   silencio — os dois numeros sao um so. */
.nua__cx .pg__in { width: min(420px, 100%); max-width: none; }

/* ============================================================ responsivo = */
@media (max-width: 1180px) {
  .app { grid-template-columns: var(--lat-min) minmax(0, 1fr); }
  .app .lat__marca b, .app .lat__marca .rec,
  .app .lat__gr > .rot, .app .lat a.nv span:not(.no),
  .app .lat__emp .rot, .app .lat__emp b, .app .lat__emp i, .app .lat__emp .lat__emp-cv,
  .app .lat__cfg span,
  .app .lat__coleta { display: none; }
  .app .lat__cfg { justify-content: center; padding: 0; margin: 0 0 6px; }
  .app .lat__marca { padding: 16px 0 20px; justify-content: center; }
  .app .lat__nav { --eixo: 30px; }
  .app .lat a.nv { justify-content: center; padding: 0; }
  .app .lat a.nv .no { margin-left: 0; }
  .app .lat__pe { margin: 0 8px 12px; padding: 10px 0; }
  .app .lat__emp { display: grid; place-items: center; padding: 0; }
  .app .lat__emp .lat__emp-ic { display: block; }
}

@media (max-width: 900px) {
  .app { grid-template-columns: minmax(0, 1fr); }
  .lat {
    position: fixed; z-index: var(--z-gaveta); top: 0; bottom: 0; left: 0; width: var(--lat);
    box-shadow: var(--sh3);
    transform: translateX(-100%); visibility: hidden;
    transition: transform var(--t3) var(--ease), visibility var(--t3);
  }
  .app.gaveta .lat { transform: none; visibility: visible; }
  .app.gaveta .lat__marca { padding: 16px 16px 20px; justify-content: flex-start; }
  .app.gaveta .lat__marca b, .app.gaveta .lat__coleta { display: flex; }
  .app.gaveta .lat__nav { --eixo: 22.5px; }
  .app.gaveta .lat__gr > .rot, .app.gaveta .lat a.nv span:not(.no),
  .app.gaveta .lat__emp .rot, .app.gaveta .lat__emp b, .app.gaveta .lat__emp i,
  .app.gaveta .lat__cfg span,
  .app.gaveta .lat__emp .lat__emp-cv { display: block; }
  .app.gaveta .lat__cfg { justify-content: flex-start; padding: 0 8px; margin: -2px -4px 0; }
  .app.gaveta .lat a.nv { justify-content: flex-start; padding: 0 10px 0 0; }
  .app.gaveta .lat a.nv .no { margin-left: 6px; }
  .app.gaveta .lat__pe { margin: 0 12px 12px; padding: 12px; }
  .app.gaveta .lat__emp { display: block; padding: 0 22px 0 0; }
  .app.gaveta .lat__emp .lat__emp-ic { display: none; }
  .hamb { display: inline-flex; }
  .arte { left: 0; }
  .pg { --pg-pb: 64px; padding: var(--e5) var(--e5) var(--pg-pb); }
  .topo { padding: 0 var(--e5); }
  /* O ESPACADOR FICA, e a regra que o escondia SAIU em 25/08/2026 (T4a). Ela
     dizia: "sem o espacador o campo de busca fica com a sobra inteira em vez de
     dividi-la com um <div> vazio — a 375 px isso e a diferenca entre 63 e 150
     px". O argumento valia enquanto o espacador nao tinha NADA A DIREITA dele:
     o campo de busca nunca existiu, e o `.espaco` era so um vao.
     Desde a T4a ele empurra o AVATAR para a borda. Escondido, o botao da conta
     ficaria colado na migalha em toda tela abaixo de 900 px — e a lei do alvo
     de toque logo abaixo ja o desenha em 44 px justamente para o telefone.
     Quando a busca nascer, quem a escrever le este bloco. */
  .topo__busca { min-width: 0; flex: 1; }
  .topo__busca > span, .topo__busca .kbd { display: none; }
  /* ⚠ A METADE INSTITUCIONAL VIRA FAIXA — ela NAO some mais. A regra antiga
     escondia o campo inteiro, com o argumento de que "em 900 px ela roubaria a
     tela do unico campo que importa ali, que e o formulario". O argumento vale
     para o DISCURSO e nao para o lockup: escondendo os dois, o telefone abria o
     produto sem marca nenhuma e sem um unico campo de cor, contra "cor precisa
     de area" — e a marca ficava sem onde morar, porque a versao NEGATIVA nao
     pode entrar no cartao claro (`#FFFAF5` sobre branco) e a lilas nao tem
     consumidor. A faixa mede 58 px (recuo + os 26 da marca) e nao disputa
     espaco com o cartao, que fica na linha de baixo. */
  .nua { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .nua__inst { padding: var(--e5); }
  /* `.seg--dens` saiu: os dois diais viraram linha do menu do operador, então
     não há mais o que esconder aqui — em 375 px eles continuam alcançáveis,
     que é mais do que a regra antiga entregava. */
}

/* O QUARTO CORTE — novo nesta versao. Abaixo de 768 a tabela vira linha de
   cartao e o ⌘K passa a ser a entrada primaria: a unica pergunta do produto
   que nasce no telefone e "essa placa tem multa?", com o motorista na linha.
   Rolagem horizontal de seis colunas nao a responde. A selecao em lote some:
   decisao em lote e gesto de mesa. */
@media (max-width: 768px) {
  /* a troca tabela -> cartao mora em lista-cartao.css, junto da peca — aqui
     ela perderia por ordem de cascata (este arquivo carrega antes). */
  .selbar { display: none; }
  .pal { padding: 0; }
  .pal__cx { width: 100vw; height: 100dvh; max-height: 100dvh; border-radius: 0; border: none;
             display: flex; flex-direction: column; }
  .pal__l { max-height: none; flex: 1; }
}

@media (max-width: 560px) {
  .topo__mig { display: none; }
  .pg { --pg-pb: 56px; padding: var(--e4) var(--e4) var(--pg-pb); }
  /* ⚠ A FOLHA DE TELA CHEIA DO MODAL SAIU DAQUI em 18/08/2026, e mudou de
     corte junto: ela nascera a 560 e a lei do card diz 768. Mora agora em
     `modal.css`, no fim — a regra da peca mora na folha da peca. */
  .nua__cx { padding: var(--e5); }
}

/* TODO HOVER MORA EM @media (hover:hover): sem o guarda, o dedo em tela deixa
   o alvo preso aceso depois do toque. E o bloco fica no FIM do arquivo porque
   media query nao acrescenta especificidade — um `pointer:coarse` no topo ja
   perdeu, neste projeto, para uma regra 200 linhas abaixo. */
@media (hover: hover) {
  .lat__cfg:hover { color: #F3F0FB; background: rgba(243,240,251,.1); }
}

/* O ALVO DE TOQUE DA BUSCA — medido em 14/08, em 375 px: o bloco de
   `pointer:coarse` la de cima cobria `.topo .bt--ico`, `.topo__id` e `.hamb`,
   e deixava de fora justamente `.topo__busca`, que abaixo de 768 px E A
   ENTRADA PRIMARIA do produto ("essa placa tem multa?", com o motorista na
   linha). Media 32 px de altura.

   A correcao amplia a AREA, nao o desenho, como a de cima: a caixa continua
   com 32 px, o alcance vai a 44. Largura de 100% porque o botao ja ocupa a
   sobra da barra em tela estreita — nada a ampliar na horizontal. */
@media (pointer: coarse) {
  .topo__busca { position: relative; }
  .topo__busca::after {
    content: ""; position: absolute; left: 0; top: 50%;
    width: 100%; height: 44px; transform: translateY(-50%);
  }
}
