/* ============================================================================
   orch.css — Design System Orch (TMS)

   Origem (extração manual, uma regra por linha, sem minificação):
     · /Users/felipe.ruiz/Herd/orch-knowledge/design-system/orquest-admin-light.html
       (1 bloco <style>, linhas 4-86)  — o CHASSI: layout, sidebar, topbar,
       tabela, botões, badges, paginação
     · /Users/felipe.ruiz/Herd/orch-knowledge/design-system/orquest-ui-components.html
       (2 blocos <style>, linhas 4-390 e 705-971) — o CATÁLOGO: modais, drawers,
       toasts, forms, chips, wizard, timeline

   Data: 2026-08-23

   DESCARTADO: orquest-design-system.html — catálogo de swatches e tipografia de
   vitrine; não contém componentes e contribuiu ZERO regras.
   NÃO USADO como fonte: wms-prototype/public/css/orquest.css (pré-retint,
   laranja da marca anterior no --primary). Nenhuma linha dele foi copiada.

   Regras de extração aplicadas:
     · Cenografia de vitrine removida (.hdr .section .sec-* .grid .page-demo
       .comp-label* .check-anim .S-ch)
     · De-duplicação "a primeira definição vence"; 2ª aditiva → fundida
     · Conflitos entre arquivos: admin-light é o chassi e vence
     · TOKENIZADO NA EXTRAÇÃO: todo hex com token equivalente virou variável
       do :root (o admin-light não tem :root e seus valores entrariam literais)
     · Contraste: texto sobre o verde #4ADE80 é sempre navy #000D3D
     · Nomes torcidos (.btn-o "orange" hoje verde, .cib-dot-orange) herdados de
       propósito — renomear quebra as regras da skill frontend-design
   ============================================================================ */

/* === Theme Tokens (:root) === */
/* 1º :root do ui-components (22 variáveis, já em cores Orch). O 2º foi descartado. */
/* `scrollbar-gutter: stable` — sem ele o layout INTEIRO salta 15px ao navegar
   de pagina longa para pagina curta, porque a barra de rolagem aparece e some.
   Medido no mesmo viewport de 1440: `clientWidth` 1425 na lista e 1440 na aba
   sem resultado. O salto nao e do conteudo, e do chassi. */
html{scrollbar-gutter:stable}
:root{
  --bg-default:#EEF1F8;--bg-paper:#FFFFFF;--bg-hover:#E4E8F1;
  --text-primary:#111827;--text-secondary:#475569;--text-disabled:#94A3B8;--text-muted:#64748B;--border-strong:#64748B  /* 4,76:1 sobre branco. Era #94A3B8 = 2,56:1, abaixo dos 3:1 de componente de interface — a borda existe para dizer onde o campo comeca */;--error-dark:#B91C1C;
  --divider:#E2E5EE;
  --primary:#4ADE80;--primary-dark:#22C55E;
  --secondary:#000D3D;--secondary-dark:#00081F;--secondary-light:#2F4A9E;
  --success:#246D4C;--success-light:#DCF1E6;
  --error:#EF4444;--error-light:#FEE2E2;
  --warning:#F59E0B;--warning-light:#FEF3C7;
  --info:#000D3D;--info-light:#E7EAF4;
  --purple:#8B5CF6;--purple-light:#EDE9FE;
}

/* === Reset & Base === */
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Plus Jakarta Sans',system-ui,sans-serif;background:var(--bg-default);color:var(--text-primary);-webkit-font-smoothing:antialiased}

/* === Keyframes (14) === */
/* 3 do admin-light + 11 do ui-components. Zero colisão de nome.
   NÃO LIMPAR — 4 estão sem consumidor no CSS hoje e isso é deliberado:
     · bob      — consumidor era .S-ch (mascote), removido como cenografia
     · checkPop — consumidor era .check-anim, removido como cenografia (0 uso no markup)
     · shake / slideUp — já eram órfãos no ui-components fonte
   O passo 7 do 01-extracao-css.md manda preservar os 14. */
@keyframes fi{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes sd{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-4px)}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes scaleIn{from{opacity:0;transform:scale(.92)}to{opacity:1;transform:scale(1)}}
@keyframes slideUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}
@keyframes slideRight{from{transform:translateX(100%)}to{transform:translateX(0)}}
@keyframes slideLeft{from{transform:translateX(-100%)}to{transform:translateX(0)}}
@keyframes slideDown{from{opacity:0;transform:translateY(-12px)}to{opacity:1;transform:translateY(0)}}
@keyframes toastIn{from{opacity:0;transform:translateX(40px)}to{opacity:1;transform:translateX(0)}}
@keyframes toastOut{to{opacity:0;transform:translateX(40px)}}
@keyframes shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-4px)}40%,80%{transform:translateX(4px)}}
@keyframes progressShrink{from{width:100%}to{width:0%}}
@keyframes checkPop{0%{transform:scale(0)}50%{transform:scale(1.2)}100%{transform:scale(1)}}

/* === Layout Shell (admin-light) === */
.L{display:flex;min-height:100vh;padding:14px;gap:14px}
.M{flex:1;min-width:0}

/* === Sidebar (admin-light) === */
/* Largura 258px e nao os 220px do design system. Medido no navegador em duas
   rodadas, nao estimado:
     220px -> linha util 190px; CINCO rotulos quebram em duas linhas (53px
              contra 44px normais)
     244px -> resolveu os itens FLAT (linha util 214px), mas nao os PAIS de
              acordeao: o pai gasta icone 18 + gap 10 + gap 10 + seta 16, e
              sobram so 132px. Tres continuavam quebrando — "Parceiros
              Operacionais" (precisa 145), "Contratos de Clientes" (136),
              "Acordos de Parceiros" (133)
     258px -> pai com 144px uteis. "Parceiros Operacionais" precisa de 145 e
              quebrou por UM pixel (medido com um probe de nowrap na fonte
              computada, nao estimado)
     264px -> pai com 150px uteis; nenhum rotulo quebra, com 5px de folga.
              A folga e de proposito: resolver na borda faz o proximo rotulo
              de modulo quebrar de novo e ninguem ligar a causa a largura
   O menu de exemplo do DS vinha de outro produto, com rotulos curtos.
   Encurtar os nossos nao e opcao: a nomenclatura e decisao fechada
   (02-menu-lateral.md) — "Parceiros Operacionais" e nao "Agregados/Autonomos"
   como raiz, e "Custo" x "Precificacao" vem das specs e nao se uniformiza. */
.S{width:264px;background:var(--bg-paper);border-radius:24px;padding:16px 14px;display:flex;flex-direction:column;position:sticky;top:14px;height:calc(100vh - 28px);border:1px solid var(--divider);transition:width .3s ease,padding .3s ease}
.S-lg{display:flex;align-items:center;gap:10px;padding:0 10px 12px}
.S-b{font-size:16px;font-weight:800}
.S-b em{color:var(--primary);font-style:normal}
.S-b b{color:var(--secondary)}
/* AFORDANCIA DE ROLAGEM (V-17) — TERCEIRA TENTATIVA. As duas anteriores
   falharam por motivos DIFERENTES, e as duas valem registro.
   1a: `mask-image` desvanecendo as pontas. PIOROU — o corte duro ao menos
       deixava um naco de texto dizendo "tem mais"; o degrade ALISA a borda e o
       menu passa a parecer que ACABA ali.
   2a: caber (padding menor) + barra fina estilizada. Tambem falhou, e a causa
       so aparece medindo: no macOS a barra e OVERLAY — `offsetWidth -
       clientWidth = 0`, ela nao ocupa espaco e fica INVISIVEL em repouso.
       Estilizar uma barra que ninguem ve nao e afordancia nenhuma. E o menu
       cresceu com os modulos novos: 65px escondidos a 1440x900 e **165px a
       1280x800**, com "Configuracoes" inteiro fora da vista.
   4a: `scrollbar-gutter:stable`. Foi INERTE ate eu achar a causa — o
       `layouts/app.blade.php` declarava `scrollbar-width:none` DEPOIS da folha
       —, e quando finalmente pegou, PIOROU: a calha e reservada mesmo SEM
       transbordo. A 1440 com o menu fechado nao ha o que rolar
       (`scrollHeight == clientHeight`) e a coluna de 11px estava la assim
       mesmo, serrilhando a borda; no `.mini` ela comia 20% de um trilho de
       54px e desalinhava TODOS os icones em 5,5px; e estreitava a nav o
       bastante para quebrar um rotulo em duas linhas.
   5a, esta: `scrollbar-width:thin` SEM calha reservada. A barra e classica
       (medido com controle positivo: 15px, nao overlay), entao ela ocupa
       espaco QUANDO EXISTE e nao ocupa quando nao ha transbordo. A afordancia
       aparece exatamente no momento em que ela e necessaria, que era o que as
       quatro anteriores tentaram de todo jeito menos o mais simples.
   `overscroll-behavior:contain` impede que a rolagem do menu vaze para a
   pagina ao chegar ao fim. */
.S-n{flex:1;display:flex;flex-direction:column;gap:2px;overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--border-strong) transparent}
.S-n::-webkit-scrollbar{width:8px}
.S-n::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:4px}
.S-n::-webkit-scrollbar-track{background:var(--bg-default);border-radius:4px}
/* NO TRILHO RECOLHIDO A CALHA CUSTA MAIS DO QUE VALE. Medido: a nav do `.mini`
   tem 54px e a barra come 11 — 20% —, empurrando TODO icone 5,5px para a
   esquerda contra o icone do "Sair", que fica fora do `.S-n` e nao encolhe.
   Duas colunas de icones desalinhadas sao mais visiveis que a rolagem que a
   barra sinaliza, e no `.mini` o rotulo nem existe para ser cortado: o que se
   perde ao rolar sem afordancia e um icone, nao uma palavra.
   `overlay` mantem a rolagem e nao ocupa espaco. */
.S.mini .S-n{scrollbar-width:none}
.S.mini .S-n::-webkit-scrollbar{width:0}
/* --text-secondary e nao --text-disabled: medido em JS, #94A3B8 sobre o
   branco do cartao da 2,56:1 em texto de 12-13px e reprova WCAG AA (4,5:1).
   #475569 da 7,58:1. --text-disabled fica reservado para o que esta mesmo
   desabilitado, nao para texto que o usuario precisa ler. */
.si{display:flex;align-items:center;gap:9px;padding:8px 11px;border-radius:12px;font-size:13px;font-weight:500;color:var(--text-secondary);cursor:pointer;transition:.2s;position:relative}
.si:hover{color:var(--text-primary);background:var(--bg-hover)}
.si.on{background:var(--primary);color:var(--secondary);font-weight:600;box-shadow:0 4px 14px rgba(74,222,128,0.25)}
.si.on svg{stroke:var(--secondary)}
.si .tip{display:none;position:absolute;left:calc(100% + 8px);top:50%;transform:translateY(-50%);background:var(--text-primary);color:var(--bg-default);padding:5px 10px;border-radius:6px;font-size:11px;font-weight:600;white-space:nowrap;z-index:100;pointer-events:none}
.si .tip::before{content:'';position:absolute;left:-4px;top:50%;transform:translateY(-50%);border:4px solid transparent;border-right-color:var(--text-primary)}
.sp{height:1px;background:var(--divider);margin:10px 10px}
.S-ct{margin-top:auto;background:linear-gradient(160deg,var(--info-light),#f0f2f8);border-radius:20px;padding:14px;text-align:center;border:1px solid var(--divider)}
.S-ct p,.S-ct-title{font-size:12px;font-weight:700;color:var(--text-primary)}
.S-ct small,.S-ct-text{font-size:10px;color:var(--text-secondary)}
.S-ct button,.S-ct-btn{margin-top:8px;padding:7px 16px;border-radius:8px;background:var(--secondary);color:var(--bg-paper);font-size:10px;font-weight:700;border:none;cursor:pointer;font-family:inherit}
.S-toggle{width:32px;height:32px;border-radius:10px;background:transparent;border:1.5px solid var(--divider);display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-muted);transition:.2s;flex-shrink:0;margin-left:auto}
.S-toggle:hover{background:var(--bg-hover);color:var(--text-primary)}
.S.mini{width:72px;padding:24px 8px}
.S.mini .S-lg span{display:none}
.S.mini .si span{display:none}
.S.mini .si{justify-content:center;padding:10px}
.S.mini .sp{margin:10px 4px}
.S.mini .S-ct{display:none}
.S.mini .S-lg{justify-content:center;padding:0 0 20px}
.S.mini .S-toggle{margin:0 auto}
.S.mini .S-toggle svg{transform:rotate(180deg)}
.S.mini .si:hover .tip{display:block}

/* === Sidebar Groups (extensão — não canônico no DS) === */
/* .sg / .sg-items / .si-sub são extensão herdada do wms-prototype (precedente
   testado, ver ai/decisions/bootstrap/02-menu-lateral.md). O admin-light canônico
   só tem .si flat + .sp. Forma herdada do WMS, cores tokenizadas aqui. */
.sg{display:flex;flex-direction:column;gap:2px}
.sg>.si{cursor:pointer}
.sg-caret{margin-left:auto;flex-shrink:0;transition:transform .2s}
.sg.open>.si .sg-caret{transform:rotate(180deg)}
.sg-items{padding-left:28px;display:flex;flex-direction:column;gap:2px}
.sg:not(.open) .sg-items{display:none}
.si-sub{padding:6px 14px;font-size:12px}
.S.mini .sg-items{display:none}
.S.mini .sg-caret{display:none}

/* === Topbar (admin-light) === */
.T{display:flex;align-items:center;padding:6px 4px 18px;gap:12px}
.T-d{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:500;color:var(--text-secondary)}
.T-r{margin-left:auto;display:flex;align-items:center;gap:8px}
.T-s{display:flex;align-items:center;gap:7px;padding:9px 16px;border-radius:12px;background:var(--bg-paper);border:1.5px solid var(--divider);width:280px;transition:.2s}
.T-s:focus-within{border-color:var(--secondary)}
.T-s input{border:none;background:none;outline:none;font-family:inherit;font-size:12px;color:var(--text-primary);width:100%}
.T-s input::placeholder{color:var(--text-muted)}
.T-i{width:40px;height:40px;border-radius:12px;background:var(--bg-paper);display:flex;align-items:center;justify-content:center;color:var(--text-muted);cursor:pointer;position:relative;border:1px solid var(--divider)}
.T-i:hover{background:var(--bg-hover);color:var(--text-primary)}
.T-i .dot{position:absolute;top:7px;right:7px;width:8px;height:8px;border-radius:50%;background:var(--primary);border:2px solid var(--bg-paper)}

/* === Buttons (admin-light — chassi) === */
/* .btn vence o admin-light (padding:9px 18px). .btn-g é a variante GHOST do
   admin-light; o .btn-g verde sólido do ui-components morreu — a variante já tem
   nome canônico próprio (.btn-ghost), agrupado abaixo. */
/* min-height fixa: sem ela, .btn-w (borda de 1,5px) e .btn-r (sem borda)
   medem 29px e 26px lado a lado — a borda entra na altura. Duas alturas na
   mesma celula lê como desalinho de render, e a diferença é invisivel no
   codigo, so aparece medindo. `box-sizing` ja e border-box no reset. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:36px;padding:9px 18px;border-radius:10px;font-family:inherit;font-size:12px;font-weight:600;cursor:pointer;transition:.2s;border:none}
.btn-a{background:var(--secondary);color:var(--bg-paper);box-shadow:0 3px 12px rgba(0,13,61,0.2)}
.btn-o{background:var(--primary);color:var(--secondary);box-shadow:0 3px 12px rgba(74,222,128,0.2)}
.btn-r{background:var(--error-dark);color:var(--bg-paper);box-shadow:0 3px 12px rgba(239,68,68,0.2)}
/* ⚠️ `--secondary` e nao `--purple`. Branco sobre #8B5CF6 da 4,23:1 a 12px/600
   — reprova o minimo de 4,5:1, e este arquivo JA REGISTRA que o roxo falhou
   antes noutro componente. O botao "Simular" e acao principal de duas telas de
   `network-routes`; usar a cor de acao do sistema resolve sem inventar token. */
.btn-pr{background:var(--secondary);color:var(--bg-paper);box-shadow:0 3px 12px rgba(0,13,61,.2)}
.btn-a:hover,.btn-o:hover,.btn-r:hover,.btn-pr:hover{transform:translateY(-1px)}
.btn-w{background:var(--bg-paper);color:var(--text-secondary);border:1.5px solid var(--divider)}
.btn-w:hover{background:var(--bg-hover)}
/* ⚠️ ARMADILHA DE NOME — LEIA ANTES DE USAR .btn-g
   A skill frontend-design (A4) diz que .btn-g e o botao VERDE. NESTE REPO NAO E.
   O ui-components tinha um .btn-g verde solido e o admin-light um .btn-g ghost;
   deu colisao SEMANTICA (mesmo nome, componente diferente) e o passo 5 da
   extracao resolveu a favor do chassi: o verde morreu, porque a variante ghost
   ja tinha nome canonico proprio (.btn-ghost).
   Resultado pratico: quem escrever class="btn btn-g" achando que faz um botao
   verde de acao afirmativa produz um botao CINZA que parece DESABILITADO —
   aconteceu com o "Ativar" da tela de detalhe de suppliers, que ficava mais
   apagado que o "Editar" secundario ao lado.
   Para acao afirmativa use .btn-a (navy) ou .btn-o (verde com texto navy). */
/* `--text-secondary` (7,58:1) e nao `--text-muted` (4,21:1). O fantasma e LINK
   VIVO — tem `href` e `cursor:pointer` — e a 4,21 ele passa a ler como
   desabilitado. E o defeito do `.btn:disabled` ao contrario, pela terceira vez
   nesta base: sinal visual mentindo sobre disponibilidade. Comparavel: o
   `.btn-w`, que faz o mesmo papel, da 4,76. */
.btn-g,.btn-ghost{background:transparent;color:var(--text-secondary);border:1.5px solid var(--divider)}
.btn-g:hover,.btn-ghost:hover{background:var(--bg-hover);color:var(--text-primary)}
/* btn-sm — ⚠️ ESTE COMENTARIO CONTRADIZIA A SKILL, e a skill vence.
   Dizia "modais, drawers, TABELAS, tab-panels". A armadilha A4 de
   `ai/skills/frontend-design.md` restringe a tres contextos:
   `.draft-band-actions`, `.fp-footer` e o filter-toggle dentro de aba.
   Em celula de tabela, use `.btn` normal ou `.btn-icon` + dropdown — foi o
   que a auditoria cobrou em operation-process-profiles.
   Em footer de modal/drawer/confirm a propria A4 manda usar `.btn` FULL. */
.btn-sm{min-height:30px;padding:6px 12px;font-size:11px}

/* ⚠️ ESTA REGRA NAO EXISTIA, e a ausencia produziu o pior defeito da auditoria.
   Havia :disabled para .fg input, .af input e .pg-b — e nenhum para .btn.
   Resultado: "Publicar versao" com o atributo `disabled` renderizava NAVY
   SOLIDO, opacity 1, cursor pointer e a mesma sombra do habilitado. O
   construtor tinha feito tudo certo no markup — `disabled`, `aria-describedby`,
   motivo escrito ao lado — e a tela mentia mesmo assim. O usuario clicava e
   nada acontecia, sem retorno nenhum.
   E a demonstracao exata do porque a auditoria de tela nao pode ser feita por
   quem construiu: quem constroi confere o que ESCREVEU, nao o que RENDERIZA. */
.btn:disabled,.btn[disabled],.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none}
.btn:disabled:hover,.btn[disabled]:hover,.btn[aria-disabled="true"]:hover{opacity:.45;box-shadow:none;transform:none}

/* === Stat Cards (admin-light) === */
.sc{background:var(--bg-paper);border-radius:16px;padding:20px 24px;border:1px solid var(--divider);animation:fi .4s ease-out both}
.sc-l{font-size:13px;font-weight:600;color:var(--text-secondary);margin-bottom:10px}
.sc-r{display:flex;align-items:baseline;gap:10px}
.sc-n{font-size:34px;font-weight:900;letter-spacing:-1.5px;line-height:1}
.sc-d{width:1.5px;height:22px;background:var(--divider);border-radius:1px;flex-shrink:0}
.sc-m{font-size:12px;color:var(--text-secondary)}
.arr-u{color:var(--success)}
.arr-d{color:var(--error)}

/* === Table Wrapper (admin-light) === */
.tw{background:var(--bg-paper);border-radius:18px;overflow:hidden;border:1px solid var(--divider);animation:fi .4s ease-out .1s both}
.tw-h{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;border-bottom:1px solid var(--divider)}
.tw-s{display:flex;align-items:center;gap:7px;padding:8px 12px;border-radius:8px;background:var(--bg-default);border:1.5px solid var(--divider);width:260px}
.tw-s:focus-within{border-color:var(--secondary)}
.tw-s input{border:none;background:none;outline:none;font-family:inherit;font-size:12px;color:var(--text-primary);width:100%}
.tw-s input::placeholder{color:var(--text-muted)}
.tw-f{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;border-top:1px solid var(--divider)}

/* === Table Base (admin-light) === */
table{width:100%;border-collapse:collapse}
thead th{padding:10px 20px;text-align:left;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;color:var(--text-secondary);background:var(--bg-default);border-bottom:1px solid var(--divider)}
thead th:first-child{padding-left:20px;width:40px}
tbody tr{border-bottom:1px solid var(--divider);transition:.1s}
tbody tr:last-child{border-bottom:none}
tbody tr:hover{background:rgba(0,13,61,0.01)}
td{padding:10px 20px;font-size:12px;vertical-align:middle}
td:first-child{padding-left:20px;width:40px}

/* === Entity & Contact Cells (admin-light) === */
.uc{display:flex;align-items:center;gap:10px}
.ua{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:11px;flex-shrink:0}
.un{font-size:13px;font-weight:600;color:var(--text-primary)}
.uh{font-size:11px;color:var(--text-secondary)}
.cc{display:flex;flex-direction:column;gap:2px}
.ce{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--text-secondary)}
.ca{font-size:10px;color:var(--secondary);font-weight:500;cursor:pointer;display:flex;align-items:center;gap:3px}
.cn{font-size:11px;color:var(--text-secondary);font-style:italic}

/* === Status Badge .ba (admin-light — canônico) === */
/* Usar em células de status, política e métricas com semântica em tabelas. */
/* `nowrap`: sem ele o chip quebra em duas linhas e a altura da linha da
   tabela pula de 21 para 33px — acontecia ate no modulo que serve de
   referencia, com "Motorista autonomo". */
.ba{display:inline-flex;align-items:center;gap:4px;padding:4px 12px;border-radius:100px;font-size:10px;font-weight:600;white-space:nowrap}
.ba-g{background:var(--success-light);color:#166534}
.ba-r{background:var(--error-light);color:#991B1B}
.ba-b{background:var(--info-light);color:var(--secondary)}
.ba-y{background:var(--warning-light);color:#92400E}
/* Neutra. Faltava: as quatro variantes eram verde, vermelha, azul e amarela,
   todas com carga semantica, e nao havia como dizer "zero" sem parecer
   sucesso ou alerta. Um chip VERDE com "0 ativas" le como "esta tudo certo"
   justamente quando nada esta valendo. */
.ba-n{background:var(--bg-hover);color:var(--text-secondary)}
.ba-n .sd{background:var(--text-secondary)}
.sd{width:5px;height:5px;border-radius:50%}
.ba-g .sd{background:var(--success)}
.ba-r .sd{background:var(--error)}
.ba-b .sd{background:var(--secondary)}
.ba-y .sd{background:var(--warning)}

/* === Row Actions & Checkbox (admin-light) === */
.ab{width:30px;height:30px;border-radius:8px;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-muted)}
.ab:hover{background:var(--bg-hover);color:var(--text-primary)}
.ck{width:16px;height:16px;border-radius:5px;border:1.5px solid var(--divider);cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.ck:hover{border-color:var(--secondary)}
.ck.on{background:var(--secondary);border-color:var(--secondary)}

/* === Pagination (admin-light) === */
/* .pb aqui é o BOTÃO de paginação 30×30 do chassi. O .pb "progress bar" do
   ui-components perdeu a colisão semântica; seu container vive como .pb-wrap. */
.pg{display:flex;align-items:center;gap:3px}
.pb{width:30px;height:30px;border-radius:8px;border:none;background:transparent;font-family:inherit;font-size:12px;font-weight:600;color:var(--text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center}
.pb:hover{background:var(--bg-hover)}
.pb.on{background:var(--secondary);color:var(--bg-paper)}

/* === Page Switch (admin-light) === */
.page{display:none}
.page.show{display:block}

/* === Filter Panel (admin-light) === */
.fp{background:var(--bg-paper);border-radius:16px;padding:18px 22px;margin-bottom:14px;border:1px solid var(--divider);display:none;animation:sd .2s ease-out}
.fp.open{display:block}
.fp-g{display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
.fp-l{font-size:10px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.3px;margin-bottom:4px}
.fi{width:100%;padding:9px 12px;border-radius:8px;border:1.5px solid var(--divider);font-family:inherit;font-size:12px;color:var(--text-primary);background:var(--bg-default);outline:none;transition:.2s}
.fi:focus{border-color:var(--secondary)}
.fi::placeholder{color:var(--text-muted)}
select.fi{appearance:none;cursor:pointer}

/* === Form Card (admin-light) === */
.fc{background:var(--bg-paper);border-radius:20px;padding:28px 32px;border:1px solid var(--divider);margin-bottom:16px;animation:fi .4s ease-out both}
.fc-t{display:flex;align-items:center;gap:10px;font-size:15px;font-weight:700;color:var(--text-primary);margin-bottom:20px;padding-bottom:14px;border-bottom:1px solid var(--divider)}
.fc-t .ic{width:32px;height:32px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.fg3{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.fg{display:flex;flex-direction:column;gap:4px}
.fg label,.fg-label{font-size:11px;font-weight:600;color:var(--text-secondary)}
.fg input,.fg select,.fg textarea{padding:10px 14px;border-radius:10px;border:1.5px solid var(--divider);font-family:inherit;font-size:13px;color:var(--text-primary);background:var(--bg-default);outline:none;transition:.2s}
.fg input:focus,.fg select:focus,.fg textarea:focus{border-color:var(--secondary);box-shadow:0 0 0 3px rgba(0,13,61,0.06)}
.fg input::placeholder,.fg textarea::placeholder{color:var(--text-muted)}
.fg select{appearance:none;cursor:pointer}
.fg textarea{resize:vertical;min-height:80px}
.fg input:disabled,.fg select:disabled,.fg textarea:disabled{background:#F1F3F6;color:#9CA3AF;border-color:#D5D8DE;cursor:not-allowed;opacity:.8}
.fg .dis-hint{font-size:9px;color:var(--text-secondary);font-style:italic;margin-top:2px}

/* === Chips (admin-light) === */
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:6px}
/* ⚠️ `cursor` E `:hover` PERTENCEM AO ELEMENTO CLICÁVEL, não à classe base —
   mesma correção que o `.sc-card` recebeu, pelo mesmo motivo e no mesmo dia.
   `.chip` é o chip ALTERNÁVEL (tem `.on`, borda que reage), e cravar
   `cursor:pointer` na base fazia toda lista de token ESTÁTICO prometer um
   clique que não existe: códigos de cobertura, linhas de diff, mapeamentos
   de área e a legenda do grafo da malha.
   Não era hipótese — DOIS módulos já carregavam o mesmo remendo local, e
   dois remendos para a mesma regra é a regra pedindo correção, não os
   módulos pedindo remendo. Os dois saíram junto com esta mudança. */
.chip{display:inline-flex;align-items:center;gap:5px;padding:6px 14px;border-radius:8px;font-size:11px;font-weight:600;background:var(--bg-default);color:var(--text-secondary);border:1.5px solid var(--divider);transition:.2s}
a.chip,button.chip,label.chip,.chip.on{cursor:pointer}
.chip:hover{border-color:var(--secondary)}
.chip.on{background:var(--secondary);color:var(--bg-paper);border-color:var(--secondary)}
.chip-o.on{background:var(--primary);color:var(--secondary);border-color:var(--primary)}

/* === Form Tabs (admin-light) === */
.ftabs{display:flex;gap:0;margin-bottom:20px;border-bottom:1px solid var(--divider)}
.ftab{padding:12px 22px;font-size:13px;font-weight:600;color:var(--text-secondary);cursor:pointer;border-bottom:2.5px solid transparent;transition:.2s}
.ftab:hover{color:var(--text-primary)}
.ftab.on{color:var(--secondary);border-color:var(--secondary)}
.ftab-content{display:none}
.ftab-content.show{display:block}

/* === Mobile Sidebar Overlay (admin-light) === */
.S-overlay{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.4);z-index:90;backdrop-filter:blur(2px)}
.S-overlay.show{display:block}
.mob-toggle{display:none;width:40px;height:40px;border-radius:12px;background:var(--bg-paper);border:1.5px solid var(--divider);align-items:center;justify-content:center;cursor:pointer;color:var(--text-muted);flex-shrink:0}
.mob-toggle:hover{background:var(--bg-hover);color:var(--text-primary)}

/* ==========================================================================
   ui-components — catálogo de componentes
   ========================================================================== */

/* === Overlay (components) === */
.overlay{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:1000;animation:fadeIn .2s ease-out;backdrop-filter:blur(4px);align-items:center;justify-content:center}
.overlay.show{display:flex}
.overlay.show-end{display:flex;justify-content:flex-end;align-items:stretch}
.overlay.show-start{display:flex;justify-content:flex-start;align-items:stretch}

/* === Modal (components) === */
.modal{background:var(--bg-paper);border-radius:20px;width:100%;max-width:520px;max-height:90vh;overflow-y:auto;animation:scaleIn .25s ease-out;box-shadow:0 20px 60px rgba(0,0,0,0.15)}
.modal-sm{max-width:400px}
.modal-lg{max-width:680px}
.modal-xl{max-width:960px;width:90vw}
.modal-hd{display:flex;align-items:center;justify-content:space-between;padding:22px 26px 0}
.modal-hd h2,.modal-title{font-size:17px;font-weight:800;display:flex;align-items:center;gap:8px}
.modal-close{width:32px;height:32px;border-radius:8px;border:none;background:var(--bg-hover);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-muted);transition:.15s}
.modal-close:hover{background:var(--divider);color:var(--text-primary)}
.modal-body{padding:18px 26px 22px}
.modal-ft{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 26px 22px}
.modal-ft-split{justify-content:space-between}

/* === Drawer (components) === */
.drawer{background:var(--bg-paper);width:420px;max-width:90vw;height:100%;animation:slideRight .3s ease-out;box-shadow:-8px 0 30px rgba(0,0,0,0.1);display:flex;flex-direction:column}
.drawer-left{animation:slideLeft .3s ease-out;box-shadow:8px 0 30px rgba(0,0,0,0.1)}
.drawer-hd{display:flex;align-items:center;justify-content:space-between;padding:22px 24px;border-bottom:1px solid var(--divider);flex-shrink:0}
.drawer-hd h2,.drawer-title{font-size:16px;font-weight:800;display:flex;align-items:center;gap:8px}
/* .drawer-hd-info — EXTENSÃO NOSSA, não canônica no DS. NÃO REMOVER.
   Originada da A19 (frontend-design.md:301), que manda pôr o code como badge
   ABAIXO do h2. O .drawer-hd é flex com space-between: sem este wrapper, o
   .drawer-subtitle vira o terceiro filho flex e para ao lado do botão de fechar
   em vez de sob o título. Agrupa h2 + subtítulo numa coluna, e o space-between
   passa a empurrar só o .modal-close.
   min-width:0 é obrigatório: sem ele um título longo estoura o flex em vez de
   truncar pelo text-overflow. As duas alternativas sem esta classe são as duas
   que o repo proíbe — <div> sem classe (passa no G2 por omissão) e inline style. */
.drawer-hd-info{display:flex;flex-direction:column;gap:4px;min-width:0}
/* Code como badge neutro abaixo do h2 (A19, frontend-design.md:301). A skill
   mostrava a forma em inline style, que a §5 proíbe — vira classe aqui. */
.drawer-subtitle{display:inline-block;margin-top:4px;padding:2px 10px;border-radius:6px;font-size:12px;font-weight:600;color:var(--text-secondary);background:var(--bg-hover);font-family:'Courier New',monospace}
.drawer-body{flex:1;overflow-y:auto;padding:20px 24px}
.drawer-ft{border-top:1px solid var(--divider);padding:16px 24px;display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-shrink:0}

/* === Confirm (components) === */
.confirm{text-align:center;padding-top:28px}
.confirm-icon{width:64px;height:64px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto 16px}
.confirm h2,.confirm-title{font-size:18px;font-weight:800;margin-bottom:6px}
.confirm p,.confirm-text{font-size:13px;color:var(--text-secondary);line-height:1.5;margin-bottom:22px;max-width:340px;margin-left:auto;margin-right:auto}
.confirm-actions{display:flex;gap:10px;justify-content:center;padding-bottom:26px}

/* === Toast (components) === */
/* Container canônico da §5 do ui-prototype.md é .toast-area; .toast-container
   é o nome do HTML fonte. Agrupados (alias do passo 9). */
.toast-area,.toast-container{position:fixed;top:20px;right:20px;z-index:2000;display:flex;flex-direction:column;gap:10px;pointer-events:none}
.toast{display:flex;align-items:flex-start;gap:12px;padding:14px 18px;border-radius:14px;background:var(--bg-paper);box-shadow:0 8px 30px rgba(0,0,0,0.12);min-width:340px;max-width:440px;animation:toastIn .3s ease-out;pointer-events:auto;position:relative;overflow:hidden}
.toast.closing{animation:toastOut .3s ease-in forwards}
.toast-icon{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.toast-content{flex:1;min-width:0}
.toast-title{font-size:13px;font-weight:700;margin-bottom:2px}
.toast-msg{font-size:11px;color:var(--text-secondary);line-height:1.4}
.toast-close{width:24px;height:24px;border-radius:6px;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-muted);flex-shrink:0}
.toast-close:hover{background:var(--bg-hover)}
.toast-progress{position:absolute;bottom:0;left:0;height:3px;border-radius:0 0 14px 14px;animation:progressShrink 4s linear forwards}
.toast-success .toast-progress{background:var(--success)}
.toast-error .toast-progress{background:var(--error)}
.toast-warning .toast-progress{background:var(--warning)}
.toast-info .toast-progress{background:var(--secondary)}

/* === App Form Field .af (components) === */
/* 1ª definição (bloco 1) vence; 2ªs aditivas fundidas: :hover, .af-error,
   .af-error-text e border-color no :disabled. */
.af{display:flex;flex-direction:column;gap:6px}
.af label,.af-label{font-size:13px;font-weight:700;color:var(--text-primary);line-height:1.2}
.af input,.af select,.af textarea{height:40px;padding:0 14px;border-radius:12px;border:1px solid var(--divider);background:var(--bg-default);font-family:inherit;font-size:13px;color:var(--text-primary);outline:none;transition:.2s}
.af textarea{height:auto;padding:10px 14px;resize:vertical;min-height:70px}
.af input:hover,.af select:hover{border-color:rgba(17,24,39,.2)}
.af input:focus,.af select:focus,.af textarea:focus{border-color:var(--secondary);box-shadow:0 0 0 3px rgba(0,13,61,.06);background:var(--bg-paper)}
.af input::placeholder,.af textarea::placeholder{color:var(--text-muted);font-size:13px;opacity:.7}
.af input:disabled,.af select:disabled{background:#F1F5F9;color:var(--text-disabled);cursor:not-allowed;border-color:var(--divider)}
.af input.af-error{border-color:var(--error) !important;box-shadow:0 0 0 3px rgba(239,68,68,.06) !important}
.af .af-error-text{font-size:12px;color:var(--error);font-weight:500}
.af .af-hint{font-size:12px;font-style:italic;color:var(--text-secondary);line-height:1.2}
.af select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;padding-right:32px;cursor:pointer}

/* === Form Grid (components) === */
.fg-grid{display:grid;gap:16px}
.fg-grid.c2{grid-template-columns:1fr 1fr}
.fg-grid.c3{grid-template-columns:1fr 1fr 1fr}
.fg-grid.c4{grid-template-columns:1fr 1fr 1fr 1fr}

/* === Divider (components) === */
.divider{height:1px;background:var(--divider);margin:14px 0}

/* === Inline Alert (components) === */
.inline-alert{border-radius:14px;padding:14px 18px;display:flex;align-items:flex-start;gap:10px;margin-bottom:12px}
.inline-alert p,.inline-alert-text{font-size:12px;line-height:1.5}
.inline-alert strong,.inline-alert-title{display:block;font-size:13px;margin-bottom:2px}
/* O `.inline-alert` nasceu SEM VARIANTE DE TOM: a base tem forma e nenhuma cor,
   entao um alerta de erro e um de informacao saiam identicos — e o unico jeito
   de diferenciar era cor inline na view, que e o que o G3 existe para impedir.
   As tres reusam a mesma paleta do `.banner`, para que alerta embutido e faixa
   de topo nao digam a mesma coisa com cores diferentes. */
.inline-alert-error{background:var(--error-light);color:var(--error-dark)}
.inline-alert-warning{background:var(--warning-light);color:#92400E}
.inline-alert-info{background:var(--info-light);color:var(--secondary)}

/* === Filter Header (components) === */
/* .fh-btn-new: 1ª definição vence (padding:8px 20px, sem box-shadow). */
.fh{display:flex;align-items:center;gap:16px;margin-bottom:8px;width:100%}
.fh-left{display:flex;align-items:center;gap:16px;flex:1;min-width:0}
.fh-back{width:40px;height:40px;border-radius:16px;border:1px solid var(--divider);background:var(--bg-paper);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-muted);transition:.15s;flex-shrink:0;padding:0}
.fh-back:hover{background:var(--bg-default);color:var(--text-primary)}
.fh-back svg{width:20px;height:20px}
/* ⚠️ O `text-overflow` daqui É LETRA MORTA sozinho — `display:flex` faz o
   texto virar item anônimo, e item anônimo não reticencia: corta seco. O
   `.fmh-title` tem a regra irmã desde sempre (`> span:first-child`, logo
   abaixo); o `.fh-title` ficou sem, e por isso "Intelipost Tracking PROD"
   virava "Intelipost Trackl" — 36% cortado, SEM nenhum sinal visível de
   corte. `min-width:0` é o que faz o item do flex aceitar encolher; sem
   ele o `overflow` nunca dispara. O `.fh-icon` fica de fora para não
   encolher o ícone junto. */
.fh-title{font-size:22px;font-weight:900;letter-spacing:-.5px;color:var(--text-primary);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:16px;min-width:0}
.fh-title > span:not(.fh-icon){min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fh-title > .s-chip,.fh-title > .ba{flex:0 0 auto}
/* Subtitulo de contexto em SUB-TELA (§3.8): a tela da versao dizia so
   "Versao v1", sem nome do produto — o usuario chegava por link e nao sabia de
   que produto era a versao. Existia `.fmh-subtitle` para o header de
   formulario e nada para o header de tela. */
.fh-subtitle{font-size:13px;font-weight:500;color:var(--text-secondary);margin-top:2px}
.fh-info{display:flex;flex-direction:column;min-width:0}
.fh-icon{display:flex;align-items:center;justify-content:center;color:var(--text-secondary);flex-shrink:0}
.fh-right{display:flex;align-items:center;gap:12px;margin-left:auto;flex-shrink:0}
/* Filtros: mesmo tamanho visual que .btn.btn-w — diferencia-se por .active-filter */
.fh-btn-filter{display:inline-flex;align-items:center;gap:6px;padding:9px 18px;border-radius:10px;border:1.5px solid var(--divider);background:var(--bg-paper);color:var(--text-secondary);font-family:inherit;font-size:12px;font-weight:600;cursor:pointer;transition:.15s;white-space:nowrap}
.fh-btn-filter:hover{background:var(--bg-hover);border-color:var(--divider)}
/* Estado ativo (§5 ui-prototype.md:388) — a fonte só comentava, nunca definiu a
   regra: sem ela, filtro ativo renderizava idêntico a inativo. */
.fh-btn-filter.active-filter{border-color:var(--secondary);background:var(--info-light);color:var(--secondary)}
.fh-btn-filter.active-filter:hover{background:var(--info-light);border-color:var(--secondary)}
.fh-btn-filter svg{width:18px;height:18px}
.fh-btn-new{display:inline-flex;align-items:center;gap:6px;padding:8px 20px;border-radius:8px;border:none;background:var(--secondary);color:var(--bg-paper);font-family:inherit;font-size:14px;font-weight:600;cursor:pointer;transition:.15s}
.fh-btn-new:hover{background:var(--secondary-dark)}
.fh-btn-new svg{width:18px;height:18px}

/* === Form Header (components) === */
/* Todas as .fmh-* mantêm a 1ª definição (bloco 1); a 2ª divergia em padding,
   gap, cor do cancelar e nowrap no título. */
.fmh{display:flex;align-items:center;gap:16px;margin-bottom:8px;width:100%}
.fmh-left{display:flex;align-items:center;gap:16px;flex:1;min-width:0}
.fmh-info{min-width:0;flex:1}
/* flex-wrap:NOWRAP, e nao wrap como vinha do design system. Com wrap, um nome
   longo empurra o chip de situacao para uma SEGUNDA LINHA, desalinhando a seta
   de voltar e desfazendo o "nome + chip inline" que a referencia de arquetipo
   fixa. Dois modulos ja tinham escrito a mesma regra local para consertar isso
   — duplicata em dois e o sinal de que o lugar da regra e aqui.
   O <span> do nome carrega o ellipsis; e ele que encolhe, nao o chip. */
.fmh-title{font-size:22px;font-weight:900;letter-spacing:-.5px;color:var(--text-primary);line-height:1.2;display:flex;align-items:center;gap:12px;flex-wrap:nowrap;min-width:0}
.fmh-title > span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fmh-title > .s-chip,.fmh-title > .ba{flex:0 0 auto}
.fmh-subtitle{font-size:13px;color:var(--text-secondary);margin-top:2px}
.fmh-right{display:flex;align-items:center;gap:10px;margin-left:auto;flex-shrink:0}
.fmh-btn-cancel{display:inline-flex;align-items:center;gap:6px;padding:8px 20px;border-radius:8px;border:1px solid var(--divider);background:var(--bg-hover);color:var(--text-secondary);font-family:inherit;font-size:14px;font-weight:500;cursor:pointer;transition:.15s}
.fmh-btn-cancel:hover{color:var(--text-primary)}
.fmh-btn-save{display:inline-flex;align-items:center;gap:6px;padding:8px 20px;border-radius:8px;border:none;background:var(--secondary);color:var(--bg-paper);font-family:inherit;font-size:14px;font-weight:600;cursor:pointer;transition:.15s}
.fmh-btn-save:hover{background:var(--secondary-dark)}
.fmh-btn-save svg,.fmh-btn-cancel svg{width:18px;height:18px}

/* === Connection Identity Bar (components) === */
/* Barra de propriedades de identidade — topo de telas de detalhe. */
.cib{display:flex;align-items:center;background:var(--bg-paper);border-radius:14px;box-shadow:0 1px 3px rgba(0,0,0,.06),0 0 0 1px var(--divider);padding:6px;gap:2px;margin-bottom:16px;border-left:3px solid var(--secondary)}
.cib-item{flex:1;display:flex;align-items:center;gap:10px;padding:8px 12px;border-radius:9px;min-width:0}
.cib-icon{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.cib-icon svg{width:15px;height:15px}
.cib-text{display:flex;flex-direction:column;gap:1px;min-width:0;overflow:hidden}
/* `line-height:1.4` e nao 1: com 9px de corpo e `uppercase`, o ascent que a
   fonte pede para o til e o agudo e 9,135px — MAIOR que a caixa. O resultado
   media era "ULTIMA PUBLICACAO" com os acentos decepados. Medido com sonda
   antes/depois no mesmo navegador. */
.cib-label{font-size:9px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;color:var(--text-secondary);line-height:1.4}
/* ⚠️ `text-overflow` NUM CONTAINER `flex` É LETRA MORTA PARA O TEXTO SOLTO
   dentro dele — a mesma família do `opacity` que não se desfaz: a regra
   afirma um resultado que não acontece, e por isso ninguém reabriu o
   assunto. O texto vira um item anônimo do flex, e item anônimo não
   reticencia: corta seco. Medido em `/guias-roteamento/{id}`: `sw 901 /
   cw 155` — 83% escondido, SEM nenhum sinal visível de corte, em TODO
   módulo que usa a barra de identidade.
   As declarações ficam no container (servem quando o filho é um único nó
   de texto herdando bloco), e a regra abaixo é a que faz o trabalho de
   verdade. `min-width:0` é obrigatório: sem ele o item do flex se recusa
   a encolher abaixo do conteúdo e o `overflow` nunca dispara. */
.cib-value{font-size:12px;font-weight:700;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:4px}
.cib-value>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cib-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.cib-dot-green{background:var(--success)}
.cib-dot-orange{background:var(--warning)}
.cib-dot-red{background:var(--error)}
.cib-dot-gray{background:var(--text-disabled)}

/* === Draft Band (components) === */
/* Card contextual entre .cib e .at — visível apenas quando existe rascunho ativo.
   Sem margin próprio: espaçamento via gap do container pai. */
.draft-band{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;background:var(--bg-paper);border-radius:12px;border:1px solid var(--divider);flex-wrap:wrap;gap:8px}
.draft-band-info{display:flex;align-items:center;gap:10px;font-size:13px;color:var(--text-secondary)}
.draft-band-actions{display:flex;gap:8px;align-items:center}

/* === Read-only Field .af-ro (components) === */
.af-ro{display:flex;flex-direction:column;gap:6px}
.af-ro label,.af-ro-label{font-size:13px;font-weight:700;color:var(--text-primary);line-height:1.2}
.af-ro-val{min-height:40px;padding:0 14px;border-radius:12px;border:1.5px solid var(--divider);background:var(--bg-default);font-size:13px;color:var(--text-primary);display:flex;align-items:center;gap:6px;cursor:default;transition:border-color .2s}
/* `.mono` era acoplada só ao campo somente-leitura, e a coluna de documento da
   lista precisava do mesmo tratamento numa célula de tabela — o que produziu
   reset local numa view (proibido pela §5). Agora é utilitária: o que ela faz
   é sempre a mesma coisa, muda só onde. `.c-cell.mono` não quebra a linha
   porque documento cortado no meio deixa de ser conferível. */
.mono{font-family:'Courier New',monospace}
.af-ro-val.mono{font-size:12px;word-break:break-all}
.c-cell.mono{font-size:12px;white-space:nowrap}

/* Só para leitor de tela. Nomeia o que só o olho entende — um botão de ícone,
   um cabeçalho de coluna de ação. `clip-path` além do `clip` legado, e SEM
   depender de cor: `color:transparent` some no modo de alto contraste forçado
   do sistema operacional, que é justamente quem mais precisa desta classe. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0}
.af-ro.ok .af-ro-val{border-color:var(--success);background:#F0FDF4}
.af-ro.warn .af-ro-val{border-color:var(--warning);background:#FFFBEB}
.af-ro.error .af-ro-val{border-color:var(--error);background:var(--error-light)}
.af-ro-missing{font-size:12px;font-style:italic;font-weight:500;color:var(--error)}

/* === Destructive Icon Button (components) === */
/* Vermelho em repouso — não usa hover como gatilho de perigo. */
/* `--error-dark` e nao `--error`: #EF4444 sobre #FEE2E2 da 3,08:1 e passava o
   1.4.11 por 0,08 — margem que some no primeiro ajuste de token. O token escuro
   ja existia e leva a ~6:1. O hover continua distinguivel pelo FUNDO. */
.btn-icon{width:30px;height:30px;border-radius:8px;border:none;background:var(--error-light);cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--error-dark);transition:background .15s,color .15s;padding:0;flex-shrink:0}
/* HOVER POR INVERSAO, e nao por escurecer o rosa. Ao subir a cor base para
   `--error-dark` eu apaguei uma das duas pistas de hover: antes mudavam FUNDO
   (#FEE2E2 -> #FECACA) E icone (#EF4444 -> #B91C1C); sobrou so o fundo, e os
   dois rosas estao a 1,18:1. Medido na tela: o que o olho pegava no hover
   passou a ser o cinza da LINHA (`tr:hover`), que e igual para qualquer celula
   e nao diz "este botao esta sob o ponteiro".
   Invertendo figura e fundo o estado vai de 5,30:1 para 6,47:1 — o mesmo par
   do `.btn-r`, que ja e o vocabulario destrutivo desta tela. */
.btn-icon:hover{background:var(--error-dark);color:var(--bg-paper)}
.btn-icon svg{width:15px;height:15px}

/* === Serpentine Timeline (components) === */
/* Itens em linhas que alternam direção (esquerda→direita, direita→esquerda). */
.tl-snake{display:flex;flex-direction:column;gap:0}
.tl-row{display:flex;align-items:flex-start;position:relative}
.tl-sitem{flex:1;display:flex;flex-direction:column;align-items:center;position:relative;padding:0 4px}
.tl-sitem:not(:last-child)::after{content:'';position:absolute;top:8px;left:50%;right:-50%;height:2px;background:var(--divider);z-index:0}
.tl-sdot{width:18px;height:18px;border-radius:50%;background:var(--dot-c,var(--divider));border:2.5px solid var(--bg-paper);box-shadow:0 0 0 2px var(--dot-c,var(--divider));position:relative;z-index:1;flex-shrink:0}
.tl-scontent{text-align:center;padding:8px 2px 0;width:100%}
.tl-saction{font-size:11px;font-weight:700;color:var(--text-primary)}
.tl-smeta{font-size:10px;color:var(--text-secondary);margin-top:3px;line-height:1.4}
.tl-sdetail{font-size:10px;color:var(--text-secondary);margin-top:1px}
.tl-bend{position:relative;height:28px;margin:2px 0}
.tl-bend::before{content:'';position:absolute;top:0;bottom:0;left:calc(100% / 6 * 5 - 1px);width:2px;background:var(--divider);border-radius:2px}
.tl-bend::after{display:none}
.tl-row.reverse{flex-direction:row-reverse}
/* Linha incompleta: o último checkpoint REAL recebe .tl-last, senão o conector
   do :not(:last-child) sai para o vazio (armadilha A2, frontend-design.md:93). */
.tl-last::after{display:none!important}
.tl-row.reverse .tl-sitem:not(:last-child)::after{left:-50%;right:50%}

/* === Param Section / Param Grid (components) === */
.param-section{font-size:10px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;color:var(--text-secondary);margin-bottom:10px;padding-left:2px}
/* `:not(:first-child)` e nao `.param-grid+`: a regra por irmao adjacente so
   cobria UM vizinho, entao secao precedida de banner ou de botao colidia em
   ZERO pixel com o rotulo. Medido: botao "Abrir cadastro da empresa" bottom
   814 / "OBSERVACOES" top 814; `.banner-error` bottom 346 / "IDENTIFICACAO"
   top 346. Espacamento que depende de QUEM vem antes quebra no primeiro
   vizinho novo. */
.param-section:not(:first-child){margin-top:20px}
.param-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:0}

/* === Stats Cards (components) === */
/* --accent recebe fallback explícito: hook de tema por página, nunca var solta. */
.sc-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:14px;align-items:stretch}
/* ⚠️ `cursor:pointer` PERTENCE AO ELEMENTO CLICÁVEL, NÃO AO CARD.
   A regra dava mãozinha e sombra de hover a TODO `.sc-card`, e 23 dos 55
   cards do repo são `<div>` de leitura: prometiam clique que não existe, em
   operational-catalog (5), operation-lanes (10), integrations (2) e
   acordos/contratos (2). O `dashboard.blade.php` já tinha diagnosticado
   isto e consertado com um reset LOCAL marcado "Escopo: só esta tela" — o
   que resolveu uma tela e deixou o defeito vivo nas outras quatro.
   Corrigir na origem dispensa os quatro resets, e o seletor faz o trabalho:
   quem é `<a>` ou `<button>` continua clicável, quem é `<div>` para de
   mentir. */
.sc-card{background:var(--bg-paper);border-radius:12px;padding:20px;border:1px solid var(--divider);transition:all .2s}
a.sc-card,button.sc-card{cursor:pointer}
a.sc-card:hover,button.sc-card:hover{box-shadow:0 2px 8px rgba(0,0,0,0.04)}
.sc-card.selected{border-color:var(--accent,var(--secondary));box-shadow:0 0 0 3px color-mix(in srgb,var(--accent,var(--secondary)) 12%,transparent)}
.sc-title{font-size:13px;font-weight:600;color:var(--text-secondary);margin-bottom:10px;line-height:1.15}
.sc-body{display:flex;align-items:center;gap:10px;flex-wrap:nowrap}
.sc-value{font-size:28px;font-weight:900;letter-spacing:-1.5px;line-height:1}
.sc-divider{width:1.5px;height:22px;flex-shrink:0;background:var(--divider);border-radius:1px}
/* SEM `nowrap`. Medido: a legenda "herdam a falta de prazo de algum trecho"
   vazava 38px para FORA do `.sc-card` e saia cortada no meio da palavra — o
   `nowrap` protegia contra quebra feia e produziu texto amputado, que e pior.
   `overflow-wrap` evita que uma palavra longa estoure sozinha. */
.sc-metric{font-size:12px;color:var(--text-secondary);overflow-wrap:anywhere}
/* Variante compacta para tabs/contextos embutidos. Semântica idêntica ao .sc-card. */
.sc-card.sc-compact{padding:9px 16px;border-radius:10px;display:inline-flex;align-items:center;gap:10px;min-width:0;width:auto}
.sc-card.sc-compact .sc-value{font-size:18px;letter-spacing:-1px}
.sc-card.sc-compact .sc-title{font-size:12px;margin-bottom:0;white-space:nowrap}
.sc-card.sc-compact .sc-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}

/* === Resolution Badge (components) === */
/* .res-direct = configuração específica do escopo · .res-inherited = herdada do pai */
.res-badge{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:6px;font-size:11px;font-weight:600;white-space:nowrap}
.res-direct{background:#F0FDF4;color:#166534;border:1px solid #BBF7D0}
.res-inherited{background:var(--info-light);color:var(--secondary);border:1px solid #BFDBFE}

/* === Component Label (components) === */
/* Reposto contra o passo 2 do 01-extracao-css.md: no HTML fonte é rótulo de
   vitrine, mas a §5 do ui-prototype.md:403 o promoveu a "badge de tipo/categoria
   de componente em tabelas", e a §5 é o vocabulário contra o qual o G2 mede.
   Ver ai/decisions/2026-08-23-comp-label-e-scope-filters.md. */
.comp-label{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:6px;font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px}
/* CATEGORIA != SITUACAO. `.comp-label-green` e `.ba-g` tem HOJE pintura
   identica — mesmo `--success-light` de fundo, mesma cor de texto — e
   conviviam na MESMA LINHA de tabela em system-modules: nivel numa coluna,
   contagem na outra, verde nas duas dizendo coisas diferentes. O G2 passava,
   porque as duas classes existem; e o gate estava certo — ele prova que a
   classe existe, nunca que o significado e unico.
   Um contorno separa as duas gramaticas sem trocar UMA cor: chip de situacao e
   solido e pilula; badge de categoria e retangular e contornado. Cor sozinha
   nunca deveria ter sido o unico portador do significado — quem nao distingue
   verde de verde tambem nao distinguia antes. */
.comp-label{border:1px solid color-mix(in srgb, currentColor 22%, transparent)}
.comp-label-blue{background:var(--info-light);color:var(--secondary)}
/* ⚠️ AQUI HAVIA UM `.comp-label-orange` COM FUNDO VERDE (`#EBFCF2`), e ele
   era regra MORTA: a família é aplicada por `@class([...])` em
   `system-modules/partials/nivel.blade.php:29-33`, com as quatro chaves
   escritas à mão, e `orange` não é uma delas. ✅ Conferido com controle
   positivo — `comp-label-blue` aparece em 3 views, `orange` em zero.

   O nome mentia porque a família inteira é batizada pela TINTA e não pelo
   PAPEL: quem escolhe a classe escolhe uma cor e inventa o sentido, e
   ninguém percebeu que a laranja era verde porque o nome não prometia nada
   verificável. Fica o débito registrado — `-categoria`, `-nivel`, `-neutro`
   diriam o que a coisa é.

   A LIÇÃO DE CONTRASTE QUE ESTAVA AQUI VALE PARA A FAMÍLIA INTEIRA e por
   isso não some com a regra: sobre verde, ou sobre fundo claro esverdeado,
   o texto é NAVY. O verde sobre `#EBFCF2` dá ~1,5:1 e reprova WCAG — é a
   mesma regra dos 14 pontos do retint. */
.comp-label-green{background:var(--success-light);color:#166534}
.comp-label-purple{background:#EDE9FE;color:#5B21B6}  /* era #8B5CF6 = 3,57:1; agora 7,4:1. O irmao .comp-label-blue da 15,53:1 na MESMA coluna — contraste assimetrico por fator 4 na mesma tabela le como defeito de render */
.comp-label-gray{background:#F1F5F9;color:var(--text-secondary)}

/* === Scope Filters Strip (origem: §5 do ui-prototype.md, NÃO o HTML) === */
/* Não existe em nenhum dos HTMLs fonte — escrito a partir da especificação da §5
   (ui-prototype.md:398, e as regras das linhas 272, 479, 480, 483), do mesmo modo
   que os .s-chip-{code} vieram da tabela statuses.
   Strip inline dentro de tabs/editor. NUNCA em sub-tela de listagem — lá é
   .filter-panel. Oculto por padrão; .open exibe (toggle via .fh-btn-filter no
   .fh-right, ou btn-ghost btn-sm no cabeçalho da aba quando não há .fh).
   SEM border-bottom: a separação vem do padding; borda aqui duplicaria a linha
   do .etc-flush logo abaixo. Contexto compacto — inputs e botões a 34px.
   .sf-actions leva SEMPRE os dois botões: [Limpar ghost] + [Aplicar btn-a]. */
.scope-filters{display:none;align-items:flex-end;gap:12px;flex-wrap:wrap;padding:16px 24px;background:var(--bg-paper)}
.scope-filters.open{display:flex}
.sf-item{flex:1;min-width:160px}
.sf-item label,.sf-label{display:block;font-size:11px;font-weight:600;color:var(--text-secondary);margin-bottom:4px;text-transform:uppercase;letter-spacing:.4px}
.sf-item input,.sf-item select{width:100%;height:34px;padding:0 10px;border-radius:10px;border:1px solid var(--divider);font-family:inherit;font-size:12px;color:var(--text-primary);background:var(--bg-default);outline:none;transition:border-color .15s}
.sf-item select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:28px;cursor:pointer}
.sf-item input:focus,.sf-item select:focus{border-color:var(--secondary)}
.sf-actions{display:flex;gap:8px;align-items:flex-end;flex-shrink:0}
.sf-actions .btn{height:34px}

/* === Entity Table Card (components) === */
.etc{background:var(--bg-paper);border-radius:18px;padding:26px;box-shadow:none}
.etc-header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:22px;flex-wrap:wrap}
.etc-search{display:flex;align-items:center;gap:8px;padding:8px 14px;border-radius:12px;border:1px solid rgba(226,229,238,.8);background:var(--bg-default);width:420px;max-width:100%;transition:.2s}
.etc-search:focus-within{border-color:var(--secondary);box-shadow:0 0 0 3px rgba(0,13,61,.06);background:var(--bg-paper)}
.etc-search svg{color:var(--text-secondary);width:18px;height:18px;flex-shrink:0}
.etc-search input{border:none;background:none;outline:none;font-family:inherit;font-size:13px;color:var(--text-primary);flex:1;height:24px}
.etc-search input::placeholder{color:var(--text-muted);font-size:13px;opacity:.7}
.etc-right{display:flex;align-items:center;gap:10px}
.etc-count{font-size:12px;color:var(--text-secondary)}
.etc-export{width:36px;height:36px;border-radius:16px;border:none;background:rgba(0,13,61,.1);color:var(--secondary);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;transition:.15s;padding:0}
.etc-export:hover{background:rgba(0,13,61,.2)}
.etc-table-wrap{overflow-x:auto;margin:16px -26px 0}
/* min-width 820px e nao 1100px. Medido: em 1280 — a largura que o proprio
   standard adota como referencia — o cartao da 959px uteis, e com 1100 a coluna
   "Situacao" era cortada NO MEIO DA PALAVRA ("SITUAC", chips lendo "Ativ") e a
   coluna do chevron ficava 100% fora da vista. Pior: a PAGINA nao rola
   horizontalmente, entao nao havia pista nenhuma de que existia conteudo a
   direita — o recorte era silencioso.
   .etc-table-fit e para tabela dentro de aba, que ja vive num container
   estreito e nao precisa de piso: nasceu para matar os style="min-width:auto"
   inline que a §5 proibe. */
.etc-table{width:100%;border-collapse:collapse;min-width:820px}
.etc-table.etc-table-fit{min-width:auto}
.etc-table thead th{background:var(--bg-default);padding:9.6px 26px;text-align:left;font-size:12px;font-weight:600;color:var(--text-secondary);border-bottom:1px solid rgba(226,229,238,.9);white-space:nowrap}
.etc-table thead th:first-child{padding-left:26px}
.etc-table thead th:last-child{padding-right:26px}
.etc-table tbody td{padding:9.6px 26px;border-bottom:1px solid rgba(226,229,238,.7);vertical-align:middle;font-size:12.5px}
.etc-table tbody td:first-child{padding-left:26px}
.etc-table tbody td:last-child{padding-right:26px}
.etc-table tbody tr{transition:background .15s}
.etc-table tbody tr:hover{background:rgba(0,0,0,.02)}
.etc-table tbody tr:last-child td{border-bottom:none}
/* .72 e nao .45: medido, a .45 derrubava a linha inteira para 1,47-2,92:1.
   'Esmaecida mas legivel' tem numero — abaixo de 4,5:1 nao e esmaecida, e ilegivel.
   SEGUNDA MEDICAO: .72 ainda deixava .e-sub em 3,76:1 e o chip inativo em
   3,52:1. Foi para .82. O sinal de "esta desligado" vem do CHIP com texto
   ("Inativo"), nao de apagar a linha ate o texto sumir — daltonismo e visao
   reduzida nao leem opacidade. */
/* TERCEIRA MEDICAO — e a correcao das duas anteriores, que estavam ERRADAS.
   `opacity` menor que 1 cria um contexto de composicao: o elemento inteiro,
   com toda a sua subarvore, e pintado e SO ENTAO composto. Um filho nao
   consegue aumentar a propria opacidade de volta. A regra que existia aqui
   (`tr.inactive .ba, tr.inactive .s-chip {opacity:1}`) era INERTE — nunca
   surtiu efeito nenhum, e o comentario anterior descrevia como resolvido um
   problema que continuava exatamente onde estava.
   A prova: aquele comentario previa o chip caindo para 4,13:1 SE nao fosse
   excluido. Uma auditoria mediu 4,17:1 na tela, com a exclusao no lugar.
   Ou seja, o numero medido e o numero que a regra dizia estar prevenindo.
   E o dano ia alem do chip: alcancava BOTAO dentro da linha, que passava a
   parecer desabilitado sem estar (3,77:1, `cursor:pointer`) — o defeito do
   `.btn:disabled` ao contrario, com o sinal visual mentindo sobre a
   disponibilidade.
   Esmaecer com COR resolve porque cor nao compoe subarvore: atinge o texto
   escolhido e nada mais. O sinal de "esta desligado" continua vindo do CHIP
   com a palavra "Inativo" — daltonismo e visao reduzida nao leem opacidade,
   nem nunca leram. */
/* QUARTA MEDICAO — e a correcao do erro que a TERCEIRA introduziu.
   Ao trocar `opacity` por `color` eu esmaeci so `.e-name` e `.c-cell` e deixei
   `.e-sub`/`.c-cell-sub` intactos. Resultado medido em quatro modulos: o NOME
   da entidade caiu de 17,74:1 para 4,76:1 enquanto o subtitulo ficou em
   7,58:1 — o texto secundario passou a ter MAIS contraste que o principal, e a
   linha inativa inverteu a propria hierarquia. O `opacity` ao menos esmaecia
   tudo junto e preservava a ordem.
   Dois degraus, portanto: o principal cai para `--text-secondary` (7,58:1) e o
   secundario para `--text-muted` (4,76:1). A ordem se mantem, "esta desligada"
   continua legivel, e os dois seguem acima de 4,5:1. */
.etc-table tbody tr.inactive .e-name,
.etc-table tbody tr.inactive .c-cell{color:var(--text-secondary)}
.etc-table tbody tr.inactive .e-sub,
.etc-table tbody tr.inactive .c-cell-sub,
.etc-table tbody tr.inactive .c-cell span{color:var(--text-muted)}
/* O avatar e o bloco de maior massa visual da linha. Sob `opacity` ele
   acompanhava; com `color` ficou em forca total, e a linha "desligada" passou a
   ter o elemento mais forte da tabela intacto. Dessatura pelo fundo, nao por
   opacidade — o texto de dentro e branco e precisa continuar legivel. */
/* Agora MORDE de verdade: o componente entrega a cor em `--e-avatar-c` e a
   folha sobrepoe a variavel. Enquanto era `style="background:"` no elemento,
   esta regra era codigo morto — escrita, comentada e sem efeito nenhum. */
.etc-table tbody tr.inactive .e-avatar{--e-avatar-c:var(--text-muted)}
/* O esmaecimento mira o TEXTO nomeado, nunca o `td`. `color` e herdada: pintar
   o `td` alcancaria chip, badge e botao pela heranca, e "devolver" a cor neles
   com `unset` os faria herdar do proprio `td` esmaecido — o mesmo erro da
   opacidade, por outra porta. Chip e badge ja definem a propria cor; botao
   tambem. Nao ha o que excluir quando nao se pintou o container. */
/* Contained flush: para contextos embutidos (tabs, painéis aninhados).
   Padding 0 no container; a tabela vai de borda a borda. NÃO inclui .etc-header.
   A paginação vive FORA do .etc-flush — a borda do card encerra no último registro. */
.etc.etc-flush{padding:0;border:1px solid var(--divider);border-radius:12px;background:var(--bg-paper);overflow:hidden}
.etc.etc-flush .etc-table-wrap{margin:0}
.etc.etc-flush .etc-table thead th{padding:10px 20px}
.etc.etc-flush .etc-table tbody td{padding:10px 20px}

/* === Table Checkbox (components) === */
/* `--border-strong` (4,76:1) e nao #CBD5E1 (1,48:1): borda de checkbox e
   componente de interface e precisa de 3:1. O token foi criado para isto e
   tinha sido aplicado so aos inputs de texto. */
.chk{width:18px;height:18px;border-radius:4px;border:2px solid var(--border-strong);background:var(--bg-paper);cursor:pointer;appearance:none;transition:.15s;flex-shrink:0;padding:0;margin:0}
.chk:checked{background:var(--secondary);border-color:var(--secondary)}
.chk:checked::after{content:'';display:block;width:5px;height:9px;border:solid var(--bg-paper);border-width:0 2px 2px 0;transform:rotate(45deg) translateY(-1px);margin:1px auto}
.chk:hover{border-color:var(--secondary)}

/* === Entity Cell / Contact Cell (components) === */
.e-cell{display:flex;align-items:center;gap:6px;min-width:0}
/* TERCEIRA FAMILIA DE BOTAO COM O MESMO DEFEITO. `.btn:disabled` e
   `.act-btn:disabled` ja existem — as duas acrescentadas como correcao, cada
   uma depois de alguem tropecar nela. `.fh-btn-new` desabilitado renderizava
   IDENTICO a um CTA vivo: navy cheio, texto branco, `opacity:1`,
   `cursor:pointer`. Clicar nao fazia nada e nada explicava.
   Corrigir familia a familia nao resolve: a quarta repete. */
.fh-btn-new:disabled,.fh-btn-new[aria-disabled="true"]{opacity:.45;cursor:not-allowed;box-shadow:none;transform:none}

/* CAMPO COM ERRO PRECISA PARECER COM ERRO. A faixa de validacao diz "Confira os
   campos DESTACADOS abaixo" e nada ficava destacado: `aria-invalid="true"` era
   setado e a borda continuava identica a de um campo valido. Mensagem que
   promete um sinal inexistente e pior que mensagem sem promessa. */
.form-input[aria-invalid="true"],.form-select[aria-invalid="true"],
textarea[aria-invalid="true"]{border-color:var(--error)}
/* `resize:vertical`: com `both` o usuario arrasta a textarea para FORA da
   coluna do grid de tres e quebra o alinhamento da ficha inteira. */
textarea.form-input{resize:vertical}

.e-avatar{width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--bg-paper);flex-shrink:0;background:var(--e-avatar-c,var(--secondary))}
.e-name{font-size:13px;font-weight:600;color:var(--text-primary);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.e-sub{font-size:11.5px;color:var(--text-secondary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Idem: "2,0 dia(s)" quebrava. So `.c-cell.mono` tinha nowrap. */
.c-cell{font-size:12px;color:var(--text-primary);white-space:nowrap}
.c-cell span,.c-cell-sub{color:var(--text-secondary)}

/* === Status Chip (components) — chassi === */
.s-chip{display:inline-flex;align-items:center;gap:4px;height:24px;padding:0 6px;border-radius:99px;font-size:11.5px;font-weight:500;white-space:nowrap}
.s-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0;margin-left:2px;margin-right:-1px}

/* === Status Chip — estados do domínio TMS === */
/* Codes reais de ai/schema/lookups/statuses.json (11 distintos, scopes:
   version · agreement · contract · network_route · service_product ·
   integration_connection). Fundo = alpha(cor,.10~.22); texto sempre escuro —
   nenhuma combinação branco-sobre-verde. */
.s-chip-draft{background:rgba(0,13,61,.10);color:var(--secondary)}
.s-chip-draft .s-dot{background:var(--secondary)}
.s-chip-published{background:rgba(36,109,76,.14);color:var(--success)}
.s-chip-published .s-dot{background:var(--success)}
.s-chip-archived{background:rgba(148,163,184,.18);color:var(--text-secondary)}
.s-chip-archived .s-dot{background:var(--text-disabled)}
.s-chip-active{background:rgba(36,109,76,.14);color:var(--success)}
.s-chip-active .s-dot{background:var(--success)}
.s-chip-inactive{background:rgba(239,68,68,.14);color:var(--error-dark)}
.s-chip-inactive .s-dot{background:var(--error)}
.s-chip-disabled{background:rgba(148,163,184,.22);color:var(--text-secondary)}
.s-chip-disabled .s-dot{background:var(--text-secondary)}
.s-chip-terminated{background:rgba(153,27,27,.14);color:#991B1B}
.s-chip-terminated .s-dot{background:#991B1B}
/* Versao substituida e estado NEUTRO, nao "roxo/permissao". O roxo dava
   3,74:1 (3,18 em linha inativa) e ainda tomava emprestado o eixo semantico
   de filtros e perfis (§4.1). */
.s-chip-superseded{background:var(--bg-hover);color:var(--text-secondary)}
/* DECLARACAO DUPLICADA REMOVIDA: a correcao foi escrita e a linha antiga
   (`--purple`) ficou LOGO ABAIXO, entao a segunda vencia e o ponto continuava
   roxo — a cor que o comentario acima diz ter removido. Comentario que afirma
   um resultado precisa da medicao depois da mudanca. */
.s-chip-superseded .s-dot{background:var(--text-secondary)}
.s-chip-cancelled{background:rgba(146,64,14,.12);color:#92400E}
.s-chip-cancelled .s-dot{background:#92400E}
.s-chip-pending{background:rgba(245,158,11,.16);color:#D97706}
.s-chip-pending .s-dot{background:#D97706}
.s-chip-error{background:rgba(239,68,68,.16);color:#B91C1C}
.s-chip-error .s-dot{background:#B91C1C}

/* === Row Action Button (components) === */
.act-btn{width:36px;height:36px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-muted);transition:.15s;padding:0}
.act-btn:hover{background:rgba(0,0,0,.04);color:var(--text-primary)}
/* Faltava, e o editor de fluxo precisa: a seta "subir" da primeira linha e a
   "descer" da ultima nao tem para onde ir. Sem isto, elas ficavam identicas as
   ativas — o mesmo defeito do .btn:disabled, na familia de botao de icone. */
.act-btn:disabled{opacity:.35;cursor:not-allowed}
.act-btn:disabled:hover{background:transparent;color:var(--text-muted)}

/* === Pagination (components) === */
.etc-pagination{display:flex;align-items:center;justify-content:flex-end;padding:12px 26px;gap:16px;font-size:12px;color:var(--text-secondary)}
.etc-pagination select{border:1px solid var(--divider);border-radius:8px;padding:4px 8px;font-family:inherit;font-size:12px;background:var(--bg-paper);cursor:pointer;color:var(--text-primary)}
.pg-btns{display:flex;gap:2px}
/* text-decoration:none acrescentado: o paginador do Blade emite .pg-b em <a>,
   e a fonte só previa <button> — sem isto o número de página sai sublinhado. */
.pg-b{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;font-family:inherit;font-size:13px;font-weight:500;color:var(--text-secondary);text-decoration:none;transition:.15s;padding:0}
.pg-b:hover{background:rgba(0,0,0,.04)}
.pg-b.active{background:rgba(0,13,61,.12);color:var(--secondary);font-weight:700}
.pg-b:disabled{opacity:.3;cursor:default}
.pg-b:disabled:hover{background:transparent}
/* As duas classes abaixo substituem os dois style= inline do HTML fonte
   (a §5 proíbe inline style ad hoc). Consumidas por
   resources/views/vendor/pagination/default.blade.php. */
/* "..." entre faixas de página: herda .pg-b, mas NÃO é clicável — nem cursor,
   nem hover, nem foco. Vem num <span>, não em <a>/<button>. */
.pg-b-ellipsis{font-size:11px;cursor:default;color:var(--text-secondary)}
.pg-b-ellipsis:hover{background:transparent}
/* Agrupamento "Por página: [select]" dentro do .etc-pagination */
.etc-pagination-perpage{display:flex;align-items:center;gap:8px}

/* === Banner (components) === */
/* Alerta inline persistente. Sempre .banner + .banner-{variante}. NUNCA .alert. */
.banner{border-radius:12px;padding:12px 16px;font-size:13px;font-weight:500;display:flex;align-items:flex-start;gap:10px;line-height:1.5}
.banner-warning{background:var(--warning-light);color:#92400E}
.banner-info{background:var(--info-light);color:var(--secondary)}
.banner-success{background:var(--success-light);color:#166534}
.banner-error{background:var(--error-light);color:#991B1B}
.banner-icon{flex-shrink:0;margin-top:1px}
.banner+.banner{margin-top:10px}

/* === Tab Content Area (components) === */
/* Padding para conteúdo de abas SEM toolbar-banda. Contextos COM toolbar-banda
   NÃO usam .at-content — cada seção tem seu próprio padding. */
.at-content{padding:24px}

/* === Draft Toolbar (components) === */
/* Faixa de contexto no topo de tabs em modo rascunho. Full-width dentro de .at,
   border-radius 0. Fundo bg-paper — o contexto é comunicado pela aba e pelo banner. */
.draft-toolbar{display:flex;align-items:center;justify-content:space-between;padding:10px 24px;background:var(--bg-paper);flex-wrap:wrap;gap:8px}
.draft-toolbar-info{font-size:13px;color:var(--text-secondary);font-weight:500}
.draft-toolbar-info strong,.draft-toolbar-info-strong{font-weight:700;color:var(--text-primary)}
.draft-toolbar-actions{display:flex;gap:8px}

/* === Filter Panel (components) === */
/* Colapsável para uso dentro de tabs, workspaces ou list pages. Oculto por padrão;
   .open exibe com slideDown. Variantes: .visible (sempre visível, sem toggle) e
   .fp-stacked (4+ campos, filhos .fp-row por linha). */
.filter-panel{background:var(--bg-paper);border-radius:14px;border:1px solid var(--divider);padding:16px 20px;display:none}
.filter-panel.open{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;animation:slideDown .18s ease-out}
.filter-panel.visible{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap}
.filter-panel.fp-stacked{flex-direction:column;gap:10px}
.filter-panel.fp-stacked .fp-row{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;width:100%}
.fp-item{flex:1;min-width:180px}
.fp-item label,.fp-item-label{display:block;font-size:11px;font-weight:600;color:var(--text-secondary);margin-bottom:4px;text-transform:uppercase;letter-spacing:.4px}
.fp-item select,.fp-item input{width:100%;height:36px;padding:0 10px;border-radius:10px;border:1px solid var(--divider);font-family:inherit;font-size:12px;color:var(--text-primary);background:var(--bg-default);outline:none;transition:border-color .15s}
.fp-item select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 10px center;padding-right:28px;cursor:pointer}
.fp-item select:focus,.fp-item input:focus{border-color:var(--secondary)}
.fp-footer{display:flex;gap:8px;align-items:flex-end;flex-shrink:0}
/* §5: botões do footer casam com os inputs de 36px do .fp-item */
.fp-footer .btn{height:36px}
.fp-input-wrap{position:relative}
.fp-input-wrap input{padding-right:30px}
.fp-input-clear{position:absolute;right:8px;top:50%;transform:translateY(-50%);width:20px;height:20px;border:none;background:none;cursor:pointer;color:var(--text-muted);display:flex;align-items:center;justify-content:center;padding:0;border-radius:50%;transition:color .15s,background .15s}
.fp-input-clear:hover{color:var(--text-secondary);background:var(--bg-hover)}

/* === Actions Dropdown (components) === */
/* Menu ⋯ em células de tabela. SEMPRE .actions-cell > .actions-btn + .dropdown-menu.
   .dropdown-item.danger = ação destrutiva. Hierarquia canônica em header de editor:
   [fh-btn-filter] [btn-w ⋯ dropdown] [btn-pr: Verificar] [btn-o: Publicar] */
.actions-cell{position:relative;text-align:right}
.actions-btn{background:transparent;border:none;color:var(--text-muted);font-size:18px;cursor:pointer;padding:2px 8px;border-radius:6px;transition:background .12s;line-height:1;display:flex;align-items:center;font-family:inherit}
.actions-btn:hover{background:var(--bg-hover);color:var(--text-primary)}
.dropdown-menu{position:absolute;right:0;top:100%;background:var(--bg-paper);border:1.5px solid var(--divider);border-radius:12px;min-width:200px;box-shadow:0 8px 24px rgba(0,0,0,.1);z-index:200;overflow:hidden;display:none}
.dropdown-menu.open{display:block}
.dropdown-item{padding:9px 16px;font-size:13px;color:var(--text-primary);cursor:pointer;transition:background .12s;background:none;border:none;width:100%;text-align:left;font-family:inherit}
.dropdown-item:hover{background:var(--bg-hover)}
.dropdown-item.danger{color:var(--error)}
.dropdown-divider{height:1px;background:var(--divider);margin:4px 0}

/* === Form Controls (components) === */
/* Campos canônicos. NUNCA .input, .field, .form-control — apenas estes.
   .form-hint NÃO é .af-hint (que pertence ao contexto .af). */
.form-group{margin-bottom:20px}
.form-label{display:block;font-size:13px;font-weight:700;color:var(--text-primary);margin-bottom:6px}
/* ⚠️ ESTE COMENTÁRIO JÁ ESTEVE ENTRE `.form-label` E `.req`, E ISSO QUEBRAVA
   A REGRA INTEIRA. O CSS descarta o comentário e mantém o espaço em branco,
   então o parser lia `.form-label .req` — um SELETOR DESCENDENTE criado por
   acidente de formatação. Efeito: o asterisco de campo obrigatório só
   pintava dentro de um `.form-label`, e ficava com a cor do corpo em
   qualquer outro contexto — medido em `.af-ro-label .req`, que saía
   `rgb(17,24,39)` em vez de `rgb(185,28,28)`. Valia para TODO módulo, e
   nenhum gate pega: a classe existe, o G2 passa, e o que falha é a
   especificidade.

   Mesma família do `@php(...)` que engole meio arquivo e do fecha-comentário
   solto que já zerou uma folha inteira aqui: o parser não enxerga intenção,
   só o próximo delimitador. Em CSS, comentário fica em LINHA PRÓPRIA antes
   do seletor — nunca entre dois.

   ⚠️ E ESTE COMENTÁRIO JÁ MATOU A REGRA UMA SEGUNDA VEZ. A primeira versão
   dele citava o fecha-comentário com os DOIS CARACTERES LITERAIS, no meio
   da frase que explica esse exato defeito. O comentário fechou ali, a prosa
   restante virou lista de seletor, e o parser descartou `.req` — não "com a
   cor errada": ELA SUMIU DO CSSOM, em 26 das 27 views que a usam.
   Foi pior que o defeito original, e passou porque medi a mudança na FONTE
   e não na TELA. Nunca cite delimitador de comentário dentro de um.

   `--error-dark` e não `--error`: o asterisco em `--error` dava 3,76:1 em
   13px, e ele é a única marca de campo obrigatório antes de o erro
   aparecer — tem de ser legível. */
.req{color:var(--error-dark);margin-left:2px}
.form-input{width:100%;padding:9px 13px;border-radius:12px;border:1px solid var(--border-strong);font-size:13px;font-family:inherit;color:var(--text-primary);background:var(--bg-default);outline:none;transition:border-color .15s}
.form-input:focus{border-color:var(--secondary);box-shadow:0 0 0 3px rgba(0,13,61,.06);background:var(--bg-paper)}
.form-input[readonly]{background:var(--bg-paper);color:var(--text-secondary);cursor:default}
.form-select{width:100%;padding:9px 13px;border-radius:12px;border:1px solid var(--border-strong);font-size:13px;font-family:inherit;color:var(--text-primary);background:var(--bg-default);outline:none;cursor:pointer;transition:border-color .15s;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 13px center;padding-right:36px}
/* `background-color:` e NAO `background:`. O shorthand reseta `background-image`
   e apagava o chevron que a regra de cima poe como data-URI — o select focado
   ficava sem a seta, e so no foco, que e quando o usuario esta olhando para
   ele. Medido: `bgImage=none` no focado, data-URI em todos os outros. */
.form-select:focus{border-color:var(--secondary);box-shadow:0 0 0 3px rgba(0,13,61,.06);background-color:var(--bg-paper)}
.form-hint{font-size:11px;color:var(--text-secondary);margin-top:5px;line-height:1.4}

/* === Toggle Switch (components) === */
.toggle{width:40px;height:22px;border-radius:11px;background:var(--divider);cursor:pointer;position:relative;transition:background .2s;flex-shrink:0;border:none;outline:none;display:inline-block}
.toggle::after{content:'';position:absolute;width:18px;height:18px;border-radius:50%;background:var(--bg-paper);top:2px;left:2px;transition:transform .2s;box-shadow:0 1px 3px rgba(0,0,0,.15)}
.toggle.on{background:var(--secondary)}
.toggle.on::after{transform:translateX(18px)}

/* === Progress Bar (components) === */
/* CONFLITO SEMÂNTICO: o container era .pb no ui-components, mas .pb no chassi
   admin-light é o botão de paginação e vence. O container ganhou .pb-wrap —
   extensão nominal, mesmas declarações do original. Semântica por cor via
   --pb-color. Thresholds sugeridos: >=90% success, >=70% warning, <70% error. */
.pb-wrap{background:var(--bg-default);border-radius:12px;padding:16px 20px}
.pb-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.pb-label{font-size:13px;font-weight:700;color:var(--text-primary)}
.pb-value{font-size:13px;font-weight:800;color:var(--pb-color,var(--text-primary))}
.pb-track{height:8px;border-radius:4px;background:var(--divider);overflow:hidden}
.pb-fill{height:100%;border-radius:4px;background:var(--pb-color,var(--secondary));transition:width .3s}
.pb-desc{font-size:11px;color:var(--text-secondary);margin-top:6px;line-height:1.4}

/* === Health Strip (components) === */
/* Barra persistente de KPIs no topo de workspaces unificados. */
.hs{background:var(--bg-paper);border-radius:16px;border:1px solid var(--divider);padding:16px 24px;display:flex;align-items:center;gap:24px;flex-wrap:wrap}
.hs-kpi{display:flex;align-items:center;gap:10px;min-width:0}
.hs-kpi-icon{width:36px;height:36px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.hs-kpi-text{display:flex;flex-direction:column;gap:1px}
.hs-kpi-value{font-size:20px;font-weight:900;letter-spacing:-.5px;line-height:1}
.hs-kpi-label{font-size:11px;color:var(--text-secondary);white-space:nowrap}
.hs-divider{width:1px;height:36px;background:var(--divider);flex-shrink:0}
.hs-actions{margin-left:auto;display:flex;gap:10px;flex-shrink:0}

/* === Empty State (components) === */
.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;text-align:center;gap:8px}
.empty-state svg{margin-bottom:4px}
.empty-state h3,.empty-state-title{font-size:15px;font-weight:700;color:var(--text-primary);margin:0}
.empty-state p,.empty-state-text{font-size:13px;color:var(--text-secondary);max-width:320px;line-height:1.5;margin:0}

/* === Wizard Multi-step (components) === */
/* Dentro de overlays (.modal), fluxos de 2–4 passos.
   .wizard-wrap > .wizard-steps + .wizard-card (um por passo, inativos display:none). */
.wizard-wrap{padding:20px 24px}
.wizard-steps{display:flex;align-items:center;justify-content:center;margin-bottom:24px}
/* GRID DE TRÊS COLUNAS NÃO CABE EM DRAWER. Medido no mesmo conteúdo e na mesma
   largura de 420px, alternando só a contagem de colunas: em c3 elas ficam com
   113px e SEIS de treze campos quebram — a data `18/08/2026 09:00` em duas
   linhas, um nome próprio em três —, produzindo TRÊS alturas de linha
   diferentes na mesma lista. Em c2 vão a 171px, quebram dois campos, e a altura
   volta a ser uma só.
   Custa +89px de rolagem e devolve o alinhamento. A regra nasce no DS, e não
   como regra local de um módulo, porque a auditoria mediu os dois workspaces e
   o defeito é do par grid×largura — não da tela.
   ⚠️ E o "drawer de 520px" que se acreditava existir NÃO EXISTE: `.drawer` é
   420px e ninguém sobrescreve. Os 520 viviam só dentro de um comentário — que,
   por ser comentário de CSS em `<style>`, ainda ia para o HTML. */
.drawer .fg-grid.c3{grid-template-columns:1fr 1fr}

/* A COLUNA DO CHEVRON NAO PODE ENCOLHER. Em duas telas de workspace o chevron
   saiu da area visivel nos tres viewports — medido em x 1429-1465 num wrap que
   acaba em 1386 —, e ele e a UNICA afordancia de abrir o registro. A Definition
   of Done exige rota alcancavel NAVEGANDO: tela cujo caminho principal so existe
   rolando a tabela para o lado nao e alcancavel, e adivinhavel.
   `td:has(> .act-btn)` e nao `td:last-child`: nem toda tabela tem acao na ultima
   coluna, e algumas terminam em dado — encolher a ultima por regra cega
   quebraria essas. Mira-se a celula que de fato carrega o botao. */
.etc-table td:has(> .act-btn),.etc-table td:has(> a.act-btn){width:56px;white-space:nowrap}

.wizard-step{display:flex;flex-direction:column;align-items:center;gap:6px;flex-shrink:0}
.wizard-step-circle{width:28px;height:28px;border-radius:50%;background:var(--bg-hover);color:var(--text-disabled);border:2px solid var(--divider);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;transition:.2s}
.wizard-step-circle.done{background:var(--success);color:var(--bg-paper);border-color:var(--success)}
.wizard-step-circle.current{background:var(--secondary);color:var(--bg-paper);border-color:var(--secondary)}
.wizard-step-label{font-size:11px;font-weight:600;color:var(--text-secondary);white-space:nowrap}
.wizard-step-label.done{color:var(--success)}
.wizard-step-label.current{color:var(--secondary);font-weight:700}
.wizard-step-line{flex:1;height:2px;background:var(--divider);margin:0 8px;align-self:flex-start;margin-top:14px;min-width:32px}
.wizard-step-line.done{background:var(--success)}
.wizard-card{padding:0}
.wizard-title{font-size:15px;font-weight:800;color:var(--text-primary);margin-bottom:4px}
.wizard-subtitle{font-size:12px;color:var(--text-secondary);margin-bottom:16px}
.wizard-footer{display:flex;align-items:center;justify-content:space-between;padding:16px 0 0;border-top:1px solid var(--divider);margin-top:16px}
.wizard-footer-right{display:flex;gap:8px}

/* === App Tabs (components) === */
.at{background:var(--bg-paper);border-radius:16px;border:1px solid var(--divider);margin-bottom:16px;overflow:hidden}
/* ⚠️ A RÉGUA PRECISA ROLAR, senão a aba que não cabe FICA INALCANÇÁVEL.
   O `.at` é `overflow:hidden` (a borda arredondada exige), e a barra
   herdava o corte: em `/config/catalogos-operacionais` são 7 abas com
   1374px de conteúdo em 1117px, e duas delas — "Motivos (69)" e
   "Tratativas (11)", 80 itens de catálogo — ficavam fora da tela SEM
   rolagem, alcançáveis só por URL digitada. A Definition of Done exige
   alcançável NAVEGANDO. Pior no destino: com a aba ativa fora do campo de
   visão, a régua não mostrava aba selecionada nenhuma.
   `scroll-snap` alinha a aba ao parar, e a barra fina não come altura. */
/* SOMBRA DE ROLAGEM NO LUGAR DE BARRA — promovida de uma regra local do
   `operational-catalog`, porque o problema não era daquela tela: toda régua
   de abas usa esta classe, e `operation-lanes` estava com o tratamento
   antigo. Regra que dois módulos precisam mora na folha.

   A barra fina crua comia 12px de 60 de altura da régua, e a altura ali é
   área de clique. Sem barra nenhuma, porém, duas abas ficavam fora da tela
   sem nada indicando que havia mais à direita.

   As quatro camadas resolvem os dois de uma vez, sem JavaScript: duas
   sombras presas à viewport da régua e duas coberturas na cor do fundo
   presas ao CONTEÚDO. Quando a rolagem está no início, a cobertura
   esquerda está sobre a sombra esquerda e some; ao rolar, o conteúdo leva
   a cobertura embora e a sombra aparece. O sinal nasce e morre sozinho.

   ⚠️ A COBERTURA COMEÇA OPACA E SÓ DEPOIS DESBOTA (16px em cor cheia
   dentro de 30px). A primeira versão desbotava desde o pixel zero e, com a
   régua parada no início, ainda sobrava sombra na borda: a cobertura já
   estava a 70% de opacidade onde a sombra ainda tinha metade da dela.
   Cobrir precisa ser mais forte que a sombra ao longo de TODA a faixa, não
   só no primeiro pixel. Foi a CAPTURA que mostrou isso; a medição não
   teria mostrado. */
.at-bar{display:flex;border-bottom:1px solid var(--divider);position:relative;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;scroll-snap-type:x proximity;background-image:linear-gradient(to right,var(--bg-paper) 16px,transparent),linear-gradient(to left,var(--bg-paper) 16px,transparent),linear-gradient(to right,var(--text-disabled),transparent),linear-gradient(to left,var(--text-disabled),transparent);background-position:left center,right center,left center,right center;background-repeat:no-repeat;background-size:30px 100%,30px 100%,14px 100%,14px 100%;background-attachment:local,local,scroll,scroll}
.at-bar::-webkit-scrollbar{height:0}
.at-tab{scroll-snap-align:start}
.at-tab{padding:0 20px;font-family:inherit;font-size:14px;font-weight:500;color:var(--text-secondary);background:none;border:none;cursor:pointer;display:flex;align-items:center;gap:6px;transition:color .15s;position:relative;white-space:nowrap;min-height:48px}
.at-tab:hover{color:var(--text-primary)}
.at-tab.active{color:var(--secondary);font-weight:700}
.at-tab.active::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:3px;background:var(--secondary);border-radius:3px 3px 0 0}
.at-tab svg{width:18px;height:18px}
.at-secondary{border-left:3px solid var(--secondary);padding-left:16px;margin-top:12px;background:rgba(0,13,61,.03);border-radius:0 8px 8px 0}
.at-sec-label{font-size:11px;color:var(--secondary);font-weight:700;text-transform:uppercase;opacity:.7;padding:8px 0 0;letter-spacing:.8px}
.at-secondary .at-bar{border-bottom:none}
.at-secondary .at-tab{font-size:13px;min-height:40px;padding:0 16px}
.at-secondary .at-tab.active{color:var(--secondary)}
.at-secondary .at-tab.active::after{height:2px;bottom:0;border-radius:2px 2px 0 0}
.at-sub{background:rgba(245,158,11,.04);border-top:1px solid var(--divider);padding:0 12px}
.at-sub-label{font-size:11px;color:var(--warning);font-weight:700;text-transform:uppercase;opacity:.7;padding:8px 12px 0;letter-spacing:.8px}
.at-sub .at-bar{border-bottom:none}
.at-sub .at-tab{font-size:13px;min-height:40px;padding:0 16px;color:var(--text-secondary)}
.at-sub .at-tab.active{color:var(--warning);font-weight:700}
.at-sub .at-tab.active::after{background:var(--warning);height:2px;bottom:0;border-radius:2px 2px 0 0}

/* === Form Section (components) === */
.fs{background:var(--bg-paper);border-radius:16px;padding:24px;border:1px solid var(--divider);margin-bottom:16px}
.fs-header{display:flex;align-items:center;gap:12px;justify-content:space-between;margin-bottom:20px}
.fs-title-group{display:flex;align-items:center;gap:12px}
.fs-icon{display:flex;align-items:center;justify-content:center;color:var(--text-secondary)}
.fs-icon svg{width:20px;height:20px}
.fs-title{font-size:16px;font-weight:700;color:var(--text-primary)}
.fs-divider{height:1px;background:var(--divider);margin-bottom:24px}

/* === Address Section (components) === */
.addr-icon{width:36px;height:36px;border-radius:8px;background:rgba(74,222,128,.1);display:flex;align-items:center;justify-content:center;flex-shrink:0}
.addr-icon svg{width:22px;height:22px;color:var(--primary)}
.addr-grid{display:grid;gap:16px;grid-template-columns:repeat(3,1fr)}
.addr-row-first{display:grid;gap:16px;grid-template-columns:1fr 2fr}

/* === Auditoria (components) === */
.aud-card{background:var(--bg-paper);border-radius:24px;padding:20px;display:flex;flex-direction:column;gap:9.6px;height:100%;box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -2px rgba(0,0,0,.1)}
.aud-icon{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.aud-icon svg{width:18px;height:18px}

/* ==========================================================================
   === Responsive (5 media queries) ===
   3 do admin-light + 2 do ui-components — as 2 do ui-components (responsivo de
   modal, drawer e toast) o WMS perdeu e nunca repôs.
   Breakpoints alinhados à escala comum 1024/640 (originais: 1200/768/480 no
   admin-light, 600 e 768 no ui-components). Os quatro blocos @640 que a
   remapeação produziu foram FUNDIDOS num só, para a ordem de cascata ser
   explícita e o diff futuro ser legível.
   Degraus de grid preservados como na fonte: .fp-g 5 -> 2 -> 1, .fg3 3 -> 2 -> 1.
   ========================================================================== */

/* 1 — admin-light @1200 -> 1024: sidebar recolhe sozinha */
@media(max-width:1024px){
  /* ── Sidebar vira DRAWER de 1024px para baixo ──────────────────────────────
     Estava em @640 e o bloco @1024 recolhia a sidebar num trilho de 72px com
     .sg-items{display:none}. Resultado medido: entre 641 e 1024px os 17
     sub-itens ficavam INALCANCAVEIS clicando — o .mob-toggle so aparecia a
     <=640, e clicar no toggle so trocava um esconderijo por outro. A faixa
     nao e exotica: iPad em paisagem, MacBook com zoom, janela lado a lado.
     E a mesma faixa causava tooltip sem tooltip, caret esmagando o icone e
     nenhum item aceso, porque TODAS as afordancias de sidebar recolhida
     dependem da classe .mini, que a recolha automatica nunca aplicava.
     O trilho automatico foi removido: quem quiser recolher clica no toggle
     (>1024, onde .mini vale), e abaixo disso existe o drawer inteiro, com
     rotulo e acordeao. */
  /* visibility:hidden tira o drawer fechado da ORDEM DE TABULACAO. So mover
     com left:-300px o esconde do olho e nao do teclado: medido, 33 dos 42
     focaveis da pagina ficavam fora da tela mas tabulaveis, e quem navega so
     por teclado apertava Tab 33 vezes vendo o foco sumir antes do 1o controle.
     A transicao inclui visibility para o drawer nao piscar ao abrir. */
  .S{visibility:hidden;position:fixed;top:0;left:-300px;width:280px!important;height:100vh!important;border-radius:0 24px 24px 0;z-index:100;padding:24px 14px!important;transition:left .3s ease,visibility 0s linear .3s}
  .S.mob-open{left:0;visibility:visible;transition:left .3s ease,visibility 0s}
  .S .S-lg span{display:inline!important}
  /* :not(.tip) obrigatório — sem ele o !important vence .si .tip{display:none}
     e TODOS os tooltips ficam presos visíveis ao lado dos itens */
  .S .si span:not(.tip){display:inline!important}
  .S .si{justify-content:flex-start!important;padding:10px 14px!important}
  .S .sg-items{display:flex}
  .S .sg-caret{display:block}
  .S .S-ct{display:block!important}
  .S .S-toggle{display:none}
  .S-overlay.show{display:block}
  .mob-toggle{display:flex}
  .L{padding:8px;gap:8px}
  /* do bloco @768 da fonte — a busca do topo encolhe antes de sumir */
  .T-s{width:180px}
  /* degrau intermediário de grid, herdado do @768 da fonte */
  .fg3{grid-template-columns:1fr 1fr}
  .fp-g{grid-template-columns:1fr 1fr}
}

/* 2 — bloco único @640: admin-light @768 + @480, ui-components @600 + @768 */
@media(max-width:640px){
  /* O drawer da sidebar subiu para o bloco @1024 — ver o comentario la.
     Aqui fica so o que e especifico de telas estreitas. */
  .S{width:86vw!important;max-width:300px}
  /* admin-light @480 — busca de topo some, grids em 1 coluna */
  .T-s{display:none}
  .fg3{grid-template-columns:1fr}
  .fp-g{grid-template-columns:1fr}
  /* ui-components @600 — overlays respiram */
  .toast{min-width:auto;max-width:calc(100vw - 40px)}
  .drawer{width:100%;max-width:100%}
  .modal{margin:16px;max-width:calc(100vw - 32px)}
  .etc{padding:18px}
  .etc-table-wrap{margin:16px -18px 0}
  /* ui-components @768 — grids de formulário e endereço em 1 coluna */
  .fg-grid.c2,.fg-grid.c3,.fg-grid.c4,.addr-grid,.addr-row-first,.param-grid{grid-template-columns:1fr}
}

/* === Movimento reduzido =====================================================
   O repo tinha 14 @keyframes e transicoes de 0,2-0,3s e NENHUMA regra de
   prefers-reduced-motion fora do login. Quem marca a preferencia no sistema
   costuma faze-lo por enjoo ou vertigem — nao e questao de gosto. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* === Promovidas do módulo (2º cadastro) ====================================
   Regras que nasceram como reset local numa view e apareceram DUPLICADAS em
   dois módulos. Duplicata em dois é coincidência; em três seria padrão tarde
   demais — a §5 proíbe inline style ad hoc justamente para isso.
   Pedidas pelo construtor, não inventadas por ele: view não escreve no DS. */

/* Stat card que navega: o card inteiro é o alvo do clique (A1), então precisa
   ser <a> sem herdar a cor e a caixa de link. */
a.sc-card{color:inherit;display:block}

/* Ausência de valor numa célula: itálico neutro, NUNCA vermelho. Campo
   opcional vazio não é erro — vermelho ali gasta o sinal onde ele importa. */
.c-cell-sub.empty-state-text{font-style:italic;font-size:12px}

/* Trava a 1ª coluna: sem isto uma razão social de 255 caracteres estica a
   célula e empurra as outras cinco para fora da tela (medido no 1º módulo). */
.etc-table .e-cell{max-width:320px}

/* .etc sem .etc-header: a listagem começa direto no cabeçalho da tabela, e
   sem o ajuste sobra uma faixa branca no topo do cartão. */
.etc-sem-header{padding-top:10px}
.etc-sem-header .etc-table-wrap{margin-top:0}

/* Header de formulário fixo no topo. Com ~19 campos e scroll longo, é o que
   evita rolar até o fim para salvar. */
.fmh{position:sticky;top:0;z-index:5}
a.fmh-btn-cancel{text-decoration:none}

/* Mensagem de erro de campo. --error-dark porque --error dá 3,76:1 em 11px. */
.form-hint.error{color:var(--error-dark);font-weight:600}

/* Modal aberto trava a rolagem do fundo. Sem isto a lista rola ATRAS do
   diálogo — o usuário move a página que não pode tocar e perde a referência
   de onde estava. `:has()` evita depender de JS lembrar de pôr e tirar classe
   no body, que e onde esse tipo de trava costuma quebrar. */
body:has(.overlay.show){overflow:hidden}


/* === Checkable Option Row (components) === */
/* Linha inteira clicavel para checkbox/radio com nome + descricao. O <label>
   embrulha caixa e texto: a area de clique deixa de ser os 18px da caixa.
   Nasce como classe do DS, e nao inline, porque foi pedida TRES vezes —
   `roles/permissions`, `users/form` e a tela de acessos. Padrao repetido em
   tres telas nao e detalhe de tela: e componente que faltou extrair, e o G2
   impede de nomea-lo enquanto nao existir aqui. */
.opt-list{display:flex;flex-direction:column;gap:8px}
.opt-row{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border:1.5px solid var(--divider);border-radius:12px;background:var(--bg-paper);cursor:pointer;transition:border-color .15s}
.opt-row:hover{background:var(--bg-hover)}
.opt-row:has(input:checked){border-color:var(--secondary)}
.opt-text{display:flex;flex-direction:column;gap:2px;min-width:0}
.opt-name{font-size:13px;font-weight:600;color:var(--text-primary)}


/* === Altura uniforme de controle (V-10) === */
/* Tres alturas na mesma linha: select 35px, input 36,5px, date 38,5px. A
   diferenca vinha de `padding:9px` mais a line-height propria de cada controle,
   e o `date` ainda tem a caixa nativa do WebKit por cima. Altura fixa com
   padding vertical zero deixa o browser centralizar os tres igual.
   `input.form-input` e nao `.form-input`: o campo de texto longo usa a MESMA
   classe num <textarea>, e altura fixa ali cortaria o conteudo. */
input.form-input,.form-select{height:38px;padding-top:0;padding-bottom:0}

/* === Empty state: respiro do CTA === */
/* Estava como `style="margin-top:8px"` repetido em 8 views. Era decisao de
   espacamento vivendo fora do DS — exatamente o que o G4 passou a tornar
   visivel, e a mesma causa da colisao de 0px do V-06: no dia em que alguem
   esquece o inline, o gap vai a zero. */
.empty-state .btn{margin-top:8px}
.empty-state .btn+.btn{margin-left:8px}

/* === Audit Stat Cards (components) === */
/* Cartao de LOG, e nao `.sc-card`: `.sc-card` e filtro clicavel e estes sao
   resumo — a divergencia esta assumida em
   `ai/decisions/2026-08-24-audit-stat-cards-nao-sao-sc-card.md`.
   Nascem como classe porque viviam em 13 `style=` inline no componente
   compartilhado de historico: divergencia assumida ainda precisa de vocabulario
   proprio, senao ela vira deriva silenciosa na proxima tela que copiar. */
.asc-grid{display:grid;gap:12px;margin-bottom:20px}
.asc-grid-2{grid-template-columns:repeat(2,1fr)}
.asc-grid-3{grid-template-columns:repeat(3,1fr)}
.asc-card{display:flex;align-items:center;gap:8px;padding:12px 16px;border-radius:12px}
.asc-card-ok{background:var(--success-light)}
.asc-card-info{background:var(--info-light)}
.asc-card-off{background:var(--error-light)}
.asc-value{font-size:18px;font-weight:800}
/* Eu criei esta familia a partir de 13 `style=` inline do componente de
   historico e ESQUECI o icone — ele continuava inline la, entao nao apareceu na
   extracao. Dois modulos ja o pediram. A cor vem do cartao por `currentColor`:
   o `.asc-card-ok` e os irmaos ja definem o tom, e repetir a cor aqui criaria
   duas fontes para a mesma decisao. */
.asc-icon{display:flex;align-items:center;color:currentColor;flex-shrink:0}
.asc-label{font-size:10px;color:var(--text-secondary)}

/* Icone do `.cib` em tom informativo. Nasce como classe porque o par
   `--info-light` + `--secondary` estava inline em TRES fichas — o G4 o
   listou, e repeticao em tres telas e componente que faltou extrair. */
.cib-icon-info{background:var(--info-light);color:var(--secondary)}
