/* ── Requisição de Estoque — catálogo + carrinho lateral (v2) ──
   Padrão do portal: tokens globais (tokens.css), botões/.card compartilhados.
   Cabeçalho + abas + toolbar espelham o módulo Compras. Layout 2 painéis no
   desktop (catálogo + carrinho sticky); carrinho vira barra fixa inferior +
   drawer no mobile. Quick-add por select de tamanho. */

#requisicoesTab { padding: 0; background: transparent; border: none; box-shadow: none; }

.requisicoes-view {
  display: flex; flex-direction: column; gap: var(--space-4);

  /* -- Cor no modulo: nao existe eixo proprio ----------------------------
     Houve um eixo laranja (#c2540b) marcando "Adicionar", "Gerar requisicao" e
     "Baixar entrega". Foi REMOVIDO em 24/08 a pedido do Henrique depois de ver
     na tela: o problema nao era o tom, era a repeticao. O catalogo mostra ate
     75 cards de uma vez, e 75 botoes coloridos em repouso viram ruido, nao
     hierarquia.

     A regra que ficou no lugar:
       repouso NEUTRO, cor so no hover  -> .req-add (o botao de cada card)
       primaria do portal (--brand-500) -> .req-generate, por heranca do botao
                                           global, sem override nenhum aqui
       cor SEMANTICA onde ela informa   -> verde em "Baixar entrega" e "Liberar
                                           retirada", vermelho em "Cancelar"

     Ou seja: cor no modulo passa a significar consequencia (deu certo, saiu
     estoque, cancelou), nunca "este e um botao". */
}

/* ── cabeçalho (padrão .compras-head) ── */
.req-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap;
  padding-bottom: var(--space-3); margin-bottom: 0;
  border-bottom: 1px solid var(--line-soft);
}
.req-head-info { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.req-head-titles { min-width: 0; }
.req-head-icon {
  width: 46px; height: 46px; flex: none; display: grid; place-items: center;
  border-radius: 14px; background: var(--bg-muted); color: var(--brand-500);
}
.req-head-icon svg { width: 24px; height: 24px; }
.req-head-eyebrow { display: block; font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--brand-500); margin-bottom: 1px; }
.req-head-title { font-size: 1.6rem; font-weight: 800; line-height: 1.1; letter-spacing: -.02em; margin: 0 0 2px; color: var(--text-primary); }
.req-head-sub { font-size: .85rem; color: var(--text-secondary); margin: 0; max-width: 64ch; }
.req-head-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }

/* ── cabecalho na ESTACAO de tela BAIXA ──────────────────────────────────────
   O escopo da estacao passou a incluir os coletores parados na expedicao, que sao
   aparelhos de 320x480. Medido nesse tamanho, antes desta frente: o cabecalho do modulo
   comia 100px, a barra de filas 40, a barra de ferramentas 204 e os contadores 125, e o
   primeiro cartao da fila nascia a 663px de uma tela de 480. Uma tela e meia de rolagem
   antes da primeira requisicao, num aparelho que serve para uma coisa so.

   O eixo aqui e ALTURA, e por isso este bloco existe alem do `@media (max-width: 640px)`
   mais abaixo, que ja aperta o cabecalho por largura (titulo, icone e o paragrafo de
   instrucao) e continua sendo o lugar de mexer nisso para qualquer conta. */
@media (max-height: 620px) {
  .is-estacao .req-head-eyebrow { display: none; }
  .is-estacao .req-head-title { font-size: 1.1rem; }
  .is-estacao .req-head-icon { width: 32px; height: 32px; }

  /* E na ESTACAO de tela baixa o cabecalho sai inteiro, devolvendo 61px de fila. A conta:
     o aparelho do balcao serve a uma tarefa so, as abas logo abaixo ja dizem que a tela e
     "Fila | Historico", e o nome do modulo continua na navegacao do portal. Num coletor de
     480px de altura, 61px e a diferenca entre ver uma requisicao e ter de rolar para ver a
     primeira.
     O `:has` e a trava: se algum dia a estacao ganhar o grant de fotos, o botao "Gerenciar
     fotos" mora AQUI DENTRO e e a unica porta para o gerenciador. Com ele visivel, o
     cabecalho fica. Esconder o container de um controle sem par em outro lugar seria
     transformar economia de altura em funcionalidade perdida. */
  .is-estacao .req-head:not(:has(.req-manage-btn:not([hidden]))) { display: none; }
}

/* abas Catálogo / Minhas requisições (padrão .compras-queues) — barra logo
   acima do conteúdo, alinhada à esquerda e colada no painel (não no header). */
.req-tabbar { margin-bottom: 0; }
/* abas em cápsula: ativa = azul preenchido (mesmo idioma dos chips de categoria) */
.req-queues { display: inline-flex; gap: var(--space-2); }
.req-queue {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 40px; padding: 0 20px; border-radius: 999px;
  border: 1.5px solid color-mix(in srgb, var(--line-strong) 30%, transparent);
  background: var(--bg-surface); color: var(--text-secondary); font-size: .86rem; font-weight: 600;
  cursor: pointer; transition: color var(--trans-fast), background var(--trans-fast), border-color var(--trans-fast);
}
/* .req-queue define display, então precisa reafirmar o [hidden] do HTML (mesma
   especificidade: o do autor vence). Sem isto, aba escondida por grant (Segurança/
   Almoxarifado) vaza visível e dá 403 no clique. Igual ao .req-queue-count[hidden]. */
.req-queue[hidden] { display: none; }
.req-queue:hover:not(.is-active) { border-color: var(--brand-500); color: var(--brand-500); }
.req-queue.is-active { background: var(--brand-500); color: #fff; border-color: var(--brand-500); }
.req-queue-icon { display: inline-flex; width: 16px; height: 16px; }
.req-queue-icon svg { width: 16px; height: 16px; }
.req-queue-count { display: inline-grid; place-items: center; min-width: 20px; height: 19px; padding: 0 6px; border-radius: 10px; background: color-mix(in srgb, var(--text-secondary) 16%, transparent); color: var(--text-secondary); font-size: .72rem; font-weight: 700; }
.req-queue.is-active .req-queue-count { background: rgba(255, 255, 255, .26); color: #fff; }
.req-queue-count[hidden] { display: none; }
/* Numero PROVISORIO: veio do cache do ultimo poll e o servidor ainda nao confirmou nesta
   sessao. Existe para o numero JA estar na tela quando ela abre, em vez de aparecer
   depois do fetch. Marcacao discreta de proposito: e o valor certo em 99% dos casos, e
   se corrige sozinho em menos de um segundo. Piscar ou por interrogacao chamaria mais
   atencao para a incerteza do que ela merece. */
.req-queue-count[data-stale] { opacity: .62; }
/* Aviso de fila maior que a pagina, na estacao da Seguranca. Discreto porque nao e erro:
   e a fila andando. So aparece quando o servidor diz que cortou. */
.req-seg-aviso { margin: 0 0 var(--space-2); font-size: .78rem; line-height: 1.4;
  color: var(--text-secondary); text-wrap: pretty; }

/* ── layout 2 painéis ── */
.req-main { display: grid; grid-template-columns: 1fr; gap: var(--space-4); align-items: start; }
/* O limiar da coluna do carrinho subiu de 1024 para 1280 de viewport. Medido no
   navegador: um tablet de 1024 entrega 920px a aba, e com 326px cravados para o
   carrinho sobravam 352px para o catalogo, que rendia 2 cards de 168px. Abaixo de
   1280 o carrinho passa a cair no tratamento de barra inferior + gaveta (ver
   .req-cart no bloco max-width:1023px, cujo limite tambem sobe), que ja existia e
   ja se provou melhor: em tablet retrato o MESMO catalogo dava 3 cards de 225px
   justamente porque o carrinho saia da linha.
   Acima de 1280 a coluna volta, agora proporcional em vez de 326px cravados.

   E @media, nao @container, ao contrario do resto do arquivo, e isso e de
   proposito: no mobile o .req-cart e `position: fixed` ancorado na viewport, e
   `container-type` aplica `contain: layout`, o que faria o painel virar bloco
   contentor do elemento fixed. O `bottom: 0` passaria a resolver contra o painel
   (alto e rolavel) em vez da tela, e a barra do carrinho deixaria de ficar
   ancorada. Mesma familia de armadilha documentada em .req-alm-foco-acts. */
@media (min-width: 1280px) {
  .req-main { grid-template-columns: minmax(0, 1fr) minmax(300px, 22%); }
}

/* ── catálogo ── */
.req-catalog { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; container-type: inline-size; }

/* toolbar arejada (sem caixa): a busca é a âncora visual, chips leves embaixo */
.req-toolbar { display: flex; flex-direction: column; gap: var(--space-3); }
.req-toolbar-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.req-filterbar { display: flex; align-items: center; gap: var(--space-2); }

.req-search { position: relative; flex: 1 1 240px; }
.req-search svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 17px; height: 17px; color: var(--text-secondary); pointer-events: none; }
.req-search input {
  width: 100%; box-sizing: border-box; height: 40px; padding: 0 12px 0 38px; font-size: .88rem;
  border: 1.5px solid color-mix(in srgb, var(--line-strong) 38%, transparent); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary); font-family: inherit;
}
.req-search input:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--focus-ring); }
.req-search input::-webkit-search-cancel-button { display: none; }
.req-search input:not(:placeholder-shown) { padding-right: 38px; }
/* Centralização por AUTO-MARGIN (top:0/bottom:0 + margin:auto), não por transform. Dois
   motivos: (1) o botão global usa `transform` no :hover (translateY(-1px)) e no :active
   (translateY(1px)), e isso ROUBAVA um translateY(-50%) de centering — o X saltava pra fora
   e, com `transition: transform` herdada, o salto ainda animava; (2) `top:50% + margin
   negativo` dependia da altura do container, e `.req-search` é reusado em toolbars de alturas
   diferentes, então o X descentralizava em algumas. `top:0;bottom:0;margin:auto` centra em
   QUALQUER altura de container, sem transform. Neutralizamos ainda o transform de hover/active
   aqui (0,2,0 vence o :where(...) global 0,1,0 e o button:active 0,1,1). Feedback = realce de fundo. */
.req-qclear {
  position: absolute; right: 6px; top: 0; bottom: 0; margin-top: auto; margin-bottom: auto;
  display: grid; place-items: center; width: 28px; height: 28px; min-height: 0; padding: 0;
  border: none; border-radius: 50%; background: transparent; color: var(--text-secondary); cursor: pointer;
}
.req-qclear:hover { background: var(--bg-muted); color: var(--text-primary); box-shadow: none; transform: none; }
.req-qclear:active { transform: none; }
.req-qclear svg { width: 14px; height: 14px; }
.req-qclear[hidden] { display: none; }

/* linha secundária da toolbar: chips de categoria roláveis + contagem discreta */
.req-toolbar-row--sub { flex-wrap: nowrap; justify-content: space-between; }

/* faixa de categorias em rolagem horizontal (não quebra em várias linhas) */
.req-chips { display: flex; gap: var(--space-2); flex: 1 1 auto; min-width: 0; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; -webkit-overflow-scrolling: touch; margin: -4px 0; padding: 4px 0; }
.req-chips::-webkit-scrollbar { display: none; }
.req-chip {
  flex: none; min-height: 34px; padding: 0 13px; border: 1.5px solid color-mix(in srgb, var(--line-strong) 30%, transparent); border-radius: 999px;
  background: var(--bg-surface); color: var(--text-secondary); font-size: .8rem; font-weight: 600; cursor: pointer;
  transition: background var(--trans-fast), color var(--trans-fast), border-color var(--trans-fast);
}
.req-chip:hover:not(.is-active) { border-color: var(--brand-500); color: var(--brand-500); }
.req-chip.is-active { background: var(--brand-500); color: #fff; border-color: var(--brand-500); }

/* 2ª linha: subtipos do tema. Nível hierárquico mais leve que os temas, chips
   menores, e o ativo é um "state-layer" da marca (tinta), não o sólido cheio,
   pra ler como refinamento e não competir com a linha de tema acima. */
.req-toolbar-row--subtipos { padding-top: 2px; }
.req-subchip { min-height: 30px; padding: 0 11px; font-size: .76rem; }
.req-subchip:hover:not(.is-active) { border-color: var(--brand-500); color: var(--brand-500); }
.req-subchip.is-active {
  background: color-mix(in srgb, var(--brand-500) 14%, transparent);
  color: var(--brand-500); border-color: color-mix(in srgb, var(--brand-500) 45%, transparent);
}

/* chip de transbordo "Mais N" → abre o popover da cauda longa de famílias */
/* popover buscável de famílias (reparentado no <body>, posicionado via JS) */
/* ===== Catálogo com lateral de departamentos (padrão de loja) ===== */
/* A área de resultados é quem manda no nº de colunas da grade, não o catálogo
   inteiro: por isso o container-query mede a .req-results. */
.req-results { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; container-type: inline-size; }
.req-results-top { display: flex; align-items: center; gap: var(--space-2); }
.req-results-bar { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-height: 24px; }
.req-applied { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; flex: 1 1 auto; min-width: 0; }
.req-appliedchip {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px 4px 11px; border: 0; cursor: pointer;
  background: color-mix(in srgb, var(--brand-500) 12%, transparent); color: var(--brand-600, var(--brand-500));
  border-radius: 999px; font-size: .78rem; font-weight: 600;
}
.req-appliedchip:hover { background: color-mix(in srgb, var(--brand-500) 20%, transparent); }
.req-appliedchip-x { font-size: 1rem; line-height: 1; opacity: .8; }
.req-applied-clear { border: 0; background: none; color: var(--text-secondary); font-size: .78rem; font-weight: 600; cursor: pointer; padding: 4px 6px; }
.req-applied-clear:hover { color: var(--brand-500); text-decoration: underline; }

/* botão "Filtros" (só aparece no mobile, abre a gaveta) */
.req-filtersbtn { display: none; align-items: center; gap: 8px; align-self: flex-start; min-height: 38px; padding: 0 14px;
  border: 1.5px solid var(--line-strong); border-radius: var(--radius-md); background: var(--bg-surface);
  color: var(--text-primary); font-size: .85rem; font-weight: 600; cursor: pointer; }
.req-filtersbtn svg { width: 17px; height: 17px; }
.req-filtersbtn-n { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px; background: var(--brand-500); color: #fff; font-size: .7rem; display: inline-flex; align-items: center; justify-content: center; }

/* a lateral em si */
.req-rail-head { display: none; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.req-rail-headtitle { font-size: 1rem; font-weight: 700; color: var(--text-primary); }
.req-rail-close { border: 0; background: none; cursor: pointer; color: var(--text-secondary); padding: 6px; }
.req-rail-close svg { width: 20px; height: 20px; }
.req-rail-toggle { padding: 6px 4px 12px; }
.req-rail-label { font-size: .68rem; letter-spacing: .07em; text-transform: uppercase; color: var(--text-secondary); opacity: .8; margin: 4px 4px 6px; font-weight: 700; }
.req-rail-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.req-dep {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 10px; border: 0; border-radius: var(--radius-md); background: transparent; cursor: pointer; text-align: left;
  color: var(--text-secondary); font-size: .84rem; font-weight: 600; transition: background var(--trans-fast), color var(--trans-fast);
}
.req-dep:hover { background: color-mix(in srgb, var(--brand-500) 9%, transparent); color: var(--brand-500); }
.req-dep.is-active { background: var(--brand-500); color: #fff; }
.req-dep-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.req-dep-count { flex: none; font-size: .72rem; font-weight: 700; opacity: .65; font-variant-numeric: tabular-nums; }
.req-dep.is-active .req-dep-count { opacity: .85; }

/* 2º NÍVEL: linha de pastilhas acima da grade, e nunca aninhada no trilho.
   O trilho já é mais alto que a janela (medido: 944px numa de 900, começando a 198 do
   topo), então uma árvore recuada empurraria departamento para fora da tela a cada
   abertura. Aqui o 2º nível cresce na horizontal e não tem como alongar o trilho.
   QUEBRA LINHA em vez de rolar na horizontal, e isto é correção de uma primeira tentativa
   minha: com rolagem, medido a 1440, os 6 tipos do EPI somavam 620px numa faixa de 605 e a
   última pastilha ficava 15px cortada, sem nada avisando que havia mais. Escondi conteúdo
   para economizar altura numa página que já rola 93 mil pixels, ou seja paguei caro por
   nada. Departamento com 8 tipos (Elétrica) quebraria de qualquer jeito. */
.req-subs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 2px 0 6px; }
/* `hidden` sozinho não esconde nada aqui: a regra do navegador ([hidden] { display: none })
   perde de qualquer classe que declare display, e a fita "escondida" seguia ocupando os 8px
   do próprio padding. Medido em Tintas, que não tem 2º nível. */
.req-subs[hidden] { display: none; }
/* No estreito a fita volta a ROLAR de lado, e a divisão tem motivo: no toque arrastar uma
   fita de pastilhas é gesto familiar e descoberto, no mouse não é. E ali a altura custa de
   verdade: medido a 375x812, os 6 tipos do EPI quebravam em 3 linhas e gastavam 152px, ou
   seja 19% da tela antes do primeiro card. 860px é o mesmo limiar em que o trilho vira
   gaveta, então a tela troca de modo uma vez só. */
@media (max-width: 859.98px) {
  .req-subs { flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-inline: contain; scrollbar-width: thin; }
}
.req-sub {
  flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px;
  border: 1.5px solid var(--line-soft); border-radius: 999px; background: var(--bg-surface); cursor: pointer;
  color: var(--text-secondary); font-size: .8rem; font-weight: 600; white-space: nowrap;
  transition: background var(--trans-fast), color var(--trans-fast), border-color var(--trans-fast);
}
.req-sub:hover { border-color: color-mix(in srgb, var(--brand-500) 45%, transparent); color: var(--brand-500); }
.req-sub.is-active { background: var(--brand-500); border-color: var(--brand-500); color: #fff; }
.req-sub-ico { flex: none; display: inline-flex; }
.req-sub-ico svg { width: 15px; height: 15px; }
.req-sub-count { flex: none; font-size: .72rem; font-weight: 700; opacity: .6; font-variant-numeric: tabular-nums; }
.req-sub.is-active .req-sub-count { opacity: .85; }

/* Desktop (>=860px): lateral fixa em coluna; sem botão/gaveta. */
@media (min-width: 860px) {
  /* minmax em vez de 210px cravados: entre 860 e ~1100 de catalogo os 210px fixos
     custavam proporcionalmente caro a grade de cards.
     O piso subiu de 170 para 196px, e o numero e medido, nao redondo. Com 170 o ROTULO
     ficava com 99px: os 12+12 de padding do trilho, os 10+10 do botao e o contador com o
     gap comem 71px, e nada disso aparece na conta de quem le "170". Resultado: 13 dos 19
     rotulos truncavam a 1440x900, a maior tela da casa. 196 e onde "Caldeiraria" (o pior
     caso depois de encurtar para uma palavra) mais um contador de 4 digitos cabem inteiros.
     A grade perde 26px e segue em 3 colunas, porque a coluna tinha 199,7 e o piso do card
     e 180. */
  .req-catalog--railed { display: grid; grid-template-columns: minmax(196px, 15%) minmax(0, 1fr); gap: var(--space-4); align-items: start; }
  /* 202px = os 186 em que o palco do catalogo comeca (cabecalho do portal mais as abas do
     modulo) mais 16 de respiro no pe. O desconto e do topo do TRILHO e nao do topo da
     janela: com `100vh - 32` a caixa dava 868px e terminava em 1054 numa janela de 900,
     ou seja o teto existia e o ultimo filtro seguia fora da vista.
     Valor fixo e nao medido em JS de proposito: fixo, todo filtro fica alcancavel em
     QUALQUER posicao de rolagem. O preco e que, com a pagina rolada e o trilho grudado em
     16, ele podia ser 170px mais alto e nao e. Trilho encurtado custa rolagem interna;
     trilho alto demais custa filtro invisivel, que e o defeito que estamos corrigindo. */
  .req-catalog--railed { --req-rail-topo: 202px; }
  /* Rolagem PROPRIA do trilho. Medido a 1440x900: 20 departamentos de 44px mais o toggle
     e o rotulo dao 991px de conteudo, e abaixo do cabecalho do modulo sobram 714px, entao
     os 6 ultimos filtros nasciam abaixo da dobra e o ultimo exigia 264px de rolagem DA
     PAGINA. Rolar a pagina e navegar o catalogo: sao dois gestos diferentes e nao podem
     ser o mesmo. Com teto de altura o trilho rola dentro de si e a grade fica parada. */
  .req-rail { position: sticky; top: var(--space-4); background: var(--bg-surface); border: 1px solid var(--line-soft); border-radius: var(--radius-md); box-shadow: var(--shadow-1); padding: 12px;
    display: flex; flex-direction: column; max-height: calc(100vh - var(--req-rail-topo)); }
  /* So a LISTA rola: o toggle de saldo e o rotulo "Departamentos" ficam ancorados, senao a
     pessoa perde a referencia de onde esta dentro do proprio filtro. `min-height: 0` porque
     item de flex nao encolhe abaixo do conteudo sem isso, e sem encolher nao ha overflow
     para rolar. Esta regra vem DEPOIS da base de propria vontade: @media nao acrescenta
     especificidade, entao empate de seletor se decide por ordem de fonte. */
  .req-rail-list { overflow-y: auto; min-height: 0; overscroll-behavior-block: contain; }
}
/* Mobile (<860px): lateral vira gaveta atrás do botão "Filtros". */
@media (max-width: 859.98px) {
  .req-filtersbtn { display: inline-flex; }
  .req-rail-head { display: flex; }
  .req-rail { position: fixed; top: 0; left: 0; bottom: 0; width: min(86vw, 300px); z-index: 70; overflow-y: auto;
    background: var(--bg-surface); border-right: 1px solid var(--line-soft); box-shadow: var(--shadow-2); padding: 16px;
    transform: translateX(-100%); transition: transform .22s ease; }
  .req-catalog--railed.is-filters-open .req-rail { transform: none; }
  .req-catalog--railed.is-filters-open::before { content: ""; position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 65; }
}
@media (prefers-reduced-motion: reduce) { .req-rail { transition: none; } }

/* toggle "só com saldo" */
.req-toggle { display: inline-flex; align-items: center; gap: 8px; font-size: .82rem; font-weight: 600; color: var(--text-secondary); cursor: pointer; user-select: none; flex: none; }
.req-toggle input { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; margin: 0; }
.req-toggle .req-switch { width: 38px; height: 22px; border-radius: 999px; background: var(--line-strong); position: relative; transition: background var(--trans-fast); flex: none; }
.req-toggle .req-switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform var(--trans-fast); }
.req-toggle input:checked + .req-switch { background: var(--brand-500); }
.req-toggle input:checked + .req-switch::after { transform: translateX(16px); }
.req-toggle input:focus-visible + .req-switch { box-shadow: 0 0 0 3px var(--focus-ring); }

/* contagem secundária de propósito — não compete com a busca nem com os chips */
.req-count { flex: none; font-size: .74rem; color: var(--text-secondary); opacity: .75; font-weight: 600; white-space: nowrap; }

/* ---------- Porta de entrada: alternancia no lugar ---------- */
/* UM bloco, duas listas, o MESMO lugar na tela. O desenho anterior empilhava duas faixas do
   card da grade, e card de 337px em duas linhas empurra o catalogo para fora da primeira tela.
   Aqui o custo e FIXO qualquer que seja a lista: fita de alternancia mais seis fichas de 112px.
   A ficha conserva do card os ganchos de clique, nao o tamanho.

   O container mantem o nome `.req-faixas` porque e o slot que a view ja monta; quem mudou foi o
   conteudo. Ele deixou de ser coluna flex de faixas e virou bloco simples. */
/* Sem `border-bottom` aqui: a divisao virou o proprio separador rotulado, e a borda do
   container desenhava uma SEGUNDA linha 20px abaixo dele. Duas reguas paralelas com um rotulo
   em cima leem como defeito de render, e era o defeito que ele apontou. */
.req-faixas { padding: 2px 0 0; margin-bottom: var(--space-4); }
.req-faixas[hidden] { display: none; }

.req-fx-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* O indicador DESLIZA em vez de piscar, e nao e enfeite: e o que diz "a mesma lista trocou de
   conteudo" em vez de "abriu outra tela". Por isso a fita fica no DOM entre uma lista e outra
   (ver renderFxGrid): recriada, ela nasceria ja na posicao nova e o movimento se perderia. */
.req-fx-seg {
  position: relative; flex: none; display: flex; width: 252px; padding: 3px;
  border: 1px solid var(--line-soft); border-radius: 999px; background: var(--bg-muted);
}
/* `left` e `width` deixam o indicador com 3px de folga a esquerda; translateX(100%) e da propria
   largura, entao ele para com os mesmos 3px a direita. E o padding da fita nas duas pontas sem
   nenhum numero repetido. */
.req-fx-ind {
  position: absolute; top: 3px; left: 3px; width: calc(50% - 3px); height: calc(100% - 6px);
  border-radius: 999px; background: var(--brand-500);
  /* `--trans-base` ja carrega duracao E curva (220ms mais a standard do token). Acrescentar
     uma curva propria aqui produziria duas curvas na mesma declaracao, que o navegador
     descarta inteira: a fita voltaria a piscar em vez de deslizar. */
  transition: transform var(--trans-base);
}
.req-fx-seg.is-seus .req-fx-ind { transform: translateX(100%); }
.req-fx-tab {
  position: relative; flex: 1 1 0; min-width: 0; padding: 6px 4px; border: 0; background: none;
  border-radius: 999px; font: inherit; font-size: .78rem; font-weight: 700; white-space: nowrap;
  color: var(--text-secondary); cursor: pointer; transition: color var(--trans-fast);
}
.req-fx-tab[aria-pressed="true"] { color: #fff; }
.req-fx-tab:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
/* O subtitulo troca com a lista: e ele que diz de quem e o recorte, porque o rotulo do botao
   pressionado sozinho nao explica o critério de ordenacao. */
.req-fx-sub { font-size: .74rem; color: var(--text-secondary); opacity: .82; font-weight: 600; }

.req-fx-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: 12px; }

/* A ficha do atalho. Sem piso de altura: quem define a altura e a banda de foto (104) mais o
   nome de duas linhas mais o pe, e um piso a mais so criaria folga morta na ficha curta.

   A entrada em cascata NAO mora aqui, e a razao e robustez, nao gosto: `animation ... both` com
   `animation-delay` deixa a ficha em opacity 0 enquanto o relogio da animacao nao anda, e ficha
   invisivel e pior que ficha sem entrada. A cascata vive no `rqAnimate` (ver renderFxGrid), que
   tem cao de guarda e forca o estado final mesmo se a animacao nunca rodar. */
.req-fx-tile {
  display: flex; flex-direction: column; gap: 6px; padding: 10px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--bg-surface);
  transition: transform var(--trans-fast), box-shadow var(--trans-fast);
}
.req-fx-tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-1); }
.req-fx-tile.is-out { opacity: .74; }
/* Banda de foto de ALTURA FIXA, e nao `aspect-ratio` como no card da grade. A diferenca e
   deliberada: com proporcao a banda cresceria com a coluna (144px a 1440, 96px a 375) e o custo
   do bloco deixaria de ser previsivel, que e a promessa deste desenho. Com 104px fixos o bloco
   custa o mesmo em qualquer largura, e a foto continua bem maior que o selinho de 22px que
   estava aqui antes. */
.req-fx-tile-foto {
  position: relative; height: 104px; flex: none;
  border-radius: 8px; background: var(--bg-muted); overflow: hidden;
}
.req-fx-tile-foto:has(img) { cursor: zoom-in; }
/* contain e fundo branco, igual ao card: mostra a peca INTEIRA, em qualquer proporcao. */
.req-fx-tile-foto img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #fff; display: block; }
/* 52px numa banda de 104 e a mesma proporcao que o card usa (72 em 148): o glifo preenche a
   moldura como a foto faria, em vez de virar selinho perdido no meio dela. */
.req-fx-tile-ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--brand-500); opacity: .38; }
.req-fx-tile-ph svg { width: 52px; height: 52px; }
.req-fx-tile-foto .req-badge { position: absolute; top: 6px; left: 6px; box-shadow: 0 1px 3px rgba(16, 26, 45, .25); }
/* A contagem vai para o PE da banda, e nao para o topo: o topo e do selo de saldo, e dois
   distintivos no mesmo canto brigariam justamente no card sem foto, que e a maioria. */
.req-fx-tile-n {
  position: absolute; right: 6px; bottom: 6px; padding: 1px 6px; border-radius: 999px;
  background: rgba(255, 255, 255, .88); color: var(--text-secondary);
  font-size: .64rem; font-weight: 700; white-space: nowrap;
}
.req-fx-tile-name {
  flex: 1 1 auto; font-size: .76rem; font-weight: 600; line-height: 1.25; color: var(--text-primary);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.req-fx-tile-foot { display: flex; align-items: center; gap: 6px; }
/* A banda segue a MESMA decisao do card: linha unica, e quem cede e o botao. Aqui o aperto e
   maior (201px de banda contra 196px de corpo de card, mas com botao de 86px), e por isso a conta
   fecha melhor: botao so de icone tem ~28px, entao sobram 167px para o select, ou ~133px de texto.
   Empilhar aqui seria pior do que no card: a banda de entrada e o espaco mais caro da tela e a
   quebra custava 50px de altura. Medido em 01/09. */
/* Na banda o quadrado e 32px e nao 44px: a altura de la e 26px, entao 44 de largura viraria um
   retangulo deitado em vez de um quadrado, e a banda e o espaco mais caro da tela. 32px continua
   sendo alvo confortavel de mouse, que e como a banda e usada. */
.req-fx-tile-foot.is-rotulo-longo .req-add { width: 32px; min-width: 0; padding: 0; gap: 0; }
.req-fx-tile-foot.is-rotulo-longo .req-add > span {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* Dois seletores de classe de proposito: as bases `.req-select` e `.req-add` vivem mais abaixo no
   arquivo, e classe unica aqui perderia por ORDEM DE FONTE (empate de especificidade decide por
   ordem). Foi essa a armadilha que ja custou duas voltas neste modulo. */
/* O botao ganhou largura em 26/08 a pedido dele, e ela sai do select: com o codigo do produto
   fora do rotulo, o campo fechado precisa de menos ("13MM X 1500MT" pede ~106px contra os ~172px
   de "13MM X 1500MT (1145000001/2)"). Entao o select para de crescer sozinho e ganha um teto, e o
   que sobra vai para o botao, que e o alvo do dedo.
   Os DOIS tem piso, e isso nao e zelo: com `flex: 1 1 auto` so no botao ele cresceu para 121px e
   deixou 45px de select numa ficha de 194 (medido com o trilho expandido, que estreita o palco),
   cortando o proprio rotulo que acabamos de limpar. Com piso nos dois, quem cede primeiro e o
   select, mas ele para em 76px em vez de sumir. */
/* Revisado em 01/09: o teto de 132px nao cumpria o criterio escrito no proprio comentario acima.
   Com 132px o campo fechado tem 100px de texto e "13MM X 1500MT" pede os 106px que aquele
   comentario mediu, entao o rotulo cortava SEMPRE, em qualquer largura de tela. Na banda de 201px
   nao existe numero que resolva mantendo o botao de 86px na mesma linha (118 mais 6 mais 86 passa
   de 201), por isso o teto sai e o rodape pode quebrar: onde nao couber, o select toma a banda
   inteira e sobram 169px de texto.
   Vale SO para rotulo longo, pelo mesmo motivo do card: a ficha de uniforme tem grade P/M/G e com
   o piso ela ganhava um campo de 199px para uma letra, mais 50px de altura na banda de entrada,
   que e o espaco mais caro da tela. */
.req-fx-tile .req-select { flex: 0 1 auto; width: 108px; min-width: 76px; max-width: 132px; height: 26px; padding: 0 22px 0 6px; font-size: .72rem; background-position: right 6px center; background-size: 12px; }
/* Texto CENTRALIZADO, e so aqui. Na ficha o campo perde o teto (`max-width: none`, logo acima)
   e fica com a banda quase inteira, entao o valor alinhado a esquerda ficava solto num campo de
   265px, com 155px de vazio depois dele: medido na tela em 01/09, na Fita Adesiva.
   O respiro vira simetrico (`0 22px`) junto, e nao por capricho: a base usa `0 22px 0 6px`,
   assimetrico porque a direita reserva o chevron, e centralizar dentro de um respiro assimetrico
   desloca o texto 8px para a esquerda do centro otico, ou seja "centralizado" sairia torto. Com
   22px dos dois lados o texto centra entre as bordas internas e o chevron continua desenhado
   dentro da reserva da direita (`right 6px`, 12px).
   NAO vale para o cartao da grade: la o campo e apertado (118px), o valor ja preenche a linha e
   pode truncar, entao centralizar nao mudaria nada visivel e mexeria no caso que acabou de ser
   medido. Centralizacao existe onde ha sobra, e a sobra e aqui. */
.req-fx-tile-foot.is-rotulo-longo .req-select { flex: 1 1 auto; width: auto; min-width: 118px; max-width: none; padding: 0 22px; text-align: center; text-overflow: ellipsis; }
.req-fx-tile .req-add { flex: 1 1 auto; min-width: 86px; justify-content: center; height: 26px; padding: 0 8px; gap: 5px; font-size: .72rem; }
.req-fx-tile .req-add.is-full { flex: 1 1 auto; justify-content: center; }
.req-fx-tile .req-add svg { width: 12px; height: 12px; }

/* A fronteira entre o atalho e o catalogo. Sem numero de proposito: a barra de contagem vem
   logo abaixo e ja diz quantos itens sao, e o mesmo numero duas vezes em 24px e ruido. */
.req-fx-sep {
  display: flex; align-items: center; gap: 10px; margin: 14px 0 0;
  font-size: .64rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-secondary); opacity: .7;
}
.req-fx-sep::after { content: ""; flex: 1; height: 1px; background: var(--line-soft); }

/* Vazio de "Os seus". Tracejado e nao cinza cheio: o bloco esta esperando conteudo que vai
   existir depois do primeiro pedido, e nao anunciando falha. */
.req-fx-vazio {
  grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 18px 14px; border: 1px dashed var(--line-soft); border-radius: var(--radius-md); text-align: center;
}
.req-fx-vazio svg { width: 20px; height: 20px; color: var(--text-secondary); opacity: .7; }
.req-fx-vazio p { margin: 0; font-size: .8rem; font-weight: 700; color: var(--text-primary); }
.req-fx-vazio p.req-fx-sub { font-weight: 500; }
/* O escape do vazio por saldo tem a MESMA aparencia de link, e classe diferente de proposito:
   `.req-fx-link` e o gancho do delegate que troca de aba, e as duas classes juntas fariam um
   clique trocar a lista antes de desligar o filtro. Aparencia compartilhada, gancho separado. */
.req-fx-vazio .req-showall,
.req-fx-link {
  border: 0; background: none; padding: 0; font: inherit; font-weight: 700;
  color: var(--brand-500); text-decoration: underline; cursor: pointer;
}
.req-fx-vazio .req-showall:focus-visible,
.req-fx-link:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); border-radius: 3px; }

/* Duas colunas E quatro fichas no estreito. 539px e o mesmo limiar que a trilha antiga usava,
   entao o atalho quebra junto com o resto do palco e nao num ponto proprio.
   O corte de 4 e do MESMO limiar das 2 colunas de proposito: um limiar so, uma verdade so. Com
   dois numeros diferentes daria para cair num estado de 6 fichas em 2 colunas (tres linhas), que
   e exatamente o custo que este corte existe para evitar.
   O corte e no CSS e nao no JS porque assim ele acompanha a largura ao VIVO (girar o tablet
   muda o palco sem nova renderizacao), e porque ficha escondida por `display: none` nao carrega
   a foto nem e lida por leitor de tela: nao ha conteudo pendurado atras do corte. */
@container (max-width: 539px) {
  .req-fx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .req-fx-tile:nth-child(n + 5) { display: none; }
}

/* `rqAnimate` ja consulta reduced-motion sozinho, entao aqui sobra o que e puramente CSS. */
@media (prefers-reduced-motion: reduce) {
  .req-fx-tile:hover { transform: none; }
  .req-fx-ind { transition: none; }
}

/* ---------- Rodape da grade: sentinela e "carregar mais" ---------- */
/* A sentinela nao ocupa espaco visual: ela existe so para o IntersectionObserver ter um alvo
   geometrico depois do ultimo card. 1px de altura, sem cor. */
.req-sentinel { height: 1px; }
.req-more-bar { display: flex; justify-content: center; align-items: center; padding: var(--space-4) 0 var(--space-2); }
.req-more-bar[hidden] { display: none; }
.req-more-end { font-size: .74rem; color: var(--text-secondary); opacity: .7; font-weight: 600; }

/* grade de cards — máx. 4 colunas (container query sobre a largura do catálogo) */
/* Catalogo AMPLO (varias familias) num painel estreito: uma coluna so. Medido a
   375px, o select do card fica com 112px uteis e 40% das opcoes escolhiveis
   estouram, porque fora do SESMT o rotulo e bitola e nao letra ("360 - 380 X
   7,8MM", "VERMELHO C F PAN186C"). Em uma coluna sobram 313px uteis e o estouro
   vai a ZERO. Duas colunas mostram mais cards, e card com a opcao ilegivel nao
   ajuda ninguem a escolher. No catalogo de uma familia (o SESMT em producao) o
   rotulo e P/M/G/38 e cabe folgado, entao ali as duas colunas ficam. */
.req-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
/* Teto de 400px e nao piso de 400px: `.req-grid.is-largo` e MAIS especifico que
   `.req-grid`, entao uma regra sem teto sequestraria as faixas de 540 e 820 abaixo e
   o catalogo amplo ficaria preso em coluna unica no desktop. Errei exatamente isso e
   a medicao pegou: card de 81px a 1440. */
@container (max-width: 399px) { .req-grid.is-largo { grid-template-columns: minmax(0, 1fr); } }
@container (min-width: 540px) { .req-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@container (min-width: 820px) { .req-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.req-card {
  display: flex; flex-direction: column;
  background: var(--bg-surface); border: 1px solid var(--line-soft);
  border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--shadow-1);
}
.req-card-photo { position: relative; aspect-ratio: 4 / 3; background: var(--bg-muted); }
.req-card-photo:has(img) { cursor: zoom-in; }
/* contain + fundo branco: mostra a peça INTEIRA sem cortar, qualquer proporção. */
.req-card-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #fff; display: block; }
/* A moldura vazia e 148 dos 337px do card, e 870 dos 873 cards nao tem foto (foto e cadastro
   a mao). Ou seja quase metade da grade e este quadro. Com 44px o glifo era um selinho perdido
   no meio dele; a 72px ele preenche a moldura como a foto faria e o card passa a ser
   reconhecivel a distancia pelo DESENHO, nao so pelo nome.
   A COR fica uma so, de proposito, e aqui eu divirjo do plano que falava de "tingido na cor do
   tema": sao 18 departamentos, e 18 matizes numa grade de 60 cards e confete. Dentro de um
   departamento todo card teria a mesma cor de qualquer jeito, entao a cor nao distinguiria nada
   justamente onde a pessoa passa o tempo. Quem distingue e o glifo, e ele agora existe para os
   18 (ver ICONS em requisicoes.js). */
.req-card-ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--brand-500); opacity: .38; }
.req-card-ph svg { width: 72px; height: 72px; }
.req-card-photo .req-badge { position: absolute; top: 8px; left: 8px; box-shadow: 0 1px 3px rgba(16, 26, 45, .25); }
/* sem saldo: o card continua visível (quando o toggle mostra), mas recua */
.req-card.is-out { opacity: .72; }

/* Botão "Gerenciar fotos" (admin/permitido) — mora no CABEÇALHO, fora da
   toolbar do operador: curadoria de foto é tarefa de admin, não do fluxo de pedir. */
.req-manage-btn { display: inline-flex; align-items: center; gap: 6px; }
/* O par [hidden] é OBRIGATÓRIO sempre que a classe declara display próprio: o
   [hidden]{display:none} do navegador mora na folha do user-agent, a de menor
   precedência que existe, então qualquer regra de autor com display o anula. Sem esta
   linha o botão continuava na tela mesmo com el.hidden = true. Mesmo padrão das outras
   ~15 classes deste arquivo (.req-pane[hidden], .req-seg-top[hidden], etc.). */
.req-manage-btn[hidden] { display: none; }
.req-manage-btn svg { width: 16px; height: 16px; }

/* Modal de gestão de fotógrafos (permissões). */
/* Busca fixa no topo; só a lista rola (a base tem centenas de usuários internos).
   A "caixa" (borda/raio/fundo/altura) e a lupa vivem no WRAPPER; o <input> por dentro é
   pelado. É o padrão do módulo Arquivos (ver comentário em views.css ~31383): dentro do
   modal, `.modal-card input[type="search"]` (especificidade 0,2,1) impõe borda/fundo/padding
   a QUALQUER input. Se a lupa fosse absoluta SOBRE o input, o padding-left de 38px seria
   engolido por essa regra e o ícone caía em cima do texto (o bug relatado). Wrapper flex +
   input pelado por seletor de 3 classes (0,3,1, vence a regra do modal sem !important). */
.req-grants { display: flex; flex-direction: column; min-height: 0; }
.req-grants-search {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto; margin-bottom: var(--space-3);
  height: 44px; padding: 0 12px; box-sizing: border-box;
  border: 1.5px solid rgba(15, 23, 42, 0.12); border-radius: 8px; background: #fff;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.req-grants-search:focus-within { border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--focus-ring); }
.req-grants-search svg { flex: none; width: 17px; height: 17px; color: var(--text-secondary); }
.modal-card .req-grants-search input {
  flex: 1; min-width: 0; border: 0; background: transparent; padding: 0; height: auto;
  box-shadow: none; border-radius: 0; outline: none; -webkit-appearance: none; appearance: none;
  font-family: inherit; font-size: 13.5px; color: var(--text-primary);
}
.modal-card .req-grants-search input:focus { border: 0; box-shadow: none; outline: none; }
.modal-card .req-grants-search input::-webkit-search-cancel-button,
.modal-card .req-grants-search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.req-uploaders { display: flex; flex-direction: column; gap: 2px; max-height: 52vh; overflow: auto; }
.req-uploader-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-2) var(--space-2); border-radius: var(--radius-sm); cursor: pointer;
}
.req-uploader-row:hover { background: var(--bg-muted); }
/* O filtro da busca faz row.hidden=true, mas a regra .req-uploader-row{display:flex}
   (0,1,0) vencia o [hidden]{display:none} do user-agent e a linha continuava à mostra —
   o filtro parecia morto. Este seletor (0,2,0) restaura o hidden sem !important. */
.req-uploader-row[hidden] { display: none; }
.req-uploader-info { display: flex; flex-direction: column; line-height: 1.25; }
/* Cabecalhos "Com acesso" / "Sem acesso". STICKY nao e enfeite: o scroll box e a
   `.req-uploaders` (`max-height: 52vh`), nao a `.req-grants` — cabecalho comum rolaria
   embora e a resposta "quem tem acesso" se perderia na primeira rolagem. Mesmo recurso
   que o `<th>` do historico usa. `background` opaco porque as linhas passam por baixo. */
.req-grants-sec {
  position: sticky; top: 0; z-index: 1;
  margin: 0 0 2px; padding: 6px 4px 4px;
  background: var(--bg-surface);
}
.req-grants-sec + .req-grants-sec, .req-uploader-row + .req-grants-sec { margin-top: var(--space-3); }
/* O `.req-state` padrao tem `padding: var(--space-10)` — dentro de uma lista compacta
   isso abre um vazio maior que a propria secao. */
.req-uploaders .req-state { padding: var(--space-2) var(--space-4); text-align: left; }
.req-uploader-info small { color: var(--text-secondary); }
/* Escopo de filial do almoxarife (migration 208). Fica DENTRO da linha-label, entre o nome e
   a caixa: pelo HTML, clicar em conteudo interativo nao ativa o label, entao o seletor nao
   alterna a permissao. `flex: 0 0 auto` para ele nao esticar e empurrar a caixa para fora,
   e `max-width` porque o nome do deposito no ERP pode ser longo ("ALMOXARIFADO PARANAIBA"). */
.req-escopo-filial {
  flex: 0 0 auto; max-width: 15rem; margin-left: auto;
  font-size: .8rem; padding: 2px 6px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary);
}
/* Mesmo motivo do `.req-uploader-row[hidden]` logo acima: a regra de display desta caixa
   venceria o [hidden] do user-agent, e o seletor continuaria a mostra em quem nao tem acesso. */
.req-escopo-filial[hidden] { display: none; }

/* Etiqueta de PLANTA nas linhas de fila (Seguranca e almoxarifado). Existe porque as duas
   filas globais passaram a misturar plantas: o servidor so manda o rotulo quando ha mais de
   uma para diferenciar, entao esta regra nunca aparece na operacao de uma planta so.

   Deliberadamente NEUTRA e nao colorida: a cor nas duas filas ja significa urgencia (idade) e
   estado do selo, e uma terceira cor competiria com as duas que exigem acao.

   O teto de largura e a reticencia sao para o tablet do balcao: planta com nome comprido corta
   em vez de empurrar o numero da requisicao para fora da linha. */
.req-filial-tag {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 6px; border-radius: 999px;
  border: 1px solid var(--line-soft); background: var(--bg-subtle);
  color: var(--text-secondary); font-size: .7rem; font-weight: 600;
  letter-spacing: .01em; white-space: nowrap; flex: 0 0 auto;
  max-width: 11rem; overflow: hidden; text-overflow: ellipsis;
}
.req-filial-tag svg { width: 12px; height: 12px; flex: 0 0 auto; }

/* ── Gerenciador de fotos de produto (pane in-tab) ──────────────────────────── */
.req-fotos { display: flex; flex-direction: column; gap: var(--space-4); }
.req-fotos-head {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  padding-bottom: var(--space-3); border-bottom: 1px solid var(--line-soft);
}
.req-fotos-back {
  display: inline-flex; align-items: center; gap: 4px; padding: 6px 12px 6px 8px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-secondary); cursor: pointer; font-weight: 600;
}
.req-fotos-back:hover { color: var(--text-primary); background: var(--bg-muted); }
.req-fotos-back svg { width: 18px; height: 18px; }
.req-fotos-titles { display: flex; flex-direction: column; }
.req-fotos-title { margin: 0; font-size: 1.05rem; font-weight: 700; color: var(--text-primary); }
.req-fotos-sub { margin: 2px 0 0; font-size: .82rem; color: var(--text-secondary); }
.req-fotos-meter { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; min-width: 180px; }
.req-fotos-meter-track { width: 100%; height: 8px; border-radius: 999px; background: var(--bg-muted); overflow: hidden; }
.req-fotos-meter-fill { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--success-500); transition: width .4s ease; }
.req-fotos-meter-label { font-size: .76rem; font-weight: 700; color: var(--text-secondary); }
.req-fotos-perms { display: inline-flex; align-items: center; gap: 6px; }
.req-fotos-perms[hidden] { display: none; }
.req-fotos-perms svg { width: 16px; height: 16px; }

.req-fotos-toolbar { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.req-fotos-filters { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.req-foto-filterbadge {
  display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px; border-radius: 999px;
  background: var(--warning-500, #d99a20); color: #fff; font-size: .68rem; font-weight: 800; text-align: center;
}
.req-chip.is-active .req-foto-filterbadge { background: rgba(255, 255, 255, .3); }

.req-fotos-grid {
  display: grid; gap: var(--space-3);
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.req-foto-tile {
  display: flex; flex-direction: column; gap: 6px; padding: 8px; cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--bg-surface);
  transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.req-foto-tile:hover { border-color: var(--brand-400, var(--brand-500)); box-shadow: var(--shadow-1); transform: translateY(-1px); }
.req-foto-tile:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }
.req-foto-tile.is-dragover { border-color: var(--brand-500); box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand-500) 35%, transparent); }
.req-foto-thumb {
  position: relative; aspect-ratio: 1 / 1; border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-muted);
}
.req-foto-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #fff; }
.req-foto-ph { position: absolute; inset: 0; display: grid; place-items: center; color: var(--brand-500); opacity: .4; }
.req-foto-ph svg { width: 40px; height: 40px; }
.req-foto-dot { position: absolute; top: 7px; right: 7px; width: 11px; height: 11px; border-radius: 50%; background: var(--warning-500, #d99a20); border: 2px solid var(--bg-surface); box-shadow: 0 0 0 1px rgba(16,26,45,.12); }
.req-foto-tile.has-photo .req-foto-dot { background: var(--success-500); }
.req-foto-busy { position: absolute; inset: 0; display: none; place-items: center; background: rgba(255,255,255,.72); }
.req-foto-tile.is-busy .req-foto-busy { display: grid; }
.req-foto-busy .req-spinner { margin: 0; width: 22px; height: 22px; }
/* Quantas cores do card ja tem foto PROPRIA. Texto e nao cor, pela mesma razao do rotulo "fora
   do catalogo" logo abaixo: o ponto de status do ladrilho ja usa cor para com/sem foto, e um
   segundo significado na mesma linguagem seria lido errado. O verde entra so no estado
   COMPLETO, que e informacao nova e nao repeticao do ponto. */
.req-foto-cores { font-size: .7rem; color: var(--text-secondary); }
.req-foto-cores.is-ok { color: var(--success-600, var(--success-500)); font-weight: 600; }
.req-foto-name {
  font-size: .82rem; font-weight: 600; color: var(--text-primary); line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.05em;
}
/* Peca que so a busca alcanca: sem pedido e sem saldo em 12 meses, logo fora da grade do
   catalogo. Existe para nao deixar ninguem gastar cadastro de foto num card que a grade nunca
   mostra. Texto e nao cor, porque o ponto de status do ladrilho ja usa cor para com/sem foto, e
   um segundo significado na mesma linguagem seria lido errado. */
.req-foto-fora {
  align-self: flex-start; font-size: .66rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-secondary);
  background: var(--bg-muted); border-radius: 999px; padding: 1px 7px;
}

/* Drawer de detalhe da peça */
.req-drawer-scrim { position: fixed; inset: 0; background: rgba(16, 26, 45, .42); z-index: 60; }
.req-drawer {
  position: fixed; top: 0; right: 0; height: 100%; width: min(420px, 92vw); z-index: 61;
  background: var(--bg-surface); box-shadow: -8px 0 30px rgba(16, 26, 45, .2);
  transform: translateX(100%); transition: transform .22s ease; overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-4);
}
.req-drawer.is-open { transform: none; }
/* A gaveta do histórico carrega foto + trilha + texto corrido; 420px (medida da gaveta de
   foto, que só tem uma imagem e dois botões) apertava as três coisas ao mesmo tempo. */
.req-drawer.is-wide { width: min(560px, 94vw); }
/* Trava a rolagem do fundo enquanto a gaveta está aberta: sem isso o scroll do mouse
   passa por cima do scrim e move a lista atrás, que é desorientador. */
body.req-drawer-aberta { overflow: hidden; }

/* ── Gaveta de detalhe do histórico ───────────────────────────────────────────
   Hierarquia deliberada, de cima para baixo, na ordem do que se pergunta ao abrir:
   QUAL requisição (número em mono grande, como na ficha) → em que ESTADO → O QUE foi
   entregue (com foto, o pedido literal) → a TRILHA → o texto longo. A trilha é o miolo:
   é a única coisa aqui que a linha da tabela não tinha como mostrar. */
.req-hd-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.req-hd-head-txt { display: flex; flex-direction: column; min-width: 0; }
.req-hd-head-txt small {
  font-size: .64rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-secondary);
}
.req-hd-head-txt b {
  margin-top: 2px; font-family: var(--font-mono); font-size: 1.7rem; font-weight: 600;
  line-height: 1.1; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}
.req-hd-quem { margin-top: 6px; font-size: .92rem; font-weight: 600; color: var(--text-primary); }
.req-hd-cc { font-size: .8rem; color: var(--text-secondary); }
/* Selo e ação na MESMA faixa: o selo diz o estado e o botão é a única coisa que se pode
   fazer a respeito dele. Separá-los em duas linhas afastaria o diagnóstico do remédio. */
.req-hd-selo { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.req-hd-selo .req-alm-h-reenviar { margin-left: 0; padding: 6px 12px; font-size: .78rem; }

.req-hd-sec { display: flex; flex-direction: column; gap: var(--space-2); }
.req-hd-sec h5 {
  margin: 0; font-size: .64rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-secondary);
}
/* Contagem à direita do rótulo da seção: `baseline` e não `center` porque os dois textos
   têm tamanhos bem diferentes e alinhar pelo centro faria a contagem flutuar. */
.req-hd-sec-top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.req-hd-sec-n { font-size: .74rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.req-hd-nota { margin: 0; font-size: .78rem; line-height: 1.4; color: var(--text-secondary); text-wrap: pretty; }
/* Fecho da seção "O que aconteceu" numa cancelada: diz o que fazer agora, que é a pergunta
   com que a pessoa saía da gaveta. Ícone alinhado ao topo (`flex-start`) e não ao centro,
   porque a frase quebra em duas linhas no estreito e um ícone centrado ficaria pendurado no
   meio do parágrafo. `flex-shrink: 0` no SVG pelo mesmo motivo de sempre: sem ele o ícone é
   o primeiro a ser comprimido e vira um risco. */
.req-hd-encerrada {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 9px 11px; border-radius: var(--radius-sm);
  color: color-mix(in srgb, var(--danger-500) 62%, var(--text-secondary));
  background: color-mix(in srgb, var(--danger-500) 7%, var(--bg-muted));
}
.req-hd-encerrada svg { flex-shrink: 0; width: 15px; height: 15px; margin-top: 1px; }
.req-hd-texto { margin: 0; font-size: .88rem; line-height: 1.45; color: var(--text-primary); text-wrap: pretty; }
.req-hd-texto.is-erro { color: var(--danger-500); }

/* Motivo do fim (cancelamento ou recusa), primeira seção da gaveta de um documento
   encerrado. Não ganhou fonte maior: ganhou posição, e o filete à esquerda porque ali fala
   uma PESSOA e não o sistema, que é a diferença que o resto da gaveta não marcava.

   Neutro por padrão e vermelho só na RECUSA da Segurança, que é a mesma separação que a
   tabela da estação faz. Cancelamento do balcão é decisão de rotina (pediu tamanho errado,
   colaborador não voltou): pintar de vermelho todo cancelamento com motivo escrito faria a
   cor deixar de significar alguma coisa. O corpo do texto fica neutro nos dois casos por
   isso mesmo, mesmo quando o `.is-erro` herdado da ficha vem no parágrafo: dentro deste
   cartão a cor já é dada pela moldura, e texto vermelho de 2 linhas grita mais que o selo. */
.req-hd-fim {
  gap: 6px; padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border-radius: var(--radius-sm); border-left: 3px solid currentColor;
  color: var(--text-secondary);
  background: color-mix(in srgb, currentColor 5%, var(--bg-muted));
}
.req-hd-fim.is-recusa { color: var(--danger-500); }
/* Cancelamento comum passou a ter acento de danger em 04/09, e isso REVERTE em parte a
   decisão descrita acima. O que mudou não foi o gosto: o lado do SOLICITANTE já pinta
   cancelada com `--danger-500` (`.req-mr-row.is-canceled`), então vermelho para cancelada
   já era a convenção do portal e esta gaveta era a exceção. Sem nenhum vermelho, a seção
   lia como nota técnica num documento morto (o print da 908838379, cancelada por "Unidade
   de medida errada").

   Mais fraco que `is-recusa` de propósito: a recusa da Segurança é `--danger-500` puro, o
   cancelamento fica numa mistura. As duas seguem distinguíveis pelo TÍTULO da seção e pela
   intensidade, e não pela ausência de cor numa delas. */
.req-hd-fim.is-encerrada { color: color-mix(in srgb, var(--danger-500) 62%, var(--text-secondary)); }
.req-hd-fim h5 { color: inherit; }
.req-hd-fim .req-hd-texto,
.req-hd-fim .req-hd-texto.is-erro { color: var(--text-primary); }
/* Quem e quando: o mesmo par que a trilha mostra no passo, repetido aqui de propósito. A
   trilha fica duas seções abaixo, e ler o motivo sem saber de quem é o texto obriga a
   procurar. É a repetição mais curta possível, em texto secundário. */
.req-hd-fim-quem { font-size: .74rem; color: var(--text-secondary); }

/* Itens: a foto é o motivo desta seção existir, então ela vem primeiro e maior que os
   48px da tabela — aqui não se varre uma lista, se reconhece um objeto físico. */
.req-hd-itens { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; background: var(--line-soft); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); overflow: hidden; }
.req-hd-item { display: flex; align-items: center; gap: var(--space-3); padding: 9px 11px; background: var(--bg-surface); }
.req-hd-item.is-vazio { color: var(--text-secondary); font-size: .84rem; }
.req-hd-item .req-alm-thumb { width: 60px; height: 60px; flex: none; }
/* Iniciais acompanham a moldura maior da gaveta: .8rem dentro de 60px ficaria perdido. */
.req-hd-item .req-alm-thumb-ini { font-size: 1.05rem; }
/* `align-self` porque a `.req-hd-item-txt` é flex COLUMN e o padrão `stretch` esticava a
   fita de chips na largura inteira: o chip de tamanho virava uma barra parecendo campo de
   formulário. Foi o segundo defeito visível na tela. */
.req-hd-item .req-alm-chips { align-self: flex-start; margin-top: 3px; }
/* Rastro do movimento no ERP. Discreto quando existe (é referência de auditoria, não
   veredicto) e vermelho quando falta, porque aí ele é o motivo do botão Reenviar.

   Deixou de ser numero em 31/08 e virou frase com um tique: a fonte mono e o
   `tabular-nums` existiam para alinhar digitos que nao estao mais aqui. Fundo segue neutro,
   pelo motivo que o paragrafo acima ja dava — quem grita nesta fita e a falta, nao o normal.
   Só o tique leva a cor de sucesso, o suficiente para varrer a lista e ver o que saiu. */
.req-hd-mov {
  display: inline-flex; align-items: center; gap: 4px; padding: 1px 8px; border-radius: 6px;
  background: var(--bg-muted); border: 1px solid var(--line-soft);
  font-size: .7rem; font-weight: 600; color: var(--text-secondary);
}
.req-hd-mov svg { width: 11px; height: 11px; flex: none; color: var(--success-500); }
/* Na falta nao ha icone, e a fita inteira e a cor. */
.req-hd-mov.is-falta svg { display: none; }
.req-hd-mov.is-falta {
  font-family: var(--font-body, inherit); color: var(--danger-500);
  background: color-mix(in srgb, var(--danger-500) 8%, var(--bg-surface));
  border-color: color-mix(in srgb, var(--danger-500) 30%, var(--line-soft));
}
.req-hd-item-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.req-hd-item-cod { font-family: var(--font-mono); font-size: .78rem; font-weight: 600; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.req-hd-item-desc { font-size: .86rem; font-weight: 600; color: var(--text-primary); line-height: 1.3; }
.req-hd-item-qtd { flex: none; text-align: right; }
.req-hd-item-qtd b { font-family: var(--font-mono); font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.req-hd-item-qtd small { margin-left: 2px; font-size: .68rem; color: var(--text-secondary); }

/* Trilha. A linha vertical é um ::before do <ol> e não uma borda de cada <li>: assim ela
   não se parte nos gaps e para exatamente no último passo. */
.req-hd-trilha { list-style: none; margin: 0; padding: 0 0 0 22px; position: relative; display: flex; flex-direction: column; gap: var(--space-3); }
.req-hd-trilha::before { content: ""; position: absolute; left: 5px; top: 7px; bottom: 7px; width: 2px; background: var(--line-soft); }
.req-hd-passo { position: relative; }
.req-hd-passo::before {
  content: ""; position: absolute; left: -22px; top: 5px; width: 12px; height: 12px;
  border-radius: 50%; background: var(--bg-surface);
  box-shadow: 0 0 0 2px var(--line-soft) inset;
}
.req-hd-passo.is-done::before { background: var(--success-500); box-shadow: none; }
.req-hd-passo.is-fail::before { background: var(--danger-500); box-shadow: none; }
.req-hd-passo.is-wait::before { background: var(--bg-surface); box-shadow: 0 0 0 2px var(--warning-500) inset; }
/* "baixada sem integração": aconteceu e terminou, só não passou pelo ERP. Cinza cheio —
   não é espera (âmbar) nem falha (vermelho), e pintar de qualquer um dos dois mentiria. */
.req-hd-passo.is-off::before { background: var(--text-secondary); box-shadow: none; }
.req-hd-passo-corpo { display: flex; flex-direction: column; gap: 1px; }
.req-hd-passo-corpo b { font-size: .88rem; font-weight: 700; color: var(--text-primary); }
/* Passo que ainda não aconteceu fica apagado mas PRESENTE: "aguardando retirada" é
   informação, e some-lo faria a trilha mentir por omissão. */
.req-hd-passo.is-vazio .req-hd-passo-corpo b { color: var(--text-secondary); font-weight: 600; }
.req-hd-passo-quando { font-size: .8rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
/* Intervalo desde o passo anterior. Fica mais apagado que o horário porque é leitura de
   segundo nível: primeiro se lê QUANDO, e só depois se pergunta quanto tempo esperou. */
.req-hd-passo-gap { font-size: .74rem; color: var(--text-secondary); opacity: .8; font-variant-numeric: tabular-nums; }
.req-hd-passo-nota { margin-top: 3px; font-size: .78rem; color: var(--text-secondary); line-height: 1.35; text-wrap: pretty; }
.req-hd-passo-nota.is-erro { color: var(--danger-500); }
/* Alinhado com o texto dos passos (o mesmo recuo de 22px do <ol>) para ler como fecho da
   trilha, e não como uma frase solta no rodapé da gaveta. */
.req-hd-ciclo { margin: 2px 0 0; padding-left: 22px; font-size: .8rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.req-hd-ciclo b { color: var(--text-primary); font-weight: 700; }

/* Linha de vida: o tempo do documento em PROPORCAO, no molde da coluna de SLA dos chamados.
   Substitui a frase "Do pedido a entrega", que dava o total sem dizer onde ele foi gasto.

   A barra e fina (6px) e sem rotulo dentro de proposito: ela e para varredura, nao para
   leitura. Quem quiser o numero de cada trecho tem o `title` no trecho e a trilha logo
   abaixo, que e o mesmo dado por extenso. */
.req-hd-vida { display: flex; flex-direction: column; gap: 5px; margin: 0 0 var(--space-2); }
.req-hd-vida-top {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3);
  font-size: .78rem; color: var(--text-secondary);
}
/* O total em tabular-nums e um pouco maior: e o unico numero que a pessoa costuma repetir
   em voz alta ("essa demorou 1h e meia"). */
.req-hd-vida-top b { font-size: .95rem; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.req-hd-vida-bar {
  display: flex; gap: 2px; height: 6px; border-radius: 999px; overflow: hidden;
  background: var(--bg-muted);
}
/* `flex-basis: 0` com `flex-grow` proporcional vindo do inline style: e o que faz a soma
   fechar exatamente 100% sem arredondar porcentagem. O `min-width` garante que um trecho de
   40 segundos ainda seja visivel como fio, em vez de sumir e dar a impressao de que a
   requisicao pulou uma etapa. */
.req-hd-vida-tr { flex-basis: 0; min-width: 3px; border-radius: 999px; }
.req-hd-vida-tr.is-seg { background: color-mix(in srgb, var(--warning-500) 78%, var(--bg-surface)); }
.req-hd-vida-tr.is-balcao { background: var(--brand-500); }
.req-hd-vida-tr.is-fim { background: color-mix(in srgb, var(--text-secondary) 55%, var(--bg-surface)); }
/* O trecho mais longo e a resposta a "onde demorou": ganha a altura inteira da barra e um
   filete escuro, porque so a largura nao chama atencao quando os dois trechos sao parecidos. */
.req-hd-vida-tr.is-maior { box-shadow: inset 0 0 0 1px color-mix(in srgb, #000 22%, transparent); }
.req-hd-vida-pes {
  display: flex; justify-content: space-between; gap: var(--space-3);
  font-size: .7rem; color: var(--text-secondary); font-variant-numeric: tabular-nums;
}
.req-hd-vida-pes em {
  font-style: normal; text-transform: uppercase; letter-spacing: .06em;
  font-size: .64rem; font-weight: 700;
}

/* Linha do histórico virou porta de entrada: precisa parecer clicável. */
.req-alm-h-row { cursor: pointer; }
.req-alm-h-row:focus-visible { outline: 2px solid var(--brand-500); outline-offset: -2px; }
/* Cancelada se anuncia na LINHA, e não só numa pastilha da última coluna. Mesmo tratamento
   que `.req-mr-row.is-canceled` já dá do lado do solicitante, que é onde essa convenção
   nasceu. Antes disto o único sinal era a pastilha cinza numa coluna chamada INTEGRAÇÃO, e
   quem varre a tabela procurando o documento morto tinha de ler a coluna errada.

   No primeiro `td` e não no `<tr>`: com `border-collapse: collapse` a borda do `tr` fica a
   cargo da resolução de conflito de bordas do navegador, e a da célula é previsível. A
   coluna 5 (centro de custo) é escondida no estreito, mas a 1 nunca, então `first-child`
   continua sendo a primeira célula visível. */
.req-alm-h-row.is-canceled > td:first-child { border-left: 3px solid var(--danger-500); }
.req-alm-h-row.is-canceled .req-alm-h-num { color: color-mix(in srgb, var(--danger-500) 72%, var(--text-primary)); }
.req-alm-h-card[data-hist-id] { cursor: pointer; }
.req-alm-h-card[data-hist-id]:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }

/* Motion: UM momento orquestrado na entrada, em vez de microanimação espalhada. A gaveta
   desliza (transição da .req-drawer) e as seções sobem atrás dela em cascata curta. O
   atraso acompanha a ordem de leitura, então a cascata REFORÇA a hierarquia em vez de
   competir com ela. Nada aqui anima na saída: fechar tem de ser instantâneo. */
@keyframes reqHdEntra { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.req-drawer.is-open#reqHistDrawer > * { animation: reqHdEntra .26s var(--ease-smooth) both; }
.req-drawer.is-open#reqHistDrawer > *:nth-child(1) { animation-delay: .05s; }
.req-drawer.is-open#reqHistDrawer > *:nth-child(2) { animation-delay: .09s; }
.req-drawer.is-open#reqHistDrawer > *:nth-child(3) { animation-delay: .13s; }
.req-drawer.is-open#reqHistDrawer > *:nth-child(4) { animation-delay: .17s; }
.req-drawer.is-open#reqHistDrawer > *:nth-child(n+5) { animation-delay: .21s; }

/* No celular a gaveta vira bottom sheet. Nao e conversao para o `.modal-card`
   compartilhado de proposito: esta gaveta carrega o drag-and-drop e o upload de foto do
   produto, e trocar o markup dela obrigaria a religar o drop, o foco e o estado
   `is-busy` por um ganho que nao aparece (quem sobe foto de produto trabalha no
   desktop). O que de fato incomoda no telefone e a geometria, e isso o CSS resolve:
   com 92vw ela era uma laje de tela cheia entrando pela DIREITA, gesto que nao casa
   com nada mais no portal, e o conteudo ficava comprimido em coluna alta.
   O limiar de 560px e o mesmo em que o resto do modulo passa a tratar celular. */
@media (max-width: 560px) {
  /* `.req-drawer.is-wide` LISTADA JUNTO, e nao e redundancia: ela vale 0,2,0 de
     especificidade contra 0,1,0 desta regra, e @media nao acrescenta especificidade nenhuma.
     Sem repeti-la aqui, a gaveta larga guardava os `min(560px, 94vw)` e no telefone de 375px
     nascia com 353, deixando 22px da tela de tras aparecendo pela direita: nem folha nem
     modal. Medido em 27/08, e valia para as TRES gavetas do modulo. */
  .req-drawer {
    top: auto; right: 0; left: 0; width: 100%; height: auto; max-height: 88vh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    box-shadow: 0 -10px 30px rgba(16, 26, 45, .24);
    transform: translateY(100%);
    /* A folha para ONDE A BARRA DO PORTAL COMECA, em vez de passar por baixo dela. No
       celular o rail vira `.mobile-bottom-nav` fixa em z-index 100, ou seja acima da gaveta
       (61) e acima do proprio scrim (60): passando por baixo, o ultimo bloco da folha fica
       coberto e, na Seguranca, sao 41px do "Liberar retirada" que e a UNICA acao da tela.
       Mesmo remedio e mesmos tokens do `.req-alm-foco-acts` do balcao, que ja pagou por
       este defeito. Com o desconto aqui, o trilho sticky em `bottom: 0` acerta sozinho e
       nenhum filho precisa saber que a barra existe. */
    bottom: calc(var(--bottom-nav-height) + var(--safe-area-bottom));
    /* Sem safe-area no padding: ela ja saiu no `bottom` acima, e somar duas vezes abriria
       uma faixa morta no pe da folha nos aparelhos com barra de gestos. */
    padding-bottom: var(--space-4);
  }
  /* SO a largura, em regra separada, e a separacao e o ponto: `.is-wide` vale 0,2,0 contra
     0,1,0 da regra acima, e @media nao acrescenta especificidade nenhuma, entao sem esta linha
     a gaveta larga guardava `min(560px, 94vw)` e num telefone de 375px nascia com 353,
     deixando 22px da tela de tras aparecendo pela direita. Medido em 27/08, e valia para as
     TRES gavetas do modulo.

     Repetir `.is-wide` no bloco inteiro seria o erro obvio, e ele foi cometido antes de chegar
     aqui: subindo o bloco todo para 0,2,0, o `transform: translateY(100%)` passou a empatar com
     `.req-drawer.is-open { transform: none }` e a vencer por ordem de fonte, ou seja a folha
     abria inteira FORA da tela. Sobe a especificidade do que precisa, nada mais. */
  .req-drawer.is-wide { width: 100%; }
  /* A preview nao pode comer a folha inteira: sem teto, uma imagem alta empurrava as
     acoes para fora do max-height e o botao de salvar ficava inalcancavel. */
  .req-drawer-preview { max-height: 42vh; }
}
.req-drawer-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.req-drawer-titles h4 { margin: 0; font-size: 1.02rem; font-weight: 700; color: var(--text-primary); }
.req-drawer-titles span { font-size: .78rem; color: var(--text-secondary); }
.req-drawer-close { display: grid; place-items: center; width: 34px; height: 34px; border: 0; border-radius: var(--radius-sm); background: var(--bg-muted); color: var(--text-secondary); cursor: pointer; }
.req-drawer-close:hover { color: var(--text-primary); }
.req-drawer-preview {
  position: relative; aspect-ratio: 4 / 3; border-radius: var(--radius-md); overflow: hidden;
  background: var(--bg-muted); display: grid; place-items: center; border: 1px dashed transparent;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.req-drawer-preview img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #fff; }
.req-drawer-preview.is-empty { border-color: var(--line-soft); }
/* Tracejado tambem no HERDADO, e a escolha do tracejado e o argumento: ele e a mesma marca do
   quadro vazio, porque o dois dizem a mesma coisa deste alvo, nada foi cadastrado AQUI. A
   imagem que aparece e emprestada da peca, e sem isso as duas telas sao identicas ao olho. */
.req-drawer-preview.is-herdada { border-color: var(--line-strong); }
.req-drawer-preview .req-foto-ph svg { width: 56px; height: 56px; }
/* A dica cresceu de .74 para .8rem com peso: ela nomeia o ALVO do arrasto, e no desenho antigo
   era o menor tipo da tela dizendo a coisa mais importante dela. */
.req-drawer-hint, .req-drawer-solta {
  position: absolute; bottom: 10px; z-index: 2; max-width: calc(100% - 24px);
  font-size: .8rem; font-weight: 600; line-height: 1.25; text-align: center;
  padding: 3px 10px; border-radius: 999px;
  color: var(--text-secondary); background: color-mix(in srgb, var(--bg-surface) 92%, transparent);
  box-shadow: 0 1px 4px rgba(16, 26, 45, .12);
}
.req-drawer-preview:not(.is-empty) .req-drawer-hint { display: none; }
/* O alvo confirma ANTES de soltar, que e o unico instante em que ainda da para desistir: no
   arrasto a dica sai e entra a frase que nomeia onde a imagem vai cair. */
.req-drawer-solta { display: none; color: var(--brand-600, var(--brand-500)); background: var(--bg-surface); }
.req-drawer-preview.is-dragover .req-drawer-hint { display: none; }
.req-drawer-preview.is-dragover .req-drawer-solta { display: block; }
/* Em card de cor a dica NAO se esconde quando ha imagem, e essa e a trava do desenho de
   02/09: quem salva arrastando precisa ler no quadro em qual cor vai cair, e o caso mais
   perigoso e justamente o que tem imagem (a herdada da peca). Fora de card de cor a regra
   de cima continua valendo, porque la o alvo e unico e nao ha o que confundir.

   O `:not(.is-dragover)` nao e defensivo, e conserto: medido no navegador, esta regra vence
   por ORDEM a que esconde a dica no arrasto (mesma especificidade, escrita antes), e as duas
   frases apareciam empilhadas no mesmo canto do quadro. Excluir o arrasto aqui resolve pela
   especificidade e nao pela posicao na folha, que e o que a proxima edicao vai preservar. */
.req-drawer-preview.is-alvo-cor:not(.is-dragover) .req-drawer-hint { display: block; }
.req-drawer-preview.is-dragover {
  border-style: solid; border-color: var(--brand-500);
  box-shadow: inset 0 0 0 3px color-mix(in srgb, var(--brand-500) 26%, transparent);
}
.req-drawer.is-busy .req-foto-busy { display: grid; }
.req-drawer-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.req-drawer-actions button { display: inline-flex; align-items: center; gap: 6px; }
.req-drawer-actions svg { width: 16px; height: 16px; }
/* Remover sai da fileira das duas acoes de CRIAR. Antes os tres botoes tinham o mesmo peso e a
   mesma vizinhanca, e "apagar a foto da peca" apaga a imagem de todas as cores que herdam
   dela: e a acao mais cara da tela sentada ao lado da mais rotineira. */
.req-drawer-rm { color: var(--danger-600, #c0392b); margin-left: auto; }
.req-drawer-note { margin: 0; font-size: .78rem; line-height: 1.45; color: var(--text-secondary); }

/* Cadastro de foto por COR, na gaveta que ja existe.

   Desenho de 02/09, pelo gesto dele: ele salva ARRASTANDO, e o unico alvo de arrasto que se
   anuncia e o quadro grande. Entao a gaveta deixou de ser uma lista de sete linhas com botao
   e passou a ter UM alvo selecionado: a tira escolhe, o quadro mostra e recebe, os tres
   botoes agem no que esta selecionado. A lista antiga escondia o alvo do arrasto numa faixa
   de 44px que nada apontava. */
.req-drawer-sub {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2);
  font-size: .74rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-secondary);
}
.req-drawer-sub span { font-weight: 500; letter-spacing: 0; text-transform: none; }
/* Verde SO no completo, mesma regra do rotulo de cores do ladrilho: enquanto falta cor, o
   numero e informacao e nao elogio. */
.req-drawer-cobertura.is-ok { color: var(--success-600, var(--success-500)); font-weight: 700; }
/* O salto para a proxima cor sem foto. Existe para o cadastro em SERIE (as 18 fotos de uma
   sentada): sem ele, cada volta pede que a pessoa varra a tira procurando qual pastilha ainda
   esta no glifo. Botao-texto e alinhado a direita porque e atalho, nao acao principal. */
.req-drawer-next {
  align-self: flex-end; display: inline-flex; align-items: center; gap: 4px;
  margin: -2px 2px 0; padding: 4px 8px; border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--brand-600, var(--brand-500));
  font-size: .78rem; font-weight: 700; cursor: pointer;
}
.req-drawer-next:hover { background: color-mix(in srgb, var(--brand-500) 10%, transparent); }
.req-drawer-next:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }
/* A seta do `back` espelhada em vez de um icone novo no dicionario do modulo. */
.req-drawer-next svg { width: 15px; height: 15px; transform: scaleX(-1); }
/* GRADE e nao rolagem horizontal, e a correcao veio de ver no navegador: eu tinha escrito que
   uma linha unica se le mais rapido que duas fileiras, mas em 420px de gaveta a linha unica
   CORTA na quinta pastilha, e regua cortada e o oposto de regua. Quebrar em duas fileiras
   mostra a cobertura inteira sem rolar nada. O teto de altura e defensivo: hoje o maior caso
   do catalogo e 7 cores, e a lista so rolaria acima de ~15. */
.req-drawer-chips {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 6px; padding: 2px; max-height: 34vh; overflow-y: auto; scrollbar-width: thin;
}
.req-drawer-chip {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  min-width: 0; padding: 6px 4px; cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-secondary);
  transition: border-color .12s ease, background-color .12s ease;
}
.req-drawer-chip:hover { border-color: var(--brand-400, var(--brand-500)); color: var(--text-primary); }
/* O selecionado e o alvo de TUDO, entao ele nao pode competir por atencao com os vizinhos:
   moldura de 2px na cor da marca mais o rotulo em peso. */
.req-drawer-chip.is-active {
  border-color: var(--brand-500); box-shadow: inset 0 0 0 1px var(--brand-500);
  background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface));
  color: var(--text-primary);
}
.req-drawer-chip.is-active .req-drawer-chip-rot { font-weight: 700; }
.req-drawer-chip-thumb {
  position: relative; width: 100%; aspect-ratio: 1 / 1; border-radius: 4px;
  overflow: hidden; background: var(--bg-muted); display: grid; place-items: center;
}
.req-drawer-chip-thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; background: #fff; }
.req-drawer-chip-thumb .req-foto-ph svg { width: 16px; height: 16px; }
/* Cor sem foto PROPRIA mostra o glifo, e nao a foto herdada: com a imagem da peca repetida
   nas sete pastilhas a tira afirmaria que o trabalho esta feito. O ponto verde e a unica marca
   de "esta cor ja tem a dela", e o mesmo vocabulario do ponto do ladrilho. */
.req-drawer-chip.has-photo .req-drawer-chip-thumb::after {
  content: ''; position: absolute; right: 3px; bottom: 3px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--success-600, var(--success-500));
  box-shadow: 0 0 0 2px var(--bg-surface);
}
.req-drawer-chip-rot {
  max-width: 100%; font-size: .72rem; line-height: 1.2; text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A IDENTIDADE do alvo mora dentro do quadro, e isto e o miolo do redesenho.
   Antes o nome do alvo e o estado dele viviam numa faixa abaixo, com a mesma tipografia
   caixa-alta do titulo "SELECIONAR COR" logo acima: um COMANDO e um ESTADO vestidos de irmaos.
   Encostados na imagem que qualificam, os dois se leem de uma vez, e "herdada da peca" para
   de ser uma nota de rodape sobre a unica tela que engana o olho. */
.req-drawer-alvo {
  position: absolute; top: 0; left: 0; right: 0; z-index: 2;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  padding: 8px;
  background: linear-gradient(to bottom, rgba(16, 26, 45, .28), rgba(16, 26, 45, 0));
}
/* Pilula solida e nao texto sobre gradiente, e a razao e contraste medivel: a imagem atras
   pode ser clara (fundo branco de produto) ou escura, entao branco com sombra chega a passar
   o AA num card e a nao passar no seguinte. Com fundo proprio, os dois lados da barra tem
   contraste fixo, independente da foto. */
.req-drawer-alvo-rot {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 3px 10px; border-radius: 999px;
  font-size: .84rem; font-weight: 800; letter-spacing: .02em;
  color: #fff; background: color-mix(in srgb, var(--text-primary) 86%, transparent);
  box-shadow: 0 1px 4px rgba(16, 26, 45, .28);
}
.req-drawer-estado {
  flex: 0 0 auto; padding: 2px 9px; border-radius: 999px;
  font-size: .68rem; font-weight: 700; letter-spacing: .02em;
  background: var(--bg-surface); color: var(--text-secondary);
  box-shadow: 0 1px 4px rgba(16, 26, 45, .25);
}
.req-drawer-estado.is-propria { color: var(--success-600, var(--success-500)); }
/* Os dois estados provisorios ficam no MESMO vocabulario, e nao em dois: o que a pessoa precisa
   distinguir e "esta cor tem a dela" de "esta cor nao tem", e nao os dois jeitos de nao ter. */
.req-drawer-estado.is-herdada, .req-drawer-estado.is-vazia { color: var(--warning-500, #d99a20); }

/* A pastilha que ACABOU de receber foto pisca uma vez, no mesmo gesto elastico da pilula do
   carrinho (`reqpillpulse`), que e o vocabulario de "isto avancou" que o modulo ja tem. */
.req-drawer-chip.is-salva { animation: reqDwSalva .5s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes reqDwSalva {
  0% { transform: scale(1); }
  40% { transform: scale(1.08); box-shadow: 0 0 0 3px color-mix(in srgb, var(--success-500) 45%, transparent); }
  100% { transform: scale(1); }
}
/* Trocar de alvo faz a imagem entrar em vez de aparecer trocada: 140ms bastam para o olho
   registrar que a coisa mudou, e o innerHTML da gaveta e reconstruido a cada troca, entao a
   animacao dispara sozinha sem uma linha de JS. */
.req-drawer-preview img { animation: reqDwFoto .14s var(--ease-smooth) both; }
@keyframes reqDwFoto { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }

/* Lightbox (lupa) — amplia a foto pra conferir o produto. */
.req-lightbox { position: fixed; inset: 0; z-index: 70; display: none; place-items: center; padding: 4vmin; background: rgba(16, 26, 45, .82); }
.req-lightbox.is-open { display: grid; animation: reqlbfade .16s ease; }
@keyframes reqlbfade { from { opacity: 0; } to { opacity: 1; } }
.req-lightbox-inner { position: relative; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); max-width: 92vw; max-height: 92vh; }
/* Quadro de tamanho FIXO: toda foto abre no mesmo tamanho (as menores são
   ampliadas pra preencher), preservando a proporção com fundo branco. */
.req-lightbox-inner img { width: min(88vw, 620px); height: min(74vh, 620px); object-fit: contain; background: #fff; border-radius: var(--radius-md); box-shadow: 0 12px 48px rgba(0, 0, 0, .4); }
.req-lightbox-cap { color: #fff; font-weight: 600; font-size: .92rem; text-align: center; }
.req-lightbox-close { position: absolute; top: -12px; right: -12px; display: grid; place-items: center; width: 38px; height: 38px; border: 0; border-radius: 50%; background: #fff; color: var(--text-primary); cursor: pointer; box-shadow: 0 2px 10px rgba(0, 0, 0, .3); }
.req-lightbox-close svg { width: 18px; height: 18px; }
@media (prefers-reduced-motion: reduce) { .req-lightbox.is-open { animation: none; } }

@media (max-width: 720px) {
  .req-fotos-meter { margin-left: 0; align-items: flex-start; width: 100%; }
  .req-fotos-head { gap: var(--space-2); }
}

/* ── mobile (≤640px): cabeçalho condensado, tabs full-width, toolbar enxuta ── */
@media (max-width: 640px) {
  .requisicoes-view { gap: var(--space-3); }
  .req-head { gap: var(--space-2); padding-bottom: var(--space-2); }
  .req-head-icon { width: 38px; height: 38px; border-radius: 11px; }
  .req-head-icon svg { width: 20px; height: 20px; }
  .req-head-title { font-size: 1.2rem; }
  .req-head-eyebrow { font-size: .64rem; }
  .req-head-sub { display: none; }

  /* OVERFLOW HORIZONTAL (corrigido 31/07): a barra de abas internas tinha min-content
     de ~382px e, como item de grid com `min-width:auto`, ESTICAVA a coluna do
     workspace — a aba inteira media 382 numa viewport de 375 e o corte ficava
     escondido pelo `overflow-x:hidden` do body. Afetava os três painéis (Catálogo,
     Minhas e Almoxarifado) porque a barra fica acima deles.
     `flex: 1 1 0` + `min-width: 0` deixam o botão realmente encolher, e o rótulo
     quebra em duas linhas em vez de forçar largura — assim as três abas continuam
     visíveis, sem rolagem lateral e sem texto cortado. */
  /* `flex-wrap: wrap` é o que efetivamente resolve: sem ele, o min-content do
     contêiner é a SOMA dos três rótulos (medido: 414px) e `flex:1 1 0` não muda isso
     — a seção é item de grid e esticava a coluna do workspace para 414 numa viewport
     de 375. Quebrando linha, o mínimo passa a ser o do maior botão isolado.
     `min-width: 0` na seção completa a correção, impedindo o mínimo automático do
     item de grid de reintroduzir o problema com qualquer conteúdo futuro. */
  #requisicoesTab { min-width: 0; }
  .req-queues { display: flex; flex-wrap: wrap; width: 100%; min-width: 0; }
  .req-queue {
    flex: 1 1 auto; min-width: 0; padding: 6px 10px; font-size: .8rem;
    line-height: 1.15; text-align: center;
  }

  .req-toolbar { gap: var(--space-2); }
  .req-search { flex: 1 1 100%; }
  .req-search input { height: 42px; }
  .req-manage-btn { margin-left: 0; width: 42px; padding: 0; justify-content: center; }
  .req-manage-btn span { display: none; }
  .req-count { margin-left: auto; }
}
/* container-type aqui e para as acoes do card (ver .req-card-actions). Verificado que
   nada dentro do corpo do card e `position: fixed`, senao o `contain: layout` que vem
   de brinde faria o corpo virar bloco contentor. */
.req-card-body { flex: 1 1 auto; display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-3); container-type: inline-size; }
.req-card-name {
  font-size: .94rem; font-weight: 600; line-height: 1.3; color: var(--text-primary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; min-height: 2.45em;
}
/* meta discreta (código / nº de tamanhos) em mono, como nos documentos do ERP */
.req-card-meta {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: .68rem; color: var(--text-secondary); opacity: .8; margin-top: -4px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* UNIDADE DE MEDIDA (KG, RL, M2) na linha de apoio do card. Herda o mono e o tabular-nums
   de .req-card-meta e sobe UM degrau: peso 700 e opacidade cheia contra a .8 da linha.
   E o unico dado dali que muda a decisao de quem pede ("por rolo ou por metro?"), enquanto
   o codigo ao lado apenas identifica - por isso o codigo fica um passo atras. */
.req-card-un { font-weight: 700; opacity: 1; letter-spacing: .02em; }

/* badge de saldo (estilo c-badge, via tokens semânticos) */
.req-badge { font-size: .68rem; font-weight: 700; padding: 2px 8px; border-radius: 999px; white-space: nowrap; letter-spacing: .01em; }
.req-badge.is-ok { color: var(--success-500); background: color-mix(in srgb, var(--success-500) 14%, var(--bg-surface)); }
/* âmbar mais escuro no texto: contraste AA sobre o fundo tintado */
.req-badge.is-warn { color: var(--warning-600, #b45309); background: color-mix(in srgb, var(--warning-500) 18%, var(--bg-surface)); }
.req-badge.is-out { color: var(--danger-600, #c2372a); background: color-mix(in srgb, var(--danger-500, #dc2626) 10%, var(--bg-surface)); }

/* Selecao de tamanho + adicionar, LADO A LADO, como na ficha do atalho. Decisao dele em 26/08,
   depois de ver as duas na tela: o empilhado deixava o card sem tamanho com um vao visivel, e a
   ficha do atalho provava que a linha unica funciona.
   O que fez a linha unica caber foi copiar a PROPORCAO da ficha, e nao so juntar os dois: o botao
   do atalho e compacto (fonte menor, padding curto, glifo de 12px) e por isso sobra select. Com o
   botao de 119px que o card usava, um card de 191px deixaria ~40px de select, onde nem
   "100 X 2,5MM" cabe. Com o botao compacto sobra o dobro.
   Custo assumido e declarado: no catalogo amplo o rotulo da variante e bitola
   ("360 - 380 X 7,8MM") e nao letra, entao parte das opcoes aparece cortada no select FECHADO. A
   opcao inteira continua legivel ao abrir a lista, que e o momento em que a pessoa escolhe.
   O empilhamento sobrevive so no aperto de verdade (abaixo de 168px de CARD, onde nem o botao
   compacto cabe ao lado de um select operavel), e nao mais como regra do catalogo amplo.
   `margin-top: auto` ancora o rodape no PE do card: a linha ganha a altura do card mais alto, e
   sem a ancora o card mais curto terminava o conteudo 63px antes do proprio pe (medido a 1440).
   O limiar e do CARD e nao da tela, porque o mesmo aperto acontece em painel estreito de desktop
   com 4 colunas e a viewport nao sabe disso. */
.req-card-actions { display: flex; align-items: center; gap: 8px; margin-top: auto; padding-top: 2px; }
/* Reparto explicito, revisado em 01/09 depois de medir a tela em producao. O criterio nao e novo,
   esta escrito no bloco acima e e do desenho de 26/08: "100 X 2,5MM" tem de caber no campo
   FECHADO. Nao cabia. No palco real (grade de 693px, porque a sidebar leva 276px, o trilho 196px e
   o carrinho 300px) o card sai com 220px, o select ficava com 87px e sobravam 53px de texto contra
   os 75px do rotulo, entao 3 de 13 cards cortavam o valor SELECIONADO, e nao apenas as opcoes da
   lista aberta.
   Quem cede deixa de ser o TEXTO e passa a ser a LINHA: o select ganha piso de 118px (84px de
   texto, que cobre o pior rotulo medido, "1500500015/1") e o rodape pode quebrar. Onde os dois
   caibam lado a lado, a linha unica de 26/08 continua valendo; onde nao caibam, o select toma a
   linha inteira em vez de mentir sobre o tamanho escolhido.
   O piso vale SO onde o rotulo e longo (`is-rotulo-longo`, posto na renderizacao por
   `temGradeDe`), e essa fronteira nao e nova: e a mesma que ja decide o vocabulario do card
   ("tamanhos" contra "opcoes"). Grade de vestuario e calcado le "P", "M", "42", entao piso de
   118px daria um campo de 199px para mostrar UMA letra e ainda subiria a linha em 48px sem
   consertar nada. Medido na tela em 01/09: sem a fronteira, a ficha do uniforme fazia exatamente
   isso. */
.req-card-actions .req-select { flex: 1 1 0; min-width: 0; }
.req-card-actions.is-rotulo-longo .req-select { flex: 1 1 auto; min-width: 118px; }
.req-card-actions .req-add { flex: none; }
/* Select do card acima de 10 opcoes: o componente compartilhado troca a lista nativa
   por um painel com busca (ver `ligarBuscaDosSelects`). O estado FECHADO nao pode
   mudar, senao a mesma grade passa a ter dois visuais de campo: o gatilho recebe aqui
   a medida, o corpo e a fonte do `.req-select` (as cores e a borda ja sao os mesmos
   tokens no componente), e por isso o ponto onde o rotulo trunca continua o mesmo.
   Toda a diferenca vive no estado ABERTO, que e onde a lista de 61 precisava mudar. */
.req-card-actions .gsel { flex: 1 1 0; min-width: 0; }
.req-card-actions.is-rotulo-longo .gsel { flex: 1 1 auto; min-width: 118px; }
.req-card-actions .gsel-trigger {
  gap: 4px; min-height: 44px; padding: 0 9px 0 10px;
  font-size: .85rem; border-radius: var(--radius-sm);
}
/* A seta do `.req-select` e desenhada em `--text-secondary` (o `%23404752` do SVG
   embutido). O chevron do componente nasce em `--brand-600`, e no card isso seria
   a unica diferenca visivel entre um select de 8 opcoes e um de 61. */
.req-card-actions .gsel-chevron { width: 16px; height: 16px; color: var(--text-secondary); }
.req-card-actions .req-add.is-full,
.req-card-actions .req-add.req-add-full { flex: 1 1 auto; justify-content: center; }
/* Botao compacto quando o card e estreito, que e a condicao de a linha unica caber. 300px e
   medido: acima disso o botao de tamanho cheio ja convive com um select folgado. */
@container (max-width: 300px) {
  .req-card-actions { gap: 6px; }
  .req-card-actions .req-add { padding: 0 10px; gap: 5px; font-size: .78rem; }
  .req-card-actions .req-add svg { width: 13px; height: 13px; }
  /* O respiro de 6px a direita era de quando a seta era NATIVA: o navegador reservava o espaco
     dela por fora da caixa de texto, entao 6px de padding sobravam para o texto. Com a seta
     propria (bloco `.req-select`) quem reserva e o padding, e com 6px o valor passava POR BAIXO
     do chevron sem reticencia, que e o defeito que a seta propria existe para consertar. Medido
     na tela em 01/09 num card de 276px: `164 X 105 X 200MM` terminava a 2px do chevron, e um
     rotulo um caractere maior entrava embaixo dele.
     Chevron menor (12px, o mesmo tamanho que a banda "Mais pedidos" ja usa) para a reserva sair
     de 30px por 20px em vez de 24px: com 24px o mesmo card cortava o valor por 1px, ou seja o
     conserto do chevron estragaria a leitura que hoje esta certa. Com 20px sobram 117px de texto
     e o pior rotulo desta faixa cabe com 3px de folga. */
  .req-card-actions .req-select {
    padding: 0 20px 0 8px; font-size: .8rem;
    background-position: right 5px center; background-size: 12px;
  }
}
/* ---------------------------------------------------------------------------------------------
   Rotulo longo (bitola, metragem, cor, medida de caixa): tres faixas de largura, e cada limiar e
   uma CONTA e nao um gosto. Decisao de 01/09, depois de medir a tela.
   O defeito de origem: no palco real (grade de 693px, card de 220px, corpo de 196px) o select
   sobrava com 87px, ou 53px de texto, contra os 75px de "100 X 2,5MM", e 3 de 13 cards cortavam o
   valor SELECIONADO, nao apenas as opcoes da lista aberta.
   Quebrar a linha foi implementado, olhado na tela e REPROVADO: o rodape ia de 46px para 96px, a
   grade passava a ter duas alturas de card e o pe perdia a cara de acao. Meio a meio tambem foi
   medido e reprovado por conta propria: 90px para cada lado deixa o select com 92px e "100 X
   2,5MM" volta a cortar por 15px, ou seja recria o defeito.
   Entao quem cede e o BOTAO, que e o unico elemento cuja largura e texto redundante: o icone de
   mais no pe de um card de catalogo ja diz adicionar, e a palavra continua no DOM por RECORTE (nao
   `display:none`, senao o botao perde o nome acessivel) mais `title` no hover.
   Piso do select: 118px, que da 84px de texto e cobre o pior rotulo de bitola do catalogo
   ("1500500015/1"). Os tres limiares saem dele:
     222px = 118 do select + 6 de vao + 98 do botao compacto COM texto. Acima daqui o texto cabe, e
             esconder era desperdicio: medido, um card de corpo 286px ficava com botao de 56px e
             select de 200px, ou seja escondia a palavra com 80px sobrando.
     180px = 118 + 6 + 56 do botao so de icone. Abaixo daqui nem sem texto os dois cabem, e o piso
             de 118 fazia o rodape TRANSBORDAR o card (medido: 44px de estouro num corpo de 136px).
             Ali o piso cai e o select volta a encolher com reticencia, que e pior que caber e
             melhor que estourar.
   Caixa com tres dimensoes ("626 X 104 X 926MM", 147px) nao cabe em faixa nenhuma desta grade e
   cai na reticencia de proposito. O conserto dela nao e largura: e o seletor com busca a partir de
   8 opcoes compostas, que e frente separada.
   --------------------------------------------------------------------------------------------- */
@container (max-width: 222px) {
  .req-card-actions.is-rotulo-longo { gap: 6px; }
  /* Os ultimos 10px vem de vao e respiro, nunca do tamanho da letra: 12,8px e o minimo de corpo de
     texto que a tela pratica, e encolher isso para caber um rotulo troca um defeito visivel por um
     de legibilidade. */
  /* O respiro da DIREITA e reserva do chevron e nao folga: comer ele poe o texto embaixo da
     seta, que e o defeito que a seta propria veio consertar. Quem cede e o lado esquerdo. */
  .req-card-actions.is-rotulo-longo .req-select { padding: 0 24px 0 6px; background-position: right 7px center; background-size: 14px; }
  /* 56x44: a largura e o teto medido (180 menos 6 menos 118) e a altura e o alvo minimo de toque
     que o modulo ja pratica, declarado no bloco base deste botao. Pastilha, nao quadrado. */
  .req-card-actions.is-rotulo-longo .req-add { width: 56px; padding: 0; gap: 0; }
  .req-card-actions.is-rotulo-longo .req-add > span {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
  }
}
/* Abaixo de 180px o piso do select vira estouro, entao ele cede. A reticencia ja esta posta acima. */
@container (max-width: 180px) {
  .req-card-actions.is-rotulo-longo .req-select { flex: 1 1 0; min-width: 0; }
}
/* O aperto de verdade: abaixo daqui nem o botao so de icone deixa select operavel, e ai empilhar
   passa a ser a unica divisao possivel. Note que este e o UNICO lugar do card onde empilhar
   sobrevive, e de proposito: com card de 153px nao existe linha unica para escolher.
   129px e do CONTENT BOX do corpo do card, e nao da largura do card: `container-type:
   inline-size` mede a caixa de conteudo, entao um card de 191px consulta como 167px (saem os 12px
   de padding de cada lado). O limiar antigo de 167 batia EXATO nesse card e o empilhava, que e
   justamente o que este bloco nao deveria fazer. 129 corresponde a card de ~153px, onde nem o
   botao compacto (~96px) conviveria com um select operavel. */
@container (max-width: 129px) {
  .req-card-actions { flex-direction: column; align-items: stretch; }
  .req-card-actions .req-select, .req-card-actions .gsel,
  .req-card-actions .req-add { width: 100%; flex: none; }
  .req-card-actions .req-add { justify-content: center; }
}
.req-select {
  /* 44px: o card e operado por toque no celular e o select fica ao lado do
     Adicionar, entao os dois precisam do mesmo alvo. */
  flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0 30px 0 10px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary); font: inherit; font-size: .85rem; cursor: pointer;
  /* Seta PROPRIA em vez da nativa, no padrao que o app ja declara em
     `consultas-producao.css` ("padrao do app: appearance:none + SVG repoe a setinha").
     Duas razoes medidas na tela em 01/09, e nenhuma e estetica:
     1. Com a seta NATIVA o valor selecionado que nao cabe e cortado no seco E ENCOSTA na
        seta: visto no card da Caixa Master, "164 X 105 X 200MM" terminava colado no
        chevron, o que le como valor errado e nao como valor truncado.
     2. `text-overflow: ellipsis` NAO funciona em select nativo. Com `appearance: none` o
        valor volta a ser texto comum e a reticencia passa a valer, entao o que nao cabe
        anuncia que nao cabe. Conferido na tela: com a seta nativa a reticencia nao
        renderizava.
     O respiro de 30px a direita e reserva DECLARADA para o chevron, no lugar da reserva
     implicita da seta nativa (~20px), entao a largura util do texto nao muda. */
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23404752' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center; background-size: 16px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.req-select::-ms-expand { display: none; }
.req-select:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--focus-ring); }
.req-add {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  /* 44px, nao 38px: o card e operado por toque no celular e este e o alvo que
     conclui a escolha. */
  min-height: 44px; padding: 0 14px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  /* Repouso NEUTRO de proposito. Sao ate 75 destes na grade ao mesmo tempo:
     qualquer cor de destaque aqui multiplica por 75 e a tela vira ruido. A cor
     entra no hover, que e quando existe intencao, e no estado adicionado, que
     e quando existe consequencia. */
  background: var(--bg-surface); color: var(--text-primary); font-size: .83rem; font-weight: 700; cursor: pointer;
  transition: background var(--trans-fast), border-color var(--trans-fast), color var(--trans-fast);
}
.req-add:hover:not(:disabled) { border-color: var(--brand-500); background: var(--brand-500); color: #fff; }
.req-add:disabled { opacity: .5; cursor: not-allowed; }
.req-add.req-add-full { flex: 1; }
.req-add.is-added { background: var(--success-500); border-color: var(--success-500); color: #fff; }
.req-add svg { width: 15px; height: 15px; }

/* estados */
.req-state { grid-column: 1 / -1; text-align: center; color: var(--text-secondary); padding: var(--space-10) var(--space-4); }
.req-state strong { display: block; color: var(--text-primary); font-size: 1rem; margin-bottom: 4px; }
.req-state-actions { display: flex; gap: var(--space-2); justify-content: center; flex-wrap: wrap; margin-top: var(--space-3); }
.req-spinner { width: 26px; height: 26px; border-radius: 50%; margin: 0 auto var(--space-3); border: 3px solid var(--line-soft); border-top-color: var(--brand-500); animation: reqspin .75s linear infinite; }
@keyframes reqspin { to { transform: rotate(360deg); } }

/* ── carrinho lateral ── */
.req-cart { background: var(--bg-surface); border: 1px solid var(--line-soft); border-radius: var(--radius-md); box-shadow: var(--shadow-1); overflow: hidden; }
.req-cart-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-3); border-bottom: 1px solid var(--line-soft); }
.req-cart-title { font-size: 1rem; font-weight: 700; color: var(--text-primary); display: flex; align-items: center; gap: 8px; }
.req-cart-title svg { width: 18px; height: 18px; color: var(--brand-500); }
.req-cart-pill { font-size: .72rem; font-weight: 700; color: #fff; background: var(--brand-500); border-radius: 999px; padding: 2px 9px; }
/* Alvo de toque de verdade. O `SVG.chevron` e viewBox puro, sem width/height, e ate
   aqui nao havia regra nenhuma para ele: o tamanho do botao saia da negociacao entre o
   sizing default de elemento substituido e o flex do cabecalho, nao de uma decisao.
   Todos os outros chevrons do arquivo ja sao dimensionados (.req-mr-month-chev svg,
   .req-mr-chev svg, .req-seg-pessoa-seta svg); este era o unico que faltava.
   44x44 e o piso de alvo de toque (WCAG 2.5.8), e `flex: none` impede que o cabecalho
   encolha o botao abaixo disso quando o titulo e longo. */
.req-cart-toggle { display: none; background: none; border: none; color: var(--text-secondary); cursor: pointer; min-height: 44px; min-width: 44px; padding: 0 var(--space-2); flex: none; }
/* A seta aponta para onde o gesto leva: recolhida aponta para CIMA (abrir), aberta
   aponta para baixo (fechar). Mesmo idioma do .req-mr-month-chev.is-open. */
.req-cart-toggle svg { width: 20px; height: 20px; transform: rotate(180deg); transition: transform var(--trans-fast); }
.req-cart.is-open .req-cart-toggle svg { transform: rotate(0deg); }
.req-cart-body { display: flex; flex-direction: column; }
.req-cart-items { display: flex; flex-direction: column; max-height: 52vh; overflow-y: auto; padding: 0 var(--space-3); }
.req-cart-item { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-3) 0; border-bottom: 1px solid var(--line-soft); }
.req-cart-item:last-child { border-bottom: none; }
.req-cart-item-info { flex: 1; min-width: 0; }
.req-cart-item-name { font-size: .86rem; font-weight: 600; color: var(--text-primary); }
.req-cart-item-sub { font-size: .74rem; color: var(--text-secondary); margin-top: 1px; }
.req-cart-item-sub code { font-family: ui-monospace, monospace; font-size: .72rem; background: var(--bg-muted); padding: 1px 5px; border-radius: 5px; }
.req-stepper { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.req-stepper button { width: 30px; height: 30px; min-height: 0; padding: 0; border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: var(--bg-surface); color: var(--text-primary); display: grid; place-items: center; cursor: pointer; }
.req-stepper button:hover { border-color: var(--brand-500); }
.req-stepper button svg { width: 14px; height: 14px; }
/* overflow hidden: o digito rola para fora do proprio quadro na troca de
   quantidade (ver setQty), e sem o recorte ele apareceria sobre os botoes.
   E item flex, entao transform se aplica normalmente. */
.req-stepper .req-qty { min-width: 22px; text-align: center; font-weight: 700; font-variant-numeric: tabular-nums; font-size: .9rem; overflow: hidden; }
/* O campo de quantidade nasce com a CARA DO MOSTRADOR que era antes (mesmo peso, mesmo
   tamanho, tabular-nums, centralizado) e so se revela editavel no hover/foco: quem pede
   1 luva nao percebe que algo mudou, e quem pede 20 mil digita em vez de clicar.
   `field-sizing` faz a largura acompanhar o conteudo onde existe; `width` em ch e o piso
   para os navegadores que ainda nao o tem. Sem separador de milhar aqui dentro (ver
   qtdCampo no JS), entao 9ch cobrem o teto de 9 digitos do ERP. */
.req-stepper input.req-qty {
  min-width: 3ch; max-width: 9ch; width: 5ch; field-sizing: content;
  padding: 2px 0; min-height: 0; border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; color: inherit; font: inherit; font-weight: 700; font-size: .9rem;
  font-variant-numeric: tabular-nums; text-align: center;
}
.req-stepper input.req-qty:hover { border-color: var(--line-soft); }
.req-stepper input.req-qty:focus { border-color: var(--brand-500); background: var(--bg-surface); outline: none; }
/* Unidade de medida: sufixo quieto, um degrau otico ABAIXO do numero. Ela qualifica o
   dado, nao compete com ele - o mesmo degrau em que o <code> do produto ja vive na linha. */
.req-qty-un { font-size: .72rem; font-weight: 600; color: var(--text-secondary); letter-spacing: .02em; flex: none; }
/* Recusa de fracao em unidade CONTAVEL (2,5 PAR). Ambar de atencao e nao vermelho de erro,
   e a escolha e deliberada: nada foi perdido (o numero anterior continua no carrinho) e o
   item nao esta com problema. Vermelho aqui faria a linha parecer barrada. Ocupa a LINHA
   inteira porque na coluna do nome, que divide espaco com o stepper, a frase quebrava em
   quatro linhas de tres palavras. */
.req-cart-item-frac {
  flex-basis: 100%; display: flex; align-items: center; gap: 5px; margin: -2px 0 0;
  font-size: .7rem; line-height: 1.35; color: var(--warning-600, #b45309);
}
/* `display: flex` na classe VENCE o `[hidden] { display: none }` da folha do navegador
   (regra de autor bate UA), entao sem esta linha o aviso aparece mesmo escondido - e o
   teste de DOM passa, porque a propriedade .hidden esta certa. Mesmo remendo que a
   .req-cart-foot[hidden] logo abaixo ja carrega. */
.req-cart-item-frac[hidden] { display: none; }
.req-cart-item-frac svg { width: 12px; height: 12px; flex: none; margin-top: 1px; }
.req-cart-rm { background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 2px; flex: none; }
.req-cart-rm:hover { color: var(--danger-500); }
.req-cart-rm svg { width: 15px; height: 15px; }
.req-cart-empty { padding: var(--space-8) var(--space-4); text-align: center; color: var(--text-secondary); font-size: .85rem; }
.req-cart-empty svg { width: 30px; height: 30px; opacity: .5; margin-bottom: var(--space-2); }
.req-cart-foot { padding: var(--space-3); border-top: 1px solid var(--line-soft); display: flex; flex-direction: column; gap: var(--space-2); }
.req-cart-foot[hidden] { display: none; }
.req-obs { width: 100%; min-height: 38px; padding: 9px 11px; resize: vertical; font: inherit; border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: var(--bg-surface); color: var(--text-primary); }
.req-obs:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--focus-ring); }
/* Linha de estado do rascunho. Discreta de proposito: ela nao e uma acao, e uma garantia -
   diz que a pessoa pode fechar a tela. Salvamento automatico invisivel nao gera confianca,
   e por isso ela existe; competir com o botao de gerar seria o oposto do objetivo. */
.req-rasc { margin: var(--space-2) 0 0; font-size: .74rem; color: var(--text-secondary); display: flex; align-items: center; gap: 6px; justify-content: center; }
.req-rasc button { background: none; border: none; padding: 0; font: inherit; color: var(--text-secondary); text-decoration: underline; cursor: pointer; min-height: 0; }
.req-rasc button:hover { color: var(--danger-500); }
.req-rasc.is-erro { color: var(--danger-600, #c2372a); }
/* O .req-generate e um <button> pelado, entao ja nasce com o --brand-500 do botao
   global (components.css) e o state-layer global cuida do hover. Nao ha override
   de cor aqui de proposito: e a acao primaria da tela e usa a primaria do portal. */
.req-cart-foot .req-generate { width: 100%; }

/* centro de custo da requisição, colado acima de "Gerar": é a última coisa lida antes de
   confirmar. Uma linha só para todos os casos (1 CC ou vários) — a mesma pessoa vê a mesma
   coisa e a porta de troca fica sempre visível. A escolha inteira (os seus + busca aberta)
   mora no painel que este botão abre, então aqui não há seletor nem link separado. */
.req-cc { display: contents; }
.req-cc[hidden] { display: none; }
.req-cc-line {
  display: flex; align-items: center; gap: var(--space-2); width: 100%;
  padding: 8px 11px; min-height: 38px; font: inherit; text-align: left; cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-muted); color: var(--text-primary);
}
.req-cc-line:hover { border-color: var(--line-strong, var(--line-soft)); }
.req-cc-line:focus-visible { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--focus-ring); }
.req-cc-line-ic { flex: none; display: inline-flex; color: var(--text-secondary); }
.req-cc-line-ic svg { width: 16px; height: 16px; }
.req-cc-line-txt { flex: 1; min-width: 0; font-size: .78rem; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.req-cc-line-txt strong { color: var(--text-primary); font-weight: 600; }
.req-cc-line-act { flex: none; font-size: .74rem; font-weight: 600; color: var(--brand-600, var(--brand-500)); }

/* Um CC so e sem direito de busca: nada a escolher, entao a linha deixa de ser botao. Mesma
   caixa, sem afordancia de clique: mostrar "alterar" para abrir um painel de opcao unica e
   oferecer uma escolha que nao existe. */
.req-cc-line.is-fixo { cursor: default; margin: 0; }

/* Barrado: sem CC nativo e sem CC liberado a pessoa nao requisita (trava de 03/09/2026). Este
   bloco existe porque sumir seria pior: ela montaria o carrinho inteiro e so descobriria no
   clique de gerar. Aviso e nao erro, porque tem conserto e o texto diz qual. */
.req-cc-bloqueio {
  display: flex; align-items: flex-start; gap: var(--space-2); width: 100%; margin: 0;
  padding: 9px 11px; font-size: .78rem; line-height: 1.4; color: var(--text-secondary);
  border: 1px solid var(--warning-500); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warning-500) 8%, var(--bg-muted));
}
.req-cc-bloqueio strong { color: var(--text-primary); font-weight: 600; }
.req-cc-bloqueio .req-cc-line-ic { color: var(--warning-600, var(--warning-500)); margin-top: 1px; }

/* busca aberta de CC (dentro do diálogo padrão do portal) */
.req-ccbusca { display: flex; flex-direction: column; gap: var(--space-2); }
.req-ccbusca-input {
  width: 100%; min-height: 40px; padding: 9px 11px; font: inherit;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary);
}
.req-ccbusca-input:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--focus-ring); }
/* altura fixa: a lista cresce e encolhe a cada tecla, e o diálogo pulando de tamanho
   embaixo do cursor faz o clique cair no item errado. */
.req-ccbusca-res {
  height: 210px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm); padding: 4px; background: var(--bg-muted);
}
/* Sem direito de busca a lista e ESTATICA (os centros da propria pessoa, e nada os muda
   enquanto o dialogo esta aberto), entao a altura fixa acima nao protege clique nenhum e
   sobra um bloco vazio. `max-height` continua para quem tem muitos centros liberados. */
.req-ccbusca.is-sem-busca .req-ccbusca-res { height: auto; max-height: 260px; }
.req-ccbusca-hint { margin: auto; font-size: .78rem; color: var(--text-secondary); text-align: center; }
/* rótulo da seção "Os seus" no repouso do painel; some quando a busca assume a área */
.req-ccbusca-titulo { margin: 2px 4px 4px; font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.req-ccbusca-item {
  display: flex; align-items: baseline; gap: var(--space-2); width: 100%; text-align: left;
  padding: 8px 10px; min-height: 38px; border: 1px solid transparent; border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary); font: inherit; cursor: pointer;
}
.req-ccbusca-item strong { font-variant-numeric: tabular-nums; font-size: .82rem; }
.req-ccbusca-item span { flex: 1; min-width: 0; font-size: .78rem; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.req-ccbusca-item:hover { border-color: var(--line-strong, var(--line-soft)); }
/* CC escolhido agora: marcado na lista dos seus, sem ser um estado de seleção pendente */
.req-ccbusca-item.is-atual { border-color: color-mix(in srgb, var(--brand-500) 40%, var(--line-soft)); }
.req-ccbusca-atual { margin-left: auto; flex: none; display: inline-flex; color: var(--brand-600, var(--brand-500)); }
.req-ccbusca-atual svg { width: 15px; height: 15px; }

/* estados de geração (ERP Senior) dentro do carrinho */
.req-gen-state {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  text-align: center; padding: var(--space-6) var(--space-3);
}
.req-gen-state strong { font-size: .95rem; color: var(--text-primary); }
.req-gen-state span { font-size: .8rem; color: var(--text-secondary); line-height: 1.45; max-width: 32ch; }
.req-gen-state .req-spinner { margin: 0 auto 2px; }
.req-gen-state .req-generate { width: 100%; margin-top: var(--space-2); }
.req-gen-state.is-error strong { color: var(--danger-600, #c2372a); }
.req-gen-err {
  display: block; max-width: 100%; overflow-wrap: break-word; font-size: .7rem;
  font-family: ui-monospace, monospace; color: var(--text-secondary);
  background: var(--bg-muted); border-radius: var(--radius-sm); padding: 6px 9px;
}
/* barra indeterminada: sinaliza processo vivo sem prometer progresso real */
.req-progress { width: 100%; max-width: 220px; height: 4px; border-radius: 999px; background: var(--bg-muted); overflow: hidden; margin-top: 4px; }
.req-progress span { display: block; width: 40%; height: 100%; border-radius: 999px; background: var(--brand-500); animation: reqprog 1.2s ease-in-out infinite; }
@keyframes reqprog { 0% { transform: translateX(-110%); } 100% { transform: translateX(280%); } }

/* banner de reposição parcial (Pedir novamente) */
.req-cart-note {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
  margin: var(--space-3) 0 0; padding: 8px 10px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warning-500) 14%, var(--bg-surface));
  color: var(--warning-600, #b45309); font-size: .78rem; font-weight: 600; line-height: 1.35;
}
.req-cart-note button { flex: none; background: none; border: none; color: inherit; font-size: 1rem; font-weight: 700; cursor: pointer; padding: 0 4px; min-height: 24px; }

/* botão-link discreto (Ver detalhes / Editar itens) */
.req-linkbtn {
  background: none; border: none; color: var(--text-secondary); font-size: .8rem; font-weight: 600;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px; padding: 6px 10px; min-height: 38px;
}
.req-linkbtn:hover { color: var(--brand-500); }

/* pulso do contador ao adicionar item */
.req-cart-pill { display: inline-block; }
.req-cart-pill.is-pulse { animation: reqpillpulse .45s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes reqpillpulse { 0% { transform: scale(1); } 45% { transform: scale(1.35); } 100% { transform: scale(1); } }

@media (min-width: 1280px) { .req-cart { position: sticky; top: var(--space-4); } }
/* Casa com o limiar de 1280 acima: entre 1024 e 1279 o carrinho e barra + gaveta,
   nao coluna. Sem isso ele ficaria sem os dois nessa faixa. */
@media (max-width: 1279.98px) {
  .req-cart { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60; border-radius: var(--radius-md) var(--radius-md) 0 0; box-shadow: var(--shadow-2); max-width: 760px; margin: 0 auto; }
  .req-cart.is-empty { display: none; }
  /* O cabecalho INTEIRO e o alvo do toque, nao so a setinha: pareado com o listener
     em #reqCartHead. So aqui, porque em >= 1280 o carrinho e coluna e nao recolhe, e
     la cursor de mao e texto nao-selecionavel seriam mentira. `touch-action` precisa
     ser explicito: o reset de base.css cobre a/button/[role=button]/.tab, e o
     cabecalho e um div, entao sem ele o iOS ainda cobra a espera de duplo-toque. */
  .req-cart-head { position: relative; padding-top: calc(var(--space-3) + 9px); cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
  /* Pega de arraste. E o sinal universal de "isto e uma gaveta, puxe" (mesmo desenho das
     folhas nativas do iOS e do Android), e e ele que faltava: o relato de campo foi de
     alguem que tocou na barra sem saber que ela era interativa. Custa quatro linhas de CSS,
     zero JS e zero dependencia, e some sozinho no desktop porque este bloco e so do modo
     gaveta. Decorativa: nao entra na arvore de acessibilidade, onde quem fala e o botao
     com aria-expanded. */
  .req-cart-head::before { content: ''; position: absolute; top: 7px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 999px; background: var(--line-soft); }
  .req-cart-toggle { display: grid; place-items: center; }
  .req-cart-body { max-height: 0; overflow: hidden; transition: max-height var(--trans-base); }
  /* drawer aberto: a lista rola, o "Gerar requisição" fica FIXO no rodapé
     (não pode escapar da dobra em carrinhos longos) */
  .req-cart.is-open .req-cart-body { max-height: 72vh; display: flex; flex-direction: column; }
  .req-cart.is-open .req-cart-items { flex: 1 1 auto; min-height: 0; overflow-y: auto; max-height: none; }
  .req-cart.is-open .req-cart-foot { flex: none; background: var(--bg-surface); }
  /* 72px foi medido com o toggle de 32px. O cabecalho subiu (alvo de toque de 44px) e,
     em <= 767px, a barra ainda sobe a faixa da bottom-nav. Sem crescer aqui, a ultima
     fileira de cards fica embaixo da barra. A faixa da NAV em si nao entra nesta conta:
     o .workspace ja a reserva no bloco mobile de layout.css. */
  .req-main { padding-bottom: 92px; }
}

/* No mobile o rail do portal vira .mobile-bottom-nav FIXA (z-index 100, layout.css).
   O carrinho e fixed com z-index 60: a barra recolhida e, pior, o .req-cart-foot com o
   "Gerar requisicao" (ultimo filho de um aside que cresce PARA CIMA) nascem ATRAS dela.
   Mesmo defeito e mesmo remedio do .req-alm-foco-acts mais abaixo neste arquivo.

   A condicao e COPIADA de layout.css palavra por palavra, inclusive o segundo termo:
   celular deitado tem largura > 767px e MESMO ASSIM mostra a bottom-nav. E entre 768 e
   1279 (tablet retrato) NAO ha bottom-nav, por isso o recuo nao pode morar no bloco de
   cima, senao a barra flutuaria acima do nada. */
@media (max-width: 767px), (pointer: coarse) and (max-height: 500px) {
  .req-cart { bottom: calc(var(--bottom-nav-height) + var(--safe-area-bottom)); }

  /* Teto da gaveta aberta. 72vh sozinho nao cabe: no iOS o `vh` mede a viewport GRANDE
     (barras recolhidas), entao num iPhone SE (375x667) 72vh da 480px e, somado ao
     cabecalho e ao recuo da nav, o topo da lista sai da tela. `dvh` mede o que esta
     visivel AGORA. O min() mantem 72vh como teto em tela alta e deixa o calc mandar na
     tela baixa.

     O calc fica INLINE, nunca dentro de custom property: `dvh` desconhecido invalida a
     declaracao no PARSE e a regra anterior (72vh) assume o posto; dentro de var() a
     falha seria no valor computado e a propriedade viraria `unset`, o oposto do
     fallback desejado. */
  .req-cart.is-open .req-cart-body {
    max-height: min(72vh, calc(100dvh - var(--bottom-nav-height) - var(--safe-area-bottom) - var(--mobile-header-height) - 60px));
  }
}

/* ── minhas requisições ── */
/* ── minhas requisições — cards com accent lateral por status ── */
.req-pane[data-pane="minhas"] { container-type: inline-size; }
.req-minhas { display: flex; flex-direction: column; gap: var(--space-4); }

/* ── Minhas requisições: layout de LISTA ──────────────────────────────────────
   Versão "Lista" do design aprovado em 31/07 (a versão "Balcão" do mesmo mockup foi
   descartada por decisão do Henrique). Uma linha por requisição, agrupada por mês,
   detalhes em disclosure — o histórico é para VARRER (achar um pedido) e só depois
   LER. Substitui o grid de cards, em que uma requisição de 9 itens virava um card de
   699px e empurrava as ações fora da área visível. */

.req-mr-sub { margin: 0 0 var(--space-3); font-size: .88rem; color: var(--text-secondary); }

.req-mr-toolbar {
  display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center;
  margin-bottom: var(--space-3);
}
.req-mr-search { flex: 1 1 260px; min-width: 0; }
.req-mr-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.req-mr-chip {
  display: inline-flex; align-items: center; gap: 7px; min-height: 44px; padding: 0 14px;
  border-radius: 999px; cursor: pointer; font-size: .84rem; font-weight: 600;
  border: 1px solid var(--line-soft); background: var(--bg-surface); color: var(--text-secondary);
  transition: border-color var(--trans-fast), background var(--trans-fast), color var(--trans-fast);
}
.req-mr-chip.is-active { background: var(--brand-500); border-color: var(--brand-500); color: #fff; }
.req-mr-chip-n { font-variant-numeric: tabular-nums; font-size: .76rem; opacity: .75; }
.req-mr-dot { width: 7px; height: 7px; border-radius: 999px; background: var(--text-secondary); flex: none; }
.req-mr-chip.is-wait .req-mr-dot { background: var(--warning-500); }
.req-mr-chip.is-done .req-mr-dot { background: var(--success-500); }
.req-mr-chip.is-canceled .req-mr-dot { background: var(--danger-500); }
.req-mr-chip.is-active .req-mr-dot { background: rgba(255, 255, 255, .85); }

/* Chip de etapa: segundo eixo dos filtros (onde a requisicao esta parada), separado do eixo
   de situacao por uma regua fina. Ele traz icone em vez de ponto de cor porque o ponto ja
   codifica situacao: dois vocabularios de cor no mesmo trilho de chips confundiriam. */
.req-mr-chips-sep {
  align-self: center; flex: none; width: 1px; height: 22px;
  margin: 0 4px; background: var(--line-soft);
}
.req-mr-chip.is-etapa svg { width: 15px; height: 15px; flex: none; opacity: .8; }
.req-mr-chip.is-etapa.is-active svg { opacity: 1; }

/* "Ver todas": troca DE QUEM e a lista, e nao qual recorte dela. Mesma pastilha dos chips
   de proposito (e o mesmo trilho, entao formato diferente pareceria controle de outra
   familia), so que ligado ele fica contornado em vez de preenchido: preenchido e o estado
   de "filtro escolhido", e escopo nao e filtro. O contorno em cor de marca da o mesmo
   "esta ligado" sem competir com o chip de situacao ativo, que continua sendo o
   preenchido. Os valores nao sao invencao: e o mesmo par de `color-mix` sobre transparente
   que `.req-subchip.is-active` ja usa neste arquivo, entao ele se resolve sobre a superficie
   real e acompanha o tema em vez de cravar um hex claro. */
.req-mr-todas svg { width: 15px; height: 15px; flex: none; opacity: .8; }
/* Sem esta linha o `hidden` do botao nao esconde nada: `.req-mr-chip` crava
   `display: inline-flex`, e regra de autor ganha do `[hidden] { display: none }` da folha
   do navegador. Medido: com a capacidade negada o botao seguia na tela com 114x44. */
.req-mr-todas[hidden] { display: none; }
.req-mr-todas.is-active {
  background: color-mix(in srgb, var(--brand-500) 14%, transparent);
  border-color: color-mix(in srgb, var(--brand-500) 45%, transparent);
  color: var(--brand-500);
}
.req-mr-todas.is-active svg { opacity: 1; }

/* Selo de etapa: o MESMO vocabulario da fila do balcao, para o colaborador e o almoxarife
   falarem da mesma coisa ao telefone.

   Em 27/08 ele saiu da LINHA da lista e ficou so na GAVETA. Na linha ele era o terceiro bloco
   empilhado de uma celula que ja passava de 60px e por isso ditava a altura de todas as
   linhas; hoje a linha diz a etapa no proprio texto da situacao (ver `mrSituacao` no JS). O
   `align-self` que existia aqui para nao esticar a pastilha numa celula em coluna morreu com
   a celula, e na gaveta o contexto ja e flex de coluna com `align-items` proprio. */
.req-mr-etapa {
  display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px;
  border-radius: 999px; font-size: .72rem; font-weight: 700; letter-spacing: .01em;
  border: 1px solid var(--line-soft); color: var(--text-secondary); background: var(--bg-muted);
}
.req-mr-etapa svg { width: 13px; height: 13px; flex: none; }
.req-mr-etapa.is-seguranca {
  color: var(--warning-600, #b45309);
  border-color: color-mix(in srgb, var(--warning-500) 42%, var(--bg-surface));
  background: color-mix(in srgb, var(--warning-500) 16%, var(--bg-surface));
}
.req-mr-etapa.is-almoxarifado {
  color: var(--success-600, #15803d);
  border-color: color-mix(in srgb, var(--success-500) 42%, var(--bg-surface));
  background: color-mix(in srgb, var(--success-500) 16%, var(--bg-surface));
}

/* Fusivel de pendentes do servidor, dito em voz alta (ver TETO_MINHAS_PENDENTES no
   repositorio). Nao e paginacao: fala do que o servidor varreu, nao do que a tela mostra. */
.req-mr-teto {
  margin-top: var(--space-3); padding-top: var(--space-2);
  border-top: 1px dashed var(--line-soft);
  font-size: .78rem; color: var(--text-secondary); text-align: center;
}

/* Mesma caixa que rola dos dois historicos, e o mesmo motivo. Os grupos de mes vivem
   dentro dela; o rodape de contagem, fora. */
.req-mr-scroll {
  max-height: min(68vh, 720px); overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--space-3);
  /* A barra de rolagem nasce encostada nos cartoes; o respiro evita que ela cubra a borda
     direita das linhas. */
  padding-right: 2px;
}

/* Mês colapsável: o corrente abre, os anteriores nascem minimizados — mesmo idioma
   das notas de atualização. Sem isso o histórico cresce sem limite.

   NÃO usar <details>/<summary> aqui. O navegador esconde o conteúdo do <details>
   fechado com `content-visibility: hidden`, que mantém LAYOUT (medido: 592px de linhas
   dentro de uma caixa de 34px) e re-renderiza esse conteúdo a cada invalidação de
   estilo — passar o mouse invalida, e a lista inteira piscava. Com `hidden` no corpo,
   `display:none` remove do layout de verdade. */
.req-mr-group + .req-mr-group { margin-top: var(--space-3); }
.req-mr-group-body { display: flex; flex-direction: column; gap: 8px; padding-top: 8px; }
/* Explícito: a classe acima venceria o `display:none` implícito do atributo. */
.req-mr-group-body[hidden] { display: none; }

/* O cabeçalho é um <button> — reset do estilo nativo, largura total. */
.req-mr-month {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 2px; margin: 0;
  border: 0; border-bottom: 1px solid var(--line-soft); background: transparent;
  font: inherit; text-align: left; cursor: pointer; user-select: none;
}
.req-mr-month:hover h3 { color: var(--text-primary); }
.req-mr-month h3 {
  margin: 0; font-size: .72rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-secondary);
}
.req-mr-month-n, .req-mr-month-mix { font-size: .72rem; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
/* O mix por situação é o que faz o mês fechado continuar informando. */
.req-mr-month-mix { margin-left: auto; text-align: right; }
.req-mr-month-mix[hidden] { display: none; }
/* O glifo do SVG e um chevron para BAIXO, entao o estado de repouso (mes fechado) e que
   precisa girar: -90deg deixa a seta apontando para a direita, e `.is-open` volta a zero e
   aponta para baixo. Estava o contrario (repouso em zero, aberto em +90deg), o que dava
   fechado apontando para baixo e aberto apontando para a esquerda: os dois errados. */
.req-mr-month-chev {
  display: inline-flex; flex: none; color: var(--text-secondary);
  transform: rotate(-90deg); transition: transform var(--trans-fast);
}
.req-mr-month-chev svg { width: 14px; height: 14px; }
.req-mr-month-chev.is-open { transform: rotate(0deg); }
.req-mr-month:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; border-radius: var(--radius-sm); }

/* A linha. Barra de acento à esquerda = situação, SEMPRE acompanhada do rótulo
   textual — nunca só cor. */
.req-mr-row {
  background: var(--bg-surface); border: 1px solid var(--line-soft);
  border-left: 3px solid var(--text-secondary); border-radius: var(--radius-md);
  overflow: hidden; transition: border-color var(--trans-fast);
}
.req-mr-row.is-wait { border-left-color: var(--warning-500); }
.req-mr-row.is-done { border-left-color: var(--success-500); }
.req-mr-row.is-canceled { border-left-color: var(--danger-500); }

.req-mr-main {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3);
  padding: 10px var(--space-3);
  cursor: pointer;
}

/* TODO o cabeçalho do card abre os detalhes — inclusive a área do selo de situação.
   SEM overlay e SEM position:relative aqui.
   A tentativa anterior esticava um pseudo-elemento (`.req-mr-toggle::after` com
   inset:0) por cima do cabeçalho. Resultado relatado: piscar já no hover e clique que
   não registrava. Não foi possível reproduzir neste ambiente (o painel embutido não
   compõe quadros — sem hover nem hit-testing real, e `requestAnimationFrame` nem
   dispara), então o mecanismo foi REMOVIDO em vez de ajustado às cegas.
   Agora o clique vem por delegação no próprio cabeçalho (ver o handler de #reqMinhas)
   e o <button> continua existindo apenas para teclado e leitor de tela.
   Nada cobre nada, nada é reposicionado. */
.req-mr-toggle:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; border-radius: var(--radius-sm); }

/* Uma linha de texto ao lado do icone, e nao um bloco de texto empilhado.

   194px, e o numero e a SOMA e nao um chute: icone 26 + gap 9 + 158 do rotulo mais longo, com
   1px de folga para arredondamento. Os 158 foram medidos no navegador com o corpo real da
   celula (12,48px / 700 / letter-spacing 0,3744px / uppercase).

   O valor anterior era 150px e vinha de uma premissa ERRADA que este comentario afirmava: que
   o rotulo mais longo passara a ser "Na Seguranca" (103px). Nao passou. `mrSituacao` devolve a
   etapa SO na pendente; fora dela devolve o rotulo do status, e ali vivem "Retirada concluida"
   (143px) e "Aguardando retirada" (158px, o fallback da pendente sem etapa). Em 150px o texto
   ficava com 115px, entao "RETIRADA CONCLUIDA" reticenciava em toda linha retirada. Regra que
   fica: o teto desta coluna e o maior rotulo de MR_STATUS mais MR_ETAPA juntos, nao o de um
   dos dois.

   O rotulo mais longo, medido:
     Aguardando retirada  158   Retirada concluida  143   Na Seguranca  103
     Cancelada             80   No balcao            76

   Custo: 44px saem do PRODUTO, a unica celula elastica. Ele acabou de receber 64px na remocao
   da coluna TAM, entao segue com mais espaco do que tinha antes das duas mudancas. */
.req-mr-status { display: flex; align-items: center; gap: 9px; flex: 0 0 auto; min-width: 194px; }
.req-mr-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 999px; flex: none;
}
.req-mr-icon svg { width: 15px; height: 15px; }
.req-mr-row.is-wait .req-mr-icon { background: color-mix(in srgb, var(--warning-500) 15%, var(--bg-surface)); color: color-mix(in srgb, var(--warning-500) 78%, #000); }
.req-mr-row.is-done .req-mr-icon { background: color-mix(in srgb, var(--success-500) 12%, var(--bg-surface)); color: color-mix(in srgb, var(--success-500) 72%, #000); }
.req-mr-row.is-canceled .req-mr-icon { background: color-mix(in srgb, var(--danger-500) 10%, var(--bg-surface)); color: var(--danger-600, var(--danger-500)); }
/* O rotulo cede por ELIPSE e nao por quebra: quebrar era exatamente o que fazia a celula
   valer 62px, e quebra ainda faria a altura da linha variar por estado. Com a coluna
   dimensionada pelo maior rotulo (ver acima) nenhum dos cinco alcanca o teto, entao a elipse
   e REDE para rotulo novo ou fonte diferente, nao comportamento esperado. Rotulo novo que
   reticencie e sinal de que o numero da coluna precisa ser refeito, nao de que a elipse
   funcionou. */
.req-mr-status b {
  font-size: .78rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.req-mr-row.is-wait .req-mr-status b { color: color-mix(in srgb, var(--warning-500) 78%, #000); }
.req-mr-row.is-done .req-mr-status b { color: color-mix(in srgb, var(--success-500) 72%, #000); }
.req-mr-row.is-canceled .req-mr-status b { color: var(--danger-600, var(--danger-500)); }
/* As duas variantes de rotulo (`.req-mr-lbl-full` e `.req-mr-lbl-short`) sairam junto com o
   texto longo: com "Na Seguranca" e "Retirada" cabendo em qualquer largura, manter um par de
   rotulos alternados seria duas verdades para o mesmo dado, e a curta era a que o celular
   mostrava. A cor segue sendo o STATUS e o texto segue sendo a ETAPA, entao a situacao
   continua nao dependendo so da cor, que era a razao do par existir. */

/* Toda a área de identificação é o alvo do disclosure — alvo grande, sem obrigar a
   caçar um chevron de 13px. */
.req-mr-toggle {
  flex: 1 1 260px; min-width: 200px; min-height: 44px;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 2px;
  padding: 4px 2px; border: 0; background: transparent; cursor: pointer; text-align: left;
}
/* Neutraliza o state-layer/elevação genérico de <button> (components.css) — aqui é
   só o alvo de clique do card inteiro, não uma ação; o card já não reage ao hover. */
.req-mr-main .req-mr-toggle:hover {
  background-image: none; box-shadow: none; transform: none;
}
.req-mr-num { font-size: .95rem; font-weight: 700; color: var(--text-primary); }
/* Data em duas partes: o dia carrega o peso e a hora vem apagada ao lado. Numa coluna de
   16 caracteres a hora e o pedaco que quase nunca decide nada, e apagada ela para de
   competir com a data sem precisar sair da tela. */
.req-mr-data { color: var(--text-secondary); white-space: nowrap; }
.req-mr-data i { font-style: normal; margin-left: 6px; opacity: .72; }
.req-mr-quem {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: .85rem; font-weight: 600; color: var(--text-primary);
}
.req-mr-pill {
  display: inline-flex; align-items: baseline; gap: 4px;
  font-size: .72rem; font-weight: 600; color: var(--text-secondary);
  background: var(--bg-muted); border-radius: 999px; padding: 2px 8px; white-space: nowrap;
}
.req-mr-pill b { font-weight: 700; }
/* `display: block` e nao `flex`: com o chevron fora (27/08) sobrou UM filho de texto, e em
   contexto flex o texto e um item ANONIMO, onde `text-overflow` nao se aplica e a celula
   corta seco em vez de reticenciar. Bloco e o contexto em que a elipse aparece, e ela importa
   aqui porque esta e a unica celula elastica da grade. */
.req-mr-resumo {
  display: block; min-width: 0; max-width: 100%;
  font-size: .85rem; color: var(--text-secondary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.req-mr-actions { display: flex; flex-wrap: wrap; gap: 6px; flex: 0 0 auto; margin-left: auto; }

.req-mr-btn {
  display: inline-flex; align-items: center; gap: 7px; min-height: 44px; padding: 0 14px;
  border-radius: var(--radius-sm); cursor: pointer; font-size: .85rem; font-weight: 600;
  border: 1px solid var(--line-soft); background: var(--bg-surface); color: var(--text-primary);
  transition: border-color var(--trans-fast), color var(--trans-fast), background var(--trans-fast);
}
.req-mr-btn svg { width: 15px; height: 15px; }
.req-mr-btn:hover { border-color: var(--brand-500); color: var(--brand-500); }
.req-mr-btn:disabled { opacity: .6; cursor: not-allowed; }
.req-mr-btn.is-danger { color: var(--danger-600, var(--danger-500)); border-color: color-mix(in srgb, var(--danger-500) 28%, var(--line-soft)); }
.req-mr-btn.is-danger:hover { background: color-mix(in srgb, var(--danger-500) 8%, transparent); color: var(--danger-600, var(--danger-500)); border-color: var(--danger-500); }

.req-mr-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums; letter-spacing: .01em;
}


/* GRADE DE COLUNAS (>= 940px de painel).
   O que o print de 27/08 mostrou: com o nome do colaborador na linha, numero, data e
   produto comecavam num x diferente por linha, porque .req-mr-main e flex de fluxo livre.
   Alinhar exige UM template compartilhado por cabeçalho e linhas, e e o que a custom
   property abaixo faz. Cada linha e a sua propria grade e nao ha subgrid: como todas tem
   a mesma largura, o mesmo template resolve identico nas duas, sem depender de um suporte
   de navegador mais novo.

   940px e medido, nao redondo: e onde a coluna de produto ainda recebe ~150px depois das
   fixas e das duas acoes. Abaixo disso vale o cartao empilhado, que ja existia. */
#reqMinhas {
  --req-mr-cols: 194px 106px 122px 46px minmax(0, 1fr) 94px;
}
/* Escopo largo ganha a coluna do colaborador. O produto cede parte do espaco (de 1fr para
   1.5fr contra 1fr do nome) porque nome de pessoa tem teto conhecido e descricao de
   produto nao: dar a folga ao produto empurraria o nome para elipse, e o nome e o que a
   pessoa procura nesta visao. */
#reqMinhas.is-todas {
  --req-mr-cols: 194px minmax(0, 1fr) 106px 122px 46px minmax(0, 1.5fr) 94px;
}

/* A coluna TAM viveu algumas horas de 27/08. Ele olhou a lista e mandou tira-la, e a razao e
   boa: com o tamanho de volta dentro da descricao do produto (ver `mrResumo` no JS) a coluna
   repetia, em 46px, um dado que a celula elastica ao lado ja dizia por inteiro. O `title` com
   a lista de tamanhos do pedido saiu junto; quem precisa dos N tamanhos abre a gaveta, que os
   mostra item por item. */

.req-mr-head { display: none; }

@container (min-width: 940px) {
  .req-mr-head {
    display: grid; grid-template-columns: var(--req-mr-cols);
    align-items: center; gap: var(--space-3);
    padding: 0 var(--space-3) 6px;
    font-size: .66rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--text-secondary); opacity: .78;
  }
  /* Bordas TRANSPARENTES com a largura exata das da linha. Sem elas o cabecalho comeca 3px
     a esquerda das celulas e a coluna elastica sai 4px mais larga, porque a linha carrega a
     faixa de situacao de 3px na esquerda e 1px na direita e o cabecalho nao. Medido: rotulo
     em 288 contra celula em 291, no mesmo template. E a grade existe justamente para o
     rotulo cair sobre a coluna. */
  .req-mr-head { border-left: 3px solid transparent; border-right: 1px solid transparent; }
  .req-mr-head-n { text-align: right; }

  .req-mr-main {
    display: grid; grid-template-columns: var(--req-mr-cols);
    align-items: center; flex-wrap: nowrap;
  }
  /* Todas as celulas precisam poder encolher: sem min-width:0 uma delas estoura a coluna e
     a grade inteira volta a desalinhar, que e o defeito original com outro nome. */
  .req-mr-main > * { min-width: 0; }
  .req-mr-status { flex: none; min-width: 0; }
  .req-mr-num { font-variant-numeric: tabular-nums; }
  .req-mr-data { font-variant-numeric: tabular-nums; font-size: .78rem; }
  /* Na grade a pastilha vira so o digito alinhado a direita: o cabecalho ja diz "Itens", e
     fundo arredondado numa coluna de 46px le como ruido, nao como dado. */
  .req-mr-pill {
    justify-content: flex-end; background: none; padding: 0;
    font-variant-numeric: tabular-nums; font-size: .85rem; color: var(--text-primary);
  }
  .req-mr-pill-un { display: none; }
  /* O botao deixa de ser o bloco elastico do meio e passa a ser a celula PRODUTO. */
  .req-mr-toggle { flex: none; min-width: 0; padding: 4px 0; }
  .req-mr-actions { margin-left: 0; flex-wrap: nowrap; justify-content: flex-end; gap: 6px; }
  /* 94px = dois alvos de 44 mais o gap de 6. O alvo continua com 44px de lado, que e o
     minimo de toque: o que sai e o texto, nao a area clicavel. */
  .req-mr-actions .req-mr-btn { padding: 0; width: 44px; justify-content: center; gap: 0; }
  .req-mr-actions .req-mr-btn span { display: none; }
}

@container (max-width: 640px) {
  /* Painel estreito: o selo de situação divide a linha com o número em vez de ocupar uma
     faixa inteira: 3 blocos empilhados davam 172px por requisição contra 66px no
     desktop. A data sai daqui e continua na gaveta, então nada de informação se perde:
     o rótulo textual da situação permanece. */
  .req-mr-status { min-width: 0; flex: 0 0 auto; }
  .req-mr-status b { font-size: .72rem; }
  .req-mr-toggle { flex: 1 1 140px; min-width: 120px; }
  .req-mr-actions { margin-left: 0; width: 100%; }
  .req-mr-actions .req-mr-btn { flex: 1 1 auto; justify-content: center; }
}
/* "Pedir novamente": ação primária (padrão-ouro de reorder B2B) */
.req-reorder {
  display: inline-flex; align-items: center; gap: 7px; min-height: 38px; padding: 0 16px;
  border: 1.5px solid var(--brand-500); border-radius: var(--radius-sm);
  background: var(--brand-500); color: #fff; font-size: .84rem; font-weight: 600; cursor: pointer;
  white-space: nowrap;
  transition: background var(--trans-fast), border-color var(--trans-fast);
}
.req-reorder:hover { background: color-mix(in srgb, var(--brand-500) 88%, #000); border-color: color-mix(in srgb, var(--brand-500) 88%, #000); }
.req-reorder svg { width: 15px; height: 15px; }

/* ── sucesso ── */
.req-success { text-align: center; padding: var(--space-6) var(--space-5); display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
.req-success-header { display: flex; align-items: center; gap: var(--space-2); }
.req-success-icon { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; color: var(--success-500); background: color-mix(in srgb, var(--success-500) 14%, var(--bg-surface)); flex-shrink: 0; }
.req-success-icon svg { width: 14px; height: 14px; }
.req-success-lead { font-size: .9rem; color: var(--text-secondary); font-weight: 600; }
.req-ticket { position: relative; background: var(--brand-500); border-radius: 14px; padding: var(--space-5) 1.75rem; display: flex; flex-direction: column; align-items: center; gap: 2px; width: 100%; max-width: 340px; box-shadow: 0 6px 28px color-mix(in srgb, var(--brand-500) 35%, transparent); animation: req-ticket-pop .35s cubic-bezier(.34,1.56,.64,1) both; }
.req-ticket-label { font-size: .65rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.55); }
.req-num-row { display: flex; align-items: center; justify-content: center; width: 100%; min-width: 0; }
/* font-size é ajustado por JS (fitTicketNum) p/ caber sem cortar — o valor abaixo é só o teto.
   width:100% (não max-width) faz o elemento ter a largura FIXA do ticket, então
   scrollWidth>clientWidth detecta corretamente o overflow do número. */
.req-success-num { width: 100%; display: block; text-align: center; font-size: 4.8rem; font-weight: 900; color: #fff; line-height: 1.05; font-variant-numeric: tabular-nums; letter-spacing: -.02em; white-space: nowrap; overflow: hidden; }
.req-copy-num { position: absolute; top: 12px; right: 12px; background: rgba(255,255,255,.12); border: none; border-radius: 8px; width: 32px; height: 32px; display: grid; place-items: center; cursor: pointer; color: rgba(255,255,255,.65); transition: background .15s, color .15s; flex-shrink: 0; padding: 0; }
.req-copy-num:hover, .req-copy-num.copied { background: rgba(255,255,255,.22); color: #fff; }
.req-copy-num svg { width: 16px; height: 16px; }
.req-success-note { font-size: .88rem; color: var(--text-secondary); max-width: 36ch; margin: 0; line-height: 1.55; }
.req-success-note b { color: var(--text-primary); }
.req-success-actions { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-2); width: 100%; max-width: 320px; }
.req-success-actions > button { width: 100%; }
/* feedback do "Copiar número": vira verde por ~1,6s */
#reqCopyBtn.is-copied { background: var(--success-500); border-color: var(--success-500); color: #fff; }
.req-success-sec { display: flex; gap: var(--space-2); flex-wrap: wrap; justify-content: center; }
.req-success-sec button { flex: 1; min-width: 100px; font-size: .84rem; }
@keyframes req-ticket-pop { from { transform: scale(.82) translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }
.req-slip { text-align: left; max-width: 420px; margin: var(--space-5) auto 0; border: 1px dashed var(--line-strong); border-radius: var(--radius-md); padding: var(--space-4); background: var(--bg-surface); }
.req-slip h4 { margin: 0 0 10px; font-size: .74rem; letter-spacing: .06em; text-transform: uppercase; color: var(--text-secondary); }
.req-slip-row { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-3); font-size: .86rem; padding: 5px 0; border-bottom: 1px solid var(--line-soft); }
.req-slip-row span:first-child { color: var(--text-secondary); }
.req-slip-item-name { display: block; }
/* O código é o dado que a Segurança do Trabalho digita ao lançar a distribuição de
   EPI — precisa ser inequívoco no papel: monoespaçado e com tabular-nums. */
.req-slip-item-code { display: block; margin-top: 1px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .82rem; font-variant-numeric: tabular-nums; letter-spacing: .02em; color: var(--text-primary); }
.req-slip-item-qty { white-space: nowrap; }
.req-slip-sign { margin-top: var(--space-5); border-top: 1px solid var(--text-primary); padding-top: 6px; font-size: .76rem; color: var(--text-secondary); text-align: center; }

.req-pane[hidden] { display: none; }

/* ── badges de status (usados no catálogo/carrinho) ── */
.req-badge.is-delivered { color: var(--success-500); background: color-mix(in srgb, var(--success-500) 12%, var(--bg-surface)); }
.req-badge.is-wait { color: var(--warning-600, #b45309); background: color-mix(in srgb, var(--warning-500) 14%, var(--bg-surface)); }

/* ── Visão do Almoxarifado ────────────────────────────────────────────────────
   Balcão: FILA (FIFO, esquerda) + FICHA de separação (direita). Densidade alta de
   propósito — o almoxarife precisa de várias requisições e da ficha inteira na
   mesma tela, não de cartões arejados.

   As quebras são @container e não @media: o portal pode dar ~470px de largura à aba
   num monitor de 1440px, então a viewport não diz nada sobre o espaço real. */

.req-pane[data-pane="almoxarifado"] { container-type: inline-size; }
.req-alm { display: flex; flex-direction: column; gap: var(--space-4); }

.req-alm-toolbar {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
}
.req-alm-search { flex: 1 1 260px; min-width: 0; }
/* Idade do saldo. Não é enfeite: diz ao almoxarife quão velha é a leitura que ele
   está usando para decidir se separa. */
.req-alm-fresh {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border: 1px solid var(--line-soft); border-radius: 999px;
  background: var(--bg-muted); font-size: .76rem; font-weight: 600;
  color: var(--text-secondary); white-space: nowrap;
}
.req-alm-fresh svg { width: 15px; height: 15px; }
.req-alm-gerenciar { flex: none; display: inline-flex; align-items: center; gap: 6px; }
.req-alm-gerenciar[hidden] { display: none; }
.req-alm-gerenciar svg { width: 16px; height: 16px; }

/* Selo "Operando": quem esta atendendo o balcao agora. So existe na CONTA DE ESTACAO (o
   login compartilhado do tablet), porque em conta pessoal a conta ja e a pessoa.

   Fica na barra, e nao dentro do dialogo de cada baixa, para o nome errado ser visto ANTES
   de o material sair. Por isso ele e mais forte que o selo de frescor ao lado: cor de marca
   quando ha alguem, cor de atencao quando falta escolher. */
.req-alm-operador {
  flex: none; display: inline-flex; align-items: center; gap: 8px;
  padding: 6px 14px 6px 12px; border-radius: 999px; cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--brand-500) 38%, var(--line-soft));
  background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface));
  color: var(--text-primary); text-align: left; white-space: nowrap;
}
.req-alm-operador[hidden] { display: none; }
.req-alm-operador svg { flex: none; width: 17px; height: 17px; color: var(--brand-600, var(--brand-500)); }
.req-alm-operador span { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.req-alm-operador small { font-size: .64rem; letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.req-alm-operador b { font-size: .82rem; font-weight: 700; }
/* Sem ninguem escolhido a estacao NAO consegue dar baixa, entao o selo tem que parecer
   pendencia e nao rotulo. */
.req-alm-operador.is-vazio {
  border-color: color-mix(in srgb, var(--warning-500, #b45309) 45%, var(--line-soft));
  background: color-mix(in srgb, var(--warning-500, #b45309) 10%, var(--bg-surface));
}
.req-alm-operador.is-vazio svg { color: var(--warning-600, #b45309); }

.req-alm-body { display: flex; flex-direction: column; }
.req-alm-grid {
  /* 34% em vez de teto de 390px: num painel de 920px (tablet de 1024) a fila fica
     com ~312px e a ficha com ~576px, em vez de 390 + 514. A fila nao precisa
     crescer junto com a tela; a ficha precisa. */
  display: grid; grid-template-columns: minmax(300px, 34%) minmax(0, 1fr);
  gap: var(--space-4); align-items: start;
}

/* Cores de escalada da espera. Escurecidas em relação ao token porque aparecem em
   texto pequeno e precisam passar AA — o mesmo tratamento dos selos. */
.is-warn { color: color-mix(in srgb, var(--warning-500) 78%, #000); }
.is-late { color: var(--danger-500); }

/* ── Fila (coluna esquerda) ── */

.req-alm-queue {
  background: var(--bg-surface); border: 1px solid var(--line-soft);
  border-radius: var(--radius-md); box-shadow: var(--shadow-1); overflow: hidden;
}
.req-alm-qhead {
  padding: var(--space-3); border-bottom: 1px solid var(--line-soft); background: var(--bg-muted);
}
.req-alm-counts { display: flex; gap: var(--space-2); flex-wrap: wrap; }
/* Os contadores são o filtro. Uma coisa só: informa quantas e leva até elas. */
.req-alm-count {
  flex: 1 1 92px; min-height: 52px; padding: 6px 12px; margin: 0;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: 2px; line-height: 1.1; text-align: left;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-secondary);
  font: inherit; cursor: pointer;
  transition: background var(--trans-fast), border-color var(--trans-fast), color var(--trans-fast);
}
.req-alm-count b {
  font-family: var(--font-mono); font-size: 1.15rem; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.req-alm-count span { font-size: .64rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.req-alm-count.is-on {
  background: var(--brand-500); border-color: var(--brand-500); color: #fff;
}
.req-alm-count.is-on b { color: #fff; }
.req-alm-qnote { margin: 10px 2px 0; font-size: .78rem; color: var(--text-secondary); }
.req-alm-qnote b { font-weight: 700; }
.req-alm-qempty { margin: 0; padding: 28px 14px; text-align: center; font-size: .84rem; color: var(--text-secondary); }

/* Aviso de chegada na fila.

   Ele e injetado com `prepend` no `.req-alm-queue`, ou seja nasce ACIMA da faixa de
   contadores e encostado na borda de cima do cartao, que tem `overflow: hidden`. Por
   isso ele e uma faixa de sangria total SEM raio proprio: o cartao recorta os cantos,
   e um raio aqui deixaria um degrau visivel.

   Ele nao tinha CSS nenhum. As quatro classes eram referenciadas pelo JS e nenhuma
   estava definida em folha alguma, o que produzia exatamente o que aparecia na tela:
   o ponto era um span sem tamanho (invisivel), a faixa era um div pelado sem fundo
   nem espacamento, e o botao caia no azul-escuro padrao do portal, porque botao sem
   classe de variante nasce assim.

   Tom: chegada, nao alerta. Nada esta errado quando uma requisicao entra na fila,
   entao a cor e a da marca e nao a de atencao, que nesta mesma tela ja significa
   falta de saldo. Reusar o amarelo aqui diluiria aquele sinal. */
.req-novidade-banner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-2);
  padding: 6px var(--space-3);
  background: color-mix(in srgb, var(--brand-500) 15%, var(--bg-surface));
  border-bottom: 1px solid color-mix(in srgb, var(--brand-500) 24%, transparent);
}
.req-novidade-txt {
  font-size: .82rem; font-weight: 600; line-height: 1.3; color: var(--text-primary);
}
.req-novidade-txt b {
  font-family: var(--font-mono); font-weight: 600; font-variant-numeric: tabular-nums;
}

/* O ponto carrega o acento, no lugar da barra lateral que a linha da fila usa. A
   barra nao serviria aqui: a faixa e de sangria total e as linhas ficam recuadas 8px
   pelo padding da `.req-alm-qlist`, entao uma barra nesta faixa NAO alinharia com as
   de baixo, e desalinhamento de 8px le como defeito. */
.req-novidade-dot {
  position: relative; width: 9px; height: 9px; border-radius: 50%;
  background: var(--brand-500);
}
/* Um anel so, uma vez. Pulso que repete em tela de operacao vira cutucao: o
   almoxarife ficaria com uma coisa piscando no canto o turno inteiro. Uma vez e
   chegada; infinitas vezes e cobranca. */
.req-novidade-dot::after {
  content: ''; position: absolute; inset: -3px; border-radius: 50%;
  border: 2px solid var(--brand-500);
  animation: reqNovidadeAnel 900ms cubic-bezier(0.2, 0, 0, 1) 1 both;
}
@keyframes reqNovidadeAnel {
  from { transform: scale(.55); opacity: .85; }
  to   { transform: scale(2.4); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .req-novidade-dot::after { animation: none; opacity: 0; }
}

.req-novidade-ver {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: .78rem; font-weight: 700; letter-spacing: .02em;
  color: var(--brand-500);
  padding: 6px 10px; border-radius: var(--radius-sm);
  transition: background var(--trans-fast), color var(--trans-fast);
}
/* Camada de estado sobre a PROPRIA cor, nunca slate fixo. Regra global do portal:
   claro continua claro, preenchido aprofunda a propria cor. */
.req-novidade-ver:hover {
  background: color-mix(in srgb, var(--brand-500) 12%, transparent);
  color: color-mix(in srgb, var(--brand-500) 82%, #000);
}
.req-novidade-ver:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }

/* O balcao e touch, e 44px e o piso do alvo de dedo. O padding da faixa cede para o
   botao crescer sem engordar a faixa inteira. */
@media (pointer: coarse) {
  .req-novidade-ver { padding-inline: var(--space-3); }
}

.req-alm-qlist {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-2); max-height: 68vh; overflow-y: auto;
}

/* A linha é um <button> de verdade: teclado, foco e hit-testing de graça. Sem
   overlay absoluto e sem div+tabindex — foi exatamente o que travou o clique na
   lista de "Minhas requisições". Nada interativo mora dentro dela. */
/* O <button> é só a casca: `display:block` e ZERO padding. O grid mora no
   `.req-alm-row-inner`.

   Medido, não estimado: `<button>` como container de grid NÃO se dimensiona pelo
   próprio conteúdo no Chromium — com `min-height:0` a linha colapsa para 22px,
   enquanto o mesmo markup num <div> mede 90,4px. O `min-height` era, portanto, a
   ÚNICA fonte de altura, e ficava 12px abaixo do necessário: o `overflow:hidden`
   (que existe para a barra de acento respeitar o raio) cortava a última linha.
   Com o grid num elemento comum, a altura volta a seguir o conteúdo. */
.req-alm-row {
  /* `flex: none` NÃO é enfeite. A `.req-alm-qlist` é flex column com `max-height: 68vh`
     e rolagem; com 20 requisições o conteúdo estoura e o `flex-shrink: 1` padrão
     COMPRIME cada linha. Normalmente o `min-height: auto` do item flex barraria isso,
     mas o tamanho mínimo automático de um <button> resolve para ~0 (mesma limitação que
     obrigou o wrapper interno), então nada segura. Medido numa janela de 868px com o
     painel largo: 44px de altura para 96px de conteúdo — idade e solicitante decepados.
     Só aparece quando a lista rola, e é por isso que passou por dois testes meus:
     com poucas linhas, ou com painel estreito (onde `max-height` vira `none`), não ocorre. */
  flex: none;
  display: block; padding: 0; margin: 0;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: inherit; font: inherit; text-align: left;
  cursor: pointer; overflow: hidden;
  transition: border-color var(--trans-fast), background var(--trans-fast);
}
/* `align-items: stretch` + padding vertical NAS CÉLULAS (não no grid): é o que deixa
   a barra de acento correr de borda a borda enquanto o texto respira. */
.req-alm-row-inner {
  display: grid; grid-template-columns: 6px 58px var(--alm-fila-thumb, ) minmax(0, 1fr);
  align-items: stretch; gap: 0 var(--space-3);
  min-height: 88px; padding-right: 14px;
}
.req-alm-qlist.has-foto .req-alm-row-inner { --alm-fila-thumb: 48px; }
/* A miniatura fica centrada na vertical porque a linha tem 88px de altura minima e o
   conteudo pode ser mais curto que isso. `align-self` e nao `align-items` no grid: as
   outras celulas continuam esticando, e e o esticar que deixa a barra de acento correr de
   borda a borda. */
.req-alm-qlist.has-foto .req-alm-thumb { align-self: center; }
/* E a miniatura da FILA sai quando a coluna nao tem folga para ela. Medido: a coluna da
   fila e 34% do painel, entao num tablet de 1024 ela tem 308px e a coluna de texto cai
   para 125px, onde TRES dos sete nomes viram reticencia. Nome em reticencia e o pior troco
   possivel aqui, porque o nome e o que a pessoa DIZ no balcao, e a foto e atalho para uma
   ficha que esta a um toque com a mesma imagem em 64px.
   Mesma decisao da tira da Seguranca (que sai abaixo de 620px de coluna), com o limiar
   medido para esta linha: 1180px de PAINEL dao ~400px de coluna, que e onde o texto ainda
   respira. Consulta anonima porque o painel ja e o contexto no almoxarifado
   (`container-type` em .req-pane[data-pane="almoxarifado"]).
   `initial` e nao valor vazio: ele torna a variavel invalida de proposito, e e isso que faz
   o `var()` cair na reserva vazia e a coluna desaparecer de verdade. */
@container (max-width: 1180px) {
  .req-alm-qlist.has-foto .req-alm-row-inner { --alm-fila-thumb: initial; }
  .req-alm-qlist.has-foto .req-alm-thumb { display: none; }
}
.req-alm-row:hover { border-color: var(--brand-500); }
.req-alm-row.is-active {
  background: var(--bg-muted); border-color: var(--brand-500);
  box-shadow: inset 0 0 0 1px var(--brand-500);
}
/* Barra de acento = estado. NUNCA é a única pista: o selo ao lado tem texto e ícone. */
.req-alm-row-bar { align-self: stretch; background: var(--line-soft); }
.req-alm-row.is-ready .req-alm-row-bar { background: var(--success-500); }
.req-alm-row.is-short .req-alm-row-bar {
  background: repeating-linear-gradient(135deg,
    var(--warning-500) 0 5px, color-mix(in srgb, var(--warning-500) 30%, transparent) 5px 10px);
}
.req-alm-row.is-missing .req-alm-row-bar { background: var(--danger-500); }
/* Saldo não lido: barra neutra listrada — "não sei", que não é nem verde nem âmbar. */
.req-alm-row.is-unknown .req-alm-row-bar {
  background: repeating-linear-gradient(135deg,
    var(--text-secondary) 0 4px, transparent 4px 8px);
}
/* Aguardando a Segurança: barra da cor da marca, não âmbar/vermelho. Não é problema —
   é uma etapa do fluxo que ainda não aconteceu. */
.req-alm-row.is-awaiting-sst .req-alm-row-bar { background: var(--brand-500); }
.req-alm-seal.is-awaiting-sst {
  color: var(--brand-600, var(--brand-500));
  background: color-mix(in srgb, var(--brand-500) 12%, var(--bg-surface));
}
.req-alm-band.is-awaiting-sst {
  color: var(--brand-600, var(--brand-500));
  border-color: color-mix(in srgb, var(--brand-500) 32%, transparent);
  border-left-color: var(--brand-500);
  background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface));
}
/* Selo na célula de contexto: liberado (com visto) x pendente. */
.req-alm-ctx-cell b.is-ok {
  display: inline-flex; align-items: center; gap: 5px;
  color: color-mix(in srgb, var(--success-500) 72%, #000);
}
.req-alm-ctx-cell b.is-ok svg { width: 15px; height: 15px; flex: none; }
.req-alm-ctx-cell b.is-pend { color: var(--brand-600, var(--brand-500)); }

/* A barra da cancelada ganhou COR em 04/09, e saiu do apagamento. Sem isto, tirar o
   `opacity: .8` da linha (logo abaixo) deixaria a cancelada indistinguível de uma pendente
   fora do texto do selo: seria trocar um sinal errado por sinal nenhum. `--danger-500` é a
   mesma cor que `.req-mr-row.is-canceled` e `.req-alm-h-row.is-canceled` usam, então as
   três telas passam a dizer a mesma coisa do mesmo jeito. `is-done` continua apagada. */
.req-alm-row.is-canceled .req-alm-row-bar { background: var(--danger-500); }
.req-alm-row.is-done .req-alm-row-bar { opacity: .5; }
/* `is-canceled` SAIU deste apagamento em 04/09. Ele era herança de tratar cancelada como
   "resolvida, pode ignorar", e apagar a linha é o oposto do que se pede dela: o documento
   morto tem de ser mais visível, não menos. `is-done` fica, porque ali apagar está certo
   (requisição entregue e baixada é assunto encerrado com final feliz). */
.req-alm-row.is-done { opacity: .8; }

.req-alm-row-age {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 12px 0; line-height: 1;
}
.req-alm-row-age b {
  font-family: var(--font-mono); font-size: 1.3rem; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.req-alm-row-age.is-warn b { color: color-mix(in srgb, var(--warning-500) 78%, #000); }
.req-alm-row-age.is-late b { color: var(--danger-500); }
.req-alm-row-age small {
  margin-top: 3px; font-size: .6rem; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-secondary);
}

.req-alm-row-main {
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  padding: 12px 0; min-width: 0;
}
.req-alm-row-top { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.req-alm-row-num {
  font-family: var(--font-mono); font-size: 1rem; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.req-alm-row-who {
  font-size: .84rem; font-weight: 600; color: var(--text-primary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.req-alm-row-meta {
  font-size: .76rem; color: var(--text-secondary);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Selo de situação: texto + ícone sempre juntos (cor nunca carrega sozinha o dado).
   Cores escurecidas em relação ao token porque é texto pequeno em negrito sobre
   fundo tintado — sem isso o contraste fica em ~4.2:1, abaixo do AA. */
.req-alm-seal {
  display: inline-flex; align-items: center; gap: 5px; padding: 2px 9px;
  border-radius: 999px; font-size: .66rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
}
.req-alm-seal svg { width: 12px; height: 12px; }
/* `cursor: help` porque o selo passou a ter `title` explicando o estado. Serve ao
   laptop da Seguranca e ao PC do balcao; no tablet, onde hover nao existe, quem informa
   e o icone proprio de cada estado mais as duas palavras de texto. */
.req-alm-seal[title], .req-alm-ctx-cell b[title] { cursor: help; }
.req-alm-seal.is-ready { color: color-mix(in srgb, var(--success-500) 72%, #000); background: color-mix(in srgb, var(--success-500) 12%, var(--bg-surface)); }
.req-alm-seal.is-short { color: color-mix(in srgb, var(--warning-500) 78%, #000); background: color-mix(in srgb, var(--warning-500) 15%, var(--bg-surface)); }
.req-alm-seal.is-missing { color: var(--danger-500); background: color-mix(in srgb, var(--danger-500) 10%, var(--bg-surface)); }
.req-alm-seal.is-done { color: color-mix(in srgb, var(--success-500) 72%, #000); background: color-mix(in srgb, var(--success-500) 10%, var(--bg-surface)); }
.req-alm-seal.is-canceled { color: var(--text-secondary); background: var(--bg-muted); }
.req-alm-seal.is-unknown { color: var(--text-secondary); background: var(--bg-muted); }
/* Selo do eixo de INTEGRAÇÃO na linha da fila: só aparece na falha (para não competir com o
   selo de estado). Vermelho, como o is-missing, mas nomeando o Senior. */
.req-alm-seal.is-int-fail { color: var(--danger-500); background: color-mix(in srgb, var(--danger-500) 12%, var(--bg-surface)); }
/* Documento ENCERRADO, e ele deixou de dividir o cinza com `is-int-off`. As duas eram muito
   diferentes com a mesma cor: `off` é uma requisição ENTREGUE num ambiente sem integração,
   `encerrada` é um documento que ninguém vai atender. Família de danger, distinta do
   `is-int-fail` pela intensidade do fundo, pelo ícone (`ban` contra `alert`) e pelo texto:
   decisão e falha continuam separadas, só não mais por cor contra ausência de cor. */
.req-alm-seal.is-int-encerrada {
  color: color-mix(in srgb, var(--danger-500) 72%, var(--text-primary));
  background: color-mix(in srgb, var(--danger-500) 7%, var(--bg-surface));
}

/* ── Eixo de integração Senior (célula de contexto + faixa de falha) ─────────────
   Teal para "integrada", separando visualmente do eixo de decisão (verde/âmbar/vermelho do
   estado de separação). Sem token de teal no tema; usamos literais com color-mix sobre a
   surface, então o fundo acompanha claro/escuro e o texto mistura para manter contraste. */
.req-alm-ctx-cell b[class*="is-int-"] { display: inline-flex; align-items: center; gap: 6px; }
.req-alm-ctx-cell b[class*="is-int-"] svg { width: 15px; height: 15px; flex: none; }
.req-alm-ctx-cell b.is-int-ok { color: color-mix(in srgb, #0f766e 78%, var(--text-primary)); }
.req-alm-ctx-cell b.is-int-fail { color: var(--danger-500); }
.req-alm-ctx-cell b.is-int-pending { color: var(--brand-600, var(--brand-500)); }
.req-alm-ctx-cell b.is-int-encerrada { color: color-mix(in srgb, var(--danger-500) 72%, var(--text-primary)); }
.req-alm-ctx-cell b.is-int-off,
.req-alm-ctx-cell b.is-int-wait { color: var(--text-secondary); }

/* Faixa de falha do Senior na ficha: nomeia a recusa, mostra a mensagem do ERP e oferece o
   reenviar ali mesmo, a falha deixa de ser um toast que some e vira ação. */
.req-alm-intfail {
  display: flex; align-items: center; gap: 12px; margin-top: 12px;
  padding: 12px 14px; border-radius: var(--radius-md);
  color: var(--danger-500);
  background: color-mix(in srgb, var(--danger-500) 8%, var(--bg-surface));
  border: 1px solid color-mix(in srgb, var(--danger-500) 28%, var(--bg-surface));
}
.req-alm-intfail > svg { width: 22px; height: 22px; flex: none; }
.req-alm-intfail-txt { min-width: 0; flex: 1; }
.req-alm-intfail-txt strong { display: block; font-family: var(--font-display); font-size: .95rem; font-weight: 700; }
.req-alm-intfail-txt small { display: block; margin-top: 2px; font-size: .8rem; color: var(--text-primary); text-wrap: pretty; }
.req-alm-reenviar {
  flex: none; display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 14px; border-radius: var(--radius-sm, 8px); cursor: pointer;
  font-family: var(--font-display); font-weight: 700; font-size: .82rem;
  color: #fff; background: var(--danger-500); border: 1px solid var(--danger-500);
}
.req-alm-reenviar svg { width: 15px; height: 15px; }
.req-alm-reenviar:hover { background: color-mix(in srgb, var(--danger-500) 88%, #000); }

/* ── Abas Fila / Histórico da estação ────────────────────────────────────────
   Duas superfícies com propósitos opostos vivem no mesmo painel: a Fila é operação
   (FIFO, mínimo garfo) e o Histórico é consulta (filtro denso). A troca é uma aba
   sublinhada, no idioma do resto do portal, não um segmented control, que puxaria a
   atenção do balcão. */
.req-alm-tabs {
  display: flex; gap: var(--space-4); align-items: flex-end;
  border-bottom: 1.5px solid var(--line-soft);
}
/* A faixa da aba ativa fica 4px ACIMA da regua da fita, e nao sobre ela.
   O `margin-bottom: -1.5px` que estava aqui fazia a faixa cobrir a regua, que e o
   padrao do portal (`.dslg-subtab` em views.css encosta o indicador do mesmo jeito).
   O Henrique olhou esta tela e pediu o respiro: com a faixa colada, o sublinhado da
   aba e o traco que atravessa o painel lem como um traco so de espessura irregular,
   e nao como indicador mais divisoria.

   4px e nao menos porque a faixa tem 3px: gap menor que a propria espessura le como
   erro de alinhamento, nao como intervalo. Os inativos tem `border-bottom` transparente
   de 3px, entao a linha de base dos rotulos nao se mexe. */
/* `border-radius: 0` NAO e detalhe: sem ele o indicador da aba ativa nao e um sublinhado, e
   um COLCHETE. O reset global do portal (`button, .btn { border-radius: var(--radius-sm) }`,
   components.css) da 12px a todo <button>, e esta regra reseta `border`, `background` e
   `appearance` mas nunca resetou o raio — entao a faixa de 3px seguia a curva nas duas pontas
   e subia formando um "U" de 12px de altura debaixo do rotulo. Media 55px de largura em "Fila"
   com 12px de raio de cada lado: quase metade do traco era curva.

   Estava assim nas duas estacoes (Almoxarifado e Seguranca), no desktop e no celular. */
.req-alm-tab {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 2px; margin-bottom: 4px; border-radius: 0;
  font-family: var(--font-display); font-weight: 700; font-size: .92rem;
  color: var(--text-secondary); border-bottom: 3px solid transparent;
}
.req-alm-tab svg { width: 18px; height: 18px; }
.req-alm-tab[hidden] { display: none; }
.req-alm-tab:hover { color: var(--text-primary); }
.req-alm-tab.is-on { color: var(--brand-700, var(--brand-600, var(--brand-500))); border-bottom-color: var(--brand-500); }
.req-alm-toolbar[hidden] { display: none; }
/* Respiro entre as abas Fila/Histórico e o conteúdo abaixo. Na Segurança o container
   (.req-seg) não é flex com gap como o .req-alm, então a faixa sublinhada da aba ativa
   encostava na busca; devolvemos o mesmo espaço que o Almoxarifado já ganha pelo gap. */
.req-seg > .req-alm-tabs { margin-bottom: var(--space-4); }

/* Selo de integração como PILL (histórico): mesma leitura da célula de contexto, mas
   com fundo, porque na tabela ele carrega a coluna. is-int-fail já existe acima. */
.req-alm-seal.is-int-ok { color: color-mix(in srgb, #0f766e 74%, #000); background: color-mix(in srgb, #0f766e 12%, var(--bg-surface)); }
.req-alm-seal.is-int-pending { color: var(--brand-600, var(--brand-500)); background: color-mix(in srgb, var(--brand-500) 10%, var(--bg-surface)); }
.req-alm-seal.is-int-off,
.req-alm-seal.is-int-wait { color: var(--text-secondary); background: var(--bg-muted); }

/* ── Histórico das baixadas ── */
.req-alm-hist { display: flex; flex-direction: column; gap: var(--space-3); }
.req-alm-hist-bar { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
/* Exportar fica na PONTA da barra, depois dos filtros: a ordem conta a operacao, primeiro
   recorta, depois leva. `margin-left: auto` empurra sozinho quando sobra espaco e some
   quando a barra quebra linha, sem breakpoint proprio. */
.req-alm-hist-export { margin-left: auto; flex: none; display: inline-flex; align-items: center; gap: 7px; }
.req-alm-hist-export svg { width: 16px; height: 16px; }
.req-alm-hist-export:disabled { opacity: .6; cursor: progress; }

/* Segunda linha da barra: recorte EXPLICITO (datas e centro de custo). Fica separada da
   primeira de proposito. A primeira e varredura rapida (chip de periodo, busca, filtro de
   integracao), a segunda e recorte de relatorio, que a pessoa monta uma vez e leva. */
.req-alm-hist-bar2 { margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px dashed var(--line-soft); }
.req-alm-hist-data { display: inline-flex; align-items: center; gap: 7px; font-size: .78rem; color: var(--text-secondary); }
.req-alm-hist-data span { font-weight: 700; letter-spacing: .04em; text-transform: uppercase; font-size: .66rem; }
.req-alm-hist-data input {
  min-height: 38px; padding: 0 10px; border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm); background: var(--bg-surface); color: var(--text-primary);
  font: inherit; font-size: .84rem; font-variant-numeric: tabular-nums;
}
.req-alm-hist-cc { flex: 0 1 240px; min-width: 180px; }
.req-alm-hist-limpar {
  display: inline-flex; align-items: center; gap: 6px; min-height: 38px; padding: 0 12px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-muted); color: var(--text-secondary);
  font: inherit; font-size: .8rem; font-weight: 600; cursor: pointer;
}
.req-alm-hist-limpar svg { width: 13px; height: 13px; }

/* Chip de periodo apagado quando existe data explicita: os dois acesos ao mesmo tempo
   diriam que os dois valem, e so a data vale (ver histFiltrosServidor). Nao e `disabled`
   porque clicar num chip DEVE voltar ao modo de periodo, limpando as datas. */
.req-alm-seg.is-desligado { opacity: .5; }

/* Altura MINIMA no carregando: sem ela a area de resultados colapsa e a barra de filtros
   salta para cima a cada recarga, que e justamente o pulo que este estado existe para
   evitar. 220px e a altura de umas tres linhas da tabela. */
.req-alm-h-carregando { min-height: 220px; }
.req-alm-hist-search { flex: 1 1 260px; min-width: 0; }
.req-alm-seg {
  display: inline-flex; padding: 3px; gap: 2px; flex: none;
  background: var(--bg-muted); border: 1px solid var(--line-soft); border-radius: 999px;
}
.req-alm-seg-btn {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  padding: 7px 14px; border-radius: 999px;
  font-family: var(--font-body, inherit); font-weight: 600; font-size: .8rem;
  color: var(--text-secondary); white-space: nowrap;
}
.req-alm-seg-btn:hover { color: var(--text-primary); }
.req-alm-seg-btn.is-on {
  background: var(--bg-surface); color: var(--brand-700, var(--brand-600, var(--brand-500)));
  box-shadow: var(--shadow-1);
}
.req-alm-hist-sum { margin: 0; font-size: .8rem; font-weight: 600; color: var(--text-secondary); }
.req-alm-h-tablewrap {
  border: 1px solid var(--line-soft); border-radius: var(--radius-md);
  background: var(--bg-surface); box-shadow: var(--shadow-1); overflow: auto;
  /* A CAIXA rola, nao a pagina: e o que da ao cabecalho sticky algo para grudar e o que
     mantem o rodape de contagem sempre a vista, como no Historico de aprovacao de OC
     (views.css:16175). Sem isto a pagina cresce a cada janela da rolagem infinita e a
     sentinela fica visivel para sempre, porque a altura do documento nunca "termina". */
  max-height: min(68vh, 720px);
}
.req-alm-h-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.req-alm-h-table th {
  position: sticky; top: 0; z-index: 1; text-align: left; white-space: nowrap;
  background: var(--bg-muted); color: var(--text-secondary);
  font-size: .68rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 10px 14px; border-bottom: 1px solid var(--line-soft);
}
.req-alm-h-table td { padding: 11px 14px; border-top: 1px solid var(--line-soft); vertical-align: middle; }
.req-alm-h-table tbody tr:hover { background: var(--bg-muted); }
.req-alm-h-when b { display: block; font-weight: 600; white-space: nowrap; }
.req-alm-h-when small { color: var(--text-secondary); font-family: var(--font-mono, ui-monospace, monospace); font-size: .72rem; }
.req-alm-h-num { font-family: var(--font-mono, ui-monospace, monospace); font-weight: 600; white-space: nowrap; }
.req-alm-h-who { font-weight: 600; }
.req-alm-h-itens, .req-alm-h-cc { color: var(--text-secondary); white-space: nowrap; }
.req-alm-h-int .req-alm-seal { white-space: nowrap; }
/* Reenviar ao Senior direto da linha do histórico (só em desligada/falha). Discreto: pill
   de contorno na cor da marca, ao lado do selo, sem competir com o dado. */
.req-alm-h-reenviar {
  appearance: none; cursor: pointer; margin-left: 8px; vertical-align: middle;
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--brand-500) 42%, var(--line-soft));
  background: var(--bg-surface); color: var(--brand-700, var(--brand-600, var(--brand-500)));
  font-family: var(--font-body, inherit); font-weight: 600; font-size: .74rem; white-space: nowrap;
}
.req-alm-h-reenviar svg { width: 13px; height: 13px; }
.req-alm-h-reenviar:hover { border-color: var(--brand-500); background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface)); }
.req-alm-h-reenviar:disabled { opacity: .6; cursor: default; }
.req-alm-h-by { color: var(--text-secondary); white-space: nowrap; }
/* ── Rodape das listas que rolam (Minhas e os dois historicos) ───────────────
   Fica FORA da caixa que rola, entao esta sempre a vista: e ele que responde "quanto ja
   carregou" sem a pessoa precisar rolar ate o fim. A sentinela NAO mora aqui — ver
   .req-roll-sentinel. */
.req-roll-bar {
  display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 4px 2px; font-size: .8rem; color: var(--text-secondary);
}
.req-roll-count { font-variant-numeric: tabular-nums; }
.req-roll-end { font-size: .74rem; opacity: .7; }
.req-roll-loading { display: inline-flex; align-items: center; gap: 8px; }
/* Botao so aparece quando o automatico desliga (teto de DOM ou freio de sequencia), entao
   ele e discreto de proposito: nao e a via principal, e a saida de emergencia. */
.req-roll-more {
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary);
  padding: 5px 12px; font-size: .78rem; font-weight: 600; cursor: pointer;
}
/* Altura 1px e nao 0: elemento sem altura nunca intersecta em alguns motores, e a
   sentinela pararia de funcionar em silencio. */
.req-roll-sentinel { width: 100%; height: 1px; }
.req-alm-h-empty { flex-direction: column; gap: 6px; text-align: center; padding: 40px 20px; }
.req-alm-h-empty svg { width: 34px; height: 34px; color: var(--text-secondary); opacity: .7; }

/* Empty-state da fila: mantém as DUAS colunas (o supervisor pediu para não "sumir tudo"). */
.req-alm-grid.is-empty .req-alm-queue { display: flex; align-items: center; justify-content: center; min-height: 320px; }
.req-alm-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 32px 22px; }
.req-alm-empty svg { width: 42px; height: 42px; color: var(--success-500); opacity: .85; }
.req-alm-empty strong { font-family: var(--font-display); font-size: 1.05rem; font-weight: 800; }
.req-alm-empty span { font-size: .86rem; color: var(--text-secondary); max-width: 34ch; text-wrap: pretty; }

/* --- Historico: tabela no largo, cartao no estreito -------------------------
   A lista de cartoes nasce escondida e a tabela visivel; abaixo do limiar as duas
   trocam de lugar. Antes o estreito so escondia a coluna de centro de custo e a
   tabela seguia rolando na horizontal: sete colunas com `white-space: nowrap` nao
   caberiam de jeito nenhum, e rolagem lateral dentro de um painel que ja rola na
   vertical e o gesto mais hostil que existe num tablet de balcao.

   O limiar e 860px, o MESMO do cockpit (ver o @container mais acima). De proposito:
   o modulo passa a ter um numero unico que significa "o painel esta estreito", em
   vez de tres limiares diferentes que ninguem consegue guardar. Num tablet de 1024
   com o rail expandido (732px de painel, que e o padrao do portal) da cartao; com o
   rail recolhido (920px) da tabela, e nos dois casos ha espaco de sobra. */
.req-alm-h-cards { display: none; flex-direction: column; gap: var(--space-2); }

.req-alm-h-card {
  display: flex; flex-direction: column; gap: 7px;
  padding: var(--space-3); border: 1px solid var(--line-soft);
  border-radius: var(--radius-md); background: var(--bg-surface); box-shadow: var(--shadow-1);
}
/* Mesmo sinal do `.req-alm-h-row.is-canceled`, no layout de cartão. O cartão já tem borda
   completa, então o filete substitui a borda esquerda em vez de somar. */
.req-alm-h-card.is-canceled { border-left: 3px solid var(--danger-500); }
.req-alm-h-card.is-canceled .req-alm-h-card-num { color: color-mix(in srgb, var(--danger-500) 72%, var(--text-primary)); }
.req-alm-h-card-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); flex-wrap: wrap; }
/* O numero e o que ele procura, entao ganha o peso e a fonte mono do modulo. */
.req-alm-h-card-num {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: 1.02rem; font-weight: 700; color: var(--text-primary);
}
.req-alm-h-card-who { font-family: var(--font-display); font-size: .96rem; font-weight: 700; letter-spacing: -.01em; }
/* auto-fit com piso em min(): abaixo de 150px de painel o par rotulo/valor encolhe
   em vez de estourar o cartao. */
.req-alm-h-card-meta {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: 7px var(--space-3); margin: 0;
}
.req-alm-h-card-meta dt {
  font-size: .64rem; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-secondary);
}
.req-alm-h-card-meta dd {
  margin: 0; font-size: .84rem; color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
/* O Reenviar e a unica acao desta tela. No cartao ele sai da linha e vira alvo de
   toque de verdade: no historico da tabela ele e uma pill de 4px de altura util. */
.req-alm-h-card-acts { display: flex; justify-content: flex-end; }
.req-alm-h-card-acts .req-alm-h-reenviar { margin-left: 0; min-height: 44px; padding: 0 16px; font-size: .82rem; }

@container (max-width: 860px) {
  .req-alm-h-tablewrap { display: none; }
  .req-alm-h-cards { display: flex; }
}

@container (max-width: 560px) {
  .req-alm-h-cc, .req-alm-h-table th:nth-child(5), .req-alm-h-table td:nth-child(5) { display: none; }
  .req-alm-hist-search { flex: 1 1 100%; }
}

/* ── Estação Segurança do Trabalho ───────────────────────────────────────────
   Público diferente do almoxarifado: o balcão de lá é operado por gente rápida e
   acostumada com a tela, e ganha com densidade. Aqui não. Então a tela obedece três
   regras, e elas explicam cada decisão abaixo:

   1. UMA COISA POR VEZ NO MIOLO, revisto em 24/08. O invólucro passou a ser o MESMO
      cockpit do balcão (fila à esquerda, atendimento à direita), porque ao lado do
      almoxarifado esta estação parecia de outra geração. O que continua valendo é o
      miolo: dentro da ficha, os passos numerados e uma coisa por vez. Master-detail é
      o invólucro; "uma coisa por vez" é o conteúdo. Abaixo de 860px de painel o
      comportamento antigo volta inteiro (lista, depois destino).
   2. O NOME MANDA — sem papel, quem chega DIZ O NOME. O número virou referência
      secundária (é o inverso da fila do almoxarifado, onde o número é a chave).
   3. PASSOS NUMERADOS — dizer "o que eu faço agora", na ordem, vale mais que mostrar
      tudo junto. Some da tela o que não muda a ação: data de emissão, tempo de fila,
      grade de contexto.

   Escala maior que o resto do módulo de propósito: alvos ≥56px e texto acima de 1rem. */

/* Contêiner NOMEADO, e o nome não é enfeite. O palco também é contêiner (a ficha precisa
   perguntar pela própria largura), e num painel de 1321px o palco tem 802px: uma consulta
   anônima de "painel estreito" resolveria contra o palco e acenderia o layout empilhado
   dentro do cockpit. Medido: o botão "Fechar" virava "Voltar à lista" com a lista visível
   ao lado. Regra de layout de PAINEL pergunta por `segpane`; regra interna da ficha
   continua anônima e pergunta ao palco. */
.req-pane[data-pane="seguranca"] { container-type: inline-size; container-name: segpane; }
/* O teto sobe acima de 861px porque a linha da fila carrega nome, setor, espera, tira de
   miniaturas e contagem: em 760px a tira e a primeira a ser cortada, e ela e o unico lugar
   onde a fila diz O QUE a pessoa vem buscar. Continua nao mudando ao abrir alguem: a ficha
   e gaveta e nao ocupa coluna, entao a tela tem UMA largura o dia inteiro. */
.req-seg { max-width: 760px; margin: 0 auto; }
@container segpane (min-width: 861px) { .req-seg { max-width: 1240px; } }

/* Busca: o elemento mais alto da tela, porque é por onde TODO atendimento começa.
   Some quando alguém está sendo atendido. */
.req-seg-top { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.req-seg-top[hidden] { display: none; }
.req-seg-busca {
  position: relative; flex: 1 1 320px; min-width: 0;
  display: flex; align-items: center;
}
.req-seg-busca > svg {
  position: absolute; left: 16px; width: 20px; height: 20px;
  color: var(--text-secondary); pointer-events: none;
}
.req-seg-busca input {
  width: 100%; height: 60px; padding: 0 48px 0 46px;
  border: 2px solid var(--line-soft); border-radius: var(--radius-md);
  background: var(--bg-surface); color: var(--text-primary);
  font-size: 1.1rem; font-family: inherit;
}
.req-seg-busca input::placeholder { color: var(--text-secondary); }
.req-seg-busca input:focus { outline: none; border-color: var(--brand-500); }
.req-seg-qclear {
  position: absolute; right: 10px; display: grid; place-items: center;
  /* 44 e não 40: é o piso de alvo de toque, e aqui se opera de pé e às vezes de luva. */
  width: 44px; height: 44px; padding: 0; border: 0; border-radius: 999px;
  background: var(--bg-muted); color: var(--text-secondary); cursor: pointer;
}
.req-seg-qclear svg { width: 16px; height: 16px; }
.req-seg-gerenciar { flex: none; display: inline-flex; align-items: center; gap: 6px; }
.req-seg-gerenciar[hidden] { display: none; }
.req-seg-gerenciar svg { width: 16px; height: 16px; }

.req-seg-body { margin-top: var(--space-4); }
/* A conta vive no rodape agora (ver .req-roll-bar), entao perdeu a margem de baixo que
   existia para separa-la da lista logo abaixo. */
.req-seg-conta { margin: 0; font-size: .9rem; color: var(--text-secondary); }

/* A fila rola por DENTRO, como a do balcao (.req-alm-qlist). Sem isto ela crescia a pagina
   e o primeiro gesto de rolagem levava embora os contadores, a busca e a contagem — tudo o
   que orienta quem esta atendendo. Mesmo 68vh do balcao de proposito: sao a mesma tela de
   operacao, em pe, e duas alturas diferentes leriam como descuido.
   O padding-right da folga para a barra de rolagem nao encostar no foco das linhas, que sao
   <button> e ganham anel de foco. */
.req-seg-fila-scroll { max-height: 68vh; overflow-y: auto; padding-right: 2px; }

/* ── A fila é a tela, e a ficha virou gaveta (27/08) ──
   Terceira etapa da mesma correção. Em 25/08 o cockpit foi invertido (fila larga, ficha em
   painel de 396px) porque a linha da Segurança carrega nome, setor, espera, saldo e a tira
   de miniaturas, e é olhando a FILA que o técnico decide a manhã. O painel de 396px foi o
   que sobrou de errado: foi ELE que produziu o mosaico de 82px e o dígito miúdo de que o
   balcão reclamou em 26/08, e remendar dentro de 396px era tratar o sintoma.

   Agora a ficha vive numa gaveta de 560px (`#reqSegDrawer`), e a fila fica com a largura
   toda. Três coisas melhoram de uma vez: o quadro da peça dobra (168px contra 82), a fila
   nunca muda de forma ao abrir alguém (o que era o objetivo do convite de palco vazio, hoje
   desnecessário), e a tira de miniaturas ganha os 396px que o painel levava. */
.req-seg-grid { display: grid; grid-template-columns: minmax(0, 1fr); }
/* A fila e contexto de consulta, e o nome (`segfila`) e OBRIGATORIO, nao estilo.
   Sem nome, as consultas anonimas de dentro da fila passariam a resolver contra ela por
   serem as mais proximas, e uma delas (`max-width: 640px`, mais abaixo) mede o painel de
   proposito. Foi exatamente essa armadilha que ja custou uma volta quando o palco virou
   contexto e roubou as consultas de painel. Regra do arquivo: quem pergunta pela largura
   da COLUNA pergunta a `segfila`, quem pergunta pela largura do PAINEL pergunta a
   `segpane`, e consulta anonima dentro da ficha pergunta ao CORPO DA GAVETA (era o palco
   ate 27/08; o palco sumiu e o contexto passou para `.req-seg-dw-body`, que e onde a ficha
   mora agora). */
.req-seg-fila { min-width: 0; container-type: inline-size; container-name: segfila; }

/* Contadores da fila: são o filtro, mesmo objeto do balcão. Alvos maiores que os de lá
   porque aqui a escala toda é maior (público não técnico, gente de pé). */
.req-seg-counts { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-3); }
.req-seg-count {
  flex: 1 1 96px; min-height: 56px; padding: 7px 13px; margin: 0;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
  gap: 1px; line-height: 1.12; text-align: left;
  border: 1.5px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-secondary);
  font: inherit; cursor: pointer;
  transition: background var(--trans-fast), border-color var(--trans-fast), color var(--trans-fast);
}
.req-seg-count b { font-size: 1.28rem; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--text-primary); }
.req-seg-count span { font-size: .72rem; font-weight: 600; }
.req-seg-count.is-on { border-color: var(--brand-500); background: color-mix(in srgb, var(--brand-500) 10%, var(--bg-surface)); }
.req-seg-count.is-on b, .req-seg-count.is-on span { color: var(--brand-500); }
.req-seg-count.is-falta b { color: var(--warning-600, #b45309); }
.req-seg-count.is-falta.is-on { border-color: var(--warning-500); background: color-mix(in srgb, var(--warning-500) 14%, var(--bg-surface)); }
.req-seg-count.is-falta.is-on b, .req-seg-count.is-falta.is-on span { color: var(--warning-600, #b45309); }
.req-seg-count.is-demora b { color: var(--danger-500); }
/* Célula de DADO, não filtro: mesma caixa dos chips para a faixa ler como uma coisa só,
   mas sem cursor de mão, sem hover e sem estado ligado. É a carga de trabalho da manhã
   (peças, não pessoas), e peça não é recorte possível de uma fila de pessoas. */
.req-seg-count.is-dado { cursor: default; background: var(--bg-muted); }
.req-seg-count.is-dado b { color: var(--brand-600, var(--brand-500)); }
.req-seg-count.is-demora.is-on { border-color: var(--danger-500); background: color-mix(in srgb, var(--danger-500) 10%, var(--bg-surface)); }
.req-seg-count.is-demora.is-on b, .req-seg-count.is-demora.is-on span { color: var(--danger-500); }

/* ── Tira de miniaturas na linha da fila ──
   O bloco de texto deixa de ser elástico e ganha base fixa (258px): sem isso o nome longo
   comeria a tira, e a tira é justamente o que a linha passou a informar. 258px é o ponto em
   que "Marlon Vinicius de Oliveira" ainda cabe sem elipse na escala de 1.15rem.

   `overflow: hidden` na tira e não `flex-wrap`: uma tira que quebra em duas linhas dobra a
   altura da linha da fila e a lista deixa de ser varrível. O que não cabe é o "+N", que já
   diz que há mais.

   `0 0` e não `0 1`, ou seja o texto NÃO encolhe: entre os dois vizinhos, quem cede espaço
   é a tira. Ela já sabe ceder (tem `overflow: hidden` e degrada mostrando menos quadros),
   e o texto não sabe: ele degrada virando elipse no nome. Medido a 625px de fila, com
   `0 1` o bloco caía de 258 para 230px, que ainda cabia nos nomes da fixture e não
   caberia em "Rosangela Aparecida Ferreira". Prioridade explícita em vez de sorte. */
.req-seg-pessoa-txt.has-tira { flex: 0 0 258px; }
.req-seg-tira {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px;
  overflow: hidden;
}
.req-seg-mini {
  position: relative; flex: none; width: 52px; height: 52px; overflow: hidden;
  border: 1px solid var(--line-soft); border-radius: 10px; background: var(--bg-muted);
}
.req-seg-mini img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block; background: var(--bg-muted);
}
.req-seg-mini-vazio { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-secondary); }
.req-seg-mini-vazio svg { width: 20px; height: 20px; }
/* Sem saldo pinta a MINIATURA, não a linha: a linha já tem o chip "sem saldo" com a
   contagem, e o que a tira acrescenta é QUAL peça é. */
.req-seg-mini.is-short {
  border-color: color-mix(in srgb, var(--warning-500) 62%, transparent);
  background: color-mix(in srgb, var(--warning-500) 12%, var(--bg-muted));
}
.req-seg-mini.is-short img { background: color-mix(in srgb, var(--warning-500) 12%, var(--bg-muted)); }
/* Quantidade só aparece acima de 1. Numa tira de 5 quadros, cinco selos "1" seriam cinco
   objetos a mais dizendo o que o padrão já diz. */
.req-seg-mini-q {
  position: absolute; right: 0; bottom: 0; z-index: 1; padding: 0 5px;
  border-radius: 6px 0 0 0; background: rgb(15 23 42 / .86); color: #fff;
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: .62rem; font-weight: 700; line-height: 1.55;
}
.req-seg-mini-mais {
  flex: none; display: grid; place-items: center; width: 34px; height: 52px;
  border: 1px dashed var(--line-soft); border-radius: 10px; background: var(--bg-muted);
  font-family: var(--font-mono); font-size: .78rem; font-weight: 700; color: var(--text-secondary);
}

/* A tira sai da linha quando a COLUNA fica estreita, e o gatilho é a largura da fila,
   não a do painel: é ela que a tira divide com o nome. Medido no tablet de 1024 em retrato,
   que é o caso que obrigou esta regra a existir: painel 905px, dois em pé (fila 489 +
   ficha 396), e a 489px o bloco de texto encolhia de 258 para 163px. Resultado: 3 das 5
   miniaturas cortadas E o nome em elipse.

   Nome em elipse é o pior troco possível. O nome é o que a pessoa DIZ no balcão; as
   miniaturas são atalho para uma ficha que está a um toque de distância, com as mesmas
   fotos a 190px. Então abaixo de 620px a tira sai e o texto recupera a elasticidade.

   O limiar é 620 e não 860: a tira não tem nada a ver com "o painel está estreito". Num
   painel de 800px em coluna única a fila tem 800px e a tira cabe folgada. Amarrar as duas
   coisas ao mesmo número faria a tira desaparecer justamente onde ela caberia melhor.

   Nada do que a tira informa se perde: o chip "sem saldo" e a contagem de itens continuam
   na linha. Só o atalho visual sai. */
@container segfila (max-width: 620px) {
  .req-seg-tira { display: none; }
  .req-seg-pessoa-txt.has-tira { flex: 1 1 auto; }
}

/* Espera e falta de saldo na linha. Nunca competem com o nome: fonte menor, terceira
   linha, e a cor só aparece quando há algo a dizer. */
.req-seg-pessoa-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-top: 2px; }
.req-seg-pessoa-espera, .req-seg-pessoa-falta {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: .76rem; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.req-seg-pessoa-espera svg, .req-seg-pessoa-falta svg { width: 13px; height: 13px; flex: none; }
.req-seg-pessoa-falta { color: var(--warning-600, #b45309); }

/* Quem está em atendimento fica marcado NA LISTA: no cockpit as duas coisas coexistem e
   sem isso a lista não diz de quem é a ficha ao lado. */
.req-seg-pessoa.is-atual {
  border-color: var(--brand-500);
  background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface));
  box-shadow: inset 3px 0 0 var(--brand-500);
}

/* ── Lista de quem está esperando ── */
/* Fluxo de blocos, não flex com max-height: a página rola (mais familiar que uma área
   de rolagem interna) e não há como o item ser comprimido por flex-shrink. */
.req-seg-lista { display: block; }
/* 12px, não 8: o mínimo da diretriz de toque é 8px, e quem opera aqui está de pé, às
   vezes de luva. Sem folga extra, tocar o nome de baixo é fácil demais. */
.req-seg-pessoa + .req-seg-pessoa { margin-top: 12px; }
.req-seg-pessoa[hidden] { display: none; }

/* Entrada escalonada: comunica "isto é uma fila viva, chegou gente" sem custo de JS.
   Só na carga da fila (a busca filtra por hidden, então não reinicia a animação). */
@keyframes reqSegEntra { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.req-seg-pessoa.is-entrando { animation: reqSegEntra 260ms ease-out both; }

/* O <button> é só a casca; o layout mora no -inner. <button> não se dimensiona pelo
   conteúdo de um grid/flex próprio no Chromium (medido: colapsa), então o padrão de
   casca + wrapper é obrigatório e não estilístico. */
.req-seg-pessoa {
  display: block; width: 100%; padding: 0; margin: 0;
  border: 2px solid var(--line-soft); border-radius: var(--radius-md);
  background: var(--bg-surface); color: inherit; font: inherit; text-align: left;
  cursor: pointer; transition: border-color var(--trans-fast), background var(--trans-fast);
}
.req-seg-pessoa:hover { border-color: var(--brand-500); background: var(--bg-muted); }
/* Num monitor de toque não existe hover: sem :active, o técnico toca e a tela não
   responde até o próximo render. Era a lacuna de feedback mais grave da estação. */
.req-seg-pessoa:active { transform: scale(.995); background: var(--bg-muted); border-color: var(--brand-500); }
.req-seg-pessoa-inner {
  display: flex; align-items: center; gap: var(--space-3);
  min-height: 84px; padding: 14px 16px;
}
.req-seg-pessoa-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
/* O nome é o dado dominante da tela inteira. */
.req-seg-pessoa-nome {
  font-size: 1.15rem; font-weight: 700; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.req-seg-pessoa-sub {
  font-size: .84rem; color: var(--text-secondary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.req-seg-pessoa-itens {
  flex: none; display: flex; flex-direction: column; align-items: center; line-height: 1;
  padding: 8px 12px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--brand-500) 10%, var(--bg-surface));
  font-family: var(--font-mono); font-size: 1.15rem; font-weight: 600;
  color: var(--brand-600, var(--brand-500));
}
.req-seg-pessoa-itens small {
  margin-top: 3px; font-family: var(--font-ui); font-size: .6rem; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
}
/* Atendimento interrompido no meio: o progresso do RHP vive por requisição, então a
   fila consegue dizer "esta pessoa já foi começada" — importante com dois técnicos. */
.req-seg-pessoa-curso {
  flex: none; display: flex; flex-direction: column; align-items: flex-end; line-height: 1.2;
  font-size: .72rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: color-mix(in srgb, var(--warning-500) 88%, #000);
}
.req-seg-pessoa-curso small {
  font-size: .72rem; font-weight: 500; letter-spacing: 0; text-transform: none;
  color: var(--text-secondary);
}
.req-seg-pessoa-seta { flex: none; display: inline-flex; color: var(--text-secondary); }
.req-seg-pessoa-seta svg { width: 20px; height: 20px; transform: rotate(-90deg); }

/* Vazio: fala o que fazer, não só que está vazio. */
.req-seg-vazio[hidden] { display: none; }
.req-seg-vazio {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 48px 24px; text-align: center;
  border: 2px dashed var(--line-soft); border-radius: var(--radius-md);
  color: var(--text-secondary);
}
.req-seg-vazio svg { width: 34px; height: 34px; opacity: .55; margin-bottom: 4px; }
.req-seg-vazio strong { font-size: 1.05rem; color: var(--text-primary); }
.req-seg-vazio span { font-size: .88rem; max-width: 42ch; text-wrap: pretty; }

/* ── Atendimento ──
   O botao "voltar/fechar" com rotulo duplo saiu em 27/08: com a ficha em gaveta o fechar e o
   `.req-drawer-close` padrao (o X no canto do cabecalho), o mesmo das outras duas gavetas do
   modulo. Deixou de existir o estado "a ficha substituiu a lista", que era a unica razao de
   o rotulo alternar entre "Voltar a lista" e "Fechar". */
.req-seg-quem { margin: var(--space-4) 0 0; }
.req-seg-quem h3 {
  margin: 0; font-family: var(--font-display); font-size: 1.7rem; font-weight: 700;
  letter-spacing: -.02em; color: var(--text-primary); text-wrap: balance;
}
/* Setor a esquerda e o numero da requisicao em pastilha mono a direita: o numero e uma CHAVE
   (o modulo ja usa mono para chave em toda tabela), e em texto corrido ele lia como parte da
   frase do setor. Quem diz o nome no balcao e a pessoa; o numero e para conferir depois. */
.req-seg-quem-meta {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin: 5px 0 0; font-size: .86rem; color: var(--text-secondary);
}
.req-seg-quem-num {
  flex: none; padding: 1px 7px; border-radius: 999px; background: var(--bg-muted);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: .78rem;
}
/* Slot de "quem vai retirar". O dado chega no item 0 desta frente, e o lugar dele e o
   cabecalho porque e a primeira pergunta do balcao quando quem pediu nao e quem retira
   ("chega 5 pessoas pedindo o protetor aqui preciso identificar para quem entrego"). */
.req-seg-quem-retira {
  display: flex; align-items: center; gap: 7px; margin: 8px 0 0;
  font-size: .86rem; color: var(--text-primary);
}
.req-seg-quem-retira svg { width: 15px; height: 15px; flex: none; color: var(--brand-500); }
.req-seg-quem-retira span {
  font-size: .62rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--text-secondary);
}
.req-seg-quem-retira b { font-weight: 700; }

.req-seg-aviso {
  display: flex; align-items: flex-start; gap: var(--space-3);
  margin-top: var(--space-4); padding: 10px 12px;
  border: 1px solid color-mix(in srgb, var(--warning-500) 36%, transparent);
  border-left: 4px solid var(--warning-500); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warning-500) 10%, var(--bg-surface));
  color: color-mix(in srgb, var(--warning-500) 78%, #000);
}
.req-seg-aviso svg { width: 18px; height: 18px; flex: none; margin-top: 1px; }
.req-seg-aviso b { display: block; font-size: .88rem; }
.req-seg-aviso span { font-size: .8rem; color: var(--text-secondary); text-wrap: pretty; }

/* ── A GAVETA do atendimento (27/08) ──
   Substitui o painel de 396px que vivia ao lado da fila. A geometria (entra pela direita,
   560px, vira bottom sheet no celular, trava a rolagem de fundo) vem inteira de
   `.req-drawer.is-wide`, entao aqui so mora o que e proprio do atendimento.

   O que NAO funcionou nas tentativas anteriores, e por que fica registrado: painel com
   `max-height: 82vh` e rolagem propria fazia "Liberar retirada" nascer a 988px numa janela
   de 900, porque o painel comecava a ~250px do topo. Na gaveta esse risco e maior, nao
   menor: ela e mais estreita, logo mais alta. A solucao e a mesma que funcionou la, agora
   com a gaveta como unica caixa que rola: as DUAS PONTAS grudam nela, cabecalho no alto e
   trilho de acao no pe, e so os itens correm entre os dois. Zero altura calculada com numero
   magico, zero rolagem dentro do corpo.

   `padding: 0` e `gap: 0` sobrescrevem `.req-drawer` de proposito: com padding no elemento
   que rola, o cabecalho sticky para 16px abaixo do topo e o conteudo aparece passando por
   tras dele. O respiro passa para cada faixa. */
#reqSegDrawer { padding: 0; gap: 0; }

.req-seg-dw-head {
  position: sticky; top: 0; z-index: 3;
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--line-soft);
  /* Fundo OPACO obrigatório: o conteúdo passa por baixo dele ao rolar. O color-mix sobre
     `--bg-surface` resolve em cor sólida, não em transparência. */
  background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface));
}
.req-seg-dw-head .req-seg-quem { flex: 1 1 auto; min-width: 0; margin: 0; }
/* 1.5rem: a gaveta devolveu largura ao nome (496px de cabecalho contra 348px do painel),
   entao ele volta a crescer. Nao vai aos 1.7rem da tela cheia porque "Josefa Maria da
   Conceicao" ainda quebraria em tres linhas aqui. */
.req-seg-dw-head .req-seg-quem h3 { font-size: 1.5rem; }
.req-seg-dw-head .req-drawer-close { flex: none; }
.req-seg-painel-eyebrow {
  display: block; margin-bottom: 2px;
  font-size: .62rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--brand-600, var(--brand-500));
}

/* `flex: 1` para o corpo empurrar o trilho ao pe quando o pedido e curto: sem isso um
   pedido de 1 item deixaria o botao flutuando no meio da gaveta.
   E o corpo e o CONTEXTO DE CONSULTA da ficha, herdando o papel que era do palco: as regras
   anonimas de dentro da ficha (o mosaico compacto, por exemplo) medem esta caixa. */
.req-seg-dw-body {
  flex: 1 1 auto; min-width: 0;
  padding: var(--space-4);
  container-type: inline-size;
}

.req-seg-dw-rail {
  position: sticky; bottom: 0; z-index: 2;
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-3) var(--space-4) var(--space-4);
  background: var(--bg-surface);
  border-top: 1px solid var(--line-soft);
  box-shadow: 0 -10px 18px -12px rgb(15 23 42 / .35);
}

/* ── CABECALHO DA CONFERENCIA: o passo 1 virou titulo de secao ────────────────
   A fita de tres pilulas saiu em 27/08. Ela custava 112px e dava peso IGUAL a tres coisas que
   acontecem em momentos diferentes, e uma checklist onde os tres itens pesam o mesmo nao diz
   onde a pessoa esta. Cada instrucao foi para junto do seu gesto: o 1 e este titulo (agora com
   a contagem de pecas, que a fita nao dava), o 2 mora no trilho no instante em que importa, e
   o 3 e o proprio botao. Proximidade fazendo o trabalho que a numeracao fingia fazer.

   A regua de 2px e o unico peso de linha da gaveta, e ela existe para dizer "daqui para baixo
   e conferencia item a item". */
/* A regua e a MESMA GRADE da linha, menos a coluna da foto: as duas colunas fixas da direita
   (46 e 44) ancoram pela direita, entao com o mesmo gap e o mesmo recuo direito os rotulos
   caem EXATAMENTE sobre as celulas, e o 1fr absorve a diferenca a esquerda. E a mesma tecnica
   do cabecalho da lista de Minhas, e existe pela mesma razao: rotulo que nao cai sobre a
   coluna nao rotula nada, confunde.

   `padding-right: 2px` copia o recuo direito da linha. E so 2px, mas sem ele os rotulos ficam
   2px a direita das celulas, e desalinhamento de rotulo e pior que rotulo ausente. */
.req-seg-conf {
  display: grid; grid-template-columns: minmax(0, 1fr) 46px 44px;
  align-items: baseline; gap: var(--space-3);
  margin: var(--space-5) 0 0; padding: 0 2px 7px 0;
  border-bottom: 2px solid var(--text-primary);
}
/* Sem nenhum tamanho no pedido a coluna nao existe, entao o rotulo dela tambem nao: a regua
   acompanha o `is-sem-tam` da lista. */
.req-seg-conf.is-sem-tam { grid-template-columns: minmax(0, 1fr) 44px; }
/* Coluna que carrega rotulo NAO-grade (bitola, cor, origem) precisa de largura: os 46px foram
   dimensionados para "39", "GG" e "ún", e "Importado" mede 72px. Sem isto a pastilha
   transbordava para cima da quantidade, medido a 375px. Mesmo raciocinio e mesmo nome do
   `is-rotulo-longo` do seletor do card (ver a regra la em cima). */
.req-seg-conf.is-rotulo-longo { grid-template-columns: minmax(0, 1fr) 96px 44px; }
.req-seg-conf-t {
  display: flex; align-items: center; gap: 8px; margin: 0; min-width: 0;
  font-family: var(--font-ui); font-size: .7rem; font-weight: 700;
  letter-spacing: .11em; text-transform: uppercase; color: var(--text-primary);
}
/* A contagem passou a viver DENTRO do titulo (a direita da regua agora e dos rotulos de
   coluna). Como o titulo e caixa alta com letter-spacing, ela precisa desligar os dois: sem
   isto lia "5 PEÇAS" espacado, com peso de titulo. */
.req-seg-conf-cont {
  flex: none; font-family: var(--font-display); font-size: .84rem; font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--text-secondary);
  text-transform: none; letter-spacing: normal;
}
/* Rotulo de coluna: miudo e apagado de proposito. Ele e consultado UMA vez, quando a pessoa
   aprende a tela, e depois vira ruido se competir com o dado. Alinhamento espelha a celula:
   o tamanho e centrado na pastilha, a quantidade e `justify-self: end`. */
.req-seg-conf-rot {
  font-family: var(--font-ui); font-size: .6rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-secondary);
  text-align: center;
}
.req-seg-conf-rot.is-qtd { text-align: right; }
/* O numeral do passo e ROTULO, nao dado: marcador discreto e nao disco de cor de marca. O
   objeto mais chamativo da gaveta tem de ser o que se le (o nome da peca) ou o que se aperta
   (o botao verde), e a versao anterior tinha tres discos competindo com os dois.

   NEUTRO e nao o teal do modulo: aqui o teal (#0f766e) significa "integrado no Senior", e usa-lo
   como numeral acrescentaria uma quarta cor que nao carrega estado nenhum, com o agravante de ja
   ter outro sentido a duas telas de distancia. Cor nesta gaveta e reservada a estado: verde no
   portao, ambar na falta, marca no tamanho repetido e na quantidade acima de um. */
.req-seg-passo-n {
  flex: none; display: grid; place-items: center; width: 18px; height: 18px;
  border-radius: 50%; background: var(--text-primary); color: var(--bg-surface);
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: .64rem; font-weight: 700;
}

/* ── A FOLHA DE CONFERENCIA ───────────────────────────────────────────────────
   Substitui o mosaico de fotos, por decisao dele em 27/08 depois de ver o print. O argumento
   dele e melhor que o meu desenho anterior: o pedido tinha "BOTINA COM BICO DE ACO - N33" em
   primeiro lugar e "BOTINA COM BICO DE ACO - Nº40" em quinto, com a MESMA foto. O mosaico
   esconde ativamente a unica diferenca que importa. Entregar a N33 para quem pediu a N40 e
   exatamente o erro que esta estacao existe para evitar.

   Reguas de 1px e nao cartoes: sete cartoes com borda sao sete retangulos concorrendo com o
   conteudo, e no print eles competiam com cinco pilulas escuras e tres pilulas de passo. Aqui
   a linha e separada por hairline e a unica cor forte da tela passa a ser o verde do portao,
   o ambar da falta e a cor de marca nos dois campos que decidem.

   COLUNAS DE LARGURA FIXA nas duas pontas sao o miolo do desenho: e o que faz a coluna de
   tamanhos e a de quantidades serem varriveis de cima a baixo, e portanto e o que faz N33 e
   N40 se contradizerem a vista. Se a largura dancasse por linha, a varredura morreria.
   `tabular-nums` pelo mesmo motivo, um nivel abaixo: digito de largura variavel desalinha a
   coluna mesmo com a celula fixa. */
.req-seg-conf-lista { margin: 0; padding: 0; list-style: none; }
.req-seg-item {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) 46px 44px;
  align-items: center; gap: var(--space-3);
  padding: 10px 2px 10px 8px;
}
/* Requisicao em que NENHUM item tem tamanho (avental, protetor auditivo) devolve os 58px da
   coluna ao nome, em vez de desenhar uma fileira de celulas vazias. */
.req-seg-conf-lista.is-sem-tam .req-seg-item { grid-template-columns: 52px minmax(0, 1fr) 44px; }
.req-seg-conf-lista.is-rotulo-longo .req-seg-item { grid-template-columns: 52px minmax(0, 1fr) 96px 44px; }
.req-seg-item + .req-seg-item { border-top: 1px solid var(--line-soft); }
/* Falta de saldo pinta a MARGEM, nao a linha: em sete linhas, fundo ambar lava o conteudo
   justamente onde se le. E `inset box-shadow` em vez de `border-left` de proposito: borda
   consome largura e desalinharia a linha com falta em relacao as outras, matando a varredura
   que e a razao de existir desta lista. */
.req-seg-item.is-short { box-shadow: inset 3px 0 0 0 var(--warning-500); }

.req-seg-item-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Duas linhas no maximo, e o inteiro fica no `title` da linha. O nome subiu de terceiro para
   primeiro em peso dentro do bloco de texto: no desenho anterior ele vinha DEPOIS de um chip
   verde de tamanho, ou seja o que se le perdia do que se compara. */
.req-seg-item-nome {
  font-family: var(--font-ui); font-size: .92rem; font-weight: 600; line-height: 1.25;
  color: var(--text-primary);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.req-seg-item-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* O CA desceu para linha secundaria e miuda: e registro da ficha NR-6, nao serve para
   reconhecer peca na bancada. No mosaico ele gastava uma linha propria em TODOS os itens. */
.req-seg-item-ca {
  font-family: var(--font-mono); font-size: .62rem; font-variant-numeric: tabular-nums;
  letter-spacing: .03em; color: var(--text-secondary);
}
.req-seg-item-falta {
  display: inline-flex; align-items: center; gap: 3px; padding: 1px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--warning-500) 16%, var(--bg-surface));
  color: color-mix(in srgb, var(--warning-500) 82%, #000);
  font-size: .6rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
}
.req-seg-item-falta svg { width: 10px; height: 10px; flex: none; }

/* O tamanho e o campo que causa a entrega errada, entao ele deixou de ser chip verde miudo ao
   lado do nome e virou pastilha tipografica numa coluna propria. */
.req-seg-item-tam {
  display: grid; place-items: center; min-height: 30px; padding: 0 4px;
  border: 1.5px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface);
  font-family: var(--font-display); font-size: 1rem; font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em; color: var(--text-primary);
  /* Rede de seguranca: rotulo mais longo que a coluna e CORTADO dentro da pastilha, nunca
     derramado sobre a quantidade. Cortar fica contido; transbordar quebra a varredura da coluna,
     que e a razao de ser desta lista. O texto inteiro continua no `title` da linha. */
  white-space: nowrap; overflow: hidden;
}
/* Celula vazia OCUPA a coluna: sem ela a quantidade escorregaria para a coluna do tamanho e a
   linha sem tamanho desalinharia toda a varredura. Espaco, sem desenho nenhum. */
.req-seg-item-tam.is-vazio { border: 0; background: none; }
/* Anel so onde ha AMBIGUIDADE: produto que aparece em mais de um tamanho no mesmo pedido. O
   realce mora no campo que difere, nao na linha inteira, e realce que aparece em toda linha
   nao e realce, e fundo. */
.req-seg-item-tam.is-alerta {
  border-color: var(--brand-500); color: var(--brand-600, var(--brand-500));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-500) 18%, transparent);
}

/* Quantidade 1 fica em cinza e quantidade maior ACENDE: o realce mora onde ha risco (levar
   mais de um) e silencia onde nao ha. E o oposto do selo antigo, que pintava as duas com peso
   forte em cima da foto e virava o objeto mais chamativo da tela, cobrindo justamente a peca
   que a pessoa precisa reconhecer. Cor de marca e nao ambar: ambar aqui significa falta de
   saldo, e dar o mesmo tom a "tem mais de um" criaria dois sentidos para a mesma cor. */
.req-seg-item-qtd {
  justify-self: end; display: flex; align-items: baseline; gap: 1px;
  font-family: var(--font-display); font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
.req-seg-item-qtd i { font-style: normal; font-size: .68rem; opacity: .65; }
.req-seg-item-qtd b { font-size: 1.06rem; font-weight: 700; line-height: 1; }
.req-seg-item-qtd.is-multi { color: var(--brand-600, var(--brand-500)); }
.req-seg-item-qtd.is-multi b { font-size: 1.24rem; }

/* 52px: a tira da FILA provou que 52px bastam para RECONHECER a peca, e aqui a foto e apoio e
   nao a prova. A prova esta a um clique, no lightbox do catalogo, em tamanho de verdade. */
.req-seg-foto {
  position: relative; width: 100%; aspect-ratio: 1; padding: 0; overflow: hidden;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-muted); cursor: zoom-in;
  transition: border-color .14s ease;
}
.req-seg-foto.is-vazio {
  cursor: default; display: grid; place-items: center; color: var(--text-secondary);
}
.req-seg-foto.is-vazio svg { width: 22px; height: 22px; opacity: .5; }
.req-seg-foto img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* A lupa nasce INVISIVEL e aparece sob o ponteiro. Em repouso, sete lupas iguais eram sete
   icones repetidos disputando com o conteudo (bem visivel no print); mas remove-la de vez
   tiraria a unica pista de que a foto amplia. Aparecer no hover resolve os dois lados. */
.req-seg-foto-lupa {
  position: absolute; right: 2px; bottom: 2px;
  display: grid; place-items: center; width: 17px; height: 17px;
  border-radius: 5px; background: var(--brand-500); color: #fff;
  opacity: 0; transform: scale(.7);
  transition: opacity .14s ease, transform .14s ease;
}
.req-seg-foto-lupa svg { width: 11px; height: 11px; }
.req-seg-foto:hover { border-color: var(--brand-500); }
.req-seg-foto:hover .req-seg-foto-lupa,
.req-seg-foto:focus-visible .req-seg-foto-lupa { opacity: 1; transform: none; }
.req-seg-foto:focus-visible { outline: 3px solid var(--brand-500); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .req-seg-foto, .req-seg-foto-lupa { transition: none; }
  .req-seg-foto-lupa { transform: none; }
}

/* O passo 2 mora no trilho porque e ali que ele acontece: colher a digital e o gesto
   imediatamente anterior a apertar o botao. Junto dele vem a CONSEQUENCIA, que e o que um
   chip de uma linha nunca cabia dizer: o selo substitui a assinatura no papel. */
.req-seg-dw-passo {
  display: flex; align-items: flex-start; gap: 8px; margin: 0;
  font-size: .8rem; line-height: 1.35; color: var(--text-secondary); text-wrap: pretty;
}
.req-seg-dw-passo > svg { width: 17px; height: 17px; flex: none; margin-top: 1px; color: var(--brand-500); }
.req-seg-dw-passo .req-seg-passo-n { margin-top: 1px; }
/* O `margin-top` do botao existia para separa-lo do bloco de texto do passo 3 na ficha antiga.
   No trilho o `gap` ja faz isso, e os dois somados abriam um buraco. */
.req-seg-dw-rail .req-seg-liberar { margin-top: 0; }

/* Bottom sheet no celular: as colunas ENCOLHEM em vez de quebrar. A coluna varrivel e a razao
   de existir desta lista, entao empilhar tamanho e quantidade abaixo do nome seria trocar o
   desenho por um pior. E a estacao e um PC de balcao: o celular e caso de borda, nao o alvo. */
@container (max-width: 420px) {
  .req-seg-item { grid-template-columns: 44px minmax(0, 1fr) 42px 40px; gap: 8px; padding-left: 7px; }
  .req-seg-conf-lista.is-sem-tam .req-seg-item { grid-template-columns: 44px minmax(0, 1fr) 40px; }
  /* A regua segue a linha: mesmas colunas fixas, mesmo gap, senao o rotulo desalinha exatamente
     na largura em que a coluna e mais estreita e o alinhamento mais importa. */
  .req-seg-conf { grid-template-columns: minmax(0, 1fr) 42px 40px; gap: 8px; }
  .req-seg-conf.is-sem-tam { grid-template-columns: minmax(0, 1fr) 40px; }
  .req-seg-conf.is-rotulo-longo { grid-template-columns: minmax(0, 1fr) 84px 40px; gap: 8px; }
  .req-seg-conf-lista.is-rotulo-longo .req-seg-item { grid-template-columns: 44px minmax(0, 1fr) 84px 40px; }
  .req-seg-item-nome { font-size: .86rem; }
  .req-seg-item-tam { min-height: 27px; font-size: .9rem; }
  .req-seg-item-qtd b { font-size: .98rem; }
  .req-seg-item-qtd.is-multi b { font-size: 1.12rem; }
}

/* ── A folha no CELULAR: o cromo cede, a lista fica ──────────────────────────
   Medido num 375x812: cabecalho 133px e trilho 157px somavam 290px dos 714 da folha, 41% de
   moldura para uma tela cujo trabalho e conferir peca. E o cabecalho repetia inteira a linha
   da fila que a pessoa acabou de tocar, o que no desktop e reforco e aqui e imposto.

   `@media` e nao `@container`: quem decide isto e a mesma largura que transforma a gaveta em
   folha (a regra da primitiva, no bloco de 560px), e a gaveta nao e contexto de consulta. A
   regra da LINHA continua em `@container` porque ali o eixo certo e a largura do corpo, que
   muda com a gaveta e nao com o aparelho. */
@media (max-width: 560px) {
  /* O "NO BALCAO AGORA" sai: no telefone a folha OCUPA a tela e cobre a fila, entao dizer que
     este e o atendimento atual e informar o que a pessoa nao tem como duvidar. No desktop ele
     fica, porque lá a fila continua visivel ao lado e o rotulo separa uma coisa da outra. */
  .req-seg-dw-head .req-seg-painel-eyebrow { display: none; }
  .req-seg-dw-head { padding: var(--space-3) var(--space-4); }
  .req-seg-quem h3 { font-size: 1.25rem; }
  /* Setor e numero em UMA linha: com 10px de gap e wrap eles quebravam em duas e o cabecalho
     ganhava 20px sem ganhar informacao. O setor cede (elipse) e o numero nao, porque numero
     truncado deixa de ser chave. */
  .req-seg-quem-meta { gap: 8px; font-size: .8rem; flex-wrap: nowrap; min-width: 0; }
  .req-seg-quem-meta > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  .req-seg-dw-body { padding: var(--space-3) var(--space-4); }
  /* A regua da conferencia encosta menos: `--space-5` de respiro existia para separar a lista
     do aviso de saldo num painel largo, e aqui ele custa uma linha de item. */
  .req-seg-conf { margin-top: var(--space-4); }

  .req-seg-dw-rail { padding: var(--space-3) var(--space-4); gap: var(--space-3); }
  /* O passo 2 quebrava em tres linhas. O texto NAO encurta (a consequencia legal e o motivo
     dele existir), so aperta: entrelinha e corpo menores devolvem ~14px sem cortar palavra. */
  .req-seg-dw-passo { font-size: .76rem; line-height: 1.3; }
  .req-seg-liberar { min-height: 56px; }
}

.req-seg-obs {
  margin: var(--space-4) 0 0; padding: 12px 16px;
  border: 1px solid var(--line-soft); border-left: 3px solid var(--brand-500);
  border-radius: var(--radius-sm); background: var(--bg-muted);
}
.req-seg-obs b {
  display: block; margin-bottom: 4px; color: var(--text-secondary);
  font-size: .64rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
}
.req-seg-obs p { margin: 0; font-size: .95rem; color: var(--text-primary); text-wrap: pretty; }

/* Itens que a pessoa leva mas não passam por aqui: uma linha, para o técnico não
   procurar ficha de algo que não tem ficha. */
.req-seg-extra {
  display: flex; align-items: center; gap: 8px; margin: var(--space-3) 0 0;
  font-size: .85rem; color: var(--text-secondary);
}
.req-seg-extra svg { width: 15px; height: 15px; flex: none; color: var(--success-500); }

/* A ação final: o maior botão da tela, sem ambiguidade — e VERDE, não azul de marca.
   Esta estação é um PORTÃO: o botão substitui a assinatura do técnico no papel e não
   tem desfazer. Pintado com a cor de marca ele lia como "Salvar", igual a qualquer
   outro botão do portal. O verde é a cor do selo, e ele só existe aqui. */
.req-seg-liberar {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; min-height: 64px; margin-top: var(--space-3); padding: 0 24px;
  border: 0; border-radius: var(--radius-md);
  background: var(--success-500); color: #fff; cursor: pointer;
  font-family: var(--font-display); font-size: 1.2rem; font-weight: 700;
  letter-spacing: -.01em; box-shadow: var(--shadow-1);
  transition: filter var(--trans-fast), transform var(--trans-fast);
}
.req-seg-liberar:hover:not(:disabled) { filter: brightness(1.08); }
.req-seg-liberar:active:not(:disabled) { transform: scale(.99); filter: brightness(.94); }
/* Desabilitado enquanto falta lançar item: some a cor de selo, para não parecer que
   basta apertar. Nunca é um beco — marcar o item é um toque, e a trava abaixo diz. */
.req-seg-liberar:disabled {
  background: var(--bg-muted); color: var(--text-secondary);
  box-shadow: none; cursor: not-allowed;
}
.req-seg-liberar svg { width: 24px; height: 24px; }

/* Recusar. A hierarquia carrega a informacao: liberar e o botao cheio de 64px porque e o
   caminho esperado; recusar e uma faixa discreta embaixo, na cor de perigo apenas no texto e
   na borda. Fundo preenchido de vermelho aqui seria pior que inutil — daria a dois gestos de
   frequencia muito diferente o mesmo peso visual, e o erro caro nesta tela e recusar por
   engano quem esta na frente do balcao esperando o EPI. */
.req-seg-recusar {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; min-height: 44px; margin-top: var(--space-2); padding: 0 16px;
  border: 1px solid color-mix(in srgb, var(--danger-500) 32%, var(--line-soft));
  border-radius: var(--radius-md);
  background: transparent; color: var(--danger-500); cursor: pointer;
  font-family: var(--font-display); font-size: .95rem; font-weight: 600;
  transition: background var(--trans-fast), border-color var(--trans-fast), transform var(--trans-fast);
}
.req-seg-recusar:hover:not(:disabled) {
  background: color-mix(in srgb, var(--danger-500) 8%, transparent);
  border-color: color-mix(in srgb, var(--danger-500) 52%, var(--line-soft));
}
.req-seg-recusar:active:not(:disabled) { transform: scale(.99); }
.req-seg-recusar:disabled { color: var(--text-secondary); border-color: var(--line-soft); cursor: not-allowed; }
.req-seg-recusar svg { width: 18px; height: 18px; }

/* O carimbo. Único movimento da estação, e de propósito: é o momento em que o ato
   acontece. Roda uma vez, ~430ms, antes de a pessoa sair da fila. */
/* Carimbo, nao pulso. A rotacao minuscula que ASSENTA em 0 e o que faz o gesto ler como
   algo prensado no papel em vez de um botao que piscou. Para publico nao tecnico um
   "pronto" inequivoco e usabilidade, nao enfeite: e o unico retorno de que a pessoa pode
   ir buscar o material. Amplitude pequena de proposito, porque a estacao e operacional. */
@keyframes reqSegSelo {
  0% { transform: scale(1) rotate(0); }
  38% { transform: scale(1.06) rotate(-.8deg); }
  70% { transform: scale(1.01) rotate(.35deg); }
  100% { transform: scale(1) rotate(0); }
}
@keyframes reqSegSeloIco {
  0% { transform: scale(.4) rotate(-14deg); opacity: 0; }
  55% { transform: scale(1.25) rotate(4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}
/* O carimbo vale para os DOIS atos da estacao desde 31/08. As keyframes so mexem em
   `transform` e `opacity`, entao a cor de cada ato e afirmada no bloco de baixo. Recusar
   tambem termina algo, e sem o carimbo o tecnico apertava, a pessoa sumia da fila e o unico
   retorno era um spinner que ja tinha ido. */
.req-seg-liberar.is-selado,
.req-seg-recusar.is-selado { animation: reqSegSelo 430ms ease-out both; opacity: 1; }
.req-seg-liberar.is-selado svg,
.req-seg-recusar.is-selado svg { animation: reqSegSeloIco 430ms cubic-bezier(.2, 1.3, .4, 1) both; }

/* O carimbo CARIMBA EM COR, e isto e correcao de 31/08. O botao e desabilitado durante a
   chamada (para nao registrar o ato duas vezes) e continua desabilitado quando o selo entra,
   entao o `:disabled` do bloco acima vencia e os dois atos carimbavam CINZA: o verde do
   portao e o vermelho da recusa apareciam desbotados no unico instante em que a cor importa.
   Sao 430ms, e e o unico retorno de que o ato foi registrado.

   `!important` porque a regra concorrente e o proprio `:disabled`, que precisa continuar
   valendo para o cursor e para o estado de trava (item de EPI ainda nao lancado). */
.req-seg-liberar.is-selado:disabled {
  background: var(--success-500) !important; color: #fff !important;
  box-shadow: var(--shadow-1) !important;
}
/* Recusar carimba PREENCHIDO de vermelho, e so aqui. Em repouso ele e discreto de proposito
   (ver o bloco do proprio botao acima, e a razao segue valendo); no instante do carimbo o ato
   ja aconteceu, e ai o vermelho cheio e a leitura correta. Nao ha "sera que pegou". */
.req-seg-recusar.is-selado,
.req-seg-recusar.is-selado:disabled {
  background: var(--danger-500) !important; color: #fff !important;
  border-color: var(--danger-500) !important;
  /* Sem transicao no carimbo: o botao em repouso tem `transition: background`, e interpolar
     de `transparent` ate o vermelho passa por tons translucidos escuros, o que aparece como
     um lampejo cinza no comeco dos 430ms — exatamente o defeito que este bloco corrige. O
     carimbo tem de chegar pronto e deixar o movimento para a keyframe, que mexe so em
     `transform`. */
  transition: none !important;
}

/* A trava (e, no erro, a falha) fica JUNTO da ação, não só num toast que some: quem
   está no balcão pode ter olhado para o lado no segundo em que o toast passou. */
.req-seg-trava {
  display: flex; align-items: flex-start; gap: 8px; margin: 10px 0 0;
  font-size: .88rem; color: var(--text-secondary);
}
.req-seg-trava[hidden] { display: none; }
.req-seg-trava svg { width: 17px; height: 17px; flex: none; margin-top: 1px; color: var(--warning-500); }
.req-seg-trava.is-erro { color: var(--danger-600, var(--danger-500)); font-weight: 600; }
.req-seg-trava.is-erro svg { color: var(--danger-500); }

/* Este bloco era UM e media DUAS coisas: as duas primeiras regras são internas da ficha
   (resolvem contra o palco), as duas últimas são da linha da fila. Com a fila virando
   contexto elas passariam a resolver contra a fila de qualquer jeito, então a divisão só
   escreve o que já ia acontecer, em vez de deixar o leitor descobrir na tela. */
@container (max-width: 640px) {
  .req-seg-quem h3 { font-size: 1.4rem; }
}
/* Coluna estreita compacta o selo de contagem: 4px de padding e uma fonte menor devolvem
   largura ao nome, que é o que a linha existe para dizer. */
@container segfila (max-width: 640px) {
  .req-seg-pessoa-itens { padding: 6px 10px; font-size: 1rem; }
  .req-seg-pessoa-curso { display: none; }
}

/* Movimento é opcional; a estação não é. Com reduced-motion tudo aparece no lugar
   final — o JS também pula a espera do carimbo, então o fluxo fica mais rápido, não
   quebrado. */
@media (prefers-reduced-motion: reduce) {
  .req-seg-pessoa.is-entrando,
  .req-seg-liberar.is-selado,
  .req-seg-liberar.is-selado svg,
  .req-seg-recusar.is-selado,
  .req-seg-recusar.is-selado svg { animation: none; }
  .req-seg-pessoa:active,
  .req-seg-liberar:active:not(:disabled),
  .req-seg-recusar:active:not(:disabled) { transform: none; }
}

/* ── Ficha (coluna direita) ── */

.req-alm-ficha {
  display: flex; flex-direction: column;
  background: var(--bg-surface); border: 1px solid var(--line-soft);
  border-radius: var(--radius-md); box-shadow: var(--shadow-1);
  max-height: 82vh; overflow-y: auto;
}
.req-alm-fhead { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--line-soft); }
/* "Voltar à fila" só existe quando a ficha é overlay (painel estreito). */
.req-alm-back { display: none; }
.req-alm-fhead-row { display: flex; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap; }
.req-alm-fnum { min-width: 0; }
.req-alm-fnum small {
  display: block; font-size: .66rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-secondary);
}
.req-alm-fnum b {
  display: block; margin-top: 4px; font-family: var(--font-mono);
  font-size: 2.05rem; font-weight: 600; line-height: 1.1; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; color: var(--text-primary);
}
.req-alm-facts { margin-left: auto; display: flex; gap: var(--space-2); flex-wrap: wrap; }
.req-alm-facts button { display: inline-flex; align-items: center; gap: 7px; }
.req-alm-facts svg { width: 16px; height: 16px; }

/* Faixa-semáforo: diz o que FAZER, não só o que é. */
.req-alm-band {
  display: flex; align-items: center; gap: var(--space-3);
  margin: var(--space-4) var(--space-5) 0; padding: 13px 15px;
  border: 1px solid var(--line-soft); border-left: 6px solid var(--line-soft);
  border-radius: var(--radius-sm); background: var(--bg-muted);
}
.req-alm-band svg { width: 22px; height: 22px; flex: none; }
.req-alm-band strong { display: block; font-family: var(--font-display); font-size: 1rem; font-weight: 700; }
.req-alm-band small { display: block; margin-top: 2px; font-size: .82rem; color: var(--text-secondary); text-wrap: pretty; }
.req-alm-band.is-ready {
  color: color-mix(in srgb, var(--success-500) 72%, #000);
  border-color: color-mix(in srgb, var(--success-500) 34%, transparent);
  border-left-color: var(--success-500);
  background: color-mix(in srgb, var(--success-500) 9%, var(--bg-surface));
}
.req-alm-band.is-short {
  color: color-mix(in srgb, var(--warning-500) 78%, #000);
  border-color: color-mix(in srgb, var(--warning-500) 36%, transparent);
  border-left-color: var(--warning-500);
  background: color-mix(in srgb, var(--warning-500) 10%, var(--bg-surface));
}
.req-alm-band.is-missing {
  color: var(--danger-500);
  border-color: color-mix(in srgb, var(--danger-500) 30%, transparent);
  border-left-color: var(--danger-500);
  background: color-mix(in srgb, var(--danger-500) 7%, var(--bg-surface));
}
.req-alm-band.is-done, .req-alm-band.is-canceled, .req-alm-band.is-unknown { color: var(--text-primary); border-left-color: var(--text-secondary); }
.req-alm-band.is-lg { padding: 16px 18px; border-left-width: 8px; border-radius: var(--radius-md); }
.req-alm-band.is-lg svg { width: 30px; height: 30px; }
.req-alm-band.is-lg strong { font-size: 1.3rem; font-weight: 800; letter-spacing: -.02em; }
.req-alm-band.is-lg small { font-size: .88rem; }

/* Contexto com células opcionais de Segurança, retirante e integração. */
.req-alm-ctx {
  /* FLEX e não grid, e a razão é a última linha. As células variam de 5 a 8 (Esperando,
     Entrega para e Segurança são condicionais) e com trilha fixa só a contagem 8 fechava
     exato: 5, 6 e 7 deixavam trilha vazia. As divisórias moraram no fundo do container até
     02/09, o que pintava esse vazio de escuro; passa-las para a célula (`box-shadow`) tirou
     o bloco escuro mas deixou o vazio do MESMO cinza das células, ou seja o card virou uma
     mancha só. Com `flex-wrap` + `flex: 1 1 140px` a base continua igual em todas (as
     colunas seguem alinhadas) e a última linha ESTICA em vez de expor fundo. */
  display: flex; flex-wrap: wrap; gap: 1px;
  margin: var(--space-3) var(--space-5) 0; background: var(--bg-muted);
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm); overflow: hidden;
  /* `flex: none` pela MESMA razao que a `.req-alm-row` acima, e a armadilha aqui e ainda
     mais silenciosa. A `.req-alm-ficha` e flex column com `max-height: 82vh`; nenhum dos
     nove filhos declara `flex`, logo todos sao `flex-shrink: 1`. O `min-height: auto`
     normalmente barraria a compressao, MAS um item flex que e scroll container
     (`overflow` != `visible`) tem tamanho minimo automatico ZERO. Esta regra e a
     `.req-alm-itens` sao os dois unicos filhos com `overflow: hidden` (que aqui existe
     so para o raio recortar o grid de gap 1px), entao TODO o espaco negativo era absorvido
     pelas duas — e recortado no meio da linha.
     Medido na requisicao 500899103, painel largo e janela de 900px: a tira perdia 175px e
     a tabela de itens 599px. E como o flex resolve o layout exatamente na altura do teto,
     o `overflow-y: auto` da ficha ficava com `scrollHeight == clientHeight` e NUNCA
     gerava barra: nao havia como rolar ate o que foi cortado. Parecia dado que sumiu.
     Nao limpar esta declaracao: sem ela o centro de custo volta a ser decapitado. */
  flex: none;
}
.req-alm-ctx-cell { display: flex; flex-direction: column; gap: 3px; flex: 1 1 140px; padding: 10px 13px; background: var(--bg-muted); box-shadow: 0 0 0 1px var(--line-soft); min-width: 0; }
.req-alm-ctx-cell small { font-size: .62rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-secondary); }
/* Sem `overflow: hidden` + `text-overflow: ellipsis` aqui: os dois estavam nesta regra
   e eram INERTES, porque elipse exige `white-space: nowrap` e nao havia. O texto so
   quebrava linha. Em repouso quebrar linha e o certo (a celula da Seguranca carrega
   "14:32 . Nome de quem liberou", e truncar perderia o nome); truncar em uma linha so
   faz sentido quando altura e escassa, e por isso o nowrap vive no bloco de paisagem
   curta acima, nao aqui. */
.req-alm-ctx-cell b { font-size: .9rem; font-weight: 700; color: var(--text-primary); }
.req-alm-ctx-cell b.is-mono { font-family: var(--font-mono); font-weight: 600; font-variant-numeric: tabular-nums; }

.req-alm-itens-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap; margin: var(--space-5) var(--space-5) var(--space-2);
}
.req-alm-itens-head h3 { margin: 0; font-family: var(--font-display); font-size: 1.05rem; font-weight: 700; }
.req-alm-itens-head span { font-size: .78rem; color: var(--text-secondary); }
/* `flex: none`: o outro filho colapsavel da ficha — ver o bloco longo na `.req-alm-ctx`.
   Sendo o filho mais alto, era ele que absorvia a maior parte do encolhimento. */
.req-alm-itens { flex: none; margin: 0 var(--space-5); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); overflow: hidden; }

/* Itens — tabela de verdade: o CÓDIGO alinhado em coluna é o que se varre na estante. */
.req-alm-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.req-alm-table thead th {
  padding: 8px 12px; background: var(--bg-muted); border-bottom: 1px solid var(--line-soft);
  font-size: .62rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--text-secondary); text-align: left;
}
.req-alm-table tbody td { padding: 10px 12px; border-top: 1px solid var(--line-soft); vertical-align: middle; }
.req-alm-table tbody tr:first-child td { border-top: 0; }
.req-alm-table tbody tr.is-short td { background: color-mix(in srgb, var(--warning-500) 6%, transparent); }

/* Coluna de foto: `width: 1%` como as outras colunas rigidas — a celula mede os 48px do
   `.req-alm-thumb` e o resto da largura sobra para a DESCRICAO. */
.req-alm-c-foto { width: 1%; }
.req-alm-c-cod { width: 1%; white-space: nowrap; }
.req-alm-cod {
  font-family: var(--font-mono); font-size: .82rem; font-weight: 600;
  color: var(--text-primary); font-variant-numeric: tabular-nums;
}
.req-alm-cod.is-empty { color: var(--text-secondary); font-weight: 400; }
.req-alm-c-desc { min-width: 0; }
.req-alm-desc { color: var(--text-primary); text-wrap: pretty; }
.req-alm-chips { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 5px; }
.req-alm-chips:empty { display: none; }
.req-alm-tam {
  display: inline-flex; align-items: center; padding: 1px 9px; border-radius: 6px;
  background: var(--bg-muted); border: 1px solid var(--line-soft);
  font-size: .74rem; font-weight: 700; color: var(--text-primary);
}
.req-alm-lack {
  display: inline-flex; align-items: center; gap: 5px; padding: 1px 9px; border-radius: 6px;
  background: color-mix(in srgb, var(--warning-500) 14%, var(--bg-surface));
  border: 1px solid color-mix(in srgb, var(--warning-500) 36%, transparent);
  font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: color-mix(in srgb, var(--warning-500) 78%, #000);
}
.req-alm-lack svg { width: 12px; height: 12px; }
/* Os dois chips que substituem o "saldo sistema 304". O justo e NEUTRO de proposito: ele
   nao pede acao, so avisa que nao ha peca de reserva na estante se uma vier danificada.
   Pintar de ambar o colocaria no mesmo nivel de "faltam 2", que trava a entrega. */
.req-alm-just, .req-alm-nd {
  display: inline-flex; align-items: center; padding: 1px 9px; border-radius: 6px;
  background: var(--bg-muted); border: 1px solid var(--line-soft);
  font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-secondary);
}
.req-alm-just { cursor: help; color: var(--text-primary); }
.req-alm-nope {
  display: inline-flex; align-items: center; padding: 1px 9px; border-radius: 6px;
  background: color-mix(in srgb, var(--danger-500) 10%, var(--bg-surface));
  border: 1px solid color-mix(in srgb, var(--danger-500) 30%, transparent);
  font-size: .68rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--danger-500);
}
.req-alm-c-qtd { width: 1%; white-space: nowrap; text-align: right; }
.req-alm-c-qtd b { font-size: 1.05rem; font-weight: 700; font-variant-numeric: tabular-nums; font-family: var(--font-mono); }
.req-alm-c-qtd small { font-size: .66rem; color: var(--text-secondary); margin-left: 2px; }
.req-alm-c-saldo { width: 1%; white-space: nowrap; text-align: right; }
.req-alm-saldo {
  display: inline-flex; align-items: center; gap: 4px; justify-content: flex-end;
  font-family: var(--font-mono); font-weight: 600; font-variant-numeric: tabular-nums;
}
.req-alm-saldo.is-ok { color: var(--text-secondary); }
.req-alm-saldo.is-short { color: color-mix(in srgb, var(--warning-500) 78%, #000); }
/* Saldo igual ao pedido. Nao e falta, entao nao usa o ambar do `is-short`; e tambem nao e
   folga, entao nao pode ficar igual ao `is-ok`. Peso, e nao cor, e o que separa: o numero
   fica no tom do texto principal em vez do secundario. */
.req-alm-saldo.is-tight { color: var(--text-primary); }
.req-alm-saldo.is-unknown { color: var(--text-secondary); opacity: .6; font-weight: 400; }

.req-alm-obs {
  margin: var(--space-3) var(--space-5) 0; padding: 12px 14px;
  border: 1px solid var(--line-soft); border-left: 3px solid var(--brand-500);
  border-radius: var(--radius-sm); background: var(--bg-muted);
  font-size: .84rem; color: var(--text-secondary); text-wrap: pretty;
}

/* Comprovante digital de recebimento. Ele estava no HTML das duas telas com SETE classes e
   ZERO regra de CSS no projeto: o selo saia no tamanho bruto do SVG, os dois rotulos do
   botao ("ver comprovante" e "ocultar") apareciam ao mesmo tempo, `is-colapsado` nao fazia
   nada (o bloco nascia sempre aberto) e o botao caia no azul preenchido que todo botao sem
   variante herda. Mesmo defeito do aviso de nova requisicao, achado no mesmo dia.

   Vive em DOIS lugares: na ficha do balcao (o almoxarife acabou de entregar) e na linha
   retirada de Minhas (o colaborador querendo a prova). Por isso nada aqui pressupoe o
   contexto: sem largura fixa, sem posicao. */
.req-comprovante {
  margin-top: var(--space-4); padding: var(--space-3);
  border: 1px solid color-mix(in srgb, var(--success-500) 30%, transparent);
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--success-500) 7%, var(--bg-surface));
}
.req-comprovante-head {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: var(--space-3);
}
.req-comprovante-selo {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%;
  background: color-mix(in srgb, var(--success-500) 16%, transparent);
  color: color-mix(in srgb, var(--success-500) 82%, #000);
}
.req-comprovante-selo svg { width: 18px; height: 18px; }
.req-comprovante-tit { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.req-comprovante-tit b { font-size: .84rem; font-weight: 700; color: var(--text-primary); }
.req-comprovante-tit small { font-size: .75rem; color: var(--text-secondary); }
/* Botao de texto, no mesmo idioma do "Entendi" do aviso da fila: aqui ele so revela dado
   que ja esta na tela, entao competir com "Baixar entrega" seria hierarquia errada. */
.req-comprovante-toggle {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: .76rem; font-weight: 700; letter-spacing: .02em;
  color: color-mix(in srgb, var(--success-500) 82%, #000);
  min-height: 0; padding: 6px 10px; border-radius: var(--radius-sm);
  transition: background var(--trans-fast);
}
.req-comprovante-toggle:hover { background: color-mix(in srgb, var(--success-500) 12%, transparent); }
.req-comprovante-toggle:focus-visible { outline: 2px solid var(--success-500); outline-offset: 2px; }
/* Um rotulo por estado. Sem estas duas regras os dois textos apareciam juntos, o que fazia
   o botao ler como "ver comprovanteocultar". */
.req-comprovante .req-comprovante-toggle-abrir { display: none; }
.req-comprovante.is-colapsado .req-comprovante-toggle-abrir { display: inline; }
.req-comprovante.is-colapsado .req-comprovante-toggle-fechar { display: none; }
/* Linha que ABRACA o conteudo, e nao grade de colunas iguais. Medido com
   `repeat(auto-fit, minmax(150px, 1fr))`: tres fatos curtos ("500899003", dois nomes)
   ganhavam 414px de coluna cada um num painel de 1250px, e o dado ficava perdido no meio
   do vao. Em flex cada campo ocupa o que precisa e todos ficam lado a lado a esquerda; no
   estreito eles quebram sozinhos. */
.req-comprovante-corpo {
  display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5);
  margin: var(--space-3) 0 0; padding-top: var(--space-3);
  border-top: 1px solid color-mix(in srgb, var(--success-500) 20%, transparent);
}
.req-comprovante.is-colapsado .req-comprovante-corpo { display: none; }
.req-comprovante-corpo > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.req-comprovante-corpo dt {
  font-size: .64rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--text-secondary);
}
.req-comprovante-corpo dd {
  margin: 0; font-size: .86rem; font-weight: 600; color: var(--text-primary);
  overflow-wrap: anywhere;
}
.req-comprovante-corpo dd.is-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.req-alm-obs b {
  display: block; margin-bottom: 4px; color: var(--text-primary);
  font-size: .62rem; letter-spacing: .08em; text-transform: uppercase;
}
.req-alm-obs.is-canceled { border-left-color: var(--danger-500); background: color-mix(in srgb, var(--danger-500) 7%, transparent); }

/* Ações da ficha. Sticky no rodapé: em requisição longa o "Baixar" não pode escapar
   da dobra — é o gesto que fecha o atendimento no balcão. */
.req-alm-foot {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-top: auto; padding: var(--space-4) var(--space-5);
  border-top: 1px solid var(--line-soft); background: var(--bg-surface);
  position: sticky; bottom: 0;
}
.req-alm-foot-note { margin-left: auto; max-width: 290px; font-size: .78rem; color: var(--text-secondary); text-wrap: pretty; }

.req-alm-baixar {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  min-height: 52px; padding: 0 24px; border: 0; border-radius: var(--radius-sm);
  /* VERDE, nao o laranja do eixo de acao: decisao do Henrique depois de ver na tela.
     A cor passa a dizer a CONSEQUENCIA em vez de "isto e irreversivel". Verde conclui a
     entrega e casa com o "Liberar retirada" da estacao da Seguranca, que ja era verde de
     proposito para acompanhar o carimbo do selo: as duas pontas do fluxo (libera / entrega)
     passam a ler igual. O hover continua sendo o state-layer relativo global de
     components.css, que aprofunda a propria cor em vez de jogar slate por cima. */
  background: var(--success-500); color: #fff; cursor: pointer;
  font-family: var(--font-display); font-size: 1rem; font-weight: 700; letter-spacing: -.01em;
  box-shadow: var(--shadow-1);
}
.req-alm-baixar:disabled { opacity: .6; cursor: not-allowed; }
.req-alm-baixar svg { width: 19px; height: 19px; }

/* CTAs preenchidos do módulo (Gerar requisição / Baixar entrega). Ambos herdam o visual do
   botão global; o hover global (:where(...):hover em components.css) levanta 1px com sombra
   forte, e num botão grande isso "pula" e fica pesado (o "feio" relatado no Baixar entrega).
   Mantemos o realce de cor (overlay do hover global, que não mexemos) e trocamos o levantar
   por uma sombra estável; o clique conserva o micro-press global de 1px, que é centrado.
   Mesmo opt-out já usado em .req-mr-toggle:hover. Especificidade 0,3,0 vence o :where global. */
.req-generate:hover:not(:disabled),
.req-alm-baixar:hover:not(:disabled) { transform: none; box-shadow: var(--shadow-1); }

/* Cancelar é destrutivo: VERMELHO PREENCHIDO, por decisão do Henrique (24/08). Antes era
   outline, para não competir com a baixa; preenchido ele tem peso visual igual. O que segura
   o clique errado deixa de ser a discrição da cor e passa a ser o diálogo de confirmação, que
   além de confirmar EXIGE o motivo (ver confirmarCancelamento). Fica menor que a baixa em
   corpo de fonte e padding: mesma família de cor forte, hierarquia mantida pelo tamanho. */
.req-alm-cancelar {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 52px; padding: 0 20px; border: 0; border-radius: var(--radius-sm);
  background: var(--danger-500); color: #fff; cursor: pointer;
  font-size: .92rem; font-weight: 700;
  box-shadow: var(--shadow-1);
}
/* Mesmo opt-out do levantar-1px que a baixa usa: em botão grande o hover global "pula". */
.req-alm-cancelar:hover:not(:disabled) { transform: none; box-shadow: var(--shadow-1); }
.req-alm-cancelar:disabled { opacity: .6; cursor: not-allowed; }
.req-alm-cancelar svg { width: 16px; height: 16px; }

/* ── Modo Separação (foco) ────────────────────────────────────────────────────
   De pé, celular na mão, uma requisição por vez: alvos grandes e conferência item a
   item contra a prateleira. A marcação é apoio de separação — não vai para o ERP. */

.req-alm-foco { max-width: 820px; margin: 0 auto; }
.req-alm-foco-bar {
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  padding-bottom: var(--space-3); border-bottom: 1px solid var(--line-soft);
}
.req-alm-foco-pos { font-size: .8rem; font-weight: 600; color: var(--text-secondary); }
.req-alm-back.is-inline {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
  background: var(--bg-surface); color: var(--text-primary);
  font: inherit; font-weight: 600; cursor: pointer;
}
.req-alm-back.is-next { margin-left: auto; }
.req-alm-back.is-next svg { transform: rotate(180deg); }
.req-alm-back svg { width: 17px; height: 17px; }

.req-alm-band.is-lg { margin: var(--space-4) 0 0; }
.req-alm-foco-id {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-5);
}
.req-alm-fnum.is-lg b { font-size: 3rem; letter-spacing: -.03em; }
.req-alm-foco-who { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
.req-alm-foco-who b { font-size: 1rem; font-weight: 700; color: var(--text-primary); }
.req-alm-foco-who small { font-size: .84rem; color: var(--text-secondary); }
.req-alm-foco-who em { font-style: normal; font-size: .8rem; font-weight: 700; }

.req-alm-prog {
  margin-top: var(--space-4); padding: 13px 15px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm); background: var(--bg-surface);
}
.req-alm-prog-top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.req-alm-prog-top strong { font-family: var(--font-display); font-size: .95rem; font-weight: 700; }
.req-alm-prog-top span { font-family: var(--font-mono); font-size: .92rem; font-weight: 600; }
.req-alm-prog-top span.is-busy { color: var(--brand-500); }
.req-alm-prog-top span.is-ready { color: color-mix(in srgb, var(--success-500) 72%, #000); }
.req-alm-prog-top span.is-missing { color: var(--danger-500); }
.req-alm-prog-track {
  display: block; height: 10px; margin-top: 9px; border-radius: 999px;
  background: var(--bg-muted); overflow: hidden;
}
.req-alm-prog-fill { display: block; height: 100%; border-radius: 999px; background: var(--brand-500); transition: width var(--trans-base); }
.req-alm-prog-fill.is-ready { background: var(--success-500); }
.req-alm-prog-fill.is-missing { background: var(--danger-500); }

.req-alm-fitens { display: flex; flex-direction: column; gap: var(--space-3); margin-top: var(--space-3); }
/* Miniatura de produto das duas telas do almoxarifado. A camera mora ATRAS da foto (mesma
   construcao da tira da Seguranca): imagem que falha deixa a celula de pe em vez de
   colapsar a coluna e desalinhar as linhas vizinhas.

   `object-fit: contain` e nao `cover`: em EPI a silhueta inteira e o que identifica a peca,
   e cortar a bota para preencher o quadrado tira justamente o bico. */
.req-alm-thumb {
  position: relative; flex: none; overflow: hidden;
  width: 48px; height: 48px; padding: 0; margin: 0;
  border: 1px solid var(--line-soft); border-radius: 10px; background: var(--bg-muted);
}
.req-alm-thumb-vazio { position: absolute; inset: 0; display: grid; place-items: center; color: var(--text-secondary); }
.req-alm-thumb-vazio svg { width: 18px; height: 18px; }
/* SEM FOTO. O ícone de câmera dentro de uma moldura, encostado em fotos de verdade, lia
   como imagem que falhou em carregar, e é o que estava incomodando na tela. As iniciais do
   produto ocupam a mesma pegada (a coluna não se move) e leem como identidade em vez de
   ausência. Fundo mais apagado que o `--bg-muted` da moldura com foto, de propósito: a
   ausência não deve competir em peso com quem tem imagem. */
.req-alm-thumb.is-sem-foto { background: color-mix(in srgb, var(--bg-muted) 55%, var(--bg-surface)); }
.req-alm-thumb-ini {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: .8rem; font-weight: 700; letter-spacing: .04em;
  color: var(--text-secondary); opacity: .75;
}
.req-alm-thumb img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; display: block; background: var(--bg-muted);
}
/* `is-zoom` e um <button>, entao precisa desligar heranca de botao (o portal da 44px de
   altura minima e padding a todo botao, e padding encolheria a area da imagem porque o
   `inset: 0` dos filhos resolve contra a caixa de padding). */
.req-alm-thumb.is-zoom {
  cursor: zoom-in; border-color: var(--line-soft); background: var(--bg-muted);
  min-height: 0; transition: border-color var(--trans-fast);
}
.req-alm-thumb.is-zoom:hover { border-color: var(--brand-500); }
.req-alm-thumb.is-zoom:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 2px; }

.req-alm-fitem {
  display: grid; grid-template-columns: var(--alm-thumb, ) minmax(0, 1fr) 140px; gap: var(--space-4);
  align-items: center; padding: 13px 15px;
  border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--bg-surface);
}
/* 64px na tela de separar contra 48px na fila: aqui a tarefa e conferir a peca contra a
   bancada, na fila e so reconhecer a natureza do pedido. Nao vai a 148px porque a propria
   miniatura AMPLIA num toque, licao medida na Seguranca (o painel de 396px rolava 1.199px
   para conferir 7 pecas com foto grande). */
.req-alm-fitem.has-foto { --alm-thumb: 64px; }
.req-alm-fitem.has-foto .req-alm-thumb { width: 64px; height: 64px; align-self: center; }
.req-alm-fitem.is-ready { border-color: color-mix(in srgb, var(--success-500) 34%, transparent); background: color-mix(in srgb, var(--success-500) 8%, var(--bg-surface)); }
.req-alm-fitem.is-missing { border-color: color-mix(in srgb, var(--danger-500) 30%, transparent); background: color-mix(in srgb, var(--danger-500) 7%, var(--bg-surface)); }
.req-alm-fitem-info { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.req-alm-fitem-top { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.req-alm-fitem-top .req-alm-cod { font-size: 1rem; }
.req-alm-fitem-tam {
  display: inline-flex; align-items: center; padding: 3px 11px; border-radius: 8px;
  background: var(--text-primary); color: var(--bg-surface); font-size: .82rem; font-weight: 700;
}
.req-alm-fitem-qtd {
  display: inline-flex; align-items: center; padding: 3px 11px; border-radius: 8px;
  background: var(--bg-muted); border: 1px solid var(--line-soft);
  font-size: .82rem; font-weight: 700; color: var(--text-primary);
}
.req-alm-fitem-desc { margin: 0; font-size: .95rem; color: var(--text-primary); text-wrap: pretty; }
.req-alm-fitem-meta { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; font-size: .78rem; }
.req-alm-fitem-acts { display: flex; flex-direction: column; gap: 6px; }

.req-alm-sep {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 56px; border-radius: var(--radius-sm); cursor: pointer;
  border: 2px solid color-mix(in srgb, var(--success-500) 34%, transparent);
  background: var(--bg-surface); color: color-mix(in srgb, var(--success-500) 72%, #000);
  font: inherit; font-size: .95rem; font-weight: 700;
}
.req-alm-sep svg { width: 20px; height: 20px; }
.req-alm-sep.is-on { background: var(--success-500); border-color: var(--success-500); color: #fff; }
.req-alm-nao {
  min-height: 44px; border-radius: var(--radius-sm); cursor: pointer;
  border: 1px solid var(--line-soft); background: var(--bg-surface);
  color: var(--text-secondary); font: inherit; font-size: .82rem; font-weight: 600;
}
.req-alm-nao.is-on { background: var(--danger-500); border-color: var(--danger-500); color: #fff; }

/* Barra de ação do modo foco: a lista é longa e o gesto que fecha o atendimento
   precisa estar sempre ao alcance do polegar.

   STICKY, não fixed — mesmo padrão do .req-alm-foot acima. O portal desloca o
   conteúdo por grid-template-columns no .app-shell (layout.css), não por margem:
   um elemento fixed sai do fluxo do grid, resolve left:0 contra a viewport e
   aparece POR CIMA do rail de menus. Sticky fica no fluxo da coluna, então se
   alinha sozinho sem precisar saber a largura do rail (72px recolhido, 260px
   expandido) e sobrevive ao transform do view-enter, que quebra fixed. */
.req-alm-foco-acts {
  position: sticky; bottom: 0; z-index: 60;
  display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  background: var(--bg-surface); border-top: 1px solid var(--line-soft); box-shadow: var(--shadow-2);
}
.req-alm-foco-acts .req-alm-baixar { flex: 1 1 240px; min-height: 58px; font-size: 1.1rem; }
.req-alm-foco-acts .req-alm-cancelar { min-height: 58px; }

/* No mobile o rail vira .mobile-bottom-nav FIXA (z-index 100). Sem este recuo a
   barra gruda atrás dela e o "Baixar entrega" fica inalcançável. */
@media (max-width: 767px), (pointer: coarse) and (max-height: 500px) {
  .req-cart,
  .req-alm-foco-acts { bottom: calc(var(--bottom-nav-height) + var(--safe-area-bottom)); }
}

/* ── Painel estreito ─────────────────────────────────────────────────────────
   Uma coluna. A ficha deixa de ser vizinha e passa a ser destino: fica escondida
   até o almoxarife escolher uma requisição, e volta pela seta. */
/* 860px, nao 1000px. Medido no navegador: um tablet de 1024 de viewport entrega
   920px a aba, logo o limiar de 1000 colapsava o cockpit EXATAMENTE no aparelho
   que o almoxarifado vai usar, e a fila e a ficha nunca apareciam juntas. Em 920
   sobra espaco de folga para 312 + 576. */
@container (max-width: 860px) {
  .req-alm-grid { grid-template-columns: minmax(0, 1fr); }
  .req-alm-grid[data-open="1"] .req-alm-queue { display: none; }
  .req-alm-grid[data-open="0"] .req-alm-ficha { display: none; }
  .req-alm-ficha { max-height: none; }
  /* A volta e STICKY, e nao so visivel. No empilhado a ficha e a tela inteira e uma
     requisicao de 6 itens rola bem alem da primeira dobra: com o botao rolando junto,
     o almoxarife terminava a separacao e tinha de rolar tudo de volta para cima para
     achar como voltar a fila. Sticky no topo, ele volta de onde estiver.
     O fundo opaco e o negative margin/padding sao para a linha da lista nao aparecer
     por tras do botao enquanto passa. */
  .req-alm-back {
    display: inline-flex; align-items: center; gap: 7px; min-height: 44px; padding: 0 14px;
    border: 1px solid var(--line-soft);
    border-radius: var(--radius-sm); background: var(--bg-surface); color: var(--text-primary);
    font: inherit; font-weight: 600; cursor: pointer;
    position: sticky; top: 0; z-index: 3; margin: 0 0 var(--space-3);
    box-shadow: 0 6px 12px -8px rgb(15 23 42 / .28);
  }
  .req-alm-qlist { max-height: none; }
}

/* ── Balcao em painel MUITO estreito (celular e coletor) ─────────────────────
   O 860px acima resolve DUAS COLUNAS virando uma. Este resolve outra coisa: a barra de
   ferramentas e a faixa de contadores empilhando ate empurrar a fila para fora da tela.
   Medido num coletor de 320x480, onde o painel recebe 296px: a barra media 204px em
   quatro linhas (busca, saldo, selo, Separadores) e os contadores 125px em duas, e o
   primeiro cartao da fila comecava a 663px. Numa tela de 480.

   420px, e o numero saiu de medicao (comecei em 520 e o tablet mostrou que era demais).
   Num painel de 456px o arranjo natural nao e pior: a barra empilha nas mesmas tres linhas
   (156px contra os 148 daqui, empate pratico) e os quatro contadores cabem numa linha de
   74px com 104px cada, ou seja o rotulo inteiro sem cortar, contra os 96px da grade 2x2.
   Somando, o natural sai 14px na frente ali, e regra que nao melhora nada nao deve existir.
   Abaixo de 420 e o contrario: sem estas regras a barra vai a QUATRO linhas (204px) e o
   rotulo "NA SEGURANCA" nao caberia em nenhum arranjo automatico. */
@container (max-width: 420px) {
  .req-alm { gap: var(--space-3); }
  .req-alm-toolbar { gap: var(--space-2); }

  /* Busca e selo com uma LINHA CADA, e nao dividindo linha:
     - a busca porque digitar numero de requisicao num campo de 140px e pior que a linha;
     - o selo porque ele carrega o NOME de quem esta separando, e nome cortado com
       reticencias ("MARIA APARECIDA DA S...") derrota a razao de o selo existir, que e o
       nome errado ser visto antes de o material sair.
     O chip de saldo e o botao Separadores dividem a terceira linha (148 + 137 + 8 = 293
     nos 296px do coletor), e caem para linhas proprias sozinhos se o painel for menor. */
  .req-alm-search { flex: 1 1 100%; }
  .req-alm-operador { flex: 1 1 100%; min-height: 44px; }

  /* O chip de saldo e o botao Separadores dividem a terceira linha, e o `flex-basis: 0` do
     chip e o que GARANTE isso.
     A tentativa obvia (deixar os dois encolherem, `flex: 0 1 auto`) nao funciona, e o
     motivo e a ordem das operacoes do flexbox: a linha e QUEBRADA primeiro, pelo tamanho
     natural dos itens, e so depois o que ficou na linha encolhe. Ou seja, encolher nunca
     evita uma quebra. Medido ao vivo: 151 do chip + 138 do botao + 8 de gap = 297 num
     painel de 296, e o botao caia para uma quarta linha. Um pixel, e a causa foi o relogio
     passar de "11:22" para "11:52" (digitos de larguras diferentes).
     Com base 0 o chip entra na conta da quebra pelo `min-width` (84px), sobra folga de
     sempre, e depois ele CRESCE para ocupar o que restou da linha. O piso de 84px tambem e
     a valvula: numa conta de coordenador, onde existe um terceiro botao ("Gerenciar
     almoxarifes"), a soma volta a nao fechar e a barra quebra de novo, mas o chip quebra
     LEGIVEL em vez de virar uma tira de 4px. */
  /* Fonte e respiro menores: com os 150px que sobram na linha, na tipografia cheia o texto
     precisava de 100px num espaco de 99 e as reticencias comiam justamente a HORA
     ("Saldo lido as 11:..."), que e a unica coisa que o chip tem para dizer. Aqui ele pede
     ~92 num espaco de ~107. As reticencias ficam como rede, nao como regra. */
  .req-alm-fresh {
    flex: 1 1 0; min-width: 84px; overflow: hidden;
    font-size: .7rem; padding: 8px 10px; gap: 4px;
  }
  .req-alm-fresh > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .req-alm-gerenciar { flex: 0 1 auto; min-width: 0; }
  .req-alm-gerenciar span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* Contadores em GRADE 2x2, e nao empilhando por acaso. Com o piso de 92px em quatro
     botoes, tres cabiam na linha e o quarto ("todas") caia sozinho numa segunda linha de
     52px: 125px de altura para quatro numeros.

     Tentei antes uma LINHA UNICA com piso zero, e foi medido como pior: cada botao ficava
     com 64px e o rotulo "NA SEGURANCA" mede 69px de min-content (palavra que nao quebra),
     ou seja o texto vazava por cima do botao vizinho. Reduzir a fonte para caber levaria o
     rotulo a ~9px de altura, ilegivel num coletor de chao de fabrica. Rolagem horizontal
     tambem esta descartada, pelo motivo ja registrado na grade de contexto da ficha:
     ninguem procura conteudo para o lado.

     A grade fixa da 135px por botao e o rotulo volta a caber numa linha na fonte cheia.
     Dentro do botao o numero e o rotulo ficam LADO A LADO, e nao empilhados: empilhado o
     botao media 59px e a faixa de 2x2 saia em 126px, ou seja a grade nao devolvia altura
     nenhuma (a base media 125). Deitado o botao fecha nos 44px do alvo de toque e a faixa
     cai para 96px. */
  .req-alm-counts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .req-alm-count {
    min-height: 44px; padding: 6px 10px;
    flex-direction: row; align-items: center; gap: 8px;
  }
  .req-alm-qhead { padding: var(--space-2); }

  /* "Mais antiga na fila: 30 min . 500882231. Atender de cima para baixo." custa 55px de
     tres linhas e descreve a LINHA LOGO ABAIXO dela: a fila e FIFO e cada linha ja carrega
     o mesmo numero e a mesma idade num selo proprio. Num painel largo isso e reforco util;
     em 296px e a mesma informacao duas vezes, empurrando a fila para fora da tela.
     A outra nota ("Mostrando as N mais antigas de M") FICA: ela nao esta escrita em lugar
     nenhum, e sem ela a fila cortada parece a fila inteira. */
  .req-alm-qnote.is-antiga { display: none; }

  /* "1a de 5 na fila" media 120px entre dois botoes de 98 e 105: a soma passava de 296 e a
     linha de navegacao do foco virava duas, 69px. Encolhendo o rotulo ele quebra em duas
     linhas DENTRO da altura dos botoes e a barra volta aos 44px do alvo de toque. */
  .req-alm-foco-pos { flex: 1 1 0; min-width: 0; font-size: .72rem; text-align: center; }

  /* A banda de estado perde a segunda linha SO no caso bom. Em "pronta para separar" ela diz
     "Os N itens tem saldo no deposito. Entrega e tudo ou nada", que e tranquilizacao, e a
     regra do tudo-ou-nada reaparece no dialogo da baixa, no momento em que decide. Nos
     outros tons a segunda linha e o motivo do BLOQUEIO (falta de saldo, falta o selo da
     Seguranca) e continua inteira: e a unica explicacao que a pessoa tem na tela. */
  .req-alm-foco .req-alm-band.is-ready small { display: none; }
}

/* ── Modo SEPARACAO em painel de uma coluna ──────────────────────────────────
   640px, e nao os 420 do bloco acima, porque a pergunta aqui e outra: nao e se os
   controles cabem lado a lado, e se o atendimento virou a tela inteira. E o MESMO limiar
   que o JS usa para abrir o modo Separacao direto ao tocar a requisicao (`painelUmaColuna`),
   e os dois precisam concordar: abrir o modo e continuar mostrando a barra da fila em cima
   dele seria trocar um problema por outro.

   Medido no coletor de 320x480: os 49px das abas mais os 148px da barra empurravam o
   atendimento inteiro (banda, progresso, cartoes dos itens) para BAIXO da barra de acao
   grudada no rodape. A tela mostrava a busca da fila e o botao verde, e nada do meio, que
   e justamente o que a pessoa tem de conferir na prateleira.

   A busca, o chip de saldo e o cadastro de separadores sao controles da LISTA, e aqui a
   lista ja foi resolvida. As abas saem porque o proprio modo tem um botao "Fila" na
   primeira linha, e duas voltas diferentes na mesma tela e uma a mais.

   O SELO fica. Ele e a razao de a feature existir: o nome errado tem de aparecer ANTES de
   o material sair, e a baixa acontece daqui.

   `:has` porque a barra vem ANTES do corpo no DOM e nao existe seletor de irmao anterior.
   Mesmo recurso que o modulo ja usa em `.form-grid:has(.req-regra-form)`. */
@container (max-width: 640px) {
  .req-alm:has(.req-alm-foco) .req-alm-search,
  .req-alm:has(.req-alm-foco) .req-alm-fresh,
  .req-alm:has(.req-alm-foco) .req-alm-gerenciar,
  .req-alm:has(.req-alm-foco) .req-alm-tabs { display: none; }
}

/* A faixa de acao de tela baixa da Seguranca (uma @media de altura que virava o trilho
   empilhado em barra fixa no rodape) saiu em 27/08 junto com o painel. O problema que ela
   resolvia era "Liberar retirada nasce a 1.252px de rolagem", e na gaveta ele nao existe
   mais em nenhuma altura: `.req-seg-dw-rail` gruda no pe da gaveta sempre, em qualquer
   janela, sem consulta de altura. Uma solucao a menos para o proximo leitor conferir. */

/* ── Estação Segurança em painel ESTREITO ────────────────────────────────────
   Este bloco perdeu quase tudo em 27/08, e o motivo e bom: ele existia para orquestrar o
   colapso de DUAS colunas em uma (esconder a fila, esconder a busca, o painel perdendo a
   moldura, o voltar virando navegacao sticky). Com a ficha em gaveta a tela tem UMA coluna
   em qualquer largura, entao nao ha mais colapso para orquestrar: a gaveta cuida do estreito
   sozinha, virando bottom sheet pela regra que as outras duas gavetas do modulo ja usam.

   O limiar continua @container e nao @media porque o portal pode dar ~470px de largura a
   aba num monitor de 1440px: a viewport nao diz nada sobre o espaco real. */
@container segpane (max-width: 860px) {
  /* Três contadores em 44px de altura cada não caberiam lado a lado num painel estreito
     sem virar texto de duas linhas: eles passam a dividir a largura em duas colunas. */
  .req-seg-count { flex: 1 1 128px; }
}

/* ── Tela BAIXA em paisagem (tablet e laptop deitados) ───────────────────────
   O relato: "o pessoal vai pegar o tablet, usar ele de lado, e no almoxarifado fica
   tudo cortado. Voce entra em itens da requisicao, ta tudo cortado. Seguranca,
   integracao Senior, ta tudo cortado tambem."

   A causa nao e largura, e ALTURA, e por isso nenhuma das 14 quebras deste arquivo
   pegava o caso. Num tablet de 1024 em paisagem o navegador entrega ~600px de altura,
   e a ficha e uma caixa com rolagem propria travada em `max-height: 82vh`, ou seja
   ~490px. Dentro dela cabem cabecalho, banda de estado, grade de contexto, cabecalho
   dos itens, tabela e rodape: conteudo de ~800px num buraco de 490. As duas coisas
   que ele citou sao o MESMO defeito. A grade de contexto, com minmax(140px) numa
   coluna de ~576px, cabe 4 celulas por linha, e as duas que sobram (justamente
   Seguranca e Integracao Senior) caem numa segunda linha abaixo da dobra DA CAIXA.
   "Itens da requisicao cortado" e a tabela disputando os ~200px que restam.

   A largura aqui esta CERTA e nao muda: 920px fica acima do limiar de 860, entao o
   cockpit segue em duas colunas, que e o desejado no balcao. O remedio e tirar a
   rolagem aninhada e deixar a pagina rolar, exatamente o que o ramo de painel
   estreito ja faz mais abaixo, pela mesma razao. O rodape continua sticky, entao o
   "Baixar entrega" segue alcancavel de onde a pessoa estiver.

   `@media` e nao `@container`, contra a convencao do resto do arquivo, e de proposito:
   altura nao tem equivalente em container query sem `container-type: size`, que traria
   contencao de layout na aba inteira. E o eixo certo e mesmo a janela: o corte vem de
   quanto o APARELHO oferece de altura, nao de quanto a aba recebeu de largura.
   O `min-width: 768px` exclui celular deitado, que ja tem tratamento proprio. */
@media (max-height: 760px) and (min-width: 768px) {
  .req-alm-ficha { max-height: none; overflow-y: visible; }
  .req-alm-qlist { max-height: none; }

  /* Contexto continua QUEBRANDO linha, so mais apertado: 3 por linha em vez de 4.
     Tentei primeiro uma linha unica com rolagem horizontal e ficou pior, medido em
     1024x600: scrollWidth 905 num clientWidth 673, ou seja Seguranca e Integracao
     Senior saiam da dobra de BAIXO e iam para a dobra da DIREITA, que e o mesmo
     defeito virado de lado (e pior, porque ninguem procura rolagem horizontal dentro
     de uma ficha). Com a rolagem aninhada da ficha removida logo acima, quebrar linha
     deixou de ser problema: a segunda linha agora esta na pagina, nao no fundo de uma
     caixa de 490px, e aparece rolando a pagina como todo o resto. */
  /* 200px e nao 115px, e o numero saiu de medicao, nao de gosto: com 115 a auto-fit
     punha 5 celulas por linha de 673px, os valores QUEBRAVAM dentro delas
     ("2010 . PRODUCAO - EXTRUSAO" em tres linhas) e o contexto inteiro subia de 76px
     para 186px. Estreitar a celula a engordou. Com 200 sao 3 por linha de ~224px, cada
     valor cabe numa linha so. 180 e nao 200 porque na tela larga (1280x700) a ficha
     divide espaco com a fila e sobram ~578px de contexto: com 200 dava 2 celulas por
     linha e TRES linhas; com 180 da 3 por linha e duas. Na tela de 1024, onde a ficha
     ocupa a aba inteira, os dois valores dao o mesmo resultado.
     Virou `flex-basis` quando o container passou a ser flex (ver a `.req-alm-ctx`): o
     numero e o mesmo e o efeito e o mesmo, porque com base igual em todas as celulas o
     flex quebra linha onde a trilha quebrava. */
  .req-alm-ctx-cell { flex-basis: 180px; padding: 7px 11px; gap: 1px; }

  /* Cabecalho do MODULO, e nao da ficha: aqui esta a maior devolucao de altura.
     Medido em 1024x600, 373 dos 600px de altura eram gastos antes de a ficha comecar,
     e 158 deles eram este header. O paragrafo de instrucao ("Peca uniformes, calcados
     e EPI pelo portal...") e onboarding do COLABORADOR: no balcao, em paisagem, quem
     esta na tela e o almoxarife, que sabe onde esta. `nowrap` para o botao de acao
     voltar a sentar ao lado do titulo em vez de descer uma linha inteira. */
  .req-head { flex-wrap: nowrap; padding-bottom: var(--space-2); }
  .req-head-sub { display: none; }
  .req-head-title { font-size: 1.15rem; }
  .req-head-icon { width: 34px; height: 34px; border-radius: 10px; }
  .req-head-icon svg { width: 18px; height: 18px; }

  /* Altura devolvida a tabela, que e o que a pessoa esta lendo. */
  .req-alm-fhead { padding-top: var(--space-3); padding-bottom: var(--space-3); }
  .req-alm-band { padding-top: 10px; padding-bottom: 10px; }
  .req-alm-itens-head { margin-top: var(--space-3); }

  /* Rodape mais raso. Ele media 134px porque a nota empurrava os botoes para a linha
     de baixo. A nota some, MENOS na variante `is-essencial`: quando falta o selo, ela e
     o unico lugar da ficha que diz ONDE a liberacao acontece (a banda de estado explica
     que esta bloqueado, nao quem destrava). Esconder as duas por igual economizaria 30px
     e deixaria o almoxarife sem saber o que esperar. */
  .req-alm-foot { padding-top: var(--space-3); padding-bottom: var(--space-3); }
  .req-alm-foot-note:not(.is-essencial) { display: none; }
  .req-alm-foot-note.is-essencial { font-size: .74rem; max-width: none; flex: 1 1 180px; }
  .req-alm-baixar { min-height: 46px; }
}

@container (max-width: 640px) {
  .req-alm-ctx-cell { flex-basis: calc(50% - 1px); }
  .req-alm-fnum b { font-size: 1.7rem; }
  .req-alm-fnum.is-lg b { font-size: 2.2rem; }
  .req-alm-facts { margin-left: 0; width: 100%; }
  .req-alm-facts button { flex: 1 1 auto; justify-content: center; }
  .req-alm-band, .req-alm-ctx, .req-alm-itens, .req-alm-obs { margin-left: var(--space-3); margin-right: var(--space-3); }
  .req-alm-itens-head { margin-left: var(--space-3); margin-right: var(--space-3); }
  .req-alm-fhead, .req-alm-foot { padding-left: var(--space-3); padding-right: var(--space-3); }
  /* Ações viram alvos cheios: o balcão é operado de pé, com uma mão. */
  .req-alm-foot { flex-direction: column-reverse; align-items: stretch; }
  .req-alm-baixar, .req-alm-cancelar { width: 100%; }
  /* `:not(.is-essencial)`: esta regra escondia a nota inteira, inclusive no caso sem selo
     da Seguranca, que e o unico em que ela diz ONDE a liberacao acontece. A banda de estado
     explica que esta bloqueado, nao quem destrava. */
  .req-alm-foot-note:not(.is-essencial) { display: none; }
  .req-alm-foot-note.is-essencial { margin-left: 0; max-width: none; }
  .req-alm-fitem { grid-template-columns: var(--alm-thumb, ) minmax(0, 1fr); }
  /* No estreito a foto CONTINUA, so menor: ela nao custa altura nenhuma nesta forma (fica
     ao lado do texto) e e no celular que reconhecer a peca rende mais. O que atravessa as
     duas colunas sao as acoes, que no estreito ja viram uma faixa de alvos cheios. */
  .req-alm-fitem.has-foto { --alm-thumb: 48px; }
  .req-alm-fitem.has-foto .req-alm-thumb { width: 48px; height: 48px; }
  .req-alm-fitem.has-foto .req-alm-fitem-acts { grid-column: 1 / -1; }
  .req-alm-fitem-acts { flex-direction: row; }
  .req-alm-fitem-acts > * { flex: 1 1 0; min-width: 0; }
  .req-alm-foco-id { align-items: flex-start; }
  .req-alm-foco-who { align-items: flex-start; text-align: left; }

  /* A tabela deixa de ser tabela e vira bloco por item. Motivo medido: as colunas
     nowrap (código + qtd + saldo) dão min-content > 375px e, com overflow:hidden
     no contêiner, o excedente era CORTADO em silêncio em vez de rolar. O código
     não pode truncar — é o que se procura na estante e o que a Segurança digita. */
  .req-alm-table, .req-alm-table tbody, .req-alm-table tr, .req-alm-table td { display: block; width: auto; }
  .req-alm-table thead { display: none; }
  .req-alm-table tbody tr { padding: 10px 12px; border-top: 1px solid var(--line-soft); }
  .req-alm-table tbody td { border: 0; padding: 0; }
  .req-alm-table .req-alm-c-cod { display: inline-block; width: auto; }
  .req-alm-table .req-alm-c-qtd { display: inline-block; width: auto; text-align: left; margin-left: 10px; }
  .req-alm-table .req-alm-c-saldo { display: inline-block; width: auto; text-align: left; margin-left: 10px; }
  .req-alm-table .req-alm-c-desc { display: block; margin-top: 3px; }
  /* Sem foto no modo bloco: aqui a linha ja e um paragrafo, e um thumb solto no topo dele
     empurra codigo e descricao para baixo sem ganhar leitura. Quem separa de pe com o
     telefone na mao usa o modo FOCO, que tem a foto em 64px e foi desenhado para isso. */
  .req-alm-table .req-alm-c-foto { display: none; }
  .req-alm-table .req-alm-saldo::before { content: 'saldo '; font-weight: 400; font-size: .72rem; opacity: .75; }
}

/* ── Motion: a bolha que voa do card ate o carrinho ──────────────────────────
   `position: fixed` e `body` como pai de proposito: a bolha atravessa o card, a
   grade e o painel, e qualquer ancestral com overflow ou containment a cortaria
   no meio do caminho. Some sozinha no fim da animacao (ver voarParaCarrinho). */
.req-fly {
  position: fixed; z-index: 300; pointer-events: none;
  border-radius: var(--radius-sm); overflow: hidden;
  background: var(--bg-surface); box-shadow: var(--shadow-2);
  display: grid; place-items: center;
}
.req-fly img { width: 100%; height: 100%; object-fit: contain; background: #fff; }
.req-fly .req-card-ph { position: static; color: var(--brand-500); opacity: .55; }
.req-fly .req-card-ph svg { width: 40px; height: 40px; }

/* ── Skeleton de carga ───────────────────────────────────────────────────────
   Substitui o spinner centralizado nas filas. O ganho nao e estetico: o spinner
   descartava a silhueta da lista e o olho tinha de se reorientar a cada carga.
   Reusa o vocabulario de shimmer que o portal ja tem em outros modulos. */
.req-skel {
  display: block; position: relative; overflow: hidden;
  border-radius: 7px; background: var(--bg-muted);
}
.req-skel::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .8), transparent);
  animation: reqSkel 1.35s infinite;
}
@keyframes reqSkel { 100% { transform: translateX(100%); } }
/* A linha fantasma nao e clicavel nem navegavel: e so a silhueta. */
.req-alm-row.is-skel { cursor: default; pointer-events: none; }
.req-alm-row.is-skel .req-alm-row-bar { background: var(--bg-muted); }
.req-alm-row.is-skel .req-alm-row-main { gap: 7px; }

/* Alvos de toque do stepper. 30px basta com mouse (o carrinho e denso de
   proposito), mas no toque os dois botoes ficam a 4px um do outro. */
@media (hover: none), (pointer: coarse) {
  .req-stepper button { width: 44px; height: 44px; }
  .req-stepper { gap: var(--space-2); }
  .req-cart-rm { min-width: 44px; min-height: 44px; }
}

/* -- Corpo dos dialogos do modulo -------------------------------------------
   Sem o prefixo de escopo `.requisicoes-view`, ao contrario de todo o resto do
   arquivo, e isso e obrigatorio: o `.modal-card` do ui.dialog e anexado ao
   <body>, fora da view. Pela mesma razao nao usa os tokens --rq-*, que sao
   declarados em `.requisicoes-view` e nao existem la. O prefixo `req-dlg-`
   sustenta o isolamento no lugar do seletor ancestral. */
.req-dlg-nota { margin: 0; color: var(--text-secondary); font-size: .92rem; line-height: 1.5; }

.req-dlg-falta {
  border: 1px solid color-mix(in srgb, var(--warning-500) 34%, var(--line-soft));
  border-left-width: 4px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warning-500) 7%, var(--bg-surface));
  padding: var(--space-3);
}
.req-dlg-falta + .req-dlg-falta { margin-top: var(--space-2); }
.req-dlg-falta-tit {
  display: block; margin-bottom: 7px;
  color: var(--warning-500); font-size: .74rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
}
.req-dlg-falta-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.req-dlg-falta-lista li {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3);
  color: var(--text-primary); font-size: .93rem; line-height: 1.4;
}
/* O numero em mono e tabular pela mesma assinatura numerica do resto do modulo:
   pedido e saldo sao lidos em comparacao, um embaixo do outro. */
.req-dlg-falta-num {
  flex: 0 0 auto; font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: .8rem; font-style: normal; color: var(--text-secondary); white-space: nowrap;
}
/* Celular: pedido/saldo desce para a linha de baixo em vez de espremer o nome. */
@media (max-width: 420px) {
  .req-dlg-falta-lista li { flex-direction: column; gap: 2px; }
}

@media print {
  .workspace-main > *:not(#requisicoesTab), .req-no-print, .req-cart { display: none !important; }
  #requisicoesTab *:not(.req-slip):not(.req-slip *):not(.req-success):not(.req-success *) { visibility: hidden; }
  .req-slip, .req-slip * { visibility: visible; }
}

/* ── Regras de curadoria do catalogo (3a sub-aba da estacao do almoxarifado) ─────────────
   A lista responde de relance "o que esta valendo hoje?": duas secoes contadas, o alcance
   medido de cada regra e o motivo escrito na propria linha. O alcance ZERO e pintado porque
   familia digitada errada e o erro de cadastro mais comum aqui, e ele nao tem outro sintoma.
   O dialogo reusa `.req-ccbusca-*` (o seletor de centro de custo do carrinho), que mora em
   escopo global e por isso alcanca o `.modal-card`. */

.req-regras { display: flex; flex-direction: column; gap: var(--space-5); }

.req-regras-top {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
}
.req-regras-lead { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.req-regras-lead strong { font-size: .95rem; }
.req-regras-lead span { font-size: .78rem; color: var(--text-secondary); max-width: 62ch; }
/* Botao preenchido de propriedade: e a unica acao que CRIA algo nesta estacao, e o
   `<button>` sem variante ja nasce preenchido no portal. So a caixa do icone entra aqui. */
.req-regras-nova { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.req-regras-nova svg { width: 15px; height: 15px; }

.req-regras-sec { display: flex; flex-direction: column; gap: var(--space-2); }
.req-regras-sechead { display: flex; flex-direction: column; gap: 1px; }
.req-regras-sechead h4 {
  margin: 0; display: flex; align-items: center; gap: 7px;
  font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--text-secondary);
}
.req-regras-sechead h4 svg { width: 14px; height: 14px; flex: none; }
.req-regras-sechead p { margin: 0; font-size: .78rem; color: var(--text-secondary); }
.req-regras-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 19px; height: 19px; padding: 0 5px;
  border-radius: 999px; background: var(--bg-muted); border: 1px solid var(--line-soft);
  font-size: .7rem; font-variant-numeric: tabular-nums; letter-spacing: 0; color: var(--text-primary);
}
.req-regras-vazia {
  padding: var(--space-4); border: 1px dashed var(--line-soft); border-radius: var(--radius-md);
  font-size: .8rem; color: var(--text-secondary);
}

.req-regras-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }

.req-regra {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, 1.4fr) 32px;
  grid-template-areas:
    "alvo ccs motivo del"
    "alvo ccs meta   del";
  align-content: start;
  gap: 2px var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  border: 1px solid var(--line-soft); border-radius: var(--radius-md);
  background: var(--bg-surface);
  transition: border-color var(--trans-fast), box-shadow var(--trans-fast);
}
.req-regra::before {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 3px;
  border-radius: var(--radius-md) 0 0 var(--radius-md);
  background: var(--line-strong, var(--line-soft));
}
/* A cor separa as leituras: restringir e um aviso de escopo (alguem fica de fora), ocultar e
   apagado de proposito (o item saiu de cena), e passar pela Seguranca e um DESVIO de caminho
   (o item continua a vista, so nao vai direto ao balcao). Nenhuma das tres e erro, entao
   nenhuma leva vermelho: `--danger-500` fica reservado para a acao de excluir.

   O tom da Seguranca e `--brand-500` porque e o que a estacao dela usa em toda a tela do
   almoxarifado (`.req-alm-seal.is-awaiting-sst`, `.req-alm-row.is-awaiting-sst`): a mesma
   coisa tem de ter a mesma cor nos dois lugares, senao a regra cadastrada aqui nao se parece
   com o efeito que ela produz la. */
.req-regra.is-restringe::before { background: var(--warning-500); }
.req-regra.is-seguranca::before { background: var(--brand-500); }
.req-regra:hover { border-color: var(--line-strong, var(--line-soft)); box-shadow: var(--shadow-1); }

.req-regra-alvo { grid-area: alvo; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; min-width: 0; }
.req-regra-escopo {
  font-size: .64rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-secondary);
}
.req-regra-alvo b { font-size: .86rem; overflow-wrap: anywhere; }
.req-regra-cod {
  font-family: var(--font-mono, monospace); font-size: .72rem;
  color: var(--text-secondary); font-variant-numeric: tabular-nums;
}
.req-regra-alcance {
  display: inline-flex; align-items: center; gap: 4px; flex-basis: 100%;
  font-size: .72rem; color: var(--text-secondary); font-variant-numeric: tabular-nums;
}
.req-regra-alcance svg { width: 13px; height: 13px; flex: none; }
.req-regra-alcance.is-zero { color: var(--danger-500); font-weight: 600; }

.req-regra-ccs { grid-area: ccs; display: flex; flex-wrap: wrap; align-content: start; gap: 4px; min-width: 0; }
.req-regra-cc {
  display: inline-flex; align-items: center; padding: 1px 7px;
  border-radius: 999px; border: 1px solid var(--line-soft); background: var(--bg-muted);
  font-size: .72rem; font-variant-numeric: tabular-nums;
}
.req-regra-ccs.is-na span { font-size: .72rem; color: var(--text-secondary); font-style: italic; }

.req-regra-motivo {
  grid-area: motivo; margin: 0; min-width: 0;
  font-size: .78rem; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-clamp: 2;
}
.req-regra-meta { grid-area: meta; font-size: .7rem; color: var(--text-secondary); }
/* `.btn-icon` do portal so reseta o padding e centraliza: quem usa PINTA o botao e dimensiona o
   proprio svg (`.req-qclear`, `.arquivos-info-close` e mais uma duzia fazem isso). Faltando as
   duas coisas, o svg media 0x0 (alvo de toque de 12px) e o botao herdava o fundo azul cheio da
   base, virando o elemento mais pesado da linha para a acao mais destrutiva dela.
   `min-height: 0` porque a base impoe 44px e deixaria um retangulo 32x44. */
.req-regra-del {
  grid-area: del; align-self: start; justify-self: end;
  display: grid; place-items: center;
  width: 32px; height: 32px; min-height: 0; padding: 0;
  border: none; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-secondary); cursor: pointer;
  transition: background var(--trans-fast), color var(--trans-fast);
}
.req-regra-del svg { width: 16px; height: 16px; }
/* Vermelho so no hover, e nunca em repouso: em repouso ele seria um alarme em cada linha de uma
   lista onde nada esta errado. */
.req-regra-del:hover {
  color: var(--danger-500);
  background: color-mix(in srgb, var(--danger-500) 10%, transparent);
}

@media (max-width: 1080px) {
  .req-regra {
    grid-template-columns: minmax(0, 1fr) 44px;
    grid-template-areas: "alvo del" "ccs del" "motivo del" "meta del";
    gap: 5px var(--space-2);
  }
  /* Estreito e o tablet do balcao: o alvo de toque vai a 44px, que e o minimo da diretriz e o
     que o resto da estacao ja pratica nos controles de dedo. */
  .req-regra-del { width: 44px; height: 44px; }
  .req-regra-motivo { -webkit-line-clamp: 3; line-clamp: 3; }
}

/* O dialogo de cadastro. Vive dentro do `.modal-card`, entao nada aqui pode depender de um
   ancestral da view. */
.req-regra-form { display: flex; flex-direction: column; gap: var(--space-4); }

.req-regra-tipos { margin: 0; padding: 0; border: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.req-regra-tipos legend {
  padding: 0 0 var(--space-2); font-size: .68rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--text-secondary);
}
/* Radio de verdade, e nao div com role: o teclado (setas, Tab, Espaco) e o leitor de tela
   ja tratam grupo de radio nativo, e aqui a escolha muda o resto do formulario. */
.req-regra-tipo {
  display: flex; align-items: flex-start; gap: var(--space-2);
  padding: var(--space-3); cursor: pointer;
  border: 1px solid var(--line-soft); border-radius: var(--radius-md); background: var(--bg-surface);
  transition: border-color var(--trans-fast), background var(--trans-fast);
}
.req-regra-tipo:hover { border-color: var(--line-strong, var(--line-soft)); }
/* O portal estiliza `input, select, textarea` como CAMPO DE TEXTO: largura 100%, borda e
   padding de 11px. Aplicado a um radio, isso vira uma barra da largura do cartao com a bolinha
   perdida no meio, e o texto ao lado colapsa para uma palavra por linha. Todo radio desta tela
   desfaz as tres coisas. */
.req-regra-tipo input[type="radio"],
.req-regra-escopos input[type="radio"] {
  flex: none; width: 16px; height: 16px; min-height: 0;
  padding: 0; border: none; background: none;
  accent-color: var(--brand-500);
}
.req-regra-tipo input[type="radio"] { margin: 1px 0 0; }
.req-regra-tipo-txt { flex: 1 1 auto; }
.req-regra-tipo:has(input:checked) {
  border-color: var(--brand-500);
  background: color-mix(in srgb, var(--brand-500) 6%, var(--bg-surface));
}
.req-regra-tipo:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--focus-ring); }
.req-regra-tipo-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.req-regra-tipo-txt strong { font-size: .84rem; }
.req-regra-tipo-txt span { font-size: .76rem; color: var(--text-secondary); }

.req-regra-campo { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.req-regra-campo > label,
.req-regra-campo-top label {
  font-size: .68rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-secondary);
}
.req-regra-campo-top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; }
.req-regra-escopos { display: inline-flex; gap: var(--space-3); }
.req-regra-escopos label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; font-size: .78rem; }

.req-regra-dica { margin: 0; font-size: .74rem; color: var(--text-secondary); }

.req-regra-busca,
#reqRegraMotivo {
  width: 100%; padding: 7px 10px; font: inherit; font-size: .82rem;
  color: var(--text-primary); background: var(--bg-surface);
  border: 1px solid var(--line-soft); border-radius: var(--radius-sm);
}
.req-regra-busca:focus,
#reqRegraMotivo:focus { outline: none; border-color: var(--brand-500); box-shadow: 0 0 0 3px var(--focus-ring); }

.req-regra-escolhido {
  margin: 0; padding: 5px 9px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface));
  border: 1px solid color-mix(in srgb, var(--brand-500) 32%, var(--line-soft));
  font-size: .78rem;
}

.req-regra-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.req-regra-chips .req-ccbusca-hint { margin: 0; text-align: left; }
.req-regra-chip {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 7px 3px 9px;
  border-radius: 999px; border: 1px solid color-mix(in srgb, var(--brand-500) 32%, var(--line-soft));
  background: color-mix(in srgb, var(--brand-500) 8%, var(--bg-surface));
  color: var(--text-primary); font-size: .74rem; cursor: pointer;
  transition: border-color var(--trans-fast), background var(--trans-fast);
}
.req-regra-chip strong { font-variant-numeric: tabular-nums; }
.req-regra-chip span { max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-secondary); }
.req-regra-chip svg { width: 12px; height: 12px; flex: none; }
.req-regra-chip:hover { border-color: var(--danger-500); background: color-mix(in srgb, var(--danger-500) 8%, var(--bg-surface)); }

/* A caixa de escolha do carrinho tem altura FIXA de 210px, porque la ela e a tela inteira do
   passo. Aqui sao duas caixas num formulario de quatro campos, e altura fixa deixava um vazio
   de 180px com uma familia na lista e empurrava o campo de setores para fora da area visivel.
   Aqui ela cresce com o conteudo e para em 210px, que e o mesmo teto de rolagem. */
.req-regra-form .req-ccbusca-res { height: auto; max-height: 210px; }
.req-regra-form .req-ccbusca-res:empty { display: none; }

/* Abaixo de 768px a `form-grid` do modal (components.css) tem UMA coluna de `1fr`, e `1fr` e
   `minmax(auto, 1fr)`: o piso da coluna e o min-content do campo. O nome do produto na lista de
   resultados nao quebra (e cortado com reticencias, como no carrinho), entao o piso ia a 456px
   dentro de um corpo de 327px e o modal rolava de lado num tablet de 375. `minmax(0, 1fr)`
   devolve o piso a zero e o corte por reticencias volta a funcionar. Escopo por `:has` para nao
   alcancar nenhum outro formulario do portal, no mesmo molde de `.cht-kb:has(> .cht-kb-doc)`.
   So aqui embaixo: a partir de 768px a grade tem tres colunas e o campo as atravessa com
   `field-span-3`, onde o piso se distribui e nao aparece. */
@media (max-width: 767px) {
  .form-grid:has(.req-regra-form) { grid-template-columns: minmax(0, 1fr); }
}


@media (prefers-reduced-motion: reduce) {
  /* A curadoria do catalogo nao anima nada por conta propria: aqui ficam so as
     transicoes de hover das linhas e dos cartoes de tipo. */
  .req-regra, .req-regra-tipo, .req-regra-chip, .req-regra-del { transition: none; }
  .req-card, .req-chip, .req-queue, .req-cart-body, .req-cart-toggle svg,
  .req-foto-tile, .req-drawer, .req-fotos-meter-fill { transition: none; }
  .req-spinner, .req-ticket, .req-cart-pill.is-pulse, .req-progress span { animation: none; }
  .req-mr-row, .req-mr-chip, .req-mr-btn { transition: none; }
  .req-alm-row, .req-alm-count, .req-alm-prog-fill { transition: none; }
  /* Novas pecas de motion. As animacoes via Web Animations API ja sao puladas no
     JS pelo gate de rqAnimate(); aqui ficam as declarativas. A bolha do voo nunca
     e criada com reduced-motion, mas a regra fica como cinto de seguranca. */
  .req-skel::after { animation: none; }
  .req-fly { display: none; }
  .req-drawer.is-open#reqHistDrawer > * { animation: none; }
}

/* ── Separadores do balcao (conta de estacao) ─────────────────────────────────── */

/* Nome de quem entrega, repetido DENTRO do dialogo de baixa: e a ultima chance de ver o
   nome errado, e quem confirma esta olhando exatamente para ca. */
.req-dlg-operador {
  margin: 0 0 var(--space-3); padding: 8px 12px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--brand-500) 9%, var(--bg-muted));
  border: 1px solid color-mix(in srgb, var(--brand-500) 22%, transparent);
  font-size: .85rem; color: var(--text-primary);
}

/* "informado no balcao" no comprovante. Rotulo deliberado: o documento diz substituir o
   papel assinado, e um nome autodeclarado num campo que parece assinatura seria lido como
   prova. Uma palavra impede isso. */
.req-comprovante-fonte {
  display: block; margin-top: 2px;
  font-size: .68rem; color: var(--text-secondary);
}

.req-oper-adm { display: flex; flex-direction: column; gap: var(--space-3); }
.req-oper-aviso {
  margin: 0; padding: 8px 12px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warning-500, #b45309) 10%, var(--bg-muted));
  font-size: .8rem; color: var(--text-secondary);
}
/* Sugestoes do RH: lista curta (limite 15 no servidor), logo abaixo da busca. */
.req-oper-sug { display: flex; flex-direction: column; gap: 2px; max-height: 34vh; overflow: auto; }
.req-oper-sug[hidden] { display: none; }
.req-oper-cand {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  width: 100%; padding: var(--space-2); border: 0; border-radius: var(--radius-sm);
  background: transparent; cursor: pointer; text-align: left; line-height: 1.25;
}
.req-oper-cand:hover { background: var(--bg-muted); }
.req-oper-cand span { font-weight: 600; font-size: .88rem; color: var(--text-primary); }
.req-oper-cand small { font-size: .74rem; color: var(--text-secondary); }
.req-oper-cand:disabled { opacity: .55; cursor: progress; }
