@charset "UTF-8";
/* =============================================================================
   E-BMM — SISTEMA VISUAL
   SaaS moderno, claro e arredondado — mesmo sistema do E-toto (tokens pw-*),
   régua de acabamento: Monday, Asana, ClickUp. Documentado em DESIGN.md.

   Três regras que governam tudo:
   1. SUPERFÍCIE FLUTUA — cartão branco sobre fundo cinza-azulado, canto
      arredondado e sombra difusa; separação por elevação, não por traço.
   2. ESTADO É PÍLULA SÓLIDA — o status do boletim é pílula de cor cheia com
      texto branco; o rótulo escrito é a redundância que não depende de cor.
   3. COR TEM DONO — azul = ação/navegação; verde/âmbar/vermelho = estado do
      boletim, nunca decoração; cinza = todo o resto.
   ============================================================================= */

:root {
    /* ---- Superfícies ---- */
    --pw-paper:      #F5F7FA;
    --pw-sheet:      #FFFFFF;
    --pw-vellum:     #F0F3F8;
    --pw-vellum-2:   #F8FAFC;

    /* ---- Texto ---- */
    --pw-ink:        #1C2333;
    --pw-ink-2:      #4E5875;
    --pw-ink-3:      #5C6580;
    --pw-ink-4:      #A3ABBF;
    --pw-ink-deep:   #10162A;

    /* ---- Bordas ---- */
    --pw-hair:       #EDF0F5;
    --pw-line:       #DFE4EE;
    --pw-heavy:      #C6CDDC;

    /* ---- A cor de um FORMATO DE ARQUIVO, e só dela ----------------------
       O verde do Excel. Ele NÃO é o verde de "aprovado" e não pode ser: pinta o ÍCONE de um
       botão de exportar, nunca um fundo, nunca um estado.

       POR QUE ISTO NÃO FERE A REGRA DAS QUATRO DONAS. A regra proíbe verde/âmbar/vermelho como
       decoração e como sinal de bom/ruim. Aqui a cor não diz nada sobre o dado: ela identifica
       o FORMATO do arquivo, do mesmo jeito que um logotipo identifica. É por isso também que
       ela é o verde da Microsoft e não o `--pw-safe` — usar o nosso verde de "aprovado" num
       ícone de planilha é que criaria a confusão que a regra existe para evitar.

       Ficou no ÍCONE e não no botão inteiro por decisão do Leandro (20/09/2026), depois de ver
       os dois renderizados: botão verde ao lado de botão vermelho, numa linha que já tem a
       pílula "Paga" em verde, vira três blocos de cor forte disputando a mesma atenção. */
    --pw-excel:      #1D6F42;

    /* O vermelho do PDF, pela MESMA razão do verde do Excel: ele pinta o ÍCONE de um botão de
       formato, nunca um fundo, nunca um estado. Não é o `--pw-danger` — usar o nosso vermelho de
       "rejeitado" num ícone de documento é que criaria a confusão que a regra das quatro donas
       existe para evitar. */
    --pw-pdf:        #B30B00;

    /* ---- Azul da marca (Buzzi #0E6CB5 no logo; UI na mesma família) ---- */
    --pw-notice:     #1570DB;
    --pw-notice-ink: #0F55A8;
    --pw-notice-bg:  #EAF2FE;

    /* ---- Estados do boletim — pílulas sólidas, texto branco ---- */
    --pw-danger:     #D1344B;  /* Rejeitado */
    --pw-danger-ink: #A8253A;  /* texto de erro sobre fundo lavado (contraste AA) */
    --pw-danger-bg:  #FDECEF;
    /* O ÂMBAR (spec 072). Era #9C5607 — no papel "âmbar escuro", no olho marrom. Ele ficou
       assim por mecânica, não por gosto: a pílula é sólida com texto BRANCO, e branco sobre
       âmbar só alcança 4,5:1 se o âmbar for escuro a esse ponto. Era a regra da pílula
       empurrando a cor.

       Agora são DOIS tokens, pelo mesmo desenho de `--pw-danger` / `--pw-danger-ink`, e a
       divisão é por PAPEL: `--pw-warn` pinta ÁREA (pílula, barra, fatia, marca de legenda) e
       `--pw-warn-ink` pinta GLIFO sobre fundo claro. Uma cor não serve aos dois usos: #D98A04
       como texto sobre branco dá 2,13:1. */
    --pw-warn:       #D98A04;  /* Em aprovação — preenchimento */
    --pw-warn-ink:   #8A5600;  /* âmbar como TEXTO sobre fundo claro (5,9:1) */
    --pw-warn-bg:    #FDF2E5;
    --pw-caution:    #8A6A00;  /* Contestado */
    --pw-caution-bg: #FDF7E3;
    --pw-safe:       #0F7B4F;  /* Aprovado */
    --pw-safe-bg:    #E8F6EF;
    --pw-idle:       #626B82;  /* Rascunho */
    --pw-idle-bg:    #F0F2F7;

    /* ---- O FUNDO LAVADO DAS PÍLULAS DE ETAPA (spec 090, 20/09/2026) ----------------------
       Treze pílulas sólidas e saturadas numa coluna só faziam a lista parecer um mostruário:
       "Paga" (desfecho bom), "Rejeitada" (desfecho ruim) e "Em análise" (andamento) tinham o
       MESMO peso visual, e o olho não sabia para onde ir primeiro. O tratamento passou a ser
       lavado — fundo claro, tinta escura e contorno de 1px.

       A MATIZ NÃO MUDOU, e isso é o ponto: a TINTA de cada pílula é o próprio token de cor da
       etapa (`--pw-safe`, `--pw-magenta`, `--pw-serie-2`…), e o que entra aqui é só o fundo
       claro da mesma família. Qual etapa tem qual cor continua sendo decisão da spec 033, e o
       dono continua sendo o `CoresDaEtapa` no C#.

       Cada fundo é declarado com o contraste da tinta que vai em cima, medido — é a régua da
       regra 10 da 090, e 4,5:1 é o piso porque a pílula é 12px em negrito (não conta como
       texto grande). Vários reaproveitam fundo que já existia: `--pw-warn-bg`, `--pw-danger-bg`,
       `--pw-safe-bg`, `--pw-caution-bg`, `--pw-idle-bg` e `--pw-notice-bg`. */
    --pw-serie-1-ink:    #1668CC;  /* azul como TINTA sobre --pw-notice-bg (4,79:1) */
    --pw-serie-2-bg:     #FBEEE5;  /* laranja lavado — --pw-serie-2 em cima: 4,77:1 */
    --pw-serie-3-bg:     #E3F5F2;  /* teal lavado — a matiz crua dá 3,37:1, por isso a tinta abaixo */
    --pw-serie-3-ink:    #0A6B60;  /* teal como TINTA sobre --pw-serie-3-bg (5,67:1) */
    --pw-serie-4-bg:     #F4EBFB;  /* violeta lavado — --pw-serie-4 em cima: 5,15:1 */
    --pw-seq-5-bg:       #E7EEF9;  /* marinho lavado — --pw-seq-5 em cima: 6,24:1 */
    --pw-magenta-bg:     #FAEAF1;  /* magenta lavado — --pw-magenta em cima: 5,20:1 */
    --pw-safe-deep-bg:   #DFF0E7;  /* verde escuro lavado — --pw-safe-deep em cima: 7,39:1 */
    --pw-ink-bg:         #E9EBF1;  /* grafite lavado — --pw-ink em cima: 13,17:1 */
    --pw-ink-4-bg:       #F3F5F8;  /* neutro lavado — --pw-ink-3 em cima: 5,30:1 */

    /* AS DUAS QUE FECHAM A CONTA DAS ETAPAS (spec 033, 10ª rodada, correção de 16/09).
       São 13 etapas e o sistema tinha 11 matizes realmente distintas: estas duas são o que
       faltava, e entram medidas como as séries da 022 foram.

       `--pw-magenta` não tem significado próprio — é matiz, e só. Ela NÃO entra na paleta de
       séries de propósito: a rosca de 5 fatias foi validada para daltonismo NA ORDEM em que as
       fatias aparecem no anel (spec 068), e acrescentar uma quinta série convidaria a refazer
       aquele anel sem refazer a validação. */
    --pw-magenta:    #A83A6B;  /* Folha de serviço aprovada — 5,99:1 com branco */
    --pw-safe-parte:    #4E7A12;  /* Aprovada parcialmente (spec 112): o verde do aprovado puxado para o oliva */
    --pw-safe-parte-bg: #EFF5E3;
    --pw-safe-deep:  #0A5638;  /* Paga: o fim da linha, mais fundo que "aprovada" — 8,70:1 */
    /* Nota fiscal devolvida (spec 116): o VINHO — da família do "voltou", mas não o vermelho de
       "Rejeitada" nem o magenta da folha aprovada, que ficam a uma etapa dela. */
    --pw-vinho:      #8E2A3C;
    --pw-vinho-bg:   #F8E8EB;  /* vinho lavado — --pw-vinho em cima: 6,97:1 */
    /* Spec 126: as duas etapas do fim do ciclo fiscal. Contrastes medidos (WCAG) sobre o fundo lavado. */
    --pw-provisionado:    #0E6470;  /* Pagamento provisionado — ciano escuro */
    --pw-provisionado-bg: #E2F2F3;  /* --pw-provisionado em cima: 5,93:1 */
    --pw-ferrugem:        #7A3B16;  /* Nota fiscal não liberada — ferrugem */
    --pw-ferrugem-bg:     #F6EAE2;  /* --pw-ferrugem em cima: 7,23:1 */

    /* ---- Séries de gráfico (spec 022) ----
       SEPARADAS das cores de estado, e isso é regra: verde quer dizer "aprovado" no produto
       inteiro, então verde não pode virar "etapa 3" — a mesma cor significaria duas coisas na
       mesma tela e o leitor não teria como saber qual.

       VALIDADAS, não escolhidas no olho: faixa de luminosidade, piso de croma, contraste contra
       o cartão e separação sob daltonismo. O par adjacente mais difícil é verde↔laranja, com
       ΔE 13,3 em deuteranopia (alvo ≥ 8). A primeira tentativa punha azul e violeta lado a lado
       e dava ΔE 4,6 — teriam virado a mesma cor para boa parte dos leitores. */
    --pw-serie-1: #1570DB;
    --pw-serie-2: #B54708;
    --pw-serie-3: #0E9384;
    --pw-serie-4: #8B3DBF;

    /* A LEITURA DA NOTA (spec 118): o ícone no véu do cartão enquanto o PDF é lido. O AZUL do botão
       primário (decisão do Leandro, 30/09 — nasceu violeta, da série 4): é o azul de marca do produto,
       e fica FORA das donas de estado (verde, âmbar, vermelho). 4,9:1 sobre branco. */
    --pw-leitura: var(--pw-notice);

    /* Escala sequencial do azul da marca, para faixa ORDENADA (mais velho = mais escuro). */
    /* A RAMPA DA BARRA DE CONSUMO (19/09/2026) — clara no começo, intensa ao encher.
       Uma cor só, cinco degraus: a barra deixou de dizer "bom/ruim" e passou a dizer QUANTO.
       Ancorada nos dois verdes que já existem (--pw-safe e --pw-safe-deep), porque o degrau
       final é o mesmo verde de "concluído" do resto do produto — encher é terminar. */
    /* O PISO DA RAMPA TEM DE SER VISÍVEL NO TRILHO (corrigido em 19/09/2026).
       A primeira tentativa começava em #E8F6EF contra um trilho #F0F3F8: **1,00:1** — luminância
       IDÊNTICA à do fundo. "Mais claro" não virou quase o fundo, virou o fundo: um pedido com 8%
       medido desenhava um fiapo de 6px literalmente invisível, e a barra parecia vazia
       justamente quando tinha algo a dizer. O novo piso está a 1,92:1.
       Rampa não começa no fundo: ela começa no PRIMEIRO tom que se enxerga sobre ele. */
    --pw-cons-1: #5CC49A;
    --pw-cons-2: #34AE7E;
    --pw-cons-3: #1B9765;
    --pw-cons-4: #0F7B4F;
    --pw-cons-5: #0A5638;

    --pw-seq-1: #DCEAFD;
    --pw-seq-2: #A8C9F5;
    --pw-seq-3: #5E97E4;
    --pw-seq-4: #1570DB;
    --pw-seq-5: #0F55A8;

    --pw-shadow-rgb: 28, 35, 51;

    /* ---- Tipografia ---- */
    --pw-font: 'Figtree', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --pw-t-2xs: 0.6875rem; --pw-t-xs: 0.75rem; --pw-t-label: 0.8125rem;
    --pw-t-base: 0.875rem; --pw-t-md: 1rem; --pw-t-lg: 1.125rem;
    --pw-t-xl: 1.5rem; --pw-t-2xl: 2rem;

    /* ---- Ritmo e raio ---- */
    --pw-1: 4px; --pw-2: 8px; --pw-3: 12px; --pw-4: 16px;
    --pw-5: 24px; --pw-6: 32px; --pw-7: 48px;
    --pw-r-1: 8px; --pw-r-2: 10px; --pw-r-3: 14px; --pw-r-4: 20px; --pw-r-pill: 999px;

    /* ---- A CASCA, em medida (spec 089, regra 5) ----
       O topo e a lateral já eram fixos com estes números, escritos à mão em cinco lugares. Eles
       viram token porque o cabeçalho fixo da tabela PARA EMBAIXO deles: o deslocamento é
       composto, e composto de número mágico é o tipo de conta que ninguém refaz quando o topo
       muda de altura. */
    --pw-topo-h: 60px;
    --pw-lateral-w: 232px;

    /* ---- AS CAMADAS, declaradas num lugar só (spec 089, regra 5) ----
       A ordem É a regra, e está escrita de cima para baixo: o topo do produto fica acima de
       tudo; a barra de filtros, abaixo dele; o cabeçalho da tabela, abaixo dos dois. Sem esta
       lista, a primeira tela que ganhar uma barra nova volta a ter cabeçalho passando por cima
       de filtro — e o defeito só aparece rolando, depois de pronto.

       Dentro da tabela a ordem também é fixa: a CÉLULA DE CANTO acima do cabeçalho, o cabeçalho
       acima da coluna congelada (regra 9). Sem isso a célula de canto desliza por baixo de um
       dos dois e o cabeçalho da primeira coluna some. */
    --pw-z-topo: 40;
    --pw-z-lateral: 30;
    --pw-z-filtros: 15;
    --pw-z-canto: 12;
    --pw-z-cabecalho: 11;
    --pw-z-congelada: 10;

    /* ATÉ ONDE a caixa da tabela cresce antes de rolar por dentro.
       Não é altura: é TETO. Lista curta encolhe a caixa e não mostra barra nenhuma; lista longa
       para aqui e rola com o cabeçalho colado. Sobra tela para o título, os filtros e o rodapé
       da paginação, que é o que a pessoa precisa ver junto com as linhas.

       Substituiu `--pw-filtros-h: 80px` + `--pw-tabela-topo`, que eram uma conta de
       deslocamento com um chute dentro — o próprio comentário admitia "mede ~80px". Com a caixa
       rolando, o topo dela É o zero do cabeçalho e não há o que compor. */
    --pw-tabela-altura: 68vh;
}

* { box-sizing: border-box; }

html, body {
    margin: 0; height: 100%;
    background: var(--pw-paper);
    color: var(--pw-ink);
    font-family: var(--pw-font);
    font-size: var(--pw-t-base);
    line-height: 1.5;
}

/* A PÁGINA NÃO ROLA PARA O LADO (spec 093, 2ª rodada).

   O defeito: rolar para a direita deixava uma faixa de fundo vazia, e o menu — que é
   `position: fixed` — ficava parado por cima do começo do conteúdo. "Pedidos emitidos" virava
   "lidos emitidos". Enquanto o DOCUMENTO rolar na horizontal, qualquer elemento preso à janela
   vai cobrir o que passa por baixo dele: não há versão disso que não machuque.

   POR QUE CLIPAR NÃO ESCONDE NADA, e esta é a medição que autoriza a regra. Na tela do Leandro,
   com o documento 75px mais largo que a janela, a varredura desceu a árvore procurando qualquer
   elemento com a largura do documento e respondeu **"nenhum filho do body tem a largura do
   documento"**. Ou seja: os 75px não são CONTEÚDO, são deslocamento — sobra de posicionamento que
   infla a área rolável sem nada desenhado ali. Clipar remove a rolagem e não tira nada da vista,
   porque não havia nada.

   `clip`, e não `hidden`: `hidden` criaria um contêiner de rolagem na raiz, o que muda o
   comportamento do `position: sticky` de toda a página — a barra de filtros gruda na JANELA, e
   com a raiz virando scrollport ela passaria a grudar em outra coisa. `clip` corta sem criar
   scrollport e sem forçar o eixo vertical, que continua rolando normalmente.

   O que NÃO é clipado: cada peça larga continua com a rolagem PRÓPRIA que já tinha — a tabela
   em `pw-tabela-rolante`, a região em `pw-scroll-x`. É a regra 7 da spec: conter, nunca esconder.

   E ISTO NÃO DISPENSA ACHAR A CAUSA. Oito tentativas de reproduzir a origem dos 75px falharam
   aqui, com a casca real, a estrutura aninhada real, a coluna congelada e a tabela rolada. Esta
   regra fecha o SINTOMA de vez, em toda tela; a origem segue registrada como aberta na spec.

   NO CONTEÚDO, E NÃO NA RAIZ. `html { overflow-x: clip }` foi a primeira tentativa e foi
   medida: não funciona. A propagação de `overflow` do elemento raiz para a janela não vale
   para `clip` no Chrome — com um intruso de 3000px o documento continuou rolando 1.854px. A
   regra vive em `.pw-main`, que é o contêiner de todo o conteúdo de página e o único lugar de
   onde a largura excedente pode vir: o topo e o menu são `position: fixed` e não fazem parte
   do fluxo. */
.pw-main { overflow-x: clip; }

/* NA CASCA TAMBÉM, e não só no conteúdo. `.pw-main` clipa o que está DENTRO dele; se a sobra
   vier de um irmão ou da própria casca, a página volta a rolar. Os dois juntos fecham o caminho
   inteiro do fluxo — o que sobra fora deles é `position: fixed`, que não rola. */
.pw-shell { overflow-x: clip; }

/* ---------------------------------------------------------------------------
   CASCA: topo de marca + sidebar + conteúdo
   --------------------------------------------------------------------------- */
.pw-shell { display: flex; min-height: 100vh; }

.pw-top {
    position: fixed; inset: 0 0 auto 0; z-index: var(--pw-z-topo); height: var(--pw-topo-h);
    display: flex; align-items: center; gap: var(--pw-5);
    padding: 0 var(--pw-5);
    background: var(--pw-sheet);
    border-bottom: 1px solid var(--pw-hair);
    box-shadow: 0 1px 2px rgba(var(--pw-shadow-rgb), .04);
}
/* ── O TOPO ENCOLHE (spec 093, medido em 21/09/2026) ────────────────────────

   Era o CULPADO do defeito que o Leandro relatou: "rolar para o lado deixa uma área vazia".
   Medido no navegador dele, com a janela em 400px: `.pw-top` com **1.600px** e o documento com
   1.739 — a barra tem sete blocos (marca, data, empresa, fornecedor, e-mail, meus fornecedores,
   sino e sair) num flex SEM quebra, e nenhum deles cedia. Abaixo de 1.600px de janela ela
   transbordava e **esticava o documento**.

   O sintoma não apontava para cá, e é por isso que custou seis tentativas de reprodução: como a
   barra é `position: fixed`, ninguém a VÊ esticar. O que se vê é o documento ficar maior, o menu
   fixo passar por cima do começo do conteúdo — "Pedidos emitidos" virando "lidos emitidos" — e
   fundo vazio à direita. Três sintomas longe da causa.

   A saída é encolher, não esconder (regra 7 da spec): cada bloco pode ceder, e o valor longo —
   o e-mail — corta com reticências em vez de empurrar a barra. O `title` leva o valor inteiro, e
   o perfil continua a um clique. */
/* E A BARRA CLIPA O PRÓPRIO TRANSBORDO. Ela é `position: fixed`, então está FORA do fluxo — nem
   `.pw-main` nem `.pw-shell` a alcançam. E fixo NÃO é inócuo: foi medido no navegador do Leandro
   que a barra de 1.600px produzia 1.339px de rolagem no documento. Sobrando 52px depois de
   clipar todo o fluxo, o resto só podia vir daqui.

   `clip` só no eixo X: o eixo Y segue `visible`, então o painel do sino e qualquer menu que
   desça continuam aparecendo inteiros. É o que `hidden` não permitiria. */
.pw-top { min-width: 0; overflow-x: clip; }
.pw-top__brand { flex: 0 0 auto; }
.pw-top__brand img { height: 34px; display: block; }

/* `flex: 0 1 auto` com `min-width: 0`: o bloco da direita CEDE. Sem o min-width, todo item de
   flex tem largura mínima igual ao seu conteúdo — é o padrão da linguagem, e é exatamente ele
   que travava a barra em 1.600px. */
.pw-top__meta {
    display: flex; gap: var(--pw-5); margin-left: auto; align-items: center;
    min-width: 0; flex: 0 1 auto;
}
.pw-top__meta > * { min-width: 0; }

.pw-field { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }

/* O RÓTULO também não quebra. Sem isto, "MEUS FORNECEDORES" vira duas linhas ao encolher, e
   numa barra de altura FIXA (60px) a segunda linha sai por baixo. */
.pw-field__key {
    font-size: var(--pw-t-2xs); font-weight: 600; color: var(--pw-ink-3);
    text-transform: uppercase; letter-spacing: .04em;
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* O VALOR corta com reticências em vez de empurrar a barra. `nowrap` aqui não é enfeite: sem
   ele o texto quebraria em duas linhas dentro de uma barra de altura fixa e sairia por baixo. */
.pw-field__val {
    font-size: var(--pw-t-label); font-weight: 600; color: var(--pw-ink);
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pw-field--env .pw-field__val { color: var(--pw-warn-ink); }
/* o usuário no topo é link para o próprio perfil — sublinhado só no hover, para a barra
   não virar um amontoado de links sublinhados */
.pw-top__usuario { color: var(--pw-ink); text-decoration: none; }
.pw-top__usuario:hover { color: var(--pw-notice-ink); text-decoration: underline; }

/* UM ÍCONE AO LADO DE CADA ITEM DO TOPO (spec 098, regra 10). O desenho fica à esquerda do par
   rótulo/valor, no cinza dos ícones de tile — acompanha, não compete com o valor. */
.pw-field--icone { flex-direction: row; align-items: center; gap: var(--pw-2); }
.pw-field__texto { display: flex; flex-direction: column; min-width: 0; }
.pw-field__icone { width: var(--pw-5); height: var(--pw-5); flex: none; color: var(--pw-ink-4); }
.pw-sino__icone { width: var(--pw-5); height: var(--pw-5); flex: none; color: var(--pw-ink-2); }

/* ── O SELETOR DE FORNECEDOR do topo (spec 098, regra 7) ────────────────────
   Era um <select> nativo: o sistema operacional desenhava a caixa e a lista — a "cara de
   Windows" — e a razão social cortava em 240px. Agora é um DROPDOWN do produto: um botão com
   borda e seta, que ganha o anel azul quando aberto, e um menu que desce com sombra, cada opção
   com a razão social inteira (quebra linha, nunca reticências), o CNPJ embaixo e o check na
   escolhida. <details> + links: abre sem JavaScript e funciona na casca estática. */
.pw-escolha { position: relative; min-width: 0; }
.pw-escolha__botao {
    display: flex; align-items: center; gap: var(--pw-2); min-width: 0; max-width: 380px;
    padding: var(--pw-1) var(--pw-3) var(--pw-1) var(--pw-2);
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-2); background: var(--pw-sheet);
    line-height: 1.25; list-style: none; cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}
.pw-escolha__botao::-webkit-details-marker { display: none; }
.pw-escolha__botao:hover { border-color: var(--pw-heavy); background: var(--pw-vellum); }
.pw-escolha__botao:focus-visible,
.pw-escolha[open] > .pw-escolha__botao {
    outline: none; border-color: var(--pw-notice); box-shadow: 0 0 0 3px var(--pw-notice-bg);
}
.pw-escolha__seta { width: var(--pw-4); height: var(--pw-4); flex: none; color: var(--pw-ink-3); transition: transform .15s ease; }
.pw-escolha[open] .pw-escolha__seta { transform: rotate(180deg); }
.pw-escolha__menu {
    position: absolute; top: calc(100% + var(--pw-2)); right: 0; z-index: 1;
    min-width: 100%; width: max-content; max-width: min(460px, calc(100vw - var(--pw-6)));
    max-height: 60vh; overflow-y: auto;
    margin: 0; padding: var(--pw-2); list-style: none;
    background: var(--pw-sheet); border: 1px solid var(--pw-line); border-radius: var(--pw-r-3);
    box-shadow: 0 16px 36px rgba(var(--pw-shadow-rgb), .16);
}
.pw-escolha__opcao {
    position: relative; display: block; min-height: 44px;
    padding: var(--pw-2) var(--pw-7) var(--pw-2) var(--pw-3);
    border-radius: var(--pw-r-2); color: var(--pw-ink); text-decoration: none;
}
.pw-escolha__opcao:hover, .pw-escolha__opcao:focus-visible { background: var(--pw-vellum); outline: none; }
.pw-escolha__opcao:focus-visible { box-shadow: inset 0 0 0 2px var(--pw-notice); }
.pw-escolha__opcao[aria-current="true"] { background: var(--pw-notice-bg); }
.pw-escolha__nome { display: block; font-size: var(--pw-t-base); font-weight: 600; white-space: normal; overflow-wrap: anywhere; }
.pw-escolha__meta { display: block; margin-top: 2px; font-size: var(--pw-t-xs); color: var(--pw-ink-3); font-variant-numeric: tabular-nums; }
.pw-escolha__marca {
    position: absolute; right: var(--pw-3); top: 50%; transform: translateY(-50%);
    width: var(--pw-4); height: var(--pw-4); color: var(--pw-notice-ink);
}
.pw-escolha__divisor { height: 1px; margin: var(--pw-1) var(--pw-2); background: var(--pw-hair); }
@media (prefers-reduced-motion: reduce) {
    .pw-escolha__botao, .pw-escolha__seta { transition: none; }
}

.pw-side {
    position: fixed; top: var(--pw-topo-h); bottom: 0; left: 0; z-index: var(--pw-z-lateral); width: var(--pw-lateral-w);
    padding: var(--pw-4) var(--pw-3);
    background: var(--pw-sheet);
    border-right: 1px solid var(--pw-hair);
    display: flex; flex-direction: column; gap: 2px;
}
.pw-nav-item {
    display: flex; align-items: center; gap: var(--pw-3);
    height: 38px; padding: 0 var(--pw-3);
    border-radius: var(--pw-r-2);
    color: var(--pw-ink-2); text-decoration: none;
    font-weight: 600; font-size: var(--pw-t-base);
    transition: background .12s ease, color .12s ease;
}
.pw-nav-item:hover { background: var(--pw-vellum); color: var(--pw-ink); }
.pw-nav-item.active { background: var(--pw-notice-bg); color: var(--pw-notice-ink); }
.pw-nav-item i { width: 18px; text-align: center; }
/* O icone do item de menu (spec 087, frente 2). Ele ACOMPANHA o texto, nunca o substitui
   (regra 8), entao herda a cor do item — inclusive a do estado ativo, que e a unica cor com
   significado nesta lateral. Tamanho por token, como todo icone do produto. */
.pw-nav-item__icone { width: var(--pw-4); height: var(--pw-4); flex: none; color: currentColor; }
.pw-nav-sep { margin: var(--pw-3) var(--pw-3) var(--pw-1); font-size: var(--pw-t-2xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--pw-ink-4); }

.pw-main {
    flex: 1; margin: var(--pw-topo-h) 0 0 var(--pw-lateral-w);
    padding: var(--pw-5);
    min-width: 0;

}

/* SOLO: casca sem lateral.
   Duas telas usam esta variante, e pelo mesmo motivo — não há produto a navegar: o
   colaborador que entrou e ainda não tem perfil (specs 026/027) e o operador da plataforma
   (spec 028), que não é usuário do BMM. Sem sidebar, a margem da esquerda sai; e o conteúdo
   ganha um limite de leitura em vez de esticar na tela inteira, porque um parágrafo com
   1600px de largura não se lê. */
/* Sem sidebar, a margem da esquerda sai e o conteúdo ganha um limite de leitura — mas o
   limite é do BLOCO inteiro, centralizado, e não de cada filho.
   Aplicá-lo em `> *` foi o erro: cada card era cortado em 1100px e encostado à esquerda,
   deixando dois terços da tela vazios à direita e a página com cara de quebrada. */
.pw-shell--solo .pw-main {
    margin-left: 0;
    max-width: 1180px;
    margin-inline: auto;
    width: 100%;

}

/* responsivo: some a sidebar, marca vira o ícone */
@media (max-width: 900px) {
    .pw-side { display: none; }
    .pw-main { margin-left: 0; }
    .pw-field--desk { display: none; }
}

/* ---------------------------------------------------------------------------
   COMPONENTES
   --------------------------------------------------------------------------- */
.pw-card {
    background: var(--pw-sheet);
    border-radius: var(--pw-r-3);
    box-shadow: 0 1px 2px rgba(var(--pw-shadow-rgb), .05), 0 4px 16px rgba(var(--pw-shadow-rgb), .05);
    padding: var(--pw-5);
}

/* RESPIRO ENTRE CARTÕES (spec 104) — uma regra só, para todas as telas. O cartão não tinha margem
   própria: o espaço dependia de cada tela lembrar do `pw-bloco`, e 62 cartões não lembravam — dois em
   sequência encostavam (a tela de perfil foi o caso relatado). Com `pw-bloco` no de cima, as margens se
   sobrepõem no fluxo normal e o espaço continua 16px, sem dobrar.

   DENTRO DE GRADE a regra não vale: a grade já tem o `gap` dela, e margem a mais desalinharia a linha. */
.pw-card ~ .pw-card { margin-top: var(--pw-4); }
:is(.pw-grid, .pw-admin-grid, .pw-duas-colunas, .pw-split, .pw-painel, .pw-painel__grade,
    .pw-painel__numeros, .pw-painel__secao, .pw-login, .pw-esqueleto--cartoes, .pw-lista-dupla)
    > .pw-card ~ .pw-card { margin-top: 0; }

.pw-page-title { font-size: var(--pw-t-xl); font-weight: 800; letter-spacing: -0.015em; margin: 0 0 var(--pw-1); }
.pw-page-sub { color: var(--pw-ink-3); font-size: var(--pw-t-base); margin: 0 0 var(--pw-5); }

/* stat tile do painel */
.pw-stat { display: flex; flex-direction: column; gap: var(--pw-1); }
/* O ícone do tile (spec 057). Decorativo, e por isso UMA cor só — `--pw-ink-4`, o mesmo cinza
   em todo estado. Verde/âmbar/vermelho têm dono (regra 3 do DESIGN.md: estado do boletim e ação
   da trilha); ícone pintado de estado seria uma terceira leitura de cor sem regra nenhuma.
   `flex: none` porque o tile é uma coluna flex: sem isso o desenho estica junto com o cartão. */
.pw-stat__icone { width: var(--pw-5); height: var(--pw-5); flex: none; color: var(--pw-ink-4); }
.pw-stat__label { font-size: var(--pw-t-label); font-weight: 600; color: var(--pw-ink-3); }
.pw-stat__value { font-size: var(--pw-t-2xl); font-weight: 800; letter-spacing: -0.02em; }
.pw-stat__meta { font-size: var(--pw-t-xs); color: var(--pw-ink-3); }

/* botões */
.pw-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: var(--pw-2);
    /* rótulo de botão não quebra linha: "Pagamentos →" partido em duas linhas estica a
       altura da célula e desalinha a tabela inteira */
    white-space: nowrap;
    height: 40px; padding: 0 var(--pw-4);
    border: none; border-radius: var(--pw-r-2); cursor: pointer;
    font-family: var(--pw-font); font-size: var(--pw-t-base); font-weight: 600;
    transition: background .12s ease;
    text-decoration: none;
}
.pw-btn--primary { background: var(--pw-notice); color: #fff; }
.pw-btn--primary:hover { background: var(--pw-notice-ink); }
.pw-btn--secondary { background: var(--pw-sheet); color: var(--pw-ink-2); border: 1px solid var(--pw-line); }
.pw-btn--secondary:hover { background: var(--pw-vellum); color: var(--pw-ink); }
/* O botão que LIBERA uma ação, e não só a destaca (19/09/2026). Hoje é o "Medir" com a janela de
   medição ABERTA: ele diz "dá para fazer agora", que é informação de estado e não decoração.
   Fechada, o botão fica desabilitado com o cadeado — e aí não há cor a dar. */
.pw-btn--liberado { background: var(--pw-safe); color: #fff; }
.pw-btn--liberado:hover { background: var(--pw-safe-deep); }

.pw-btn--danger { background: var(--pw-danger); color: #fff; }

/* Atalho discreto, sem peso de botão de ação (spec 046).
   A classe era usada em "Tudo conforme especificado" e NÃO EXISTIA: o botão saía com o base,
   sem fundo e sem borda, parecendo quebrado. O nome pedia um botão de texto, e é o que faz
   sentido ali — o atalho tem de estar visível sem competir com "Salvar avaliação". */
.pw-btn--ghost {
    background: transparent; color: var(--pw-notice);
    border: 1px solid transparent; padding: 0 var(--pw-2);
}
.pw-btn--ghost:hover { background: var(--pw-vellum); color: var(--pw-notice-ink); }

/* Ação destrutiva de linha de tabela (spec 031, item 7.2).
   "Desativar" estava com o botão base — que, sem variante, herda fundo escuro — ao lado de
   "Salvar perfil" desabilitado, em azul pálido. A leitura ficava invertida: a ação normal
   parecia indisponível e a destrutiva parecia a principal.
   Contorno, e não preenchimento: a cor de perigo fica na borda e no texto, presente o
   suficiente para avisar, discreta o suficiente para não convidar. */
.pw-btn--danger-suave {
    background: var(--pw-sheet); color: var(--pw-danger);
    border: 1px solid var(--pw-danger);
}
.pw-btn--danger-suave:hover { background: var(--pw-danger); color: #fff; }

/* Ícone DENTRO de um botão (spec 083, a coluna do comprovante).
   `currentColor` e não um cinza fixo: o botão desabilitado já apaga o conjunto inteiro pela
   opacidade, e uma cor própria aqui deixaria o desenho aceso num controle apagado. */
.pw-btn__icone { width: var(--pw-4); height: var(--pw-4); flex: none; color: currentColor; }

/* BOTÃO SÓ DE ÍCONE — quadrado, e com o desenho MAIOR (19/09/2026).
   16px é tamanho de acompanhamento: o ícone caminha ao lado de um texto que já disse o que o
   botão faz. Quando ele é o ÚNICO rótulo, vira o texto — e aí 16px não basta. O desenho do
   recibo tem um cifrão dentro que simplesmente some nesse tamanho, e o botão passa a ser um
   quadradinho cinza que ninguém sabe o que faz. */
.pw-btn--so-icone { width: 36px; padding: 0; }
.pw-btn--so-icone .pw-btn__icone { width: 20px; height: 20px; }

/* O ÍCONE DO FORMATO, na cor do formato — e só ele (spec 089, 3ª rodada).
   `color:` e não `fill:`: os desenhos do catálogo são traço (`stroke="currentColor"`), então
   quem os pinta é a cor do texto do próprio elemento. Um `fill` aqui não faria nada. */
.pw-btn__icone--excel { color: var(--pw-excel); }
.pw-btn__icone--pdf { color: var(--pw-pdf); }

/* pílula de estado do boletim */
.pw-pill {
    display: inline-flex; align-items: center;
    padding: 4px 12px; border-radius: var(--pw-r-pill);
    font-size: var(--pw-t-xs); font-weight: 700; color: #fff; white-space: nowrap;
}
.pw-pill--rascunho    { background: var(--pw-idle); }
.pw-pill--emaprovacao { background: var(--pw-warn); color: var(--pw-ink-deep); }
.pw-pill--aprovado    { background: var(--pw-safe); }
.pw-pill--rejeitado   { background: var(--pw-danger); }
.pw-pill--contestado  { background: var(--pw-caution); }

/* ACESSO REVOGADO (spec 091) — grafite, e não o vermelho de "rejeitado".

   Os dois estados convivem na MESMA coluna da mesma tela, e a spec existe justamente para
   separá-los: "recusado na fila, nunca teve acesso" e "teve acesso e foi tirado" são duas
   histórias. Pintá-los igual devolveria ao olho a confusão que o dado deixou de ter.

   O grafite não é uma cor nova no produto: é a mesma de "folha cancelada" na paleta de etapa,
   e pela mesma ideia — algo que valia e foi anulado. Não entra na conta de verde/âmbar/
   vermelho (regra 3 do DESIGN.md), porque não é nenhum dos três. */
.pw-pill--revogado    { background: var(--pw-ink); }

/* ETAPA da medição — UMA COR POR ETAPA (spec 033, 10ª rodada, regra E4).

   Até 16/09/2026 a cor agrupava por SITUAÇÃO: treze etapas em cinco cores, e o azul sozinho
   engolia cinco pontos diferentes do ciclo. Numa lista que se varre justamente para saber ONDE
   cada medição parou, a cor não estava dizendo nada nessas cinco linhas. (E `FolhaAprovada` e
   `FolhaCancelada` nem estavam no mapa: saíam com a cor de RASCUNHO.)

   A PRIMEIRA TENTATIVA ERROU A FERRAMENTA, e vale ficar escrito: o trecho do SAP usava a escala
   sequencial do azul (--pw-seq-1..5), que existe para faixa ORDENADA em GRÁFICO, onde vizinhos
   DEVEM parecer parecidos. Numa pílula pequena, lado a lado numa tabela, "parecidos" vira "iguais"
   — e era o defeito que a rodada vinha consertar. Aqui a paleta é CATEGÓRICA: uma matiz por etapa,
   tirada das séries da 022, que foram validadas para luminosidade, croma, contraste e separação
   sob daltonismo.

   A divisão que a paleta segue:
     MARCO é decisão   -> cor de ESTADO (cinza, âmbar, verde, vermelho, ocre)
     PASSO é andamento -> MATIZ das séries dos gráficos, uma por etapa

   Quem decide a classe é `CoresDaEtapa` no C#, nunca a tela: sufixo escrito à mão aqui ou num
   .razor é bug de revisão.

   ── LAVADAS desde 20/09/2026 (spec 090, frente 2) ─────────────────────────────────────────
   Treze pílulas SÓLIDAS numa coluna só faziam a lista parecer um mostruário: desfecho bom,
   desfecho ruim e andamento chegavam com o mesmo peso visual. O tratamento passou a ser fundo
   claro + tinta escura + contorno; a MATIZ de cada etapa é a mesma de antes, e a tinta é o
   próprio token de cor dela — é assim que a 090 mexe no PESO sem mexer no mapa da 033.

   O CONTORNO NÃO É ENFEITE: o fundo lavado fica entre 1,07:1 e 1,19:1 do branco da linha, ou
   seja, quase o fundo. Sem a borda, "Rascunho" lavado deixa de parecer uma pílula e vira texto
   solto. Ela sai da PRÓPRIA tinta da pílula (30% sobre o fundo dela), e por isso é uma regra
   só para as catorze: nenhum token novo, e nenhuma chance de uma borda cinza aparecer numa
   pílula violeta.

   O padding cai 1px de cada lado para a borda não engordar a pílula — ela tem de ficar do
   mesmo tamanho das de STATUS, que continuam sólidas (a 090 deixou isso explícito no escopo). */
.pw-pill[class*="pw-pill--et-"] {
    padding: 3px 11px;
    border: 1px solid;
    border-color: color-mix(in srgb, currentColor 30%, transparent);
}

/* A COR DA ETAPA É A FAMÍLIA DO ESTADO (spec 033, alteração de 03/10/2026, decisão do Leandro):
   VERMELHO só para erro, ÂMBAR para o que espera alguém, AZUL para o que anda, VERDE para o que passou
   com sucesso, cinza para o rascunho. Era uma matiz por etapa (17 cores), e o magenta de "Folha de
   serviço aprovada", o vinho e a ferrugem liam-se como erro. Etapas vizinhas podem ter a mesma cor:
   quem as distingue é o TEXTO da pílula. A classe continua uma por etapa — trocar a cor de uma família
   é aqui, e nenhuma tela muda. */

/* Cinza: ainda não saiu. */
.pw-pill--et-rascunho        { background: var(--pw-idle-bg);       color: var(--pw-idle); }        /* 4,75:1 */

/* Âmbar: esperando alguém (a CN, a aprovação da folha, a aprovação da nota). */
.pw-pill--et-enviada         { background: var(--pw-warn-bg);       color: var(--pw-warn-ink); }    /* 5,57:1 */
.pw-pill--et-folha-emitida   { background: var(--pw-warn-bg);       color: var(--pw-warn-ink); }    /* 5,57:1 */
.pw-pill--et-nota-registrada { background: var(--pw-warn-bg);       color: var(--pw-warn-ink); }    /* 5,57:1 */
/* Contestada fica no OCRE, o âmbar escuro que é de contestado no produto inteiro (regra 2 do DESIGN.md). */
.pw-pill--et-contestada      { background: var(--pw-caution-bg);    color: var(--pw-caution); }     /* 4,73:1 */

/* Azul: andando. */
.pw-pill--et-analise         { background: var(--pw-notice-bg);     color: var(--pw-notice-ink); }  /* 6,46:1 */
.pw-pill--et-folha-pedida    { background: var(--pw-notice-bg);     color: var(--pw-notice-ink); }  /* 6,46:1 */
.pw-pill--et-nota-enviada    { background: var(--pw-notice-bg);     color: var(--pw-notice-ink); }  /* 6,46:1 */
.pw-pill--et-pagamento-provisionado { background: var(--pw-notice-bg); color: var(--pw-notice-ink); } /* 6,46:1 */

/* Verde: passou com sucesso. */
.pw-pill--et-aprovada        { background: var(--pw-safe-bg);       color: var(--pw-safe); }        /* 4,75:1 */
.pw-pill--et-aprovada-em-parte { background: var(--pw-safe-bg);     color: var(--pw-safe); }        /* 4,75:1 */
.pw-pill--et-folha-aprovada  { background: var(--pw-safe-bg);       color: var(--pw-safe); }        /* 4,75:1 */
.pw-pill--et-paga            { background: var(--pw-safe-bg);       color: var(--pw-safe); }        /* 4,75:1 */

/* Vermelho: só erro — a medição devolvida, a nota devolvida ou não liberada, a folha cancelada. */
.pw-pill--et-rejeitada       { background: var(--pw-danger-bg);     color: var(--pw-danger-ink); }  /* 6,16:1 */
.pw-pill--et-folha-cancelada { background: var(--pw-danger-bg);     color: var(--pw-danger-ink); }  /* 6,16:1 */
.pw-pill--et-nota-devolvida  { background: var(--pw-danger-bg);     color: var(--pw-danger-ink); }  /* 6,16:1 */
.pw-pill--et-nota-nao-liberada { background: var(--pw-danger-bg);   color: var(--pw-danger-ink); }  /* 6,16:1 */

/* ── A ETAPA QUE ESTA VERSÃO NÃO CONHECE ────────────────────────────────────
   Portal antigo contra API nova: ela sai NEUTRA, nunca vermelha. O texto ao lado continua certo,
   porque vem do servidor.

   ELA SE SEPARA POR FORMA, E NÃO POR COR, e isso é o conserto de um defeito que a versão lavada
   criou: com as pílulas sólidas, este cinza e o de Rascunho estavam a ΔE 24,8 e ninguém os
   confundia; lavados, caíram para ΔE 3,4 — duas cores só para o compilador. Numa lista, quatro
   "Rascunho" e uma etapa desconhecida viravam cinco pílulas iguais, e quem varre pela cor lia
   "nem foi enviado" num boletim que está andando. É o mesmo defeito que a spec 033, 10ª rodada,
   veio consertar, voltando por outra porta.

   E O CONSERTO NÃO PODE SER OUTRO CINZA. O `--pw-ink-2` foi medido e recusado aqui mesmo, duas
   regras acima, por ficar perto demais do cinza de rascunho — adotá-lo seria repetir um erro que
   o próprio arquivo documenta ter evitado. Fora ele, a paleta neutra acabou: `--pw-ink-4` dá
   2,10:1 (ilegível) e `--pw-ink` já é da Folha cancelada.

   O TRACEJADO RESOLVE PORQUE A PERGUNTA É OUTRA. "Desconhecida" não é a 14ª etapa disputando
   espaço no ciclo — é o Portal admitindo que não sabe, e isso nenhuma das treze matizes pode
   dizer. Contorno tracejado é uma categoria, não um tom: ele se distingue de TODAS as treze ao
   mesmo tempo, inclusive das que ainda não existem. */
.pw-pill--et-desconhecida    { background: var(--pw-ink-4-bg); color: var(--pw-ink-3); border-style: dashed; border-color: currentColor; }  /* 5,30:1 */

/* As três abaixo NÃO são mais da etapa — quem as usa é a `PilulaDaDecisao`. Apagá-las junto com
   o agrupamento antigo arrancaria a cor de outra tela. */
.pw-pill--espera      { background: var(--pw-warn); color: var(--pw-ink-deep); }
.pw-pill--andando     { background: var(--pw-notice); }
.pw-pill--concluida   { background: var(--pw-safe); }

/* Situação do PEDIDO (spec 011) — não confundir com a do boletim, que é a lista acima.
   Azul, e não âmbar: âmbar no e-BMM significa "esperando alguém agir" (boletim em
   aprovação), e pedido em andamento não espera ninguém — é o estado normal de quem ainda
   tem saldo para medir. Verde continua sendo o fim da linha. */
.pw-pill--andamento   { background: var(--pw-notice); }

/* Situação do COLABORADOR (spec 027): ativo, desativado, nomeado sem primeiro acesso.
   Neutro é cinza de propósito — "nomeado, ainda não entrou" não é alerta nem sucesso, é só
   um passo que ainda não aconteceu. */
.pw-pill--ok      { background: var(--pw-safe); }
.pw-pill--neutro  { background: var(--pw-ink-4); }

/* SITUAÇÃO DA DELEGAÇÃO (spec 103): lavada e NEUTRA, a mesma para as seis situações. Delegação não
   é status de boletim, e verde/âmbar/vermelho têm donas (CLAUDE.md) — quem diz a situação é o
   rótulo. Tratamento das pílulas lavadas da 090: fundo claro, tinta escura (5,30:1) e contorno. */
.pw-pill--situacao {
    padding: 3px 11px;
    background: var(--pw-ink-4-bg); color: var(--pw-ink-3);
    border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
}

/* A LISTA DUPLA da delegação (spec 103): duas colunas com os botões de mover no meio. Em tela
   estreita, as colunas empilham e os botões ficam entre elas, na horizontal. */
.pw-lista-dupla {
    display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: var(--pw-3); align-items: stretch;
}
.pw-lista-dupla__coluna {
    display: flex; flex-direction: column; gap: var(--pw-2); min-width: 0;
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-2); padding: var(--pw-3);
    background: var(--pw-sheet);
}
.pw-lista-dupla__titulo { margin: 0; font-size: var(--pw-t-label); font-weight: 600; color: var(--pw-ink-2); }
.pw-lista-dupla__itens {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-direction: column; gap: var(--pw-1);
    max-height: 280px; overflow-y: auto;
}
.pw-lista-dupla__item {
    display: flex; align-items: flex-start; gap: var(--pw-2);
    padding: var(--pw-2); border-radius: var(--pw-r-1); cursor: pointer;
}
.pw-lista-dupla__item:hover { background: var(--pw-vellum); }
.pw-lista-dupla__texto { display: flex; flex-direction: column; min-width: 0; overflow-wrap: anywhere; }
.pw-lista-dupla__vazio { margin: 0; color: var(--pw-ink-3); font-size: var(--pw-t-label); }
.pw-lista-dupla__botoes { display: flex; flex-direction: column; justify-content: center; gap: var(--pw-2); }
/* O sinal (› » ‹ «) É o rótulo visível do botão: no tamanho de texto de botão ele sumia (visto na
   bancada da spec 103). Alvo de toque de 44px. */
.pw-lista-dupla__botoes .pw-btn { min-width: 44px; min-height: 44px; justify-content: center; font-size: var(--pw-t-lg); line-height: 1; }
@media (max-width: 720px) {
    .pw-lista-dupla { grid-template-columns: minmax(0, 1fr); }
    .pw-lista-dupla__botoes { flex-direction: row; justify-content: center; }
}

/* AÇÃO da trilha de auditoria (spec 054). As três eram a mesma pílula cinza, e quem audita
   varre uma lista longa procurando o que mudou e, principalmente, o que sumiu — a varredura é
   justamente o que a cor resolve.
     verde    = nasceu um registro
     âmbar    = mudou de valor
     vermelho = saiu de cena (exclusão lógica)
   Isto EMENDA a regra 3 do DESIGN.md: verde/âmbar/vermelho passam a ter duas donas — o status
   do boletim e a ação da trilha. Fora desses dois casos continuam proibidos como decoração.
   As duas leituras nunca dividem a mesma tela: a trilha não mostra status de boletim em
   pílula (ele aparece como texto dentro do diff). O rótulo continua escrito na pílula: a cor
   acelera a varredura, não substitui a leitura. */
.pw-pill--criacao     { background: var(--pw-safe); }
.pw-pill--atualizacao { background: var(--pw-warn); color: var(--pw-ink-deep); }
.pw-pill--exclusao    { background: var(--pw-danger); }

/* texto de apoio dentro de célula: presente, mas claramente secundário */
.pw-muted { color: var(--pw-ink-4); }

/* ---------------------------------------------------------------------------
   ABERTURA: a tela de quem entrou e ainda não tem perfil (specs 026/027)

   Ela é a ÚNICA tela que essa pessoa vê, e por isso não pode parecer um aviso de erro
   empilhado sobre outro. A composição é a de uma etapa do caminho: um selo dizendo o estado,
   um título afirmativo, uma frase de contexto e a trilha do que falta — o que já aconteceu,
   o que está com ela agora, e quem decide depois.
   --------------------------------------------------------------------------- */
/* A coluna INTEIRA desta tela é estreita — a abertura e o cartão de ação, na mesma largura.
   Larguras diferentes empilhadas deixam a borda direita em degrau, e é esse tipo de detalhe
   que faz uma tela parecer montada às pressas. */
.pw-coluna-estreita { max-width: 860px; }

.pw-abertura {
    background: var(--pw-sheet);
    border: 1px solid var(--pw-hair);
    border-radius: var(--pw-r-3);
    padding: var(--pw-6) var(--pw-5);
}

.pw-selo {
    display: inline-flex; align-items: center;
    padding: 4px 12px; border-radius: var(--pw-r-pill);
    background: var(--pw-notice-bg); color: var(--pw-notice-ink);
    font-size: var(--pw-t-2xs); font-weight: 700;
    text-transform: uppercase; letter-spacing: .04em;
}

.pw-abertura__titulo {
    margin: var(--pw-4) 0 var(--pw-2);
    font-size: var(--pw-t-xl); font-weight: 700; color: var(--pw-ink-deep);
}

.pw-abertura__texto {
    margin: 0; color: var(--pw-ink-2); font-size: var(--pw-t-base);
    /* Medida de leitura: linha longa demais faz o olho perder o começo da seguinte. */
    max-width: 62ch;
}

.pw-trilha {
    list-style: none; margin: var(--pw-5) 0 0; padding: 0;
    display: flex; flex-direction: column; gap: var(--pw-4);
}

.pw-trilha__item { display: flex; gap: var(--pw-4); align-items: flex-start; }
.pw-trilha__item strong { display: block; color: var(--pw-ink-4); font-size: var(--pw-t-base); }
.pw-trilha__item p { margin: 2px 0 0; color: var(--pw-ink-4); font-size: var(--pw-t-label); }

/* A marca é um círculo com número; o passo concluído troca o número por um confirme. */
.pw-trilha__marca {
    flex: 0 0 auto;
    width: 26px; height: 26px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--pw-t-xs); font-weight: 700;
    background: var(--pw-vellum); color: var(--pw-ink-4);
    border: 1px solid var(--pw-line);
}

/* Concluído e ATUAL ganham contraste; o que ainda não chegou fica deliberadamente apagado,
   para o olho encontrar sozinho onde a pessoa está. */
.pw-trilha__item--feito strong { color: var(--pw-ink-2); }
.pw-trilha__item--feito .pw-trilha__marca {
    background: var(--pw-safe-bg); color: var(--pw-safe); border-color: transparent;
}

.pw-trilha__item--agora strong { color: var(--pw-ink-deep); }
.pw-trilha__item--agora p { color: var(--pw-ink-2); }
.pw-trilha__item--agora .pw-trilha__marca {
    background: var(--pw-notice); color: #fff; border-color: transparent;
}

/* tabela */
.pw-table { width: 100%; border-collapse: collapse; font-size: var(--pw-t-base); }
.pw-table thead th {
    background: var(--pw-vellum);
    color: var(--pw-ink-3); font-size: var(--pw-t-label); font-weight: 600;
    text-align: left; padding: 10px var(--pw-4);

    /* O CABEÇALHO NÃO QUEBRA EM DUAS LINHAS. Num grid, rótulo de coluna que dobra desalinha a
       fileira inteira e faz a tabela parecer montada às pressas — e o rótulo é curto por
       desenho, então quebrar é sinal de coluna espremida, não de texto longo. Quem tem de ceder
       é a largura da coluna, não a altura da linha. */
    white-space: nowrap;
}
.pw-table thead th:first-child { border-radius: var(--pw-r-1) 0 0 var(--pw-r-1); }
.pw-table thead th:last-child  { border-radius: 0 var(--pw-r-1) var(--pw-r-1) 0; }
/* A ALTURA DA LINHA é 52px com a ação de 36px dentro — 8px de respiro de cada lado.
   Eram 12px, e a linha fechava em 61px: numa tela de 1000px isso é quatro linhas a menos por
   página, e a lista passa a rolar quando não precisaria. Grid de trabalho fica entre 48 e 52;
   acima disso a tabela parece um formulário empilhado. O que NÃO encolhe é a fonte — tabela de
   dinheiro com letra menor se lê errado (regra 17). */
.pw-table tbody td,
.pw-table tbody th { padding: var(--pw-2) var(--pw-4); border-bottom: 1px solid var(--pw-hair); }
.pw-table tbody th { text-align: left; font-weight: 400; }
.pw-table tbody tr:hover { background: var(--pw-vellum-2); }
.pw-table .num { font-variant-numeric: tabular-nums; }

/* A ÚLTIMA LINHA não desenha divisória: dentro da caixa com borda, ela vira um traço duplo
   rente ao rodapé. Detalhe pequeno, e é dos que separam "tabela" de "grid". */
.pw-table tbody tr:last-child > td,
.pw-table tbody tr:last-child > th { border-bottom: 0; }

/* ── A LISTA VAZIA, DENTRO DA TABELA ────────────────────────────────────────
   O cabeçalho fica de pé e o recado ocupa a área das linhas. Antes a tabela inteira era
   trocada por um bloco, e o produto aparecia SEM CABEÇALHO em toda tela sem resultado. */
.pw-table__vazio-linha:hover { background: transparent; }
.pw-table__vazio-linha > td { border-bottom: 0; padding: 0; }

.pw-table__vazio {
    display: flex; flex-direction: column; align-items: center; gap: var(--pw-2);
    padding: var(--pw-7) var(--pw-5);
    text-align: center;
}

.pw-table__vazio-titulo {
    margin: 0; color: var(--pw-ink-deep);
    font-size: var(--pw-t-base); font-weight: 600;
}

.pw-table__vazio-texto {
    margin: 0; color: var(--pw-ink-2); font-size: var(--pw-t-label);
    max-width: 46ch;
}

/* ═══ A TABELA COMO FERRAMENTA DE TRABALHO (spec 089) ═══════════════════════
   Três coisas que qualquer tabela de trabalho tem e estas não tinham: cabeçalho que fica,
   identidade da linha que fica, e um jeito de caber mais linha na tela. Todas são OPÇÃO do
   componente `Tabela`, ligadas só nas 12 listas de trabalho (regra 6): cabeçalho fixo numa
   tabela de cinco linhas não faz nada, e coluna congelada numa tabela estreita come largura
   para resolver um problema que ali não existe. */

/* ── O INVÓLUCRO QUE ROLA ───────────────────────────────────────────────────
   A CAIXA ROLA NOS DOIS EIXOS, e o cabeçalho gruda NELA. É assim que todo datagrid de verdade
   funciona — MudBlazor, Radzen, AG Grid, todos —, e a primeira versão desta spec fez o oposto.

   O QUE DEU ERRADO, escrito para não voltar. A regra 4 recusou "caixa com altura" temendo duas
   barras de rolagem, e mandou a página rolar nos dois eixos (`overflow: visible`). O efeito nas
   12 listas de trabalho foi imediato e feio: sem caixa que rola, toda tabela larga empurra a
   PÁGINA INTEIRA para o lado, por baixo do menu fixo. O produto ficou torto em Boletins,
   Pedidos, Pagamentos, Histórico e na fila da CN de uma vez. O medo estava certo sobre o
   sintoma e errado sobre a causa: o problema de "duas barras" é altura FIXA, não altura MÁXIMA.

   `max-height` não força altura nenhuma: lista curta encolhe a caixa até o conteúdo e não
   aparece barra alguma; lista longa para no teto e rola por dentro, com o cabeçalho colado.
   E como o referencial do `sticky` passa a ser esta caixa, o cabeçalho fixo, a coluna congelada
   e a célula de canto passam a ter o MESMO referencial — que é o que faz os três funcionarem
   juntos sem conta de deslocamento nenhuma.

   Some com isso o `--pw-filtros-h: 80px`, que era um chute admitido no próprio comentário. Não
   há mais o que compor: o topo da caixa é o zero do cabeçalho. */
.pw-tabela-rolante {
    overflow: auto;

    /* `position: relative` É O QUE FAZ O `overflow` ACIMA VALER (spec 093, 21/09/2026).
       Foi a causa REAL da "faixa branca à direita" que o Leandro relatou, e custou nove
       tentativas de reprodução porque o culpado mede 1px e é invisível.

       `pw-sr-only` — o texto que só o leitor de tela lê — é `position: absolute` SEM
       deslocamento, então fica na posição estática. Dentro de um `<td>` da última coluna, isso é
       a ponta direita de uma tabela de 1.810px. E `td` comum não é posicionado: para um elemento
       absoluto, o navegador sobe procurando um ancestral posicionado e, não achando nenhum,
       ancora no QUADRO INICIAL. A partir daí ele está FORA deste contêiner — `overflow` não corta
       quem não pertence a você —, e estica o documento inteiro.

       O sintoma não parecia ter nada a ver: a página passava a rolar para o lado, o menu fixo
       cobria o começo do conteúdo ("Pedidos emitidos" virava "lidos emitidos") e sobrava uma
       faixa de fundo à direita, sem nada desenhado nela. Medido: documento de 1.972px numa janela
       de 1.239. Com `relative`, os mesmos spans ancoram AQUI e o `overflow` volta a alcançá-los.

       Por que o cabeçalho nunca teve o problema: `.pw-table--fixa thead th` é `sticky`, logo
       posicionado, logo já ancorava os spans dele. Só as linhas do corpo escapavam. */
    position: relative;
    max-height: var(--pw-tabela-altura);
    /* A rolagem para no fim de uma linha, e não no meio dela — meia linha visível no rodapé faz
       a pessoa pensar que a lista continua quando ela acabou. */
    scroll-snap-type: y proximity;
    border-radius: var(--pw-r-2);
    border: 1px solid var(--pw-hair);
    background: var(--pw-sheet);
}

/* ── CABEÇALHO FIXO (regras 4, 5 e 6) ───────────────────────────────────────
   `top: 0` e nada de deslocamento composto: o referencial é a caixa acima, e o topo dela já é o
   lugar certo. */
.pw-table--fixa thead th {
    position: sticky;
    top: 0;
    z-index: var(--pw-z-cabecalho);

    /* O fundo é OBRIGATÓRIO: é ele que impede as linhas de passarem por baixo do cabeçalho
       enquanto a caixa rola. O traço embaixo separa o cabeçalho grudado do corpo — sem ele,
       cabeçalho e primeira linha viram um bloco só no meio da rolagem. `box-shadow` e não
       `border` porque borda em célula grudada descola um pixel ao rolar, num efeito de serrilha
       que aparece em toda tabela e ninguém sabe nomear. */
    background: var(--pw-vellum);
    box-shadow: inset 0 -1px 0 var(--pw-line);
}

/* Dentro de caixa que rola, cabeçalho com canto arredondado mostra um naco do corpo por baixo
   do canto. Quem arredonda é a CAIXA. */
.pw-tabela-rolante .pw-table thead th:first-child,
.pw-tabela-rolante .pw-table thead th:last-child { border-radius: 0; }

/* ── A CÉLULA DA LISTA DE TRABALHO NÃO QUEBRA ───────────────────────────────
   É a diferença visual entre "tabela" e "grid", e foi o que fez a primeira versão parecer
   quebrada: sem isto, "BM-2026-000003" vira três linhas, "01/08/2026 a 31/08/2026" vira três
   e a memória de cálculo vira quatro. Cada linha fica com uma altura, a fileira perde o
   alinhamento, e a tabela deixa de se ler de cima a baixo — que é a única coisa que uma lista
   de trabalho precisa saber fazer.

   Quando não cabe, quem cede é a LARGURA e a caixa rola. É o que MudBlazor, Radzen e AG Grid
   fazem, e é honesto: a linha continua sendo uma linha.

   SÓ NA LISTA DE TRABALHO (`--fixa`). As tabelas de edição e de detalhe continuam quebrando —
   ali há descrição de serviço e motivo de devolução, texto que existe para ser lido inteiro, e
   forçá-lo numa linha só daria uma tabela de dois metros de largura. */
.pw-table--fixa tbody td,
.pw-table--fixa tbody th,
.pw-table--fixa tfoot td,
.pw-table--fixa tfoot th { white-space: nowrap; }

/* A exceção declarada pela TELA, para a coluna que de fato é um parágrafo. */
.pw-table--fixa .pw-col-quebra { white-space: normal; min-width: 28ch; }

/* ── A PRIMEIRA COLUNA, E SÓ ELA (regras 7 a 10) ────────────────────────────
   É a que identifica a linha: número da medição, número do pedido, nome do fornecedor.
   Congelar duas come a largura que a rolagem existe para liberar. */
.pw-table--congelada thead th:first-child,
.pw-table--congelada tbody tr > *:first-child,
.pw-table--congelada tfoot tr > *:first-child {
    position: sticky;
    left: 0;
    z-index: var(--pw-z-congelada);

    /* FUNDO PRÓPRIO (regra 8). Sem ele o conteúdo das outras colunas passa POR BAIXO dela e os
       textos se sobrepõem — é o defeito clássico, e é invisível até alguém rolar de lado. */
    background: var(--pw-sheet);
}

/* O fundo da coluna congelada acompanha o realce da linha: sem isto, passar o mouse pintaria a
   linha inteira menos a primeira célula, que é onde o olho está. */
.pw-table--congelada tbody tr:hover > *:first-child { background: var(--pw-vellum-2); }

/* A SOMBRA QUE DIZ "TEM MAIS COISA POR BAIXO" (regra 8).
   Não é decoração, e a borda sozinha não bastava: com só um traço, a coluna de trás passando
   por baixo lê-se como TEXTO CORTADO — na bancada apareceu "dido" no lugar de "Pedido" e
   "i10034663" no lugar de "4510034663", e o efeito é de tela quebrada, não de coluna fixa.
   A sombra dá profundidade: o que some, some POR BAIXO de algo, e isso o olho entende sozinho.

   Fica sempre desenhada porque `position: sticky` não tem como avisar o CSS de que já saiu do
   lugar — é o mesmo motivo pelo qual todo grid desenha essa sombra o tempo todo. */
.pw-table--congelada thead th:first-child,
.pw-table--congelada tbody tr > *:first-child,
.pw-table--congelada tfoot tr > *:first-child {
    border-right: 1px solid var(--pw-line);
    box-shadow: 4px 0 6px -4px rgba(var(--pw-shadow-rgb), .18);
}

/* A CÉLULA DE CANTO (regra 9). O cruzamento gruda nos DOIS eixos e fica acima dos dois; sem
   isso ela desliza por baixo de um deles e o cabeçalho da primeira coluna some. O fundo aqui é
   o do CABEÇALHO, e não o da coluna: ela pertence à linha de cima. */
.pw-table--fixa.pw-table--congelada thead th:first-child {
    z-index: var(--pw-z-canto);
    background: var(--pw-vellum);

    /* AS DUAS SOMBRAS, e não uma. `box-shadow` não acumula entre regras: a última declaração
       ganha inteira. Esta célula pertence às duas famílias — é cabeçalho (traço embaixo, que
       separa do corpo) e é coluna congelada (sombra à direita, que diz que há conteúdo por
       baixo). Declarar só uma apaga a outra em silêncio, e some justamente no canto, que é
       onde as duas se encontram. */
    box-shadow:
        inset 0 -1px 0 var(--pw-line),
        4px 0 6px -4px rgba(var(--pw-shadow-rgb), .18);
}

/* CONGELAR NÃO VALE EM TELA ESTREITA (regra 10): numa tela de 360px a coluna consumiria metade
   da largura para resolver um problema que, ali, se resolve rolando. O ponto de quebra é o
   mesmo em que a lateral some — é a mesma pergunta ("cabe?") respondida uma vez só. */
@media (max-width: 900px) {
    .pw-table--congelada thead th:first-child,
    .pw-table--congelada tbody tr > *:first-child,
    .pw-table--congelada tfoot tr > *:first-child {
        position: static;
        border-right: 0;
        background: transparent;
    }
}

/* A DENSIDADE SAIU em 21/09/2026 (spec 092, frente 2), e saiu INTEIRA: o par de botões
   "Compacta / Confortável" da spec 089, o script que guardava a escolha no navegador, o atributo
   do `<html>` de que estas regras partiam e as classes da tabela apertada.

   Na prática ninguém trocava — a confortável é a certa —, e o par ocupava a barra de ações de
   toda lista do produto. Classe que ninguém aplica é o caminho pelo qual uma opção removida
   volta seis meses depois, e é por isso que não ficou nada desligado aqui. A varredura que
   impede a volta é `ADensidadeNaoVoltaTests`. */

/* ── O RODAPÉ DA TABELA: posição e ações ────────────────────────────────────
   Uma linha só embaixo da lista, com onde-você-está à esquerda e o que-fazer à direita. */
.pw-tabela__rodape {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--pw-3);
    margin-top: var(--pw-4);
}
.pw-tabela__rodape > .pw-paginacao { margin-left: auto; }

/* ── A BARRA ACIMA DA TABELA (20/09/2026) ───────────────────────────────────
   Exportar morava no rodapé, ao lado da paginação, e ali só é encontrado por quem rola até o
   fim — numa lista de centenas de linhas, ninguém rola para procurar um botão que não sabe que
   existe. Subiu para cá, onde a pessoa já olha ao ler o título da lista.

   ENCOSTADA À DIREITA, e alinhada com o rodapé logo abaixo: as ações da lista ficam na mesma
   coluna vertical, em cima e embaixo, em vez de uma de cada lado.

   O rodapé ficou com o que é DA ROLAGEM — onde você está e como a lista se apresenta. */
.pw-tabela__barra {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end;
    gap: var(--pw-2);
    margin-bottom: var(--pw-3);
}

/* ── PAGINAÇÃO (regras 11 a 16) ─────────────────────────────────────────────
   A navegação é por LINK e não por botão (regra 12): funciona nas telas de render estático, o
   "voltar" do navegador funciona, e o endereço de uma página pode ser mandado para alguém. O
   `<a>` sem `href` é justamente o estado desabilitado da regra 16 — o navegador o tira da
   ordem de tabulação sozinho, e `aria-disabled` diz o mesmo a quem usa leitor de tela. */
.pw-paginacao { display: flex; align-items: center; gap: var(--pw-3); }
.pw-paginacao__posicao {
    color: var(--pw-ink-3); font-size: var(--pw-t-label); font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.pw-paginacao__passo { display: flex; gap: var(--pw-2); }

/* SEM PÁGINA SEGUINTE, O CONTROLE NÃO APARECE MENTINDO (regra 16). A ação existe, mas não
   agora — e isso precisa SER VISÍVEL, senão a pessoa clica, nada acontece e ela conclui que o
   sistema está quebrado. É o mesmo desenho de `.pw-btn:disabled`. */
.pw-paginacao .pw-btn[aria-disabled="true"] {
    opacity: .45; cursor: not-allowed; box-shadow: none; pointer-events: none;
}

/* CABEÇALHO QUE ORDENA (spec 088) — um link dentro do <th>, nunca o <th> inteiro clicável.
   Ele herda cor, peso e tamanho do próprio cabeçalho: a coluna ordenável não é um botão
   colorido no meio das outras, é a mesma coluna que responde ao clique. O que muda no estado
   ativo é a TINTA e a SETA, e nunca só a cor — a seta é o que informa quem não a distingue. */
.pw-ordenar {
    display: inline-flex; align-items: center; gap: var(--pw-1);
    color: inherit; font: inherit; text-decoration: none;
    border-radius: var(--pw-r-1);
    /* O ALVO OCUPA A ALTURA DA CÉLULA: o padding devolve, por dentro do link, o espaço que o
       <th> já reservava, e a margem negativa o tira de volta do fluxo. A linha não muda de
       altura e o dedo não precisa acertar a palavra — só a vertical, de propósito: mexer na
       horizontal empurraria a largura das colunas de número. */
    padding: 10px 0; margin: -10px 0;
}
.pw-ordenar:hover { color: var(--pw-ink); text-decoration: underline; }
.pw-ordenar:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: var(--pw-1); }
.pw-ordenar--ativa { color: var(--pw-ink); }
/* A seta acompanha o texto, no mesmo tamanho do ícone que acompanha um botão — e a cor sai do
   próprio texto (currentColor), para não virar mais uma dona de cor no produto. */
.pw-ordenar__seta { width: var(--pw-4); height: var(--pw-4); flex: none; color: currentColor; }

/* campos */
.pw-input, .pw-select {
    height: 40px; padding: 0 var(--pw-3);
    background: var(--pw-sheet); color: var(--pw-ink);
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-1);
    font-family: var(--pw-font); font-size: var(--pw-t-md);
}
.pw-input:focus, .pw-select:focus { outline: 2px solid var(--pw-notice); outline-offset: -1px; border-color: var(--pw-notice); }
.pw-label { display: block; font-size: var(--pw-t-label); font-weight: 600; color: var(--pw-ink-2); margin-bottom: var(--pw-1); }

/* A MENSAGEM — uma só no Portal (spec 106; substitui as cinco variantes de .pw-band).

   Mesmo desenho da confirmação (spec 105): ícone à esquerda num círculo, e à direita título, texto,
   o resumo rótulo → valor e os itens. Fundo lavado e filete à esquerda na cor do TIPO.

   AS CORES: vermelho = erro, VERDE = sucesso (dona nova do verde, decisão do Leandro de 24/09/2026),
   azul = informação, neutro = nota, ÂMBAR = atenção (03/10/2026). Texto sempre na tinta escura do tipo (-ink), nunca na cor cheia
   sobre o lavado: #D1344B sobre --pw-danger-bg dá 4,28:1, abaixo do AA. */
.pw-aviso {
    --aviso-fundo: var(--pw-notice-bg); --aviso-cor: var(--pw-notice); --aviso-tinta: var(--pw-notice-ink);
    display: flex; align-items: flex-start; gap: var(--pw-3);
    background: var(--aviso-fundo); color: var(--aviso-tinta);
    border: 1px solid color-mix(in srgb, var(--aviso-cor) 22%, transparent);
    border-left: 3px solid var(--aviso-cor);
    border-radius: var(--pw-r-2);
    padding: var(--pw-4) var(--pw-5);
    font-size: var(--pw-t-base); line-height: 1.5;
}
.pw-aviso--erro    { --aviso-fundo: var(--pw-danger-bg); --aviso-cor: var(--pw-danger); --aviso-tinta: var(--pw-danger-ink); }
.pw-aviso--sucesso { --aviso-fundo: var(--pw-safe-bg);   --aviso-cor: var(--pw-safe);   --aviso-tinta: var(--pw-safe-deep); }
.pw-aviso--info    { --aviso-fundo: var(--pw-notice-bg); --aviso-cor: var(--pw-notice); --aviso-tinta: var(--pw-notice-ink); }
.pw-aviso--nota    { --aviso-fundo: var(--pw-vellum-2);  --aviso-cor: var(--pw-heavy);  --aviso-tinta: var(--pw-ink-2); }
/* ATENÇÃO (alteração de 03/10/2026 da spec 106): o que segura o passo seguinte sem ser erro. Âmbar é
   a SEXTA dona. A tinta é a escura (5,57:1 sobre o --pw-warn-bg), e o --pw-warn só pinta ÁREA (o filete):
   como glifo sobre o círculo branco ele dá 2,13:1 (spec 072), por isso o sino usa o -ink. */
.pw-aviso--atencao { --aviso-fundo: var(--pw-warn-bg);   --aviso-cor: var(--pw-warn);   --aviso-tinta: var(--pw-warn-ink); }
.pw-aviso--atencao .pw-aviso__marca { color: var(--pw-warn-ink); }
/* O mesmo balanço do sininho da pendência (099/069): um sino só no produto. */
.pw-aviso__sino { transform-origin: 50% 10%; animation: pw-sino-balanca 2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
    .pw-aviso__sino { animation: none; }
}

.pw-aviso__marca {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 32px; height: 32px; border-radius: var(--pw-r-pill);
    background: var(--pw-sheet); color: var(--aviso-cor);
}
.pw-aviso--nota .pw-aviso__marca { color: var(--pw-ink-3); }
.pw-aviso__icone { width: 20px; height: 20px; }
.pw-aviso__corpo { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: var(--pw-1); }

/* Frase única: o texto alinha pelo centro do ícone, numa linha só. */
.pw-aviso--linha { align-items: center; padding-top: var(--pw-3); padding-bottom: var(--pw-3); }

.pw-aviso__titulo { font-weight: 700; font-size: var(--pw-t-md); color: var(--aviso-tinta); line-height: 1.35; }
.pw-aviso__subtitulo { color: var(--aviso-tinta); opacity: .85; font-size: var(--pw-t-base); }
.pw-aviso__texto { margin: 0; color: var(--aviso-tinta); overflow-wrap: anywhere; }
/* A frase (Mensagem) preserva a quebra que o servidor mandou; o conteúdo com marcação não — a quebra
   do código-fonte viraria linha em branco na tela. */
p.pw-aviso__texto { white-space: pre-line; }
.pw-aviso__titulo + .pw-aviso__texto,
.pw-aviso__subtitulo + .pw-aviso__texto { margin-top: var(--pw-1); }
.pw-aviso__texto p { margin: 0; }
.pw-aviso__texto a { color: inherit; font-weight: 600; }

/* O resumo: os NÚMEROS saem da frase (regra 3). Mesma grade da confirmação, sobre folha branca. */
.pw-aviso__fatos {
    margin: var(--pw-2) 0 0; padding: var(--pw-1) var(--pw-3);
    background: var(--pw-sheet); border-radius: var(--pw-r-1);
    display: flex; flex-direction: column; max-width: 560px;
}
.pw-aviso__fato {
    display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: var(--pw-3);
    padding: var(--pw-2) 0; border-top: 1px solid var(--pw-hair);
}
.pw-aviso__fato:first-child { border-top: none; }
.pw-aviso__fato dt { color: var(--pw-ink-3); font-size: var(--pw-t-label); font-weight: 600; }
.pw-aviso__fato dd { margin: 0; color: var(--pw-ink); font-weight: 700; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pw-aviso__linha { display: block; }

.pw-aviso__rotulo {
    margin: var(--pw-2) 0 0; color: var(--aviso-tinta);
    font-size: var(--pw-t-xs); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
.pw-aviso__itens { margin: var(--pw-1) 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--pw-1); }
.pw-aviso__itens li { position: relative; padding-left: var(--pw-4); color: var(--aviso-tinta); overflow-wrap: anywhere; }
.pw-aviso__itens li::before {
    content: ""; position: absolute; left: 2px; top: .62em;
    width: 6px; height: 6px; border-radius: var(--pw-r-pill); background: var(--aviso-cor);
}

.pw-aviso__rodape { margin-top: var(--pw-2); display: flex; flex-wrap: wrap; align-items: center; gap: var(--pw-2); }

/* o rastro da falha (spec 061): o número que a pessoa dita ao suporte e que acha a linha do log.
   Em letra menor e em linha própria — ele é para ser copiado, não para ser lido junto da frase.
   Fonte tabular porque é um identificador: dígito de largura fixa não se confunde na leitura. */
.pw-aviso__rastro {
    display: block;
    font-size: var(--pw-t-2xs);
    font-variant-numeric: tabular-nums;
    opacity: .8;
    word-break: break-all;
}

/* Estreito pela largura do PRÓPRIO aviso (a lição da spec 105: ele mora em coluna estreita de tela
   larga). O rótulo sobe para cima do valor. */
.pw-aviso { container-type: inline-size; }
@container (max-width: 480px) {
    .pw-aviso__fato { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}
@media (max-width: 560px) {
    .pw-aviso { padding: var(--pw-3) var(--pw-4); }
}

/* grid utilitário do painel */
.pw-grid { display: grid; gap: var(--pw-4); }
/* Cartão de número tem UMA trilha em todo o produto (spec 031, item 6).
   Havia duas: esta e `--stats-compacto`, que travava a coluna em 300px. No Painel as duas
   apareciam uma sob a outra, e o resultado eram cartões de 300px acima de cartões de 376px,
   na mesma coluna — borda direita em degrau, a mesma família de defeito que a spec 027
   corrigiu na tela de primeiro acesso. A classe compacta foi REMOVIDA, e não só deixou de
   ser usada: enquanto ela existir, alguém a usa de novo. */
.pw-grid--stats { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

/* TRÊS COLUNAS FIXAS, para fileiras vizinhas alinharem (spec 031, item 6).
   `auto-fit` dimensiona pela QUANTIDADE de cartões: uma fileira de 2 e outra de 3, uma sob a
   outra, saem com larguras diferentes e a borda direita fica em degrau — que é o defeito que
   o Leandro viu no Painel. E a quantidade varia por PERMISSÃO: o mesmo painel tem 3 cartões
   para Suprimentos e 2 para o Usuário CN, então não há como acertar contando à mão.
   Com trilhas fixas, a fileira incompleta deixa um vão à direita em vez de esticar os
   cartões — vão é o desenho da grade aparecendo, degrau é erro. */
@media (min-width: 1080px) {
    .pw-grid--stats-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------------------
   BLOCOS DE FORMULÁRIO E MATRIZ (tela de perfis e permissões)
   --------------------------------------------------------------------------- */

/* título de bloco dentro de um cartão — um degrau abaixo do título da página */
.pw-section__title { font-size: var(--pw-t-lg); font-weight: 700; letter-spacing: -0.01em; margin: 0 0 var(--pw-1); }
.pw-section__sub   { color: var(--pw-ink-3); font-size: var(--pw-t-xs); margin: 0 0 var(--pw-4); }

.pw-hint { color: var(--pw-ink-3); font-size: var(--pw-t-xs); }

/* o ÚNICO mecanismo de seleção do sistema: o input nativo, 18px, tingido com accent-color */
.pw-check {
    width: 18px; height: 18px; margin: 0;
    accent-color: var(--pw-notice); cursor: pointer;
}
.pw-check:disabled { cursor: not-allowed; opacity: .55; }

/* ══ A árvore do pedido: item → serviços (spec 110) ═══════════════════════
   Na medição e na lista de pedidos. O item com serviços ganha uma linha de CABEÇALHO (fundo de
   papel, + / −, subtotal) e os serviços ficam recuados embaixo, com o ramo "└" — é o desenho que o
   Leandro pediu ("+ ITEM / |___ SERVIÇO"). O + / − é BOTÃO, com aria-expanded: é a ação de abrir. */
.pw-arvore__item > td, .pw-arvore__item > th { background: var(--pw-paper); }
.pw-arvore__botao {
    display: inline-flex; align-items: center; justify-content: center;
    width: 24px; height: 24px; margin-right: var(--pw-2);
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-1);
    background: var(--pw-sheet); color: var(--pw-ink);
    font-weight: 700; line-height: 1; cursor: pointer;
}
.pw-arvore__botao:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: var(--pw-1); }
.pw-arvore__resumo { display: block; color: var(--pw-ink-3); font-size: var(--pw-t-xs); }
/* A situação do item (spec 112) na linha de BAIXO do número, com respiro: ao lado, a pílula colava no
   número e parecia fazer parte dele. */
.pw-arvore__situacao { display: flex; width: fit-content; margin-top: var(--pw-2); }
.pw-arvore__ramo { color: var(--pw-ink-4); padding-left: var(--pw-4); }

/* Na LISTA de pedidos, a árvore abre sem código no navegador: a caixa escondida guarda o estado,
   o rótulo é o botão (+ fechado, − aberto) e a linha de baixo aparece com a caixa marcada. */
.pw-arvore__rotulo::before { content: "+"; }
.pw-arvore__estado:checked + .pw-arvore__rotulo::before { content: "−"; }
.pw-arvore__estado:focus-visible + .pw-arvore__rotulo { outline: 2px solid var(--pw-notice); outline-offset: var(--pw-1); }
.pw-arvore__detalhe { display: none; }
tr:has(.pw-arvore__estado:checked) + .pw-arvore__detalhe { display: table-row; }
/* TABULADA: cada nível entra recuado em relação ao de cima (alteração de 25/09/2026) — o item
   dentro do pedido, o serviço dentro do item. */
.pw-arvore__detalhe > td, .pw-arvore__sub > td {
    background: var(--pw-paper);
    padding: var(--pw-3) var(--pw-4);
}
/* A SUB-TABELA é que entra recuada, e não o conteúdo dela (alteração de 25/09/2026): uma caixa de
   folha com borda e filete à esquerda, deslocada para dentro — o aspecto de "interno". Como a caixa
   do serviço mora dentro da do item, o recuo soma a cada nível. */
.pw-arvore__caixa {
    margin-left: var(--pw-7);
    background: var(--pw-sheet);
    border: 1px solid var(--pw-line);
    border-left: 3px solid var(--pw-line);
    border-radius: var(--pw-r-2);
}

.pw-check:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: var(--pw-1); }

/* A caixa fica em 18px (regra do sistema), mas a ÁREA DE TOQUE ocupa a célula inteira:
   as margens negativas sangram até a borda da td e o padding devolve o respiro. */
.pw-check-cell {
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    margin: calc(var(--pw-3) * -1) calc(var(--pw-4) * -1);
    padding: var(--pw-3) var(--pw-4);
}
.pw-check-cell:has(.pw-check:disabled) { cursor: not-allowed; }

/* rótulo só para leitor de tela — cabeçalho de coluna de ações, por exemplo */
.pw-sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* matriz perfil × permissão: colunas de marcação centradas e de largura estável */
.pw-table--matrix th.pw-col-check,
.pw-table--matrix td.pw-col-check { text-align: center; width: 150px; }
.pw-table--matrix tbody tr.pw-row-group th {
    background: var(--pw-vellum-2); color: var(--pw-ink-2); font-weight: 700;
    text-align: left; padding: 10px var(--pw-4);
}
.pw-table__field { width: 100%; }

/* Textarea de DUAS linhas dentro de tabela (spec 031, item 7.4): alta o bastante para a
   descrição caber, baixa o bastante para a linha da tabela não dobrar de altura. */
.pw-textarea--curta { min-height: 58px; line-height: 1.35; }

/* linha de ações de um formulário */
/* estado vazio DENTRO de um cartão — não confundir com .pw-empty, que é a casca de
   tela inteira do login. Centralizado e com a linha curta: é um recado, não um parágrafo. */
.pw-vazio { padding: var(--pw-6) var(--pw-4); text-align: center; }
.pw-vazio .pw-section__sub { max-width: 46ch; margin: var(--pw-1) auto 0; }

/* botão desabilitado: a ação existe, mas não agora — e isso precisa SER VISÍVEL, senão a
   pessoa clica, nada acontece e ela conclui que o sistema está quebrado. */
.pw-btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }

.pw-actions { display: flex; flex-wrap: wrap; gap: var(--pw-3); align-items: center; margin-top: var(--pw-4); }
.pw-actions--end { justify-content: flex-end; }

/* A célula de AÇÕES de uma LINHA de tabela — e não é `pw-actions` (19/09/2026).
   Aquela é a barra de ações de um BLOCO: traz `margin-top`, que dentro de um <td> empurra o
   conteúdo e desalinha a linha inteira, e `flex-wrap`, que em tela estreita empilha os botões e
   estica a altura. Os dois estragam justamente o que uma tabela precisa ter: linhas do mesmo
   tamanho.
   Os botões aqui são MENORES que os de bloco: numa lista de 20 linhas, o botão de formulário
   inteiro vira uma parede. */
.pw-acoes-linha {
    display: flex; gap: var(--pw-2); align-items: center;
    justify-content: flex-end; flex-wrap: nowrap;
}
.pw-acoes-linha .pw-btn { height: 36px; padding: 0 var(--pw-3); font-size: var(--pw-t-label); }

/* rolagem horizontal da matriz em telas estreitas, sem estourar o cartão.

   `position: relative` NÃO É ENFEITE — é o que faz o `overflow` valer (spec 093, 21/09/2026).
   Ver o porquê em `.pw-tabela-rolante`, logo abaixo: um descendente `position: absolute` sem
   ancestral posicionado ancora no QUADRO INICIAL e atravessa qualquer contêiner de rolagem. */
.pw-scroll-x { overflow-x: auto; position: relative; }

/* ---------------------------------------------------------------------------
   TELA DE ENTRADA (/entrar)
   --------------------------------------------------------------------------- */
.pw-empty { min-height: 100vh; background: var(--pw-paper); }

.pw-login {
    min-height: 100vh;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: var(--pw-4); padding: var(--pw-5);
}
.pw-login__card {
    width: 100%; max-width: 420px;
    display: flex; flex-direction: column; align-items: stretch;
    padding: var(--pw-7) var(--pw-6);
    border-radius: var(--pw-r-4);
}
.pw-login__logo { height: 64px; align-self: center; margin-bottom: var(--pw-5); }
.pw-login__lead {
    text-align: center; color: var(--pw-ink-2);
    font-size: var(--pw-t-md); margin: 0 0 var(--pw-6);
}
.pw-login__btn { width: 100%; margin-bottom: var(--pw-3); height: 44px; font-size: var(--pw-t-md); }
/* A marca da Cimento Nacional DENTRO do botão de entrar (spec 042, 28/09/2026): a versão branca,
   na altura do texto, para "Entrar com" + marca lerem como uma frase só. */
.pw-login__btn-marca {
    height: 22px; width: auto; display: block;
    /* O PNG tem uma sobra transparente EMBAIXO (~27% da altura): centralizada pela caixa, a marca
       ficava acima da linha do texto. O deslocamento devolve o desenho ao centro óptico. */
    transform: translateY(3px);
}
.pw-login__hint {
    text-align: center; color: var(--pw-ink-3);
    font-size: var(--pw-t-label); line-height: 1.6; margin: var(--pw-4) 0 0;
}
.pw-login__foot { color: var(--pw-ink-4); font-size: var(--pw-t-xs); }

/* login do fornecedor (/entrar/fornecedor) — formulário dentro do mesmo cartão */
.pw-login__title {
    text-align: center; font-size: var(--pw-t-xl); font-weight: 800;
    letter-spacing: -0.015em; margin: 0 0 var(--pw-1);
}
.pw-login__title + .pw-login__lead { margin-bottom: var(--pw-5); }
.pw-login__msg { margin-bottom: var(--pw-4); }
.pw-login__form { display: flex; flex-direction: column; gap: var(--pw-4); }
.pw-login__field { display: flex; flex-direction: column; }
.pw-login__field .pw-input,
.pw-login__field .pw-select { width: 100%; }
.pw-login__actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--pw-3); }
.pw-login__actions .pw-btn { width: 100%; height: 44px; font-size: var(--pw-t-md); }
.pw-login__links {
    display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
    gap: var(--pw-2); margin-top: var(--pw-4);
}
.pw-login__links-sep { color: var(--pw-ink-4); }
/* alvo de toque confortável no celular, sem engordar o link inline */
.pw-login__links .pw-link {
    display: inline-flex; align-items: center;
    min-height: 40px; padding: 0 var(--pw-2);
}

/* link discreto — vale para <a> e para <button> de ação sem navegação */
.pw-link {
    background: none; border: none; padding: 0;
    font-family: var(--pw-font); font-size: var(--pw-t-label); font-weight: 600;
    color: var(--pw-notice); text-decoration: none; cursor: pointer;
}
.pw-link:hover { color: var(--pw-notice-ink); text-decoration: underline; }
.pw-link:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: var(--pw-1); border-radius: var(--pw-r-1); }

/* telas pequenas: o cartão respira menos e as ações empilham */
@media (max-width: 420px) {
    .pw-login__card { padding: var(--pw-6) var(--pw-5); }
    .pw-login__actions { grid-template-columns: 1fr; }
}

/* marca da empresa-mãe (Cimento Nacional) — dentro do cartão de login */
.pw-login__cn {
    display: flex; justify-content: center;
    margin-top: var(--pw-5); padding-top: var(--pw-4);
    border-top: 1px solid var(--pw-hair);
}
.pw-login__cn img { height: 30px; opacity: .9; }
.pw-side__foot { margin-top: auto; padding: var(--pw-4) var(--pw-3) var(--pw-2); border-top: 1px solid var(--pw-hair); display: flex; flex-direction: column; gap: var(--pw-1); }
.pw-side__foot span { color: var(--pw-ink-4); font-size: var(--pw-t-2xs); font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.pw-side__foot img { height: 22px; align-self: flex-start; opacity: .85; }

/* ══ Acesso do fornecedor (spec 005) ═══════════════════════════════════════
   Quatro componentes que o design system ainda não tinha: busca com sugestões,
   caixas do código de verificação, medidor de força de senha e chips de
   fornecedor. Tudo em tokens — nenhum valor de cor, espaço ou raio solto. */

/* combo pesquisável: a lista só existe quando há resultado */
.pw-busca { position: relative; }
.pw-busca__lista {
    position: absolute; z-index: 20; top: calc(100% + var(--pw-1)); left: 0; right: 0;
    margin: 0; padding: var(--pw-1); list-style: none;
    background: var(--pw-sheet); border: 1px solid var(--pw-line);
    border-radius: var(--pw-r-2); box-shadow: 0 12px 28px rgba(var(--pw-shadow-rgb), .12);
    max-height: 260px; overflow-y: auto;
}
.pw-busca__item {
    display: block; width: 100%; text-align: left; cursor: pointer;
    padding: var(--pw-3); min-height: 44px; border: 0; border-radius: var(--pw-r-1);
    background: transparent; font-family: var(--pw-font); font-size: var(--pw-t-base);
    color: var(--pw-ink);
}
.pw-busca__item:hover, .pw-busca__item:focus-visible { background: var(--pw-vellum); outline: none; }
.pw-busca__item[aria-selected="true"] { background: var(--pw-notice-bg); }
.pw-busca__nome { display: block; font-weight: 600; }
.pw-busca__meta { display: block; color: var(--pw-ink-3); font-size: var(--pw-t-xs); margin-top: 2px; }
.pw-busca__vazio { padding: var(--pw-3); color: var(--pw-ink-3); font-size: var(--pw-t-base); }
.pw-busca__item:disabled { cursor: default; opacity: .6; background: transparent; }
/* A lupa dentro do campo (spec 098): diz "isto procura" antes de a pessoa ler o exemplo. */
.pw-busca__campo { position: relative; }
.pw-busca__lupa {
    position: absolute; left: var(--pw-3); top: 50%; transform: translateY(-50%);
    width: var(--pw-4); height: var(--pw-4); color: var(--pw-ink-4); pointer-events: none;
}
.pw-busca__campo .pw-busca__input { padding-left: calc(var(--pw-3) + var(--pw-4) + var(--pw-2)); width: 100%; }
.pw-busca__dica { margin: var(--pw-1) 0 0; }

/* código de verificação: 6 caixas, colar permitido */
.pw-codigo { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--pw-2); }
.pw-codigo__caixa {
    width: 100%; height: 56px; text-align: center;
    font-family: var(--pw-font); font-size: var(--pw-t-xl); font-weight: 700;
    color: var(--pw-ink); background: var(--pw-sheet);
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-2);
}
.pw-codigo__caixa:focus {
    outline: 2px solid var(--pw-notice); outline-offset: -1px; border-color: var(--pw-notice);
}

/* medidor de força da senha */
.pw-forca { display: flex; flex-direction: column; gap: var(--pw-1); margin-top: var(--pw-2); }
.pw-forca__trilha { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--pw-1); }
.pw-forca__parte { height: 4px; border-radius: var(--pw-r-pill); background: var(--pw-hair); }
.pw-forca--fraca .pw-forca__parte:nth-child(1) { background: var(--pw-danger); }
.pw-forca--media .pw-forca__parte:nth-child(-n+2) { background: var(--pw-warn); }
.pw-forca--forte .pw-forca__parte { background: var(--pw-safe); }
.pw-forca__rotulo { font-size: var(--pw-t-xs); font-weight: 600; color: var(--pw-ink-3); }
.pw-forca--fraca .pw-forca__rotulo { color: var(--pw-danger-ink); }
.pw-forca--media .pw-forca__rotulo { color: var(--pw-warn-ink); }
.pw-forca--forte .pw-forca__rotulo { color: var(--pw-safe); }

/* critérios da política de senha */
.pw-criterios { margin: var(--pw-2) 0 0; padding: 0; list-style: none; display: grid; gap: var(--pw-1); }
.pw-criterios li { font-size: var(--pw-t-xs); color: var(--pw-ink-3); display: flex; gap: var(--pw-2); }
.pw-criterios li::before { content: "○"; color: var(--pw-ink-4); }
.pw-criterios li.ok { color: var(--pw-safe); }
.pw-criterios li.ok::before { content: "●"; color: var(--pw-safe); }

/* fornecedores escolhidos no 1º acesso */
.pw-chips { display: flex; flex-wrap: wrap; gap: var(--pw-2); }
.pw-chip {
    display: inline-flex; align-items: center; gap: var(--pw-2);
    padding: var(--pw-1) var(--pw-3); border-radius: var(--pw-r-pill);
    background: var(--pw-vellum); border: 1px solid var(--pw-line);
    font-size: var(--pw-t-xs); font-weight: 600; color: var(--pw-ink-2);
}
.pw-chip--erro { background: var(--pw-danger-bg); border-color: var(--pw-danger); color: var(--pw-danger-ink); }
.pw-chip__x {
    border: 0; background: transparent; cursor: pointer;
    min-width: 24px; min-height: 24px; padding: var(--pw-1);
    color: var(--pw-ink-3); font-size: var(--pw-t-md); line-height: 1;
}
.pw-chip__x:hover { color: var(--pw-danger); }

/* passos do 1º acesso */
.pw-passos { display: flex; gap: var(--pw-2); margin-bottom: var(--pw-5); }
.pw-passo {
    flex: 1; height: 4px; border-radius: var(--pw-r-pill); background: var(--pw-hair);
}
.pw-passo--ativo { background: var(--pw-notice); }
.pw-passo--feito { background: var(--pw-safe); }
.pw-chips--bloco { margin-bottom: var(--pw-4); }

/* ══ Fila de aprovação de cadastros (spec 006) ═════════════════════════════ */

/* espaçamento de bloco — substitui o style inline que a tela usaria para isso */
.pw-bloco { margin-bottom: var(--pw-4); }

/* ── BARRA DE FILTRO — uma só, para todas as telas (spec 031, item 4) ──────
   Havia duas classes fazendo este mesmo trabalho de formas diferentes: `pw-filtros`
   (grade de colunas fixas) e `pw-toolbar` (flex com wrap). A de flex quebrava: com cinco
   controles em /pagamentos os botões caíam 68px abaixo dos campos, alinhados ao título e
   longe do formulário que eles submetem. Medido a 1440px:

       campos  em y529 · botões em y597

   Quebrar por acidente é o problema — não o wrap em si. Uma barra de filtro tem uma coisa a
   dizer: "estes são os campos, esta é a ação". Jogar a ação para outra linha desmancha a
   frase. A correção é dar aos campos uma base PEQUENA e liberdade de encolher, de modo que a
   linha caiba por construção, e só empilhar quando de fato não couber (celular).

   As larguras não são estéticas. 260px é onde cabe inteiro o maior placeholder do produto
   ("Pedido, descrição ou centro", que a 200px era cortado em "…ou cen"); 116px é onde
   "Pesquisar" respira, contra os 77px a que o botão encolhia quando a coluna era só `auto`. */
.pw-filtros {
    display: flex; flex-wrap: wrap; align-items: flex-end;
    gap: var(--pw-3);
    margin-bottom: var(--pw-5);
}

/* O título ocupa uma LINHA INTEIRA (base 100%), acima dos campos. Ele descreve o resultado,
   não o filtro — mantê-lo na mesma linha dos campos era o que empurrava as ações para fora. */
.pw-filtros__titulo { flex: 1 0 100%; }
.pw-filtros__titulo h2 { font-size: var(--pw-t-lg); font-weight: 700; margin: 0; }
.pw-filtros__titulo p { font-size: var(--pw-t-label); color: var(--pw-ink-3); margin: 2px 0 0; }

/* Base pequena e livre para ENCOLHER (`min-width: 0`) é o que garante a linha única: com
   quatro campos e as ações, 4×160 + 250 cabe folgado numa coluna de 1100px, e cada campo
   estica com o que sobrar. Base grande é o que fazia a barra quebrar. */
.pw-filtros__campo { flex: 1 1 120px; min-width: 0; }
.pw-filtros__campo .pw-input,
.pw-filtros__campo .pw-select { width: 100%; }

/* A busca vale por dois: é o campo que a pessoa usa, e o único cujo placeholder precisa
   caber inteiro. */
.pw-filtros__campo--busca { flex: 2 1 145px; }

/* A ETAPA precisa de base maior que os demais (20/09/2026): "Folha de serviço solicitada" é o
   rótulo mais longo do catálogo, e um `select` estreito corta o valor ESCOLHIDO — não o que
   está na lista aberta, que o navegador dimensiona sozinho. Foi assim que a 1ª rodada da 089
   exibiu "Tod". Ela ENCOLHE como os outros; o que muda é de onde começa. */
.pw-filtros__campo--etapa { flex: 1 1 212px; }

/* As ações não encolhem nem esticam, e ficam coladas à direita. */
.pw-filtros__acoes {
    display: flex; gap: var(--pw-3); align-items: flex-end;
    flex: 0 0 auto; margin-left: auto;
}
.pw-filtros__acoes .pw-btn { min-width: 100px; }

/* No celular a barra empilha e as ações ocupam a largura toda — lá empilhar é o certo. O
   que não podia era empilhar num monitor de 1440px. */
@media (max-width: 719px) {
    .pw-filtros__campo { flex: 1 1 100%; }
    .pw-filtros__acoes { margin-left: 0; flex: 1 1 100%; }
    .pw-filtros__acoes .pw-btn { flex: 1; }
}

/* decisão por linha: o motivo acima, as ações abaixo */
.pw-decisao { display: flex; flex-direction: column; gap: var(--pw-2); }
.pw-decisao .pw-actions { margin-top: 0; }

/* A LINHA JÁ DECIDIDA da fila de acessos (spec 091): o laudo à esquerda, a ação à direita, na
   MESMA linha.

   Empilhada — que é o padrão da célula, feito para o campo de motivo mais os dois botões —, a
   ação de revogar flutuava no canto direito ABAIXO do texto, e cada linha ganhava uma altura
   diferente conforme o laudo tivesse uma ou duas linhas. Altura irregular é justamente o que
   uma tabela não pode ter: é o que faz o olho perder a horizontal ao varrer a coluna. */
.pw-decisao--decidida {
    flex-direction: row; align-items: center;
    justify-content: space-between; gap: var(--pw-3);
}

/* A CONFIRMAÇÃO — uma só no Portal (spec 105; substitui o .pw-confirmacao__texto da 091).

   Um painel NEUTRO dentro do cartão: fundo lavado, contorno e um filete à esquerda na tinta do
   produto. Vermelho/âmbar/verde têm donas (CLAUDE.md) — o tom de perigo fica só no botão.

   O miolo é para CONFERIR, não para ler: o resumo é uma grade rótulo → valor (o rótulo numa coluna
   fixa, o valor quebra dentro da dele), e as consequências são itens curtos. Era um parágrafo com
   quatro fatos quebrando linha no meio de um nome — o que o Leandro chamou de "quebrando linha à toa". */
.pw-confirmacao {
    background: var(--pw-vellum-2);
    border: 1px solid var(--pw-line);
    border-left: 3px solid var(--pw-ink);
    border-radius: var(--pw-r-2);
    padding: var(--pw-5);
    display: flex; flex-direction: column; gap: var(--pw-4);
    max-width: 720px;
    margin-top: var(--pw-4);
}
.pw-confirmacao:focus { outline: none; }
.pw-confirmacao:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 2px; }

.pw-confirmacao__cabeca { display: flex; align-items: center; gap: var(--pw-3); }
.pw-confirmacao__marca {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 40px; height: 40px; border-radius: var(--pw-r-pill);
    background: var(--pw-ink-bg); color: var(--pw-ink);
}
.pw-confirmacao__icone { width: var(--pw-5); height: var(--pw-5); }
.pw-confirmacao__titulos { min-width: 0; }
.pw-confirmacao__titulo {
    margin: 0; font-size: var(--pw-t-lg); font-weight: 700; color: var(--pw-ink);
    line-height: 1.3; overflow-wrap: anywhere;
}
.pw-confirmacao__subtitulo { margin: 2px 0 0; color: var(--pw-ink-3); font-size: var(--pw-t-base); }

/* O resumo: rótulo em coluna fixa, valor ocupando o resto. Nome longo quebra NA coluna do valor. */
.pw-confirmacao__fatos {
    margin: 0; padding: var(--pw-3) var(--pw-4);
    background: var(--pw-sheet); border: 1px solid var(--pw-hair); border-radius: var(--pw-r-1);
    display: flex; flex-direction: column;
}
.pw-confirmacao__fato {
    display: grid; grid-template-columns: 9.5rem minmax(0, 1fr); gap: var(--pw-3);
    padding: var(--pw-2) 0; border-top: 1px solid var(--pw-hair);
}
.pw-confirmacao__fato:first-child { border-top: none; }
.pw-confirmacao__fato dt {
    color: var(--pw-ink-3); font-size: var(--pw-t-label); font-weight: 600;
}
.pw-confirmacao__fato dd {
    margin: 0; color: var(--pw-ink); font-size: var(--pw-t-base); font-weight: 600;
    overflow-wrap: anywhere;
}
.pw-confirmacao__linha { display: block; }
.pw-confirmacao__linha + .pw-confirmacao__linha { margin-top: 2px; }

.pw-confirmacao__campos { display: flex; flex-direction: column; gap: var(--pw-2); }
.pw-confirmacao__campos .pw-textarea,
.pw-confirmacao__campos .pw-input { width: 100%; }

/* Ações: a principal primeiro, Cancelar depois — sempre (regra 2). Separadas do miolo por um filete. */
.pw-confirmacao__acoes {
    display: flex; flex-wrap: wrap; gap: var(--pw-2);
    padding-top: var(--pw-4); border-top: 1px solid var(--pw-line);
}

/* COMPACTA: dentro de linha de tabela. Mesmo desenho, espaçamento de célula, sem o rótulo
   "O que acontece" — a célula não tem altura para cabeçalho de seção. */
.pw-confirmacao--compacta {
    padding: var(--pw-3) var(--pw-4); gap: var(--pw-3); margin-top: var(--pw-2);
    /* A LARGURA MÍNIMA é o que faz a coluna de ações da tabela abrir: sem ela a célula encolhia
       e o título quebrava letra a letra ("Recusar / a / delegaç / ão") — medido na bancada. */
    min-width: 20rem; max-width: 480px; text-align: left; white-space: normal;
}
.pw-confirmacao--compacta .pw-confirmacao__marca { width: 32px; height: 32px; }
.pw-confirmacao--compacta .pw-confirmacao__icone { width: var(--pw-4); height: var(--pw-4); }
.pw-confirmacao--compacta .pw-confirmacao__titulo { font-size: var(--pw-t-base); }
.pw-confirmacao--compacta .pw-confirmacao__acoes { padding-top: var(--pw-3); }

/* ESTREITO pela largura do PRÓPRIO painel, e não da janela: ele mora também em coluna estreita de
   tela larga (a de "Meu acesso", a célula da tabela). Com @media, o valor ficava numa coluna de 60px
   quebrando "bmm@po/werwaveso/lutions" — medido na bancada da spec 105. */
.pw-confirmacao { container-type: inline-size; }
@container (max-width: 480px) {
    .pw-confirmacao__fatos { padding: var(--pw-2) var(--pw-3); }
    /* O rótulo sobe para cima do valor: coluna fixa de 9,5rem espremeria o valor. */
    .pw-confirmacao__fato { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .pw-confirmacao__acoes .pw-btn { flex: 1 1 auto; }
}
@media (max-width: 560px) {
    .pw-confirmacao { padding: var(--pw-4); }
}


/* ─────────────────────────────────────────────────────────────────────────
   Componentes das telas do fornecedor (spec 011)

   Vieram do protótipo aprovado (docs/marca/proto-telas.html) sem reescrita:
   o desenho já estava validado e já usava só tokens --pw-*. Copiar em vez de
   redesenhar é o que garante que a tela entregue seja a tela aprovada.
   ───────────────────────────────────────────────────────────────────────── */
.pw-tabs { display:flex; gap:4px; background:var(--pw-vellum); padding:4px; border-radius:var(--pw-r-2); margin-bottom:var(--pw-5); }
.pw-tab { flex:1; text-align:center; padding:9px 12px; border-radius:var(--pw-r-1); font-weight:600; font-size:var(--pw-t-base); color:var(--pw-ink-3); cursor:pointer; border:none; background:none; font-family:var(--pw-font); text-decoration:none; }
.pw-tab:hover { color:var(--pw-ink); }
.pw-tab.ativo { background:var(--pw-sheet); color:var(--pw-ink); box-shadow:0 1px 2px rgba(var(--pw-shadow-rgb),.08); }
.pw-progress { display:flex; align-items:center; gap:var(--pw-2); min-width:120px; }
.pw-progress__trilho { flex:1; height:6px; background:var(--pw-vellum); border-radius:999px; overflow:hidden; }
/* A FAIXA ÚNICA DE CONSUMO (spec 068, 4ª rodada, regra D1): verde tranquilo, âmbar a partir
   de 80% e vermelho quando o saldo acabou. As três classes saem de Charts.FaixaDoConsumo e são
   as MESMAS de .pw-medidor__barra e .pw-medidor__fill — é uma paleta só para "quanto já foi",
   e não uma por tela. O azul de antes não dizia nada em 100%. */
/* A base é o degrau MAIS CLARO da rampa, e não o verde cheio: se por algum motivo a classe do
   degrau não chegar, a barra aparece vazia — que é o estado honesto — em vez de "concluída". */
.pw-progress__barra { height:100%; background:var(--pw-cons-1); border-radius:999px; }
.pw-progress__barra--cons-1 { background:var(--pw-cons-1); }
.pw-progress__barra--cons-2 { background:var(--pw-cons-2); }
.pw-progress__barra--cons-3 { background:var(--pw-cons-3); }
.pw-progress__barra--cons-4 { background:var(--pw-cons-4); }
.pw-progress__barra--cons-5 { background:var(--pw-cons-5); }
/* A BARRA DE SINCRONIZAÇÃO (spec 076, regra 17) tem classes PRÓPRIAS, e não as três de consumo.
   Lá 100% é crítico (o pedido estourou); aqui 100% é sucesso (a carga terminou) — a mesma forma
   com significados opostos na mesma instalação é o tipo de coisa que ninguém explica depois.
   Reusar as de consumo faria, além disso, a guarda "toda classe de consumo sai de
   Charts.FaixaDoConsumo" passar a ver chamada legítima como violação.
   Enquanto roda é AZUL: andamento não é bom nem ruim, e 60% não é "atenção". */
.pw-progress__barra--sync-andamento { background:var(--pw-notice); }
.pw-progress__barra--sync-ok { background:var(--pw-safe); }
.pw-progress__barra--sync-falhou { background:var(--pw-danger); }
.pw-progress__barra--sync-neutro { background:var(--pw-ink-4); }
/* Barra INDETERMINADA: a primeira carga da view não tem régua, então não há percentual — e
   inventar um total ali seria mentir com precisão de duas casas. O trilho pulsa para dizer
   "andando, sem saber quanto falta", em vez de mostrar uma barra parada em zero. */
.pw-progress__trilho--indeterminado { position:relative; }
.pw-progress__trilho--indeterminado .pw-progress__barra { width:35%; animation:pw-sync-desliza 1.4s ease-in-out infinite; }
@keyframes pw-sync-desliza { 0% { margin-left:0; } 50% { margin-left:65%; } 100% { margin-left:0; } }
/* Quem pediu para reduzir movimento não perde a informação: a barra fica cheia e quieta, e o
   texto ao lado continua dizendo o número de linhas. */
@media (prefers-reduced-motion: reduce) {
    .pw-progress__trilho--indeterminado .pw-progress__barra { width:100%; animation:none; }
}
.pw-progress__valor { font-size:var(--pw-t-xs); color:var(--pw-ink-3); font-variant-numeric:tabular-nums; min-width:32px; text-align:right; }
.pw-toolbar { display:flex; align-items:flex-end; gap:var(--pw-3); margin-bottom:var(--pw-4); flex-wrap:wrap; }
.pw-toolbar__titulo { margin-right:auto; }
.pw-toolbar__titulo h2 { font-size:var(--pw-t-lg); font-weight:700; margin:0; }
.pw-toolbar__titulo p { font-size:var(--pw-t-label); color:var(--pw-ink-3); margin:2px 0 0; }
.pw-form { display:grid; grid-template-columns:repeat(12,1fr); gap:var(--pw-4); }
/* Campo dentro da grade OCUPA a coluna inteira. Sem isto o input fica no tamanho default do
   navegador (~180px) dentro de uma coluna de 500px, e o conteúdo é cortado — e-mail e razão
   social somem no meio. A grade já decide a largura; o campo só precisa obedecer. */
.pw-form .pw-input,
.pw-form .pw-select,
.pw-form .pw-textarea { width: 100%; }
/* `pw-c2` NÃO EXISTIA e três campos da tela de medições a usavam: sem regra, cada um caía no
   `span 1` implícito da grade de 12 e ficava com um doze avos da largura. O efeito visível era
   o seletor de situação cortado em "Tod" e os dois campos de data espremidos. */
.pw-c2{grid-column:span 2} .pw-c3{grid-column:span 3} .pw-c4{grid-column:span 4}
.pw-c6{grid-column:span 6} .pw-c12{grid-column:span 12}
@media(max-width:760px){ .pw-c2,.pw-c3,.pw-c4,.pw-c6{grid-column:span 12} }
.pw-textarea { width:100%; min-height:78px; padding:var(--pw-3); background:var(--pw-sheet); color:var(--pw-ink); border:1px solid var(--pw-line); border-radius:var(--pw-r-1); font-family:var(--pw-font); font-size:var(--pw-t-base); resize:vertical; }
.pw-total-linha { display:flex; justify-content:flex-end; align-items:baseline; gap:var(--pw-4); padding:var(--pw-4) 0 0; border-top:1px solid var(--pw-hair); margin-top:var(--pw-3); }
.pw-total-linha span { font-size:var(--pw-t-label); font-weight:600; color:var(--pw-ink-3); }
.pw-total-linha strong { font-size:var(--pw-t-xl); font-weight:800; letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
/* O CAMPO DE ANEXO (spec 101) — o `CampoDeAnexo.razor`, única porta de arquivo do Portal.
   Substitui o `.pw-upload`, que era o input NATIVO numa moldura tracejada.

   O input real fica TRANSPARENTE por cima da área inteira (`__entrada`): é ele que recebe o
   clique, o Tab e o arquivo solto, sem JavaScript. Por isso o foco visível mora na ÁREA, via
   `:focus-within` — o input está lá, só não aparece.

   O destaque do arrasto usa o azul de FOCO/SELEÇÃO do produto (`--pw-notice`), que já é o do
   foco do seletor do topo: não é cor de status, e verde/âmbar/vermelho seguem com as donas. */
.pw-anexo {
    position: relative;
    display: flex; flex-direction: column; align-items: flex-start; gap: var(--pw-2);
    padding: var(--pw-4);
    border: 1px dashed var(--pw-heavy); border-radius: var(--pw-r-2);
    background: var(--pw-sheet); color: var(--pw-ink-3); font-size: var(--pw-t-label);
    transition: border-color .15s ease, background-color .15s ease, box-shadow .15s ease;
}
.pw-anexo__entrada {
    position: absolute; inset: 0; width: 100%; height: 100%;
    opacity: 0; cursor: pointer;
}
/* Fora de "pronto" o input fica na PÁGINA, mas fora do jogo: o arquivo escolhido ainda é lido
   dele (ver o comentário no `CampoDeAnexo.razor`), e escondido ele não recebe o soltar. */
.pw-anexo__entrada--inerte { display: none; }
.pw-anexo__corpo { display: flex; align-items: center; flex-wrap: wrap; gap: var(--pw-3); min-width: 0; }
/* O "botão" é desenho: quem recebe o clique é o input por cima dele. */
.pw-anexo__botao { pointer-events: none; }
.pw-anexo__frase { color: var(--pw-ink-3); }
.pw-anexo__aceite { margin: 0; color: var(--pw-ink-3); overflow-wrap: anywhere; }
.pw-anexo__aceite strong, .pw-anexo__texto strong { color: var(--pw-ink); font-weight: 600; }
/* `flex: 1 1 12rem`: o texto cresce e encolhe AO LADO do ícone. Sem a base, num celular o nome
   longo empurrava o `loader` para uma linha sozinho (medido na bancada da spec 101). */
.pw-anexo__texto { flex: 1 1 12rem; display: flex; flex-direction: column; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.pw-anexo__icone { width: var(--pw-5); height: var(--pw-5); flex: none; color: var(--pw-ink-3); }
/* O Cancelar é clicável sem truque de camada: fora de "pronto" o input nem é desenhado. */
.pw-anexo__cancelar { margin-left: auto; }

.pw-anexo:hover:not(.pw-anexo--enviando, .pw-anexo--bloqueado, .pw-anexo--desabilitado) {
    border-color: var(--pw-notice); background: var(--pw-vellum);
}
.pw-anexo:focus-within:not(.pw-anexo--enviando) {
    border-color: var(--pw-notice); box-shadow: 0 0 0 3px var(--pw-notice-bg);
}
.pw-anexo--arrastando {
    border-style: solid; border-color: var(--pw-notice); background: var(--pw-notice-bg);
}
.pw-anexo--arrastando .pw-anexo__frase { color: var(--pw-notice-ink); font-weight: 600; }
.pw-anexo--enviando { border-style: solid; border-color: var(--pw-line); }
.pw-anexo--bloqueado, .pw-anexo--desabilitado { background: var(--pw-paper); border-color: var(--pw-line); }
.pw-anexo--desabilitado .pw-anexo__botao { opacity: .5; }

@media (prefers-reduced-motion: no-preference) {
    .pw-anexo__icone--girando { animation: pw-anexo-gira 1.2s linear infinite; }
    /* O passo em andamento da janela do "Nota Fiscal" do frete (spec 109, R15): o mesmo giro do
       campo de anexo — o passo gira enquanto a chamada dele não volta. */
    .pw-timeline__girando { animation: pw-anexo-gira 1.2s linear infinite; }
}
/* O ícone cabe na marca de 24px da linha do tempo. */
.pw-timeline__marca .pw-timeline__girando { width: 14px; height: 14px; color: var(--pw-notice); }
@keyframes pw-anexo-gira { to { transform: rotate(360deg); } }
.pw-split { display:grid; grid-template-columns:1fr 300px; gap:var(--pw-4); align-items:start; }

/* hub de administração — cards de acesso rápido */
.pw-admin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--pw-4); }
.pw-admin-card { display: flex; flex-direction: column; gap: var(--pw-2); }
.pw-admin-card h3 { font-size: var(--pw-t-md); font-weight: 700; margin: 0; }
.pw-admin-card p { font-size: var(--pw-t-label); color: var(--pw-ink-3); margin: 0; flex: 1; }
.pw-admin-card .pw-badge { align-self: flex-start; background: var(--pw-notice-bg); color: var(--pw-notice-ink); font-size: var(--pw-t-xs); font-weight: 700; padding: 3px 10px; border-radius: var(--pw-r-pill); }
/* O botão do cartão tem a largura do rótulo, e não a da coluna: esticado de ponta a ponta ele
   viraria uma barra, e a grade inteira perderia a hierarquia entre título, frase e ação.
   (Vive aqui, e não num `style=` na tela, porque acabamento de componente é do CSS.) */
.pw-admin-card .pw-btn { align-self: flex-start; }

/* ---------------------------------------------------------------------------
   TABELA EDITÁVEL (nova medição) — inputs dentro de células
   --------------------------------------------------------------------------- */
/* Dentro da tabela o input não pode ter a altura de 40px do formulário: com 8 linhas a tela
   vira uma torre. 32px é o degrau que mantém a linha densa e ainda dá alvo de toque. */
.pw-table .pw-input { height: 32px; width: 100%; font-size: var(--pw-t-label); }
/* Número alinhado à direita e com dígitos de largura fixa: é assim que uma coluna de dinheiro
   se lê de cima a baixo sem os algarismos dançarem. */
.pw-input--num { text-align: right; font-variant-numeric: tabular-nums; max-width: 130px; }

/* O CAMPO DE VALOR da medição SAIU em 21/09/2026 (spec 092, frente 3), e com ele a classe
   `--valor` que o desenhava. O valor da linha é `quantidade × preço unitário` e não se digita —
   é a regra da casa desde 19/08/2026, que a 3ª rodada da spec 033 tinha desfeito sem
   reconciliar. Quem desenha o número agora é `.pw-valor-da-linha`, abaixo. */

/* A QUANTIDADE — o ÚNICO campo de número da linha desde a spec 092. O peso da fonte ficou com
   ela: é o número que a pessoa informa e o que ela confere, e era o campo de dinheiro ao lado
   que carregava o destaque enquanto os dois eram editáveis. Tabular como todas as colunas de
   número, para as casas decimais alinharem entre linhas. */
.pw-input--qtd {
    text-align: right; font-variant-numeric: tabular-nums;
    max-width: 120px; min-width: 90px; font-weight: 600;
}

/* O VALOR DA LINHA, agora TEXTO (spec 092, frente 3) — e não caixa desabilitada, pelo mesmo
   motivo da descrição, da unidade e do preço ao lado: não há o que digitar aqui, e uma caixa
   cinza só convidaria ao clique que não faz nada.

   Ele mantém o alinhamento à direita e os dígitos de largura fixa que a coluna tinha como
   campo: a coluna é a mesma, e o total do rodapé precisa cair debaixo dela. */
.pw-valor-da-linha {
    text-align: right; font-variant-numeric: tabular-nums;
    white-space: nowrap; color: var(--pw-ink);
}

/* O asterisco do preço médio: marca discreta ao lado do número quando o item tem mais de uma
   linha de serviço e o preço mostrado é a média ponderada delas. A explicação inteira está no
   title da célula — aqui é só o sinal de que há o que ler. aria-hidden no HTML: o leitor de
   tela recebe o texto completo pelo title, e um "asterisco" lido em voz alta não informa. */
.pw-nota-media {
    color: var(--pw-ink-3); font-weight: 600; margin-left: 2px;
}


/* ── A BARRA DE % MEDIDO (2ª rodada da spec 033) ─────────────────────────────
   Quanto do item aquele valor consome, desenhado. Uma coluna de números é lida linha a
   linha; uma coluna de barras é lida de uma vez, e é assim que se acha a linha estranha
   num pedido de doze itens.

   A COR NÃO SOBE COM O VALOR, e essa foi uma decisão contra o pedido original ("começa
   fraco e vai aumentando"). O motivo: aqui número alto NÃO é problema. Medir 100% de um
   item é o fim normal e correto do trabalho — pintar de vermelho quem chegou lá diria ao
   fornecedor que ele errou quando ele acertou. O que é problema é PASSAR DO SALDO daquele
   item, e é só isso que fica vermelho.

     azul    = medindo, dentro do saldo (o mesmo azul de "andando" das pílulas)
     verde   = item fechado em 100% (o mesmo verde de "concluído" do resto do produto)
     vermelho= passou do saldo do item — o único estado que pede ação

   A TRILHA é neutra, e não um tom claro do preenchimento: com três estados possíveis, uma
   trilha que mudasse junto faria a linha inteira piscar de cor a cada dígito digitado.

   ACESSIBILIDADE: o par verde↔vermelho fica em ΔE 7,7 para protanopia — dentro da faixa
   que só é aceitável COM codificação secundária. Ela existe e é obrigatória: o número da
   porcentagem fica sempre ao lado da barra, e a linha fora do saldo já carrega borda
   vermelha e aria-invalid no campo. Quem remover o número torna a barra inacessível. */
/* A coluna precisa caber a barra inteira: sem largura mínima ela encolhe até a barra virar
   um traço de 20px, e uma barra que não distingue 20% de 80% não informa nada. */
.col-medido { min-width: 104px; }

/* MESMO TRILHO da barra de pedidos (19/09/2026): `--pw-vellum`, e não `--pw-hair`.
   As duas dizem a MESMA coisa — quanto já foi medido — e apareciam com fundos diferentes, o que
   fazia a mesma informação parecer duas escalas. A cor da rampa já vinha do mesmo lugar
   (Charts.FaixaDoConsumo); o que faltava era o resto do desenho acompanhar. A largura continua
   diferente de propósito: aqui a barra mora numa coluna estreita de tabela. */
.pw-medidor {
    display: block; width: 100%; max-width: 88px; margin: 4px 0 0 auto;
    height: 6px; border-radius: 999px;
    background: var(--pw-vellum); overflow: hidden;
}
.pw-medidor__fill {
    display: block; height: 100%; border-radius: 999px;
    background: var(--pw-cons-1);
    transition: width 120ms linear;
}
/* O EXCEDIDO EM VERMELHO SAIU (spec 090, frente 3 — relato do Leandro, 20/09/2026: "está
   ficando com uma linha horizontal vermelha, não entendi para que serve, isso confunde o
   usuário parecendo algum erro").

   O aviso estava certo; a FORMA dele enganava. Um traço vermelho de 6px embaixo de um campo
   lê-se como "campo com erro" — e não como "passou do limite" —, e nesta coluna ele convivia
   com a rampa verde, que responde outra pergunta (QUANTO já foi medido). Quem avisa que passou
   agora é TEXTO, embaixo do campo (`.pw-ajuste--limite`), dizendo o que houve e qual é o
   limite. A barra voltou a ter um assunto só.

   O que TRAVA o envio não mudou: `aria-invalid` no campo, a borda vermelha do próprio campo, a
   marca na borda esquerda da linha e a recusa do servidor continuam onde estavam. */

.pw-medidor__fill--cons-1 { background: var(--pw-cons-1); }
.pw-medidor__fill--cons-2 { background: var(--pw-cons-2); }
.pw-medidor__fill--cons-3 { background: var(--pw-cons-3); }
.pw-medidor__fill--cons-4 { background: var(--pw-cons-4); }
.pw-medidor__fill--cons-5 { background: var(--pw-cons-5); }

/* Movimento é decoração aqui: quem pediu para o sistema parar de animar não perde
   informação nenhuma ao ver a barra saltar para a largura certa. */
@media (prefers-reduced-motion: reduce) { .pw-medidor__fill { transition: none; } }

/* O AVISO DE AJUSTE, embaixo do campo: o valor digitado não cabia na unidade do pedido e foi
   arredondado. Discreto de propósito — é uma explicação, não um erro: o número está certo, só
   não é o que a pessoa digitou, e ela precisa saber por quê sem levar um susto vermelho. */
.pw-ajuste {
    display: block; margin-top: 4px; text-align: right;
    font-size: var(--pw-t-xs); line-height: 1.3; color: var(--pw-ink-3);
}
/* O AVISO DE LIMITE (spec 090, frente 3): a MESMA forma do aviso de ajuste — frase curta,
   embaixo do campo, alinhada com ele —, e é de propósito: é ali que a pessoa está olhando
   quando digita o número que não coube.

   A tinta é a de ERRO e não a neutra do ajuste, porque as duas frases não dizem a mesma coisa:
   o ajuste explica um número que ESTÁ certo, este recusa um número que não está — o envio
   trava enquanto ele estiver ali. `--pw-danger-ink`, e não `--pw-danger`: o vermelho de área
   como texto sobre branco fica abaixo de AA. */
/* O CORPO É MENOR QUE O DO AJUSTE, e é medida e não gosto: a coluna do campo de quantidade
   tem 120px. A 12px a frase quebrava em três linhas e a linha da tabela triplicava de altura
   — numa tabela cujo valor inteiro é ter linhas do mesmo tamanho. A 11px, com o texto curto,
   ela ocupa duas. */
.pw-ajuste--limite {
    color: var(--pw-danger-ink); font-weight: 600;
    font-size: var(--pw-t-2xs); line-height: 1.25;
}
/* Campo com número que a regra recusa. A borda vermelha aparece NA LINHA errada — dizer só
   "há um erro na tabela" obrigaria a pessoa a conferir doze linhas para achar qual. */
.pw-input--erro, .pw-input--erro:focus { border-color: var(--pw-danger); }
/* A unidade tem 2 ou 3 letras — um campo largo aqui só empurra as colunas de valor. */
.pw-input--un { max-width: 72px; text-transform: uppercase; }
/* A OPACIDADE DAQUI SAIU (spec 090, frente 3, 20/09/2026) — e era um nome reaproveitado, não
   uma decisão.

   `pw-linha--fora` já quis dizer "linha do pedido que NÃO entra nesta medição", e apagá-la a
   48% era o certo para aquilo. Esse papel passou a ser de `pw-linha--apagada` (logo abaixo, a
   .6) e o `--fora` virou "passou do limite" — mas a regra de opacidade ficou. Resultado: a
   linha que a tela precisa que a pessoa CONSERTE era a única desbotada da tabela, e com ela
   desbotava o aviso de limite que esta spec acabou de pôr embaixo do campo.

   Apagar quem errou é o oposto do que se quer: a linha fora do limite é a que tem de puxar o
   olho. Quem a marca é a borda vermelha à esquerda e a borda do campo — as duas logo abaixo. */
/* O rodapé da tabela fecha a conta: mesma régua tipográfica do cabeçalho, sem a hairline
   pendurada embaixo do último total. */
.pw-table tfoot th, .pw-table tfoot td {
    padding: 12px var(--pw-4); border-top: 2px solid var(--pw-heavy);
    border-bottom: 0; font-weight: 700; font-variant-numeric: tabular-nums;
}
.pw-table tfoot th { text-align: right; }

/* ---------------------------------------------------------------------------
   REGRAS DE NEGÓCIO — dois níveis dentro do mesmo cartão
   --------------------------------------------------------------------------- */
/* A linha separa GLOBAL de EXCEÇÕES sem precisar de outro cartão: são a mesma regra, e
   parti-las em dois blocos faria parecer que são duas coisas diferentes. */
.pw-regra__nivel + .pw-regra__nivel {
    margin-top: var(--pw-5); padding-top: var(--pw-5); border-top: 1px solid var(--pw-hair);
}

/* ---------------------------------------------------------------------------
   UMA NOTA POR FOLHA (spec 111) — um trecho por folha dentro do cartão da nota
   --------------------------------------------------------------------------- */
/* UM CARTÃO POR ITEM dentro do card principal (spec 111, alteração de 26/09/2026): cada item tem a
   FS e o campo de anexar dele; o envio é embaixo, no card principal. Folha de papel com borda, como a
   caixa da árvore da medição — o mesmo vocabulário de "interno". */
.pw-folhas-da-nota { display: grid; gap: var(--pw-4); }
.pw-folha-da-nota {
    padding: var(--pw-4); background: var(--pw-sheet);
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-2);
}
.pw-folha-da-nota__cabecalho {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--pw-2) var(--pw-4);
    margin-bottom: var(--pw-3);
}
.pw-folha-da-nota__cabecalho h3 { margin: 0; font-size: var(--pw-t-md); }
.pw-folha-da-nota__cabecalho p { margin: 0; color: var(--pw-ink-3); }

/* O VÉU DA LEITURA (spec 118): o cartão da folha cuja nota está sendo lida. O conteúdo fica
   esmaecido e INERTE (`inert` no markup), e por cima vão o brilho, a frase e o Cancelar. É uma
   CAMADA, nunca uma troca de conteúdo: o `<InputFile>` do cartão está sendo lido naquela hora e
   não pode sair do DOM (regra 13). Só o ÍCONE se move (regra 15), e com movimento reduzido nem ele. */
.pw-veu { position: relative; }
.pw-veu--ativo { min-height: calc(var(--pw-4) * 9); }
.pw-veu--ativo > .pw-veu__conteudo { opacity: .3; }
.pw-veu__resultado:focus { outline: none; }
.pw-veu__camada {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: var(--pw-3); padding: var(--pw-4); text-align: center;
    background: color-mix(in srgb, var(--pw-sheet) 55%, transparent);
    border-radius: var(--pw-r-2);
}
.pw-veu__icone { width: 32px; height: 32px; color: var(--pw-leitura); }
.pw-veu__icone--espera { color: var(--pw-ink-3); }
.pw-veu__frase { margin: 0; font-size: var(--pw-t-base); font-weight: 600; color: var(--pw-ink); }
.pw-veu__frase:focus { outline: none; }
@media (prefers-reduced-motion: no-preference) {
    .pw-veu__icone--lendo { animation: pw-veu-brilha 1.6s ease-in-out infinite; }
    .pw-veu__icone--espera { animation: pw-anexo-gira 1.2s linear infinite; }
}
@keyframes pw-veu-brilha {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.15); opacity: .55; }
}
/* Checkbox e rótulo na mesma linha, alinhados pelo texto — o padrão .pw-check sozinho é só
   a caixa. */
.pw-check-linha { display: flex; align-items: center; gap: var(--pw-2); cursor: pointer; }
.pw-check-linha span { font-size: var(--pw-t-base); }
/* A linha que se arruma pelo TAMANHO do campo (spec 099, regra 8). Na grade de 12 colunas, com
   tudo em pw-c4, a checkbox ocupava a largura de um campo de texto e a linha quebrava com espaço
   sobrando. Aqui cada campo pede a largura do seu tipo (TamanhoDoCampo, no C#) e a linha só quebra
   quando o próximo não cabe. */
.pw-form--fluido { display: flex; flex-wrap: wrap; gap: var(--pw-4); align-items: flex-start; }
.pw-form--fluido .pw-input,
.pw-form--fluido .pw-select { width: 100%; }
.pw-form--fluido > .pw-campo { flex: 1 1 14rem; max-width: 22rem; min-width: 0; }
.pw-form--fluido > .pw-campo--curto { flex: 0 1 11rem; }
.pw-form--fluido > .pw-campo--longo { flex: 2 1 28rem; max-width: none; }
.pw-form--fluido > .pw-campo--ajustado { flex: 0 0 auto; max-width: none; }
@media (max-width: 760px) {
    .pw-form--fluido > .pw-campo { flex: 1 1 100%; max-width: none; }
}
.pw-lista-erros { margin: 0; padding-left: var(--pw-4); }
.pw-lista-erros li + li { margin-top: var(--pw-1); }

/* Qtde de recursos é um contador pequeno — largura de valor, não de quantidade. */
.pw-input--recursos { max-width: 90px; text-align: right; font-variant-numeric: tabular-nums; }
/* Stat tile com TEXTO em vez de número: a razão social não cabe no tamanho do valor. */
.pw-stat__value--texto { font-size: var(--pw-t-lg); line-height: 1.2; }
/* Tile de texto longo (descrição do serviço) ocupa duas colunas da grade de stats — quebrar
   uma frase inteira na largura de um número produziria cinco linhas de duas palavras. */
.pw-stat--largo { grid-column: span 2; }
@media (max-width: 720px) { .pw-stat--largo { grid-column: auto; } }

/* ══ Aprovação de medição (spec 012) e central de notificações (spec 018) ══ */

/* A análise ao lado do painel de próximos passos, como no draft. Colapsa numa coluna
   antes de a tabela de itens ficar estreita demais para ler. */
.pw-duas-colunas { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: var(--pw-4); }
@media (max-width: 1100px) { .pw-duas-colunas { grid-template-columns: minmax(0, 1fr); } }

/* O par ✓/✕ de cada linha. Dois botões e não um toggle: "aprovado", "reprovado" e "ainda
   não decidido" são TRÊS estados, e um toggle só sabe contar até dois — o boletim nasceria
   com todas as linhas já decididas sem ninguém ter olhado. */
.pw-decisao { display: flex; gap: var(--pw-1); }
.pw-decisao__btn {
    width: 32px; height: 32px; border-radius: var(--pw-r-1);
    border: 1px solid var(--pw-hair); background: #fff; cursor: pointer;
    font-size: var(--pw-t-base); line-height: 1; color: var(--pw-ink-2);
}
.pw-decisao__btn:hover { border-color: var(--pw-ink-2); }
.pw-decisao__btn:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 1px; }
.pw-decisao__btn--sim { background: var(--pw-safe); border-color: var(--pw-safe); color: #fff; }
.pw-decisao__btn--nao { background: var(--pw-danger); border-color: var(--pw-danger); color: #fff; }

/* A cor fica na BORDA ESQUERDA, não no fundo da linha: fundo colorido em tabela de dinheiro
   compete com o número, e é o número que o analista está lendo. */
.pw-linha--aprovada th[scope="row"] { box-shadow: inset 3px 0 0 var(--pw-safe); }
.pw-linha--reprovada th[scope="row"] { box-shadow: inset 3px 0 0 var(--pw-danger); }
/* Na árvore da medição (spec 112, alteração de 26/09/2026) a faixa fica na PRIMEIRA célula da linha
   do item — na tela de medir ela é a caixa de marcar, e a faixa no meio da linha não se leria. */
.pw-arvore__item.pw-linha--aprovada > th[scope="row"],
.pw-arvore__item.pw-linha--reprovada > th[scope="row"] { box-shadow: none; }
.pw-arvore__item.pw-linha--aprovada > :first-child { box-shadow: inset 3px 0 0 var(--pw-safe); }
.pw-arvore__item.pw-linha--reprovada > :first-child { box-shadow: inset 3px 0 0 var(--pw-danger); }

/* Itens do pedido na tela de medição (spec 017, 6ª rodada).

   NÃO marcada: apagada, mas legível e ainda na tabela. A linha sai da CONTA, não da VISTA — o
   fornecedor precisa enxergar o item que decidiu não medir para poder mudar de ideia. Opacidade
   .6, e não .3: ela continua tendo de ser lida para ser escolhida. */
.pw-linha--apagada > td { opacity: .6; }

/* Quantidade acima da do pedido — mesma razão da regra acima: a cor vai na BORDA, nunca no
   fundo. Quem recusa de verdade é o servidor (422); aqui a linha só diz qual é, antes do
   clique. A borda no campo é o que liga o aviso ao número que precisa mudar. */
.pw-linha--fora > td:first-child { box-shadow: inset 3px 0 0 var(--pw-danger); }
.pw-linha--fora .pw-input--num { border-color: var(--pw-danger); }

/* Próximos passos: etapas que ainda acontecem no SAP. Apagadas e sem cursor de clique —
   a tela não promete o que o sistema não faz. */
.pw-passos--futuros { list-style: none; padding: 0; margin: 0; opacity: .55; }
.pw-passos--futuros li {
    display: flex; align-items: center; gap: var(--pw-2);
    padding: var(--pw-2) 0; border-bottom: 1px solid var(--pw-hair);
    font-size: var(--pw-t-label);
}
.pw-passos--futuros li:last-child { border-bottom: 0; }
.pw-passos--futuros li::before {
    content: ""; width: 14px; height: 14px; border-radius: 50%;
    border: 2px solid var(--pw-hair); flex: none;
}

.pw-lista-anexos { list-style: none; padding: 0; margin: 0; }
.pw-lista-anexos li { padding: var(--pw-2) 0; border-bottom: 1px solid var(--pw-hair); }
.pw-lista-anexos li:last-child { border-bottom: 0; }

/* ── O sino do topo ──────────────────────────────────────────────────────── */
.pw-sino { position: relative; display: inline-flex; padding: var(--pw-2); text-decoration: none; }
.pw-sino:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 2px; border-radius: var(--pw-r-1); }
.pw-sino__badge {
    position: absolute; top: 0; right: 0; min-width: 18px; height: 18px;
    padding: 0 5px; border-radius: var(--pw-r-pill);
    background: var(--pw-danger); color: #fff;
    font-size: 11px; line-height: 18px; text-align: center; font-weight: 700;
}

/* ── A central ───────────────────────────────────────────────────────────── */
/* ── Central de notificações (spec 018) ──────────────────────────────────
   A marca de "não lida" mora numa COLUNA PRÓPRIA da grade, e a coluna existe sempre —
   vazia quando o aviso já foi lido.

   Antes era `box-shadow: inset` no <li> mais um `padding-left` só nos não lidos, e isso tinha
   dois defeitos. O primeiro é de especificidade: `.pw-notificacoes li` (classe + elemento)
   vence `.pw-notificacao--nova` (classe), então o `padding: … 0` do primeiro anulava o
   `padding-left` do segundo — a barra ficava POR CIMA da primeira letra de cada linha. O
   segundo só apareceria depois: com o recuo funcionando, o item saltaria 12px para a esquerda
   no instante em que alguém clicasse em "marcar como lida".

   Com a coluna, os dois estados ocupam exatamente o mesmo lugar. */
.pw-notificacoes { list-style: none; padding: 0; margin: 0; }

.pw-notificacoes li {
    position: relative;
    padding: var(--pw-4) 0 var(--pw-4) var(--pw-5);
    border-bottom: 1px solid var(--pw-hair);
}
.pw-notificacoes li:last-child { border-bottom: 0; }

.pw-notificacoes li::before {
    content: ""; position: absolute; left: 0; top: var(--pw-4); bottom: var(--pw-4);
    width: 3px; border-radius: var(--pw-r-pill); background: transparent;
}

/* O seletor repete `li` de propósito. A regra acima tem especificidade de classe MAIS
   elemento; escrever só `.pw-notificacao--nova::before` perderia para ela e a barra ficaria
   transparente — que é a versão nova do mesmo erro que este bloco conserta. */
.pw-notificacoes li.pw-notificacao--nova::before { background: var(--pw-notice); }

/* A largura de leitura é limitada, e é o que conserta a sensação de tela quebrada: numa
   janela larga a mensagem corria quase 1900px e a data ia parar no outro extremo, longe do
   título a que pertence. Texto corrido passa de ~90 caracteres e o olho perde a linha. */
.pw-notificacao__topo,
.pw-notificacoes li > p {
    max-width: 92ch;
}

.pw-notificacao__topo {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--pw-4);
}
.pw-notificacao__topo strong { color: var(--pw-ink); }
/* Os detalhes do aviso (spec 108, alteração de 26/09/2026): rótulo em negrito e valor ao lado, um
   por linha — o mesmo desenho do e-mail. O valor pode ter várias linhas (descrição e motivo). */
.pw-notificacao__detalhes { margin: var(--pw-2) 0 var(--pw-3); }
.pw-notificacao__detalhes > div {
    display: grid; grid-template-columns: minmax(8rem, 12rem) minmax(0, 1fr); gap: var(--pw-4);
    padding: var(--pw-2) 0; border-top: 1px solid var(--pw-hair);
}
.pw-notificacao__detalhes dt { margin: 0; font-weight: 700; color: var(--pw-ink); }
.pw-notificacao__detalhes dd { margin: 0; color: var(--pw-ink-2); white-space: pre-line; overflow-wrap: anywhere; }
@media (max-width: 480px) {
    .pw-notificacao__detalhes > div { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}
.pw-notificacao__topo .pw-hint { white-space: nowrap; }

.pw-notificacoes li > p { margin: var(--pw-1) 0 var(--pw-3); color: var(--pw-ink-2); }

/* "Abrir" é a ação; "marcar como lida" é arrumação. Dois botões de mesmo peso numa lista
   longa viram uma parede — o segundo vai para o estilo discreto. */
.pw-notificacoes .pw-actions { gap: var(--pw-2); }

/* Campo do PEDIDO exibido dentro do formulário: mesma altura de um input, sem a moldura —
   parece dado, não campo, e ninguém tenta clicar. */
.pw-valor-lido {
    margin: 0; min-height: 40px; display: flex; align-items: center;
    font-weight: 600; color: var(--pw-ink);
}
/* Selo de campo exigido no título da seção. Discreto: é informação, não alarme. */
.pw-obrigatorio {
    margin-left: var(--pw-2); padding: 2px 8px; border-radius: var(--pw-r-pill);
    background: var(--pw-warn-bg); color: var(--pw-warn-ink);
    font-size: var(--pw-t-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
}

/* Descrição do serviço é a coluna que carrega a frase — as outras carregam números curtos.
   Sem um piso de largura, o navegador reparte a tabela igualmente e sobra um campo de três
   palavras ao lado de colunas de dinheiro vazias. */
.pw-table th.col-descricao, .pw-table td.col-descricao { min-width: 320px; width: 45%; }

/* ══ Linha do tempo da medição (spec 019) ═════════════════════════════════ */

/* VERTICAL: seis etapas, rótulos de tamanhos diferentes e uma data em cada. Na horizontal, ou
   o texto quebra em três linhas ou a data some — e a data é o dado que a operação usa para
   cobrar. O traço que liga os passos é um ::before da lista, não borda de cada item: assim ele
   não aparece pendurado embaixo do último. */
.pw-timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.pw-timeline::before {
    content: ""; position: absolute; left: 11px; top: 12px; bottom: 12px;
    width: 2px; background: var(--pw-hair);
}
.pw-timeline__item {
    position: relative; display: flex; gap: var(--pw-3);
    padding: var(--pw-2) 0; align-items: flex-start;
}
.pw-timeline__marca {
    position: relative; z-index: 1; flex: none;
    width: 24px; height: 24px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--pw-sheet); border: 2px solid var(--pw-hair);
    font-size: var(--pw-t-xs); font-weight: 700; line-height: 1;
}
.pw-timeline__titulo { display: block; font-weight: 600; font-size: var(--pw-t-base); }
.pw-timeline__meta { display: block; font-size: var(--pw-t-xs); color: var(--pw-ink-3); }

/* Três estados, porque "já foi", "é agora" e "vem depois" são informações diferentes para
   quem cobra andamento. O check é verde; o passo atual é azul e o texto fica cheio; o futuro
   apaga sem sumir. */
.pw-timeline__item--feito .pw-timeline__marca {
    background: var(--pw-safe); border-color: var(--pw-safe); color: #fff;
}
.pw-timeline__item--atual .pw-timeline__marca {
    border-color: var(--pw-notice); box-shadow: 0 0 0 4px var(--pw-notice-bg);
}
.pw-timeline__item--atual .pw-timeline__titulo { color: var(--pw-notice-ink); }
.pw-timeline__item--futuro { opacity: .5; }

/* ── O traço que PREENCHE (spec 109, janela do "Nota Fiscal" do frete) ───────
   A fração vem da tela em `--progresso` (0 a 1): até a marca do passo mais adiantado que já
   começou. O verde é o mesmo do check — é o caminho já andado —, e a transição é o que mostra o
   passo "indo" para o próximo. Em pé ele desce; deitado (abaixo) ele atravessa. */
.pw-timeline--progresso::after {
    content: ""; position: absolute; left: 11px; top: 12px;
    width: 2px; height: calc((100% - 24px) * var(--progresso, 0));
    background: var(--pw-safe);
}
@media (prefers-reduced-motion: no-preference) {
    .pw-timeline--progresso::after { transition: height .6s ease, width .6s ease; }
}

/* ── A mesma linha do tempo, DEITADA (spec 020, 23/08/2026) ─────────────────
   Pedido do negócio depois de ver a versão em pé: "acho que o acompanhamento deveria ser
   horizontal, assim acho que fica melhor".

   Quem decide é a largura do CARTÃO, não a da janela: o componente aparece num cartão largo na
   tela do fornecedor e pode aparecer numa coluna estreita na visão interna. `@media` olharia a
   janela e deixaria a versão espremida justamente onde o espaço é menor.

   O vertical acima é o PADRÃO e continua valendo em navegador sem consulta de contêiner —
   degradar para o que já era bom é melhor que degradar para o que nunca foi testado. */
.pw-timeline-caixa { container-type: inline-size; }

@container (min-width: 720px) {
    .pw-timeline { display: flex; align-items: flex-start; }

    /* O traço deixa de descer e passa a atravessar, na altura do centro das marcas. Continua
       sendo um ::before da lista, e não borda de cada item, para não sobrar pendurado na ponta. */
    .pw-timeline::before {
        left: 12px; right: 12px; top: 11px;
        bottom: auto; width: auto; height: 2px;
    }

    .pw-timeline__item {
        flex: 1 1 0;
        min-width: 0;
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: var(--pw-2);
        padding: 0 var(--pw-1);
    }

    /* Sem isto o traço aparece por cima do intervalo entre marcas e a linha fica cortada. */
    .pw-timeline__marca { background: var(--pw-sheet); }

    .pw-timeline__texto { min-width: 0; }

    .pw-timeline__titulo { font-size: var(--pw-t-label); }

    /* A data é o dado que a operação usa para cobrar: ela quebra em duas linhas, não some. */
    .pw-timeline__meta { overflow-wrap: anywhere; }

    /* Deitada, a linha que preenche vai do CENTRO da primeira marca ao da última (spec 109): com
       itens de largura igual, os centros ficam a 1/(2n) das pontas — aqui, três passos. */
    .pw-timeline--progresso::before { left: calc(100% / 6); right: calc(100% / 6); }
    .pw-timeline--progresso::after {
        left: calc(100% / 6); top: 11px;
        height: 2px; width: calc((100% - 100% / 3) * var(--progresso, 0));
    }
}

/* ── Conferência da nota fiscal (specs 020 e 067) ──────────────────────────
   Laudo de LEITURA: o que se procurou na nota, se foi achado e onde. Nada é editável —
   campo editável deixaria o fornecedor digitar por cima o valor que a validação quer ver. */

.pw-conferencia {
    border: 1px solid var(--pw-line);
    border-radius: 10px;
    padding: 16px;
    background: var(--pw-surface, #fff);
}

.pw-conferencia__topo {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.pw-conferencia__topo h3 { margin: 0; font-size: 1rem; }

.pw-conferencia__arquivo {
    font-size: .8125rem;
    color: var(--pw-idle);
    overflow-wrap: anywhere;
}

/* O laudo por VALOR ESPERADO (spec 067): Conferência · Esperado · Status · Onde. O trecho mostra
   onde o valor foi achado, com o valor em negrito — é o que prova, de qualquer layout de nota. */
.pw-laudo th[scope="row"] { font-weight: 600; white-space: nowrap; }
.pw-laudo td { vertical-align: top; }
.pw-laudo__trecho { overflow-wrap: anywhere; }
.pw-laudo__trecho strong { font-variant-numeric: tabular-nums; }
.pw-laudo__motivo {
    display: block;
    margin-top: 2px;
    font-size: var(--pw-t-label);
    color: var(--pw-ink-3);
}

/* O resultado de cada conferência — NEUTRO (spec 067, correção de 15/09/2026). Verde/âmbar/vermelho
   têm duas donas no e-BMM, o status do boletim e a ação da trilha, e o laudo não é nenhuma delas.
   O que distingue os estados é o ÍCONE (✓ encontrado, ✕ não encontrado, – dispensado/desligado) e o
   texto escrito na pílula; a recusa em si aparece na faixa de erro, que é onde o erro mora. */
/* O RESULTADO DA CONFERÊNCIA DA NOTA (spec 073, regra 4). A pílula era neutra desde 15/09/2026,
   quando verde/vermelho tinham duas donas e o laudo não era nenhuma delas; a 073 o admitiu como a
   QUARTA, pelo mesmo motivo da barra de consumo: o resultado tem polaridade.
   Dispensado e desligado ficam NEUTROS — não são falha, são "ninguém conferiu isto". */
.pw-pill--laudo {
    gap: var(--pw-1);
    background: var(--pw-vellum);
    color: var(--pw-ink);
    border: 1px solid var(--pw-line);
}
.pw-pill--laudo--ok      { background: var(--pw-safe); color: #fff; border-color: var(--pw-safe); }
.pw-pill--laudo--falhou  { background: var(--pw-danger); color: #fff; border-color: var(--pw-danger); }
.pw-pill--laudo--neutro  { background: var(--pw-vellum); color: var(--pw-ink); }
/* O âmbar de "não confirmado" (spec 081) saiu na spec 095, junto com o OCR: não encontrado voltou
   a barrar em todo documento, e o laudo tem de novo três faixas — ok, falhou e neutro. */

/* A célula "Encontrado": o rótulo lido em tom secundário, o valor em destaque — é o valor que se
   compara com o papel, e o rótulo é o contexto dele. */
.pw-laudo__achado { overflow-wrap: anywhere; }
.pw-laudo__valor { font-variant-numeric: tabular-nums; }
.pw-pill__icone { font-weight: 700; }
/* Estado escrito para leitor de tela: cor sozinha não é informação. */
.pw-visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ── Gráficos do painel (spec 022) ─────────────────────────────────────────
   SVG próprio, sem biblioteca: são quatro formas e cada uma cabe em poucas dezenas
   de linhas. Biblioteca traria tema para brigar com este sistema, peso no primeiro
   carregamento da tela que todo mundo abre de manhã, e mais um pacote para
   acompanhar CVE. */

.pw-gr { margin-top: var(--pw-2); }
.pw-gr__svg { display: block; width: 100%; height: 140px; }
.pw-gr__base { stroke: var(--pw-hair); stroke-width: 2; }
.pw-gr__barra { fill: var(--pw-serie-1); }
.pw-gr__col:hover .pw-gr__barra { fill: var(--pw-notice-ink); }

.pw-gr__eixo { display: flex; margin-top: var(--pw-1); }
.pw-gr__eixo-item {
    flex: 1 1 0; min-width: 0; text-align: center;
    display: flex; flex-direction: column; gap: 1px;
}
.pw-gr__eixo-valor { font-size: var(--pw-t-xs); font-weight: 700; color: var(--pw-ink); }
.pw-gr__eixo-rotulo { font-size: var(--pw-t-xs); color: var(--pw-ink-3); }

/* Tabela alternativa: recolhida, para não competir com o desenho, mas sempre presente. */
.pw-gr__tabela { margin-top: var(--pw-3); }
.pw-gr__tabela summary {
    cursor: pointer; font-size: var(--pw-t-xs); color: var(--pw-ink-3);
    font-weight: 600;
}
.pw-gr__tabela summary:hover { color: var(--pw-notice-ink); }
.pw-gr__tabela .pw-table { margin-top: var(--pw-2); }

/* Barras horizontais — nome, trilho, valor. Grade de três colunas para os valores
   ficarem alinhados: valor desalinhado obriga a comparar número lendo, não olhando. */
.pw-gr__barras { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--pw-2); }
.pw-gr__barra-linha {
    display: grid; grid-template-columns: minmax(120px, 34%) 1fr auto;
    align-items: center; gap: var(--pw-3);
}
.pw-gr__barra-nome {
    font-size: var(--pw-t-base);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pw-gr__barra-trilho { display: block; height: 16px; background: var(--pw-hair); border-radius: 4px; }
.pw-gr__barra-preenchida {
    display: block; height: 100%; border-radius: 4px; background: var(--pw-serie-1);
}
.pw-gr__barra-valor {
    font-size: var(--pw-t-xs); color: var(--pw-ink-3);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* Barra empilhada — 2px de respiro entre fatias, para elas não virarem uma só. */
.pw-empilhada { display: flex; height: 34px; border-radius: var(--pw-r-1); overflow: hidden; gap: 2px; }
.pw-empilhada__fatia {
    display: flex; align-items: center; justify-content: center;
    min-width: 3px; border-radius: 4px;
}
.pw-empilhada__valor { font-size: var(--pw-t-xs); font-weight: 700; color: #fff; }

.pw-serie-1 { background: var(--pw-serie-1); }
.pw-serie-2 { background: var(--pw-serie-2); }
.pw-serie-3 { background: var(--pw-serie-3); }
.pw-serie-4 { background: var(--pw-serie-4); }

.pw-legenda {
    list-style: none; margin: var(--pw-3) 0 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: var(--pw-2) var(--pw-4);
}
.pw-legenda__item {
    display: flex; align-items: center; gap: var(--pw-2);
    font-size: var(--pw-t-xs); color: var(--pw-ink-2);
}
.pw-legenda__marca { width: 10px; height: 10px; border-radius: 3px; flex: none; }

/* Faixas de idade — escala SEQUENCIAL: mais velho, mais escuro. */
.pw-seq-1 .pw-gr__barra { fill: var(--pw-seq-2); }
.pw-seq-2 .pw-gr__barra { fill: var(--pw-seq-3); }
.pw-seq-3 .pw-gr__barra { fill: var(--pw-seq-4); }
.pw-seq-4 .pw-gr__barra { fill: var(--pw-seq-5); }

/* Medidor — a ÚNICA peça do painel que usa cor de estado, porque o número tem
   polaridade: consumir 95% do pedido é ruim, e 20% não é. */
/* A coluna precisa caber a barra inteira: sem largura mínima ela encolhe até a barra virar
   um traço de 20px, e uma barra que não distingue 20% de 80% não informa nada. */
.col-medido { min-width: 104px; }

.pw-medidor { margin-bottom: var(--pw-4); }
.pw-medidor__topo {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: var(--pw-3); margin-bottom: var(--pw-1);
}
.pw-medidor__nome { font-size: var(--pw-t-base); font-weight: 600; }
.pw-medidor__pct { font-size: var(--pw-t-xs); font-weight: 700; white-space: nowrap; }
.pw-medidor__pct--ok { color: var(--pw-ink-3); }
.pw-medidor__pct--atencao { color: var(--pw-warn-ink); }
.pw-medidor__pct--critico { color: var(--pw-danger-ink); }
/* A TERCEIRA família de barra de consumo, e agora com o MESMO desenho das outras duas
   (19/09/2026): 6px e o trilho em `--pw-vellum`. Ela estava com 10px e outro fundo — a mesma
   informação, em três telas, com três aparências. A cor já vinha de Charts.FaixaDoConsumo; o que
   faltava era o resto acompanhar. */
.pw-medidor__trilho {
    height: 6px; border-radius: var(--pw-r-pill);
    background: var(--pw-vellum); overflow: hidden;
}
.pw-medidor__barra { height: 100%; border-radius: var(--pw-r-pill); }
.pw-medidor__barra--cons-1 { background: var(--pw-cons-1); }
.pw-medidor__barra--cons-2 { background: var(--pw-cons-2); }
.pw-medidor__barra--cons-3 { background: var(--pw-cons-3); }
.pw-medidor__barra--cons-4 { background: var(--pw-cons-4); }
.pw-medidor__barra--cons-5 { background: var(--pw-cons-5); }
.pw-medidor__meta { font-size: var(--pw-t-xs); color: var(--pw-ink-3); }

/* Pendências — lista de tarefas, não gráfico: três pendências viram três linhas
   com link, e um gráfico de três pontos seria decoração. */
.pw-pendencias { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--pw-2); }
.pw-pendencia {
    display: flex; align-items: center; justify-content: space-between; gap: var(--pw-3);
    padding: var(--pw-3); border-radius: var(--pw-r-2);
    background: var(--pw-vellum); text-decoration: none; color: inherit;
}
.pw-pendencia:hover { background: var(--pw-notice-bg); }
.pw-pendencia__texto { display: flex; flex-direction: column; }
.pw-pendencia__titulo { font-weight: 600; }
/* O sininho das ações pendentes (spec 069, 01/10/2026): na cor da pílula ao lado, balançando com o
   mesmo movimento do sino da pendência da CN (spec 099). Parado com movimento reduzido, mais abaixo. */
.pw-pendencia__sino {
    width: var(--pw-4); height: var(--pw-4); flex: none; vertical-align: -2px;
    margin-right: var(--pw-1);
    transform-origin: 50% 10%; animation: pw-sino-balanca 2s ease-in-out infinite;
}
.pw-pendencia__sino--rascunho  { color: var(--pw-idle); }
.pw-pendencia__sino--rejeitado { color: var(--pw-danger); }
.pw-pendencia__sino--aprovado  { color: var(--pw-safe); }
.pw-pendencia__meta { font-size: var(--pw-t-xs); color: var(--pw-ink-3); }
.pw-pendencia__seta { color: var(--pw-notice-ink); font-weight: 700; }

/* Degraus da escala sequencial nas colunas. Começa no segundo degrau: o primeiro é
   claro demais para uma coluna cheia sobre fundo branco — sumiria. */
.pw-gr__barra--seq-2 { fill: var(--pw-seq-2); }
.pw-gr__barra--seq-3 { fill: var(--pw-seq-3); }
.pw-gr__barra--seq-4 { fill: var(--pw-seq-4); }
.pw-gr__barra--seq-5 { fill: var(--pw-seq-5); }

/* ---------------------------------------------------------------------------
   MODAL (spec 026, 2ª rodada)

   A escolha de fornecedores saiu da página e foi para uma sobreposição: empilhado na
   página, bastava uma dezena de linhas para a rolagem crescer e o botão de enviar sumir
   no fim. O modal fixa a decisão numa área com rodapé próprio.

   Sobreposição própria, e não <dialog>: abrir e fechar pelo estado do componente Blazor
   não depende de JS, e continua funcionando quando o circuito reconecta.
   --------------------------------------------------------------------------- */
.pw-modal-fundo {
    position: fixed;
    inset: 0;
    background: rgba(var(--pw-shadow-rgb), .45);
    z-index: 40;
}

.pw-modal {
    position: fixed;
    z-index: 41;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(46rem, calc(100vw - 2rem));
    /* Teto de altura + corpo rolável: a LISTA rola, o cabeçalho e o rodapé ficam. É o que
       mantém "Concluir" sempre à vista, que era o problema da versão em página. */
    /* A folga era de 3rem e passou a 6rem: com 48px de margem total, um modal alto encostava nas
       bordas da janela e a barra de rolagem dele ficava rente ao limite da tela — dava para
       rolar, mas não dava para VER onde a rolagem termina. Meia polegada de respiro em cima e
       embaixo é o que mostra que o modal acabou. */
    max-height: min(38rem, calc(100vh - 6rem));

    /* GRID, e não flex column (19/09/2026, quarta rodada — e a que funcionou).
       `minmax(0, 1fr)` na linha do meio é a forma DETERMINÍSTICA de dizer "esta linha ocupa o que
       sobrar e pode encolher até zero". Em flex, a mesma ideia depende de `min-height: 0` vencer
       o `min-height: auto` implícito do item, e isso não estava acontecendo aqui: o corpo ficava
       do tamanho do conteúdo, empurrava o modal para além do teto, e o `overflow: hidden` do
       modal cortava o fim do corpo — junto com o fim da barra de rolagem, que foi o sintoma
       descrito ("não vejo o final da barra de rolagem").

       As três linhas cobrem os dois formatos de modal do produto: com rodapé (topo, corpo,
       rodapé) e sem (topo, corpo — a terceira fica com altura zero). */
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;

    background: var(--pw-sheet);
    border-radius: var(--pw-r-3);
    box-shadow: 0 8px 40px rgba(var(--pw-shadow-rgb), .25);

    /* CONTÉM o que passar do teto (19/09/2026). Sem isto, o conteúdo que escapa do corpo é
       desenhado por cima da sombra e por fora dos cantos arredondados — o sintoma que o Leandro
       viu foi "o texto está saindo pra fora do modal". É a segunda metade do `min-height: 0`
       abaixo: um faz o corpo encolher e rolar, o outro impede o vazamento se alguma coisa ainda
       escapar. */
    overflow: hidden;
}

/* O modal LARGO (spec 109, 2ª rodada): a janela do "Nota Fiscal" do frete tem a linha do tempo
   DEITADA, e ela só deita com 720px de caixa (a consulta de contêiner da `pw-timeline-caixa`). Com
   os 46rem do modal comum o corpo ficava abaixo disso, a linha ficava em pé e o modal rolava. Em
   tela estreita a largura cai com a janela, a linha volta a ficar em pé — e isso é o certo. */
.pw-modal--largo {
    width: min(60rem, calc(100vw - 2rem));
    max-height: min(46rem, calc(100vh - 4rem));
}

.pw-modal__topo,
.pw-modal__rodape {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--pw-3);
    padding: var(--pw-4) var(--pw-5);

    /* NÃO ENCOLHEM. Eles são a moldura: o "Fechar" e o título precisam ficar à vista enquanto o
       corpo rola. Com o modal em grid isso já vem das linhas `auto`, e a declaração fica como
       proteção para o dia em que alguém puser um quarto filho no modal. */
    flex: 0 0 auto;
    min-height: 0;
}

.pw-modal__topo { border-bottom: 1px solid var(--pw-line); }
.pw-modal__rodape { border-top: 1px solid var(--pw-line); }

.pw-modal__corpo {
    overflow-y: auto;
    padding: var(--pw-4) var(--pw-5);
    display: flex;
    flex-direction: column;
    gap: var(--pw-3);

    /* `min-height: 0` É O QUE FAZ A ROLAGEM EXISTIR (19/09/2026). Num contêiner flex, o item
       nasce com `min-height: auto`, e isso o impede de encolher abaixo do próprio conteúdo: o
       corpo empurrava o modal para além do `max-height` em vez de rolar, e o `overflow-y: auto`
       acima nunca tinha o que fazer. O sintoma é a barra de rolagem que não aparece — e o rodapé
       que some fora da tela junto. Só apareceu quando um modal ganhou texto longo (a ajuda das
       telas da avaliação); com listas curtas, o defeito estava lá e não dava sinal. */
    min-height: 0;

    /* Resto do desenho anterior, quando o modal era flex: inofensivo em grid, e é o que mantém o
       comportamento caso alguém volte o pai para flex sem ler o porquê acima. */
    flex: 1 1 auto;

    /* Rolar até o fim do texto não passa a rolagem para a página atrás do modal. */
    overscroll-behavior: contain;

    /* Palavra comprida (um e-mail, um número de pedido) não empurra a largura: ela quebra. O
       vazamento HORIZONTAL é o outro jeito de "o texto sair pra fora", e não tem nada a ver com
       altura. */
    overflow-wrap: anywhere;

    /* TETO PRÓPRIO, como rede: com o modal em grid, quem limita o corpo é a linha
       `minmax(0, 1fr)`. Este `max-height` é a segunda trava, para o caso de a linha do grid não
       ser respeitada — e o desconto de 12rem cobre o topo, o rodapé e a margem do modal na
       janela. Duas travas porque este defeito voltou quatro vezes. */
    max-height: calc(100vh - 12rem);
}

/* ── A CAUSA REAL DE "NÃO MOSTRA TUDO E NÃO ROLA" (19/09/2026) ──────────────
   O corpo é `flex-direction: column` COM altura limitada, e todo flex item nasce com
   `flex-shrink: 1`. Diante da restrição, o navegador faz o que lhe é pedido: ESPREME os filhos
   até caberem, em vez de deixar o pai rolar. Um parágrafo espremido não some — ele continua
   desenhando o texto para fora da própria caixa, por cima do que vem depois. E como tudo
   "coube", não há nada que transborde do pai, então `overflow-y: auto` não tem motivo para
   mostrar barra de rolagem alguma.

   Daí o sintoma ser exatamente o par que o Leandro descreveu três vezes: o texto aparece
   cortado/sobreposto E não há rolagem. Nenhuma das minhas tentativas anteriores tocava nisso —
   `min-height: 0`, `flex: 1 1 auto` e `max-height` governam o CORPO diante do modal, e o
   problema estava um nível abaixo, entre o corpo e os filhos dele.

   Os modais antigos escapavam porque o conteúdo deles é tabela e formulário dentro de UM
   contêiner, e um item só não tem por onde ser espremido; a ajuda é uma pilha de parágrafos e
   listas, e aí cada um vira um item comprimível.

   Vale para TODO modal do produto: quem rola é o corpo, os filhos ficam do tamanho que são. */
.pw-modal__corpo > * { flex-shrink: 0; }

/* ── O MODAL DA AJUDA DA TELA (spec 087, frente 4) ──────────────────────────
   Mesmo desenho dos demais modais (`pw-modal` acima), mas quem abre e fecha é o NAVEGADOR, pelo
   par `popovertarget`/`popover` — sem circuito e sem script.

   O porquê está no componente: metade das telas do produto é renderizada de forma estática de
   propósito, e nelas um botão que depende do circuito fica desenhado e mudo. O `::backdrop`
   substitui o `pw-modal-fundo`, que continua servindo aos modais com estado (escolha de
   fornecedor, detalhe da trilha).

   FECHADA POR PADRÃO, e esta linha é deliberada: num navegador que não conheça o recurso, a
   regra de abrir (`:popover-open`) é descartada e a ajuda continua fechada. Sem ela, o conteúdo
   apareceria solto no meio da página — o defeito visível, e o pior dos dois. */
.pw-ajuda-modal {
    display: none;

    /* Desfaz o que o navegador põe de fábrica em [popover]: `inset: 0` com `top`/`left` já
       definidos esticaria a caixa de uma borda à outra, e a moldura padrão desenharia uma
       segunda borda por dentro da nossa. */
    right: auto;
    bottom: auto;
    margin: 0;
    border: 0;
    padding: 0;
}

.pw-ajuda-modal:popover-open { display: grid; }

.pw-ajuda-modal::backdrop { background: rgba(var(--pw-shadow-rgb), .45); }

/* O título e o subtítulo empurram a ajuda para a direita da barra; dentro de uma faixa
   (`pw-aviso`, spec 106), a barra não pode abrir um vão abaixo do texto que ela já fecha. */
.pw-aviso .pw-toolbar:last-child { margin-bottom: 0; }

/* ── AVALIAÇÃO DO FORNECEDOR (spec 037) ─────────────────────────────────────
   Cinco linhas de rótulo + combo. Grid de duas colunas e não uma tabela: são pares
   rótulo/valor, e tabela aqui obrigaria um cabeçalho que não diz nada ("Critério | Resposta").

   A coluna do rótulo tem largura fixa para as cinco combos alinharem — desalinhadas, a lista
   parece cinco perguntas soltas em vez de uma escala aplicada cinco vezes. */
.pw-avaliacao { display: grid; gap: 10px; }

.pw-avaliacao__linha {
    display: grid; grid-template-columns: 160px minmax(0, 1fr);
    align-items: center; gap: 12px;
}

.pw-avaliacao__criterio { font-weight: 600; color: var(--pw-ink-2); }

@media (max-width: 640px) {
    /* Em tela estreita a combo vai para baixo do rótulo: 160px + combo não cabem, e encolher
       a combo esconderia justamente o texto que evita o erro de escala. */
    .pw-avaliacao__linha { grid-template-columns: minmax(0, 1fr); gap: 4px; }
}

/* Campo de MUNICÍPIOS do motor de regras (spec 048): o estado, a busca por nome e a lista do
   que já entrou. Grade e não flex solto — a caixa de digitar precisa de largura fixa em
   relação ao estado, e não do que sobrar depois dele. */
.pw-municipios { display: grid; gap: var(--pw-2); }
.pw-municipios__escolha {
    display: grid; gap: var(--pw-2);
    grid-template-columns: 1fr 2fr; align-items: center;
}
.pw-municipios__lista { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--pw-1); }
.pw-municipios__lista li {
    display: flex; align-items: center; justify-content: space-between; gap: var(--pw-2);
    background: var(--pw-vellum); border: 1px solid var(--pw-line);
    border-radius: var(--pw-r-2); padding: var(--pw-1) var(--pw-2);
}

/* A lista de resultados da busca de município (spec 048). Altura limitada e rolagem própria:
   50 resultados não podem empurrar o resto do formulário para fora da tela. */
.pw-municipios__achados {
    list-style: none; margin: 0; padding: var(--pw-1);
    display: grid; gap: 2px; max-height: 240px; overflow-y: auto;
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-2);
    background: var(--pw-sheet);
}
.pw-municipios__achados li { display: block; }
.pw-municipios__achados .pw-btn { width: 100%; justify-content: flex-start; height: 32px; }

/* ── Termo de uso (spec 051) ────────────────────────────────────────────────────────────────

   Duas peças: o BLOCO DE LEITURA, que o fornecedor rola antes de marcar o aceite, e o EDITOR
   VISUAL da administração.

   O bloco de leitura tem altura limitada e rolagem PRÓPRIA de propósito: um termo de quatro mil
   palavras empurraria a caixa de marcar e o botão para fora da tela, e a pessoa teria de rolar a
   página inteira para achar o que assinar. Com a rolagem dentro do bloco, o aceite fica sempre à
   vista — e rolar o texto vira um gesto deliberado, que é o que se quer de quem está aceitando
   um contrato. */
.pw-termo { display: grid; gap: var(--pw-3); margin-top: var(--pw-4); }

.pw-termo__texto {
    max-height: 260px; overflow-y: auto;
    padding: var(--pw-4);
    background: var(--pw-vellum-2);
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-2);
    font-size: var(--pw-t-base); color: var(--pw-ink-2); line-height: 1.6;
}
.pw-termo__texto--alto { max-height: 420px; }
.pw-termo__texto:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 2px; }

/* O subconjunto fechado, e só ele: parágrafo, três níveis de título, negrito, itálico, lista e
   link. Não há estilo para mais nada porque não sai mais nada do renderizador. */
.pw-termo__texto > :first-child { margin-top: 0; }
.pw-termo__texto > :last-child { margin-bottom: 0; }
.pw-termo__texto p { margin: 0 0 var(--pw-3); }
.pw-termo__texto h2 { font-size: var(--pw-t-lg); color: var(--pw-ink); margin: var(--pw-4) 0 var(--pw-2); }
.pw-termo__texto h3 { font-size: var(--pw-t-md); color: var(--pw-ink); margin: var(--pw-4) 0 var(--pw-2); }
.pw-termo__texto h4 { font-size: var(--pw-t-base); color: var(--pw-ink); margin: var(--pw-3) 0 var(--pw-1); }
.pw-termo__texto ul,
.pw-termo__texto ol { margin: 0 0 var(--pw-3); padding-left: var(--pw-5); }
.pw-termo__texto li { margin-bottom: var(--pw-1); }
.pw-termo__texto strong { color: var(--pw-ink); font-weight: 600; }
.pw-termo__texto a { color: var(--pw-notice); }

/* O aceite é o alvo de clique inteiro, texto incluído: caixa de 16px é alvo pequeno demais para
   a decisão mais importante da tela. */
.pw-termo__aceite {
    display: flex; align-items: center; gap: var(--pw-2);
    font-size: var(--pw-t-base); color: var(--pw-ink-2); cursor: pointer;
}

/* O link do termo dentro da frase do aceite: mesmo corpo do texto ao redor, para ler como parte
   da frase e não como um botão encaixado nela. */
.pw-termo__link { font-size: inherit; }

/* O texto dentro do MODAL do cadastro. Quem rola é o corpo do modal, então o bloco solta o teto de
   altura e a moldura — rolagem dentro de rolagem é a que ninguém acha. */
.pw-termo__texto--modal {
    max-height: none; overflow: visible;
    padding: 0; background: none; border: 0;
}

/* O diálogo recebe foco por programa ao abrir, para o teclado entrar nele. O contorno de foco num
   contêiner do tamanho do modal não diz nada a ninguém; os controles de dentro mantêm o deles. */
.pw-modal:focus { outline: none; }

/* O card do login é estreito (420px) porque login é um formulário curto. O termo não cabe nisso
   e ler contrato em coluna estreita é pior; esta variante só solta a largura. */
.pw-login__card--largo { max-width: 640px; }

/* ── Editor visual do termo (spec 051) ───────────────────────────────────────────────────────

   O que está dentro da área é do NAVEGADOR (contenteditable), não do Blazor. O estilo espelha o
   da leitura de propósito: quem escreve tem de ver o que o fornecedor vai ver, senão a única
   forma de conferir o resultado é publicar. */
.pw-editor {
    border: 1px solid var(--pw-line); border-radius: var(--pw-r-2);
    background: var(--pw-sheet); overflow: hidden;
}
.pw-editor__barra {
    display: flex; align-items: center; gap: var(--pw-1); flex-wrap: wrap;
    padding: var(--pw-2); background: var(--pw-vellum);
    border-bottom: 1px solid var(--pw-line);
}
.pw-editor__barra .pw-btn { min-width: 40px; padding: 0 var(--pw-3); }
.pw-editor__sep { width: 1px; height: 20px; background: var(--pw-heavy); margin: 0 var(--pw-1); }

.pw-editor__area {
    min-height: 320px; max-height: 520px; overflow-y: auto;
    padding: var(--pw-4);
    font-size: var(--pw-t-base); color: var(--pw-ink-2); line-height: 1.6;
}
.pw-editor__area:focus { outline: 2px solid var(--pw-notice); outline-offset: calc(var(--pw-1) * -1); }
.pw-editor__area > :first-child { margin-top: 0; }
.pw-editor__area p { margin: 0 0 var(--pw-3); }
.pw-editor__area h2 { font-size: var(--pw-t-lg); color: var(--pw-ink); margin: var(--pw-4) 0 var(--pw-2); }
.pw-editor__area h3 { font-size: var(--pw-t-md); color: var(--pw-ink); margin: var(--pw-4) 0 var(--pw-2); }
.pw-editor__area h4 { font-size: var(--pw-t-base); color: var(--pw-ink); margin: var(--pw-3) 0 var(--pw-1); }
.pw-editor__area ul,
.pw-editor__area ol { margin: 0 0 var(--pw-3); padding-left: var(--pw-5); }
.pw-editor__area a { color: var(--pw-notice); }

/* ---------------------------------------------------------------------------
   DEVOLUÇÃO E REENVIO (spec 065)

   A faixa da devolução vigente é um Aviso de erro (spec 106), com as linhas em itens. O
   vermelho é do ESTADO da medição (devolvida) — a mesma dona da pílula "Rejeitado" —, e só
   aparece enquanto a medição está devolvida: o servidor manda, a tela não deduz. */
.pw-lista-devolucao { margin: var(--pw-2) 0 0; padding-left: var(--pw-5); }
.pw-lista-devolucao li { margin-bottom: var(--pw-1); white-space: pre-line; }
.pw-lista-devolucao a { color: inherit; font-weight: 700; }

/* O motivo NA PRÓPRIA linha reprovada (alteração de 15/09): em linha separada, o item parecia
   estar duas vezes na tabela. Pílula em cima, texto embaixo, na largura da coluna. */
.pw-celula-motivo { min-width: 14rem; }
.pw-celula-motivo__texto {
    display: block; margin-top: var(--pw-1);
    color: var(--pw-danger-ink); font-size: var(--pw-t-xs); white-space: pre-line;
}
/* Título da página com o selo de reenvio ao lado, e não empilhado no cartão do número. */
.pw-titulo-com-selo { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pw-2); }
.pw-titulo-com-selo .pw-page-title { margin: 0; }

/* A marca do que mudou entre o envio anterior e o atual: texto em cinza, nunca cor de estado. */
.pw-mudanca { display: inline-block; font-size: var(--pw-t-xs); font-weight: 700; color: var(--pw-ink-2); }
.pw-mudanca--sem { color: var(--pw-ink-4); font-weight: 600; }
.pw-anterior { display: block; font-size: var(--pw-t-xs); color: var(--pw-ink-3); }
.pw-linha--removida > * { opacity: .6; text-decoration: line-through; }

/* Um bloco RECOLHIDO por padrão dentro de um cartão — a conferência da nota já enviada (spec 111). O
   mesmo <details> do histórico, com o título no tamanho do texto do cartão. */
.pw-recolhivel { margin-top: var(--pw-3); }
.pw-recolhivel > summary {
    cursor: pointer; list-style: revert;
    font-size: var(--pw-t-base); font-weight: 700; color: var(--pw-ink);
}
.pw-recolhivel > summary:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 2px; }
.pw-recolhivel[open] > summary { margin-bottom: var(--pw-3); }

/* Histórico de envios: recolhido por padrão, uma entrada por rodada. */
.pw-historico > summary {
    cursor: pointer; list-style: revert;
    font-size: var(--pw-t-md); font-weight: 700; color: var(--pw-ink);
}
.pw-historico > summary:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 2px; }
.pw-rodada { padding-block: var(--pw-4); border-top: 1px solid var(--pw-hair); }
/* Na tabela das notas devolvidas (spec 116), a linha de apoio fica embaixo do dado, não ao lado. */
.pw-historico td .pw-hint, .pw-historico th .pw-hint { display: block; }
.pw-rodada:first-of-type { margin-top: var(--pw-3); }
.pw-rodada__topo { display: flex; flex-wrap: wrap; align-items: center; gap: var(--pw-2); }
.pw-rodada__topo h3 { margin: 0; font-size: var(--pw-t-base); }
.pw-rodada__bloco { margin: var(--pw-2) 0 0; white-space: pre-line; }
.pw-contador { display: block; text-align: right; font-size: var(--pw-t-xs); color: var(--pw-ink-3); }
.pw-contador--fora { color: var(--pw-danger-ink); font-weight: 700; }

/* ---------------------------------------------------------------------------
   REVISÃO DA DECISÃO (spec 066)

   A revisão mora dentro do envio que ela reviu, no histórico, e na linha do tempo como passo
   próprio. Nenhuma cor nova: as pílulas são as da decisão (065), e o resto é texto em tons de tinta.
   A justificativa pode ter 2.000 caracteres — quebra de linha preservada, e a palavra longa quebra. */
.pw-timeline__nota { margin-top: var(--pw-1); white-space: pre-line; overflow-wrap: anywhere; }
.pw-revisoes { margin-top: var(--pw-4); padding-top: var(--pw-3); border-top: 1px dashed var(--pw-hair); }
.pw-revisoes__titulo { margin: 0; font-size: var(--pw-t-base); color: var(--pw-ink); }
.pw-revisao { margin-top: var(--pw-3); padding-left: var(--pw-3); border-left: 2px solid var(--pw-hair); }

/* ---------------------------------------------------------------------------
   DASHBOARD EXECUTIVO (spec 068)

   Uma fileira de números-chave e quatro blocos de cartões lado a lado. Tudo por token: o dashboard
   é o mesmo sistema visual do resto do produto, com mais densidade — não um tema à parte.

   COR: as séries usam --pw-serie-1..4 e a escala sequencial do azul (022); a quinta fatia de uma
   rosca é o cinza neutro --pw-ink-4. Verde/âmbar/vermelho SÓ na rosca de etapas, porque ali a
   fatia É o status do boletim (regra 3 do DESIGN.md), e a classe sai do VALOR da etapa. A variação
   do número-chave não tem cor (regra 9).
   --------------------------------------------------------------------------- */

.pw-painel { display: grid; gap: var(--pw-5); }
.pw-painel__secao { display: grid; gap: var(--pw-3); }
.pw-painel__bloco {
    font-size: var(--pw-t-lg); font-weight: 700; letter-spacing: -0.01em;
    margin: 0; color: var(--pw-ink);
}

/* Números-chave: 6 por linha em tela larga, 3 em média, 2 em estreita. */
.pw-painel__numeros { display: grid; gap: var(--pw-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 760px) { .pw-painel__numeros { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1440px) { .pw-painel__numeros { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
/* Sete números (o painel do fornecedor, spec 069): a fileira abre uma coluna a mais no monitor
   largo em vez de deixar o último cartão sozinho numa segunda linha. Abaixo disso a grade é a
   mesma — 3 e 2 colunas —, e quem sobra na última linha é o último da ordem, nunca o primeiro. */
@media (min-width: 1440px) { .pw-painel__numeros--sete { grid-template-columns: repeat(7, minmax(0, 1fr)); } }
/* Oito números (o painel da CN, spec 068, 2ª rodada): 4 + 4 no monitor largo. Sete colunas com um
   cartão sozinho na segunda linha ficaria pior do que duas linhas cheias — e com os três primeiros
   condicionais (regra B7), a fileira pode vir com 5, 6 ou 7 cartões, que a grade acomoda igual. */
@media (min-width: 1440px) { .pw-painel__numeros--oito { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
/* Nove números (spec 099: "Acessos de colaborador a decidir" entrou): 3 + 3 + 3, que é a grade
   de 760px continuando no monitor largo. Com quatro colunas o nono ficaria sozinho numa terceira
   linha. */
@media (min-width: 1440px) { .pw-painel__numeros--nove { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* A FILEIRA DA CN NUMA LINHA SÓ (spec 068, 5ª rodada, regra E1, 28/09/2026). Nove números em 3 + 3 + 3
   eram três linhas de cartão antes do primeiro gráfico. Aqui o cartão fica COMPACTO (menos respiro, o
   valor um degrau menor, o rótulo em corpo menor quebrando em até duas linhas — nunca cortado) e a
   grade decide pela largura da SEÇÃO, não da janela: com a lateral do Portal, a janela mente sobre o
   espaço (foi o que cortou a legenda da rosca na 069). A classe --nN diz quantos vieram (5 a 9):
   cabe numa linha → uma linha; não cabe → duas equilibradas; estreito → 3; muito estreito → 2.
   A coluna mínima é ~150px. O painel do FORNECEDOR não usa --linha e fica como estava (regra E2). */
.pw-painel__secao--numeros { container-type: inline-size; }
.pw-painel__numeros.pw-painel__numeros--linha { gap: var(--pw-3); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pw-painel__numeros--linha .pw-numero { padding: var(--pw-3) var(--pw-4); gap: var(--pw-1); }
.pw-painel__numeros--linha .pw-numero .pw-stat__value { font-size: var(--pw-t-lg); }
.pw-painel__numeros--linha .pw-stat__label { font-size: var(--pw-t-xs); line-height: 1.3; }
@container (min-width: 480px) { .pw-painel__numeros.pw-painel__numeros--linha { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@container (min-width: 800px) { .pw-painel__numeros.pw-painel__numeros--n5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@container (min-width: 960px) { .pw-painel__numeros.pw-painel__numeros--n6 { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
@container (min-width: 640px) { .pw-painel__numeros.pw-painel__numeros--n7,
                                .pw-painel__numeros.pw-painel__numeros--n8 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@container (min-width: 1130px) { .pw-painel__numeros.pw-painel__numeros--n7 { grid-template-columns: repeat(7, minmax(0, 1fr)); } }
@container (min-width: 1290px) { .pw-painel__numeros.pw-painel__numeros--n8 { grid-template-columns: repeat(8, minmax(0, 1fr)); } }
@container (min-width: 800px) { .pw-painel__numeros.pw-painel__numeros--n9 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@container (min-width: 1450px) { .pw-painel__numeros.pw-painel__numeros--n9 { grid-template-columns: repeat(9, minmax(0, 1fr)); } }

/* O SINO DA PENDÊNCIA (spec 099; refeito em 24/09/2026 a pedido do Leandro: "tem que ser algo
   chamativo, e a posição não ficou boa").

   É um SELO no canto superior direito do cartão — onde se procura notificação —, com o sino e a
   contagem, em ÂMBAR SÓLIDO. Âmbar é a 5ª dona das cores de estado (CLAUDE.md, decisão de
   24/09): "há algo esperando você decidir". A tinta é a escura, não branco: branco sobre o âmbar
   não passa de 2,6:1. Chama atenção por três coisas juntas — o preenchimento, um halo que se
   expande e some, e o sino balançando —, num ciclo de 2s (longe dos 3 flashes por segundo do
   WCAG 2.3.1). Com movimento reduzido, o selo aparece PARADO: continua âmbar e continua lá. */
.pw-numero__canto { display: inline-flex; align-items: center; gap: var(--pw-2); margin-left: auto; }
.pw-numero__selo {
    display: inline-flex; align-items: center; gap: var(--pw-1);
    padding: 2px var(--pw-2) 2px 6px; border-radius: var(--pw-r-pill);
    background: var(--pw-warn); color: var(--pw-ink);
    font-size: var(--pw-t-xs); font-weight: 800; line-height: 1.4; font-variant-numeric: tabular-nums;
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--pw-warn) 55%, transparent);
    animation: pw-selo-halo 2s ease-out infinite;
}
.pw-numero__sino {
    width: var(--pw-4); height: var(--pw-4); flex: none; color: currentColor;
    transform-origin: 50% 10%; animation: pw-sino-balanca 2s ease-in-out infinite;
}
@keyframes pw-selo-halo {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--pw-warn) 55%, transparent); }
    70%, 100% { box-shadow: 0 0 0 10px color-mix(in srgb, var(--pw-warn) 0%, transparent); }
}
@keyframes pw-sino-balanca {
    0%, 60%, 100% { transform: rotate(0); }
    10% { transform: rotate(16deg); }
    20% { transform: rotate(-14deg); }
    30% { transform: rotate(10deg); }
    40% { transform: rotate(-6deg); }
}
/* O cartão com pendência ganha o contorno âmbar: é o que faz ele se destacar na fileira antes
   de a pessoa ler qualquer número. */
.pw-numero--pendente { border-color: var(--pw-warn-ink); }
@media (prefers-reduced-motion: reduce) {
    .pw-numero__selo, .pw-numero__sino { animation: none; }
    .pw-pendencia__sino { animation: none; }
}

.pw-numero__topo { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--pw-2); }
.pw-numero .pw-stat__value { font-size: var(--pw-t-xl); color: var(--pw-ink); text-decoration: none; }
.pw-numero__link:hover { color: var(--pw-notice-ink); text-decoration: underline; }
.pw-numero__link:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: var(--pw-1); border-radius: var(--pw-r-1); }
.pw-numero__variacao { color: var(--pw-ink-2); font-variant-numeric: tabular-nums; }

/* Grade dos blocos: 2 colunas a partir de 1024px, 1 abaixo. Cartões da mesma linha com a
   MESMA altura: a célula estica (padrão do grid) e o cartão ocupa a célula inteira. */
.pw-painel__grade { display: grid; gap: var(--pw-4); grid-template-columns: minmax(0, 1fr); align-items: stretch; }
@media (min-width: 1024px) { .pw-painel__grade { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.pw-painel__cartao { display: flex; flex-direction: column; gap: var(--pw-3); height: 100%; min-width: 0; }
.pw-painel__titulos { min-width: 0; }
.pw-painel__cabecalho { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--pw-3); }
.pw-painel__titulo { font-size: var(--pw-t-md); font-weight: 700; margin: 0; color: var(--pw-ink); }
.pw-painel__subtitulo { font-size: var(--pw-t-label); color: var(--pw-ink-3); margin: 2px 0 0; }
.pw-painel__vazio { margin: auto 0; padding-block: var(--pw-5); text-align: center; }
.pw-painel__erro { display: grid; justify-items: start; gap: var(--pw-2); }

/* Número pequeno (revisões de decisão). */
.pw-painel__pequeno { display: flex; align-items: center; gap: var(--pw-5); flex-wrap: wrap; }
.pw-painel__pequeno-valor { font-size: var(--pw-t-2xl); font-weight: 800; letter-spacing: -0.02em; color: var(--pw-ink); }
.pw-painel__pequeno-lista { margin: 0; display: grid; gap: var(--pw-1); }
.pw-painel__pequeno-lista div { display: flex; gap: var(--pw-3); justify-content: space-between; }
.pw-painel__pequeno-lista dt { font-size: var(--pw-t-label); color: var(--pw-ink-3); }
.pw-painel__pequeno-lista dd { margin: 0; font-weight: 700; font-variant-numeric: tabular-nums; }

/* Ajuda: o "como é calculado", fora da área visível até o foco ou o mouse. */
.pw-ajuda { position: relative; display: inline-flex; flex: none; }
.pw-ajuda__botao {
    width: var(--pw-5); height: var(--pw-5); border-radius: var(--pw-r-pill);
    border: 1px solid var(--pw-line); background: var(--pw-sheet); color: var(--pw-ink-3);
    font: inherit; font-size: var(--pw-t-xs); font-weight: 700; cursor: help; padding: 0;
}
.pw-ajuda__botao:hover { color: var(--pw-notice-ink); border-color: var(--pw-heavy); }
.pw-ajuda__botao:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 2px; }
.pw-ajuda__balao {
    position: absolute; right: 0; top: calc(100% + var(--pw-1)); z-index: 20;
    width: min(280px, 70vw); padding: var(--pw-2) var(--pw-3);
    background: var(--pw-ink-deep); color: var(--pw-sheet); border-radius: var(--pw-r-1);
    font-size: var(--pw-t-xs); font-weight: 400; line-height: 1.45;
    opacity: 0; visibility: hidden; pointer-events: none;
}
.pw-ajuda:hover .pw-ajuda__balao,
.pw-ajuda:focus-within .pw-ajuda__balao { opacity: 1; visibility: visible; }

/* Esqueleto: a forma do conteúdo que vem, sem animação chamativa (spec 068 para os gráficos,
   spec 087 — frente 3 — para as telas).

   O CINZA SAI DOS TOKENS que já existem: `--pw-hair` é a peça e `--pw-vellum` o contorno de
   cartão. Cinza novo aqui seria uma terceira superfície inventada para um estado temporário. */
.pw-esqueleto { display: flex; gap: var(--pw-2); align-items: flex-end; min-height: 140px; }
.pw-esqueleto__peca { flex: 1; border-radius: var(--pw-r-1); background: var(--pw-hair); }
.pw-esqueleto--colunas .pw-esqueleto__peca:nth-child(odd) { height: 60%; }
.pw-esqueleto--colunas .pw-esqueleto__peca:nth-child(even) { height: 90%; }
.pw-esqueleto--barras { flex-direction: column; align-items: stretch; justify-content: center; }
.pw-esqueleto--barras .pw-esqueleto__peca { flex: none; height: var(--pw-4); }
.pw-esqueleto--barras .pw-esqueleto__peca:nth-child(2n) { width: 70%; }
.pw-esqueleto--tabela { flex-direction: column; align-items: stretch; }
.pw-esqueleto--tabela .pw-esqueleto__peca { flex: none; height: var(--pw-5); }
.pw-esqueleto--rosca { justify-content: center; align-items: center; }
.pw-esqueleto--rosca .pw-esqueleto__peca { display: none; }
.pw-esqueleto--rosca .pw-esqueleto__peca:first-child {
    display: block; flex: none; width: 140px; height: 140px; border-radius: 50%;
    background: transparent; border: var(--pw-4) solid var(--pw-hair);
}
.pw-esqueleto--numero .pw-esqueleto__peca,
.pw-esqueleto--numeros .pw-esqueleto__peca { height: 80px; }
.pw-esqueleto--numero .pw-esqueleto__peca:nth-child(n+2) { display: none; }

/* As formas de TELA (spec 087, regra 14). Elas não são decoração: o esqueleto tem de ocupar o
   espaço que o conteúdo vai ocupar, senão a página se desloca quando o dado chega — que é o
   defeito que o girador central tinha e o motivo de ele não ter sido escolhido. */

/* Grade de cartões: a MESMA medida de `pw-grid--stats`, para o contorno cair nas colunas em que
   os cartões vão cair. */
.pw-esqueleto--cartoes {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    align-items: stretch; gap: var(--pw-4);
}
.pw-esqueleto--cartoes .pw-esqueleto__peca { height: calc(var(--pw-7) * 2); }

/* Campos empilhados. A primeira peça de cada trio é curta: é o rótulo. */
.pw-esqueleto--formulario { flex-direction: column; align-items: stretch; justify-content: flex-start; }
.pw-esqueleto--formulario .pw-esqueleto__peca { flex: none; height: var(--pw-7); }
.pw-esqueleto--formulario .pw-esqueleto__peca:nth-child(3n+1) { width: 40%; height: var(--pw-3); }

/* Parágrafos. `min-height: 0` porque este é o esqueleto que cabe dentro de um modal, onde os
   140px do padrão empurrariam o resto para fora da vista. */
.pw-esqueleto--texto {
    flex-direction: column; align-items: flex-start; justify-content: flex-start;
    min-height: 0; gap: var(--pw-3);
}
.pw-esqueleto--texto .pw-esqueleto__peca { flex: none; width: 100%; height: var(--pw-3); }
.pw-esqueleto--texto .pw-esqueleto__peca:nth-child(3n) { width: 62%; }

@media (prefers-reduced-motion: no-preference) {
    .pw-esqueleto__peca { animation: pw-esqueleto 1.6s ease-in-out infinite; }
}
@keyframes pw-esqueleto { 50% { opacity: .55; } }

/* Capa de "Carregando…" do dashboard (spec 068, 2ª rodada): cobre a página enquanto o recorte
   troca, esmaecendo o conteúdo em vez de tirá-lo do lugar — assim a página não pula quando ela sai.
   O `position: relative` do painel é o que a prende ao bloco, e não à janela. */
.pw-painel { position: relative; }
.pw-painel__capa {
    position: absolute; inset: 0; z-index: 20;
    display: flex; align-items: flex-start; justify-content: center;
    padding-top: var(--pw-7);
    background: color-mix(in srgb, var(--pw-paper) 72%, transparent);
    backdrop-filter: blur(1px);
    border-radius: var(--pw-r-3);
}
.pw-painel__capa-caixa {
    position: sticky; top: var(--pw-7);
    padding: var(--pw-3) var(--pw-5);
    border-radius: var(--pw-r-pill);
    border: 1px solid var(--pw-line);
    background: var(--pw-vellum-2);
    color: var(--pw-ink-2);
    font-size: var(--pw-t-label); font-weight: 600;
}

/* Barra de filtros, fixa no topo da área de conteúdo.

   O `top` é COMPOSTO (spec 089, regra 5): ela para abaixo do topo do produto, que é `fixed`.
   Ficava em `var(--pw-2)` — oito pixels da borda da JANELA, ou seja, atrás do topo, que está na
   camada 40 contra a 15 dela. O sintoma era a barra sumir ao rolar em vez de ficar; a causa não
   aparece em lugar nenhum do markup. */
.pw-filtros {
    position: sticky; top: calc(var(--pw-topo-h) + var(--pw-2));
    z-index: var(--pw-z-filtros); padding-block: var(--pw-3);
}
.pw-filtros__linha { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--pw-3) var(--pw-4); }
.pw-filtros__grupo { min-width: 0; }
/* AS DUAS DATAS SÃO UM CAMPO SÓ para a barra: "de quando até quando" é uma pergunta, e
   separá-las na quebra deixaria "Período de" no fim de uma linha e "até" no começo da seguinte.

   E ELAS PRECISAM ENCOLHER. Sem o `min-width: 0` nos filhos, o campo de data do Chrome tem
   largura mínima própria (o "dd/mm/aaaa" mais o ícone do calendário), o grupo não cede, e o que
   sobra ESTOURA PARA FORA do cartão — a página inteira ganha barra de rolagem horizontal. Foi o
   que aconteceu na primeira tentativa desta correção, e só apareceu na captura. */
.pw-filtros__datas { display: flex; gap: var(--pw-2); flex: 1 1 250px; }
.pw-filtros__datas > div { flex: 1 1 0; min-width: 0; }
.pw-filtros__datas .pw-input { width: 100%; min-width: 0; }
.pw-filtros__empresa { width: 96px; }
.pw-filtros__fornecedor { flex: 1 1 220px; }
.pw-filtros__acoes { display: flex; gap: var(--pw-2); margin-left: auto; }
/* Barra só com o período (spec 069): o grupo fica no meio, e "Limpar" logo ao lado — encostado à
   esquerda de um cartão largo, um punhado de botões sozinho parece resto de layout. */
.pw-filtros__linha--centralizada { justify-content: center; }
.pw-filtros__linha--centralizada .pw-filtros__acoes { margin-left: 0; }
.pw-filtros__aviso { margin: var(--pw-2) 0 0; font-size: var(--pw-t-label); color: var(--pw-ink-2); }
.pw-filtros__aviso--recusa { color: var(--pw-danger-ink); font-weight: 600; }

.pw-segmentado {
    display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 2px;
    border-radius: var(--pw-r-2); background: var(--pw-vellum); border: 1px solid var(--pw-line);
}
.pw-segmentado__opcao {
    border: 0; background: transparent; color: var(--pw-ink-2); cursor: pointer;
    font: inherit; font-size: var(--pw-t-label); font-weight: 600;
    padding: 6px var(--pw-3); border-radius: var(--pw-r-1); white-space: nowrap;
}
.pw-segmentado__opcao:hover { color: var(--pw-ink); background: var(--pw-sheet); }
.pw-segmentado__opcao--ativa { background: var(--pw-sheet); color: var(--pw-notice-ink); box-shadow: 0 1px 2px rgba(var(--pw-shadow-rgb), .08); }
.pw-segmentado__opcao:focus-visible { outline: 2px solid var(--pw-notice); outline-offset: 1px; }

/* Rosca: desenho à esquerda, legenda com valor e % à direita (empilha em cartão estreito).

   QUEM DECIDE É A LARGURA DO CARTÃO, e não a da janela (spec 069, 3ª rodada, 28/09/2026): com a lateral
   do Portal, o cartão do painel fica com ~360px numa janela de 1280, e a regra por janela punha o anel
   de 160px e a legenda lado a lado num espaço onde os nomes não cabiam — "Aguardando fo…". Agora:
   até 300px empilha; até 440px o anel encolhe para 120px; acima, 160px. */
.pw-rosca { container-type: inline-size; }
.pw-rosca__grade { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--pw-4); align-items: center; }
@container (min-width: 300px) { .pw-rosca__grade { grid-template-columns: 120px minmax(0, 1fr); } }
@container (min-width: 440px) { .pw-rosca__grade { grid-template-columns: 160px minmax(0, 1fr); } }
.pw-rosca__grade .pw-gr__tabela { grid-column: 1 / -1; }
.pw-rosca__desenho { position: relative; width: 100%; max-width: 160px; aspect-ratio: 1; justify-self: center; }
.pw-rosca__svg { display: block; width: 100%; height: 100%; }
.pw-rosca__trilho { fill: none; stroke: var(--pw-hair); stroke-width: 16; }
.pw-rosca__fatia { fill: none; stroke-width: 16; }
.pw-rosca__fatia--link { cursor: pointer; }
a:hover > .pw-rosca__fatia--link, a:focus-visible > .pw-rosca__fatia--link { stroke-width: 20; }
.pw-rosca__centro {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; text-align: center; pointer-events: none;
}
.pw-rosca__total { font-size: var(--pw-t-md); font-weight: 800; color: var(--pw-ink); font-variant-numeric: tabular-nums; }
.pw-rosca__rotulo { font-size: var(--pw-t-2xs); color: var(--pw-ink-3); }
.pw-rosca__legenda { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--pw-2); max-width: 360px; }
.pw-rosca__item {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
    align-items: center; gap: var(--pw-2); font-size: var(--pw-t-label);
}
/* O nome QUEBRA a linha em vez de sair cortado com reticências (28/09/2026): "Aguardando fo…" não diz
   de que fase é a fatia, e a legenda existe justamente para dizer. */
.pw-rosca__nome { color: var(--pw-ink-2); overflow-wrap: anywhere; }
.pw-rosca__valor { font-weight: 700; color: var(--pw-ink); font-variant-numeric: tabular-nums; }
.pw-rosca__pct { color: var(--pw-ink-3); font-variant-numeric: tabular-nums; min-width: 4ch; text-align: right; }
/* A frase de uma fatia só (spec 069, 3ª rodada): embaixo do anel E da legenda, na largura inteira. */
.pw-rosca__nota { grid-column: 1 / -1; margin: 0; }

/* Uma fatia só: não há anel a desenhar, então o número aparece escrito, com a tabela abaixo. */
.pw-rosca__so-uma { display: grid; gap: var(--pw-3); }
.pw-rosca__unica { margin: 0; display: flex; flex-direction: column; gap: var(--pw-1); }

.pw-rosca__cor--serie-1 { stroke: var(--pw-serie-1); }
.pw-rosca__cor--serie-2 { stroke: var(--pw-serie-2); }
.pw-rosca__cor--serie-3 { stroke: var(--pw-serie-3); }
.pw-rosca__cor--serie-4 { stroke: var(--pw-serie-4); }
.pw-rosca__cor--serie-5 { stroke: var(--pw-ink-4); }
.pw-marca--serie-1 { background: var(--pw-serie-1); }
.pw-marca--serie-2 { background: var(--pw-serie-2); }
.pw-marca--serie-3 { background: var(--pw-serie-3); }
.pw-marca--serie-4 { background: var(--pw-serie-4); }
.pw-marca--serie-5 { background: var(--pw-ink-4); }

/* Etapas da medição: a ÚNICA rosca com cor de estado, porque a fatia é o status do boletim. */
.pw-rosca__cor--espera    { stroke: var(--pw-warn); }
.pw-rosca__cor--andando   { stroke: var(--pw-notice); }
.pw-rosca__cor--concluida { stroke: var(--pw-safe); }
.pw-rosca__cor--rejeitado { stroke: var(--pw-danger); }
.pw-rosca__cor--neutro    { stroke: var(--pw-idle); }
.pw-marca--espera    { background: var(--pw-warn); }
.pw-marca--andando   { background: var(--pw-notice); }
.pw-marca--concluida { background: var(--pw-safe); }
.pw-marca--rejeitado { background: var(--pw-danger); }
.pw-marca--neutro    { background: var(--pw-idle); }

/* Colunas clicáveis: a coluna inteira é o alvo, invisível. */
.pw-gr__alvo { fill: transparent; }
.pw-gr__col { cursor: pointer; }
.pw-gr__col:focus-visible .pw-gr__barra { fill: var(--pw-notice-ink); }

/* Tabela curta: o medidor usa a FAIXA ÚNICA de consumo (regra D1 da 068), como toda barra de
   "quanto já foi". Ele já foi azul de série, por decisão da 1ª entrega — e azul em 100% não
   dizia nada; a classe de cor própria desta tabela saiu junto. */
.pw-tabela-curta { display: grid; gap: var(--pw-2); }
.pw-tabela-curta__medidor { display: flex; align-items: center; gap: var(--pw-2); }
.pw-tabela-curta__medidor .pw-medidor__trilho { flex: 1; min-width: 56px; }
.pw-tabela-curta__pct { font-size: var(--pw-t-xs); font-weight: 700; color: var(--pw-ink-2); font-variant-numeric: tabular-nums; }
.pw-tabela-curta__rodape { display: flex; justify-content: space-between; align-items: center; margin: 0; gap: var(--pw-3); }

/* ── Avaliacao de desempenho (spec 086) ───────────────────────────────────────
   O texto que diz "abaixo da regua". A regra 3 do DESIGN.md continua valendo: a nota NAO vira
   pilula verde/ambar/vermelha, porque a pergunta nao e "que cor" e sim "passou da linha?" — o
   medidor com a regua marcada responde isso. Esta classe existe para o caso em que a resposta e
   NAO: ela pinta o TEXTO e acompanha um icone, nunca cor sozinha.
   Tokens, como tudo: nenhum valor de cor escrito a mao. */
.pw-danger { color: var(--pw-danger-ink); font-weight: 700; }
.pw-danger .pw-pill__icone { vertical-align: -2px; }

/* O PAR DE `pw-danger` (19/09/2026, decisão do Leandro). Eu havia deixado a nota que PASSOU do
   mínimo na cor do texto, pelo argumento de que pintar o curso normal gasta a cor. Ele recusou:
   "a cor preta pra seta pra cima não ficou bom, acho que tem que ser verde" — e o argumento dele
   é mais forte na prática. Sem o verde, o par fica torto: o mesmo lugar da mesma coluna mostra um
   sinal forte de um lado e nada do outro, e "nada" lê-se como "não avaliado" em vez de "passou".
   É a mesma leitura do `lock`/`lock-open`: o par existe para a ausência não ser ambígua.

   O verde é `--pw-safe`, o MESMO de "aprovado" no resto do produto — é a mesma ideia de desfecho
   bom, e uma segunda tonalidade só para esta coluna abriria um vocabulário paralelo. */
.pw-aprovado { color: var(--pw-safe); font-weight: 700; }
.pw-aprovado .pw-pill__icone { vertical-align: -2px; }

/* A contagem da fila na aba. Herda o selo do produto em vez de inventar outro badge — um
   segundo desenho para a mesma coisa diverge no primeiro ajuste de espacamento. */
.pw-tab .pw-selo { margin-left: var(--pw-2); }


/* O NOME DESTA CLASSE, e por que ele é longo.

   ESTE `/*` FALTAVA, e a falta matava a folha inteira a partir daqui (achado de 21/09/2026,
   introduzido em feabe3e, spec 087). Sem ele, o navegador lia esta prosa como seletor; o par de
   aspas de "texto cortado E sem / rolagem" abre numa linha e fecha na outra, e string em CSS não
   atravessa quebra de linha — a aspa ficava aberta e ENGOLIA todo o resto do arquivo. Três
   classes pararam de existir para o navegador (`pw-ajuda-texto`, `pw-fatos` e, depois,
   `pw-resumo-da-recusa`), sem um erro, sem um teste vermelho e sem nada na tela apontando para
   cá: o modal de ajuda simplesmente ficava sem estilo.

   A lição é a mesma que a spec 089 já pagou uma vez — guarda que lê CSS com regex não sabe se o
   NAVEGADOR aplicou o arquivo. A conferência que pega isto é de SINTAXE, e ela está em
   `AFolhaDeEstiloEhValidaTests`.

   A CLASSE É `pw-ajuda-texto`, e NÃO `pw-ajuda`. O nome curto já tinha dono: o balão de
   tooltip do `AjudaDoPainel` (`.pw-ajuda { display: inline-flex }`, mais abaixo neste
   arquivo). Duas regras de mesma especificidade casando o mesmo elemento: vence a que vem
   DEPOIS, e o corpo do modal virava `inline-flex` — os parágrafos saíam lado a lado,
   transbordavam na horizontal, e a rolagem vertical não tinha o que mostrar.

   É o par de sintomas que já custou três rodadas de correção neste modal ("texto cortado E sem
   rolagem"): as correções anteriores mexeram no modal e no corpo, e a causa estava no NOME. */

/* ── A AJUDA DA TELA (spec 086, alteração de 19/09/2026) ────────────────────
   O corpo do modal que explica o que cada palavra da tela significa.

   É uma LISTA DE DEFINIÇÃO de verdade (`dl`/`dt`/`dd`), e não parágrafos com negrito: termo e
   significado são exatamente o que o elemento existe para marcar, e é o que faz o leitor de tela
   anunciar "Pilar, definição: cada pergunta da avaliação" em vez de uma frase corrida.

   Nada de cor aqui além dos tokens de texto: verde/âmbar/vermelho têm donas no DESIGN.md, e
   ajuda não é uma delas. */
.pw-ajuda-texto h3 {
    margin: var(--pw-3) 0 0;
    font-size: .95rem;
    font-weight: 600;
    color: var(--pw-ink);
}

.pw-ajuda-texto h3:first-child { margin-top: 0; }

.pw-ajuda-texto p {
    margin: 0;
    color: var(--pw-ink-2);
    line-height: 1.55;
}

.pw-ajuda-texto dl {
    margin: 0;
    display: grid;
    gap: var(--pw-2);
}

.pw-ajuda-texto dt {
    font-weight: 600;
    color: var(--pw-ink);
}

/* O recuo é o que separa a definição do próximo termo sem precisar de linha nem de fundo —
   numa lista de seis termos, seis caixas viram uma parede. */
.pw-ajuda-texto dd {
    margin: 0 0 var(--pw-2) var(--pw-3);
    color: var(--pw-ink-2);
    line-height: 1.55;
}

.pw-ajuda-texto dd:last-child { margin-bottom: 0; }

/* ── OS FATOS DE UM REGISTRO, em grade (19/09/2026) ─────────────────────────
   Pares rótulo/valor lado a lado, em vez de um por linha.

   Existe porque não havia grade para ISTO: `pw-grid--stats` é de cartão de número, com ícone e
   caixa própria, e usá-la aqui transformaria oito fatos em oito cartões — oito caixas para
   dizer "pedido 4500001234". O empilhado que havia antes gastava oito linhas de altura antes de
   a pessoa chegar ao que ela veio fazer na tela.

   `auto-fit` e não coluna fixa: a quantidade de fatos VARIA (requisitante e categoria só
   aparecem quando o pedido os traz), e contar à mão erraria na primeira medição sem eles.
   O piso de 200px é o que impede "Folha de serviço" de quebrar no meio. */
.pw-fatos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--pw-3) var(--pw-4);
}

/* ── OS NÚMEROS DE UMA RECUSA (spec 092, frente 5) ──────────────────────────
   O pedido não tem mais saldo a medir, e a tela mostra POR QUÊ: valor do pedido, faturado,
   reservado em medições em aberto e saldo. É a justificativa de uma recusa, e ela fica ao lado
   da frase que a explica.

   TEXTO, e não `pw-grid--stats`: tile é vocabulário de painel, e quatro tiles aqui dariam à
   recusa a cara de um resumo gerencial — a pessoa veio lançar uma medição e precisa entender
   em uma leitura por que não vai dar.

   É uma LISTA DE DEFINIÇÃO de verdade (`dl`/`dt`/`dd`): rótulo e número são exatamente o que o
   elemento marca, e é o que faz o leitor de tela anunciar "Saldo disponível, definição:
   R$ 0,00" em vez de uma frase corrida.

   NEUTRA, sem cor: não ter saldo não é falha de ninguém — é o pedido tendo sido medido.
   Verde/âmbar/vermelho têm donas no DESIGN.md, e recusa de conveniência não é uma delas. */
.pw-resumo-da-recusa {
    display: grid;
    grid-template-columns: 1fr auto;
    /* COLUNA sem vão, e o respiro vai no padding do rótulo. O filete que separa o saldo das
       três parcelas é `border-top` em dt E dd: com vão entre as colunas ele sai PARTIDO ao
       meio, e uma conta cujo traço de fechamento é interrompido lê-se como dois blocos. */
    gap: var(--pw-2) 0;
    margin: var(--pw-4) 0 0;
    padding: var(--pw-3) var(--pw-4);
    background: var(--pw-vellum);
    border: 1px solid var(--pw-hair);
    border-radius: var(--pw-r-2);
}

.pw-resumo-da-recusa dt {
    margin: 0;
    padding-right: var(--pw-4);
    color: var(--pw-ink-2);
}

/* O número à direita, tabular: as quatro linhas são a mesma conta lida de cima a baixo, e
   algarismo que dança quebra justamente essa leitura. */
.pw-resumo-da-recusa dd {
    margin: 0;
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--pw-ink);
}

/* O SALDO é a última linha e é a que responde a pergunta: separado por um filete, como o total
   de uma tabela. Pelo par, e não por `:last-child` sozinho, porque o "reservado" só aparece
   quando existe — contar posições erraria no pedido sem medição em aberto. */
.pw-resumo-da-recusa dt:last-of-type,
.pw-resumo-da-recusa dd:last-of-type {
    padding-top: var(--pw-2);
    border-top: 1px solid var(--pw-hair);
}

/* O detalhe estruturado do aviso (spec 106) — hoje, as linhas a corrigir da devolução: o item como
   link, a descrição em tinta secundária e o motivo abaixo, um bloco por linha. */
.pw-aviso__detalhe { margin-top: var(--pw-2); }
.pw-aviso__linhas { margin: var(--pw-1) 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: var(--pw-2); }
.pw-aviso__linhas li {
    background: var(--pw-sheet); border-radius: var(--pw-r-1); padding: var(--pw-2) var(--pw-3);
    color: var(--pw-ink-2); overflow-wrap: anywhere;
}
.pw-aviso__linhas a { color: var(--aviso-tinta); font-weight: 700; }
.pw-aviso__linhas .pw-aviso__desc { color: var(--pw-ink-3); font-size: var(--pw-t-label); }
.pw-aviso__linhas .pw-aviso__motivo { display: block; margin-top: 2px; color: var(--pw-ink); }
