.btn{display:inline-flex;align-items:center;gap:var(--sp-2);padding:var(--sp-15) var(--sp-4);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text);font-size:var(--fs-sm);cursor:pointer;transition:.12s;white-space:nowrap;font-family:inherit}
.btn:hover{border-color:var(--accent)}
.btn-primary{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:600}
.btn-primary:hover{background:var(--accent-hover);border-color:var(--accent-hover)}
.btn-danger{background:var(--danger);border-color:var(--danger);color:#fff}
.btn-danger:hover{opacity:.85}
.btn-sm{padding:var(--sp-1) var(--sp-3);font-size:var(--fs-xs)}
/* Botao SO de icone tem que ter a MESMA altura do botao de texto ao
   lado. [[Padrao_Tabela]]:397: "Mantem alinhamento vertical. Sem isso,
   uma linha com 2 icones fica desalinhada com uma de 3, e o olho perde
   o padrao da coluna." A fonte Phosphor declara line-height:1, entao a
   caixa de linha do icone nascia 5,5px menor que a do texto e a coluna
   de acoes desalinhava linha a linha. Medido em 02/11: 21px contra
   26,5px na mesma linha. Nao e altura fixa de proposito: herdando o
   line-height, os dois acompanham juntos se a escala de fonte mudar. */
.btn>i{line-height:inherit}
.btn-outline{background:transparent}
/* Dourado da marca (Calcular). O texto era branco: 2,65:1, o pior contraste
   do sistema. O dourado e cor RATIFICADA em 2026-07-29 e nao se mexe, entao
   quem muda e a letra - escuro em cima do dourado da 6,26:1.
   [[regua]] D5: *"no botao, escureca a cor ou troque o texto pra escuro"*. */
.btn-info{background:var(--gold);border-color:var(--gold);color:var(--text)}

.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:var(--sp-5);box-shadow:var(--shadow)}
.card-title{font-size:var(--fs-lg);font-weight:600;margin-bottom:var(--sp-4);padding-bottom:var(--sp-3);border-bottom:1px solid var(--border)}
.glass{background:var(--surface-glass);backdrop-filter:var(--blur);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-glass)}

.table-wrap{
  overflow-x:auto;
  -webkit-overflow-scrolling:touch;
  background:
    linear-gradient(to right, var(--surface) 30%, rgba(255,255,255,0)) left center / 20px 100% no-repeat,
    linear-gradient(to right, rgba(255,255,255,0), var(--surface) 70%) right center / 20px 100% no-repeat,
    linear-gradient(to right, rgba(15,23,42,.08), rgba(15,23,42,0)) left center / 12px 100% no-repeat,
    linear-gradient(to left, rgba(15,23,42,.08), rgba(15,23,42,0)) right center / 12px 100% no-repeat;
  background-attachment: local, local, scroll, scroll;
}
.table{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.table th,.table td{padding:var(--sp-2) var(--sp-3);text-align:left;border-bottom:1px solid var(--border)}
.table th{color:var(--text-dim);font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.5px;font-weight:600;white-space:nowrap;vertical-align:top}
.table tr:hover td{background:var(--bg-elev)}
.table .num{text-align:right}
/* Moeda vai no titulo da coluna, "(R$)", e nao em cada linha (pedido dela,
   2026-11-07). Numero nao quebra no meio e os digitos ficam em coluna. */
.table td.num{white-space:nowrap;font-variant-numeric:tabular-nums}
/* Tabela de itens da proposta: o cabecalho em 2 linhas devolve a largura que
   os titulos compridos tomavam, e o residuo para de virar uma torre. */
.table .col-residuo{min-width:180px}
/* Titulos da tabela de itens centralizados na coluna (pedido dela, 2026-11-07). */
/* `.table .num` (direita) tem mais peso que `.table--itens th`, entao as colunas
   numericas ficavam de fora; este seletor ganha dele. */
.table.table--itens th,.table.table--itens th.num{text-align:center}
.table .actions{text-align:right;white-space:nowrap}
.table--outros-itens{table-layout:fixed}
.table--outros-itens th:nth-child(1),.table--outros-itens td:nth-child(1){width:auto}
.table--outros-itens th:nth-child(2),.table--outros-itens td:nth-child(2){width:160px}
.table--outros-itens th:nth-child(3),.table--outros-itens td:nth-child(3){width:80px}
.table--outros-itens th:nth-child(4),.table--outros-itens td:nth-child(4){width:120px}

/* ── Padrao de tabela completo: card, menu sanduiche, filtro por coluna ──── */
/* Padrao_Cabecalho_da_Tabela: titulo+contagem+menu sao a 1a faixa DENTRO do
   card branco; o card NAO pode ter overflow:hidden (corta o popup do menu) -
   quem arredonda os cantos e o .table-wrap de dentro. */
.tabela-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius)}
.tabela-card > .table-wrap{border-radius:0 0 var(--radius) var(--radius)}
.tabela-card__head{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border)}
.tabela-card__titulo{font-size:var(--fs-base);font-weight:600;color:var(--text);margin:0}
.tabela-card__contagem{font-size:var(--fs-xs);color:var(--text-dim);margin-left:auto}
.tabela-card__head .ta-menu-wrapper{margin-left:var(--sp-2)}
.tabela-card__head .ta-menu-wrapper:first-of-type{margin-left:0}
/* Tabela sem contagem no cabecalho (paginacao no servidor: quem mostra o
   total e o rodape) - empurra o menu pra direita do mesmo jeito. */
.tabela-card__titulo + .ta-menu-wrapper{margin-left:auto}

.ta-menu-wrapper{position:relative}
.ta-menu-btn{width:32px;height:32px;display:grid;place-items:center;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);cursor:pointer;color:var(--text-dim)}
.ta-menu-btn:hover{border-color:var(--accent);color:var(--accent-text)}
.ta-menu-btn.ativo{border-color:var(--accent);color:var(--accent-text);background:var(--accent-soft)}
.ta-menu-btn i{font-size:18px}
/* Busca global da tabela ([[Padrao_Tabela]]:367): quem injeta a caixa e o
   componente, aqui dentro da faixa e logo depois do titulo. Altura 32px e a do
   `.ta-menu-btn` do lado, NAO a do campo de formulario (40px): a faixa do
   cartao e barra de ferramentas, e 40px aqui engordaria a faixa em 8px nas 13
   telas de uma vez. `flex` com base de 220px e `min-width` curto pra caixa
   encolher ANTES de empurrar o titulo - e o titulo que diz em qual tabela se
   esta buscando.

   Seletor com a faixa na frente de proposito: as regras base do `.input`
   (altura 40px, padding do campo de formulario) estao mais ABAIXO neste
   arquivo e venceriam por ordem com a mesma especificidade - a caixa nasceu
   com 40px na primeira medicao justamente assim. */
.tabela-card__head .ta-busca{flex:0 1 220px;width:220px;min-width:120px;
  height:32px;padding:var(--sp-1) var(--sp-25);font-size:var(--fs-sm)}
/* O X de limpar do `type=search` no WebKit nasce com margem propria e
   desalinha a caixa baixa. */
.ta-busca::-webkit-search-cancel-button{margin:0}

.ta-menu{position:absolute;top:100%;right:0;margin-top:var(--sp-15);min-width:200px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);display:none;z-index:60}
.ta-menu.aberto{display:block}
.ta-menu-item{display:flex;align-items:center;gap:var(--sp-25);padding:var(--sp-25) var(--sp-35);font-size:var(--fs-sm);cursor:pointer;color:var(--text)}
.ta-menu-item:hover{background:var(--bg);color:var(--accent-text)}
.ta-menu-item.ativo{color:var(--accent-text);font-weight:600}
.ta-menu-item i{font-size:16px;color:var(--text-dim)}
.ta-menu-item:hover i{color:var(--accent-text)}
.ta-menu-divider{height:1px;background:var(--border);margin:var(--sp-1) 0}

.ta-popup{position:absolute;top:100%;right:0;margin-top:var(--sp-15);min-width:280px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);display:none;z-index:60}
.ta-popup.aberto{display:block}
.ta-popup-cab{padding:var(--sp-3) var(--sp-35);border-bottom:1px solid var(--border);font-weight:700;font-size:var(--fs-sm);display:flex;align-items:center;gap:var(--sp-2);color:var(--text)}
.ta-popup-cab i{color:var(--accent-text)}
.ta-popup-corpo{max-height:280px;overflow-y:auto;padding:var(--sp-2) 0}
.ta-popup-linha{display:flex;align-items:center;gap:var(--sp-25);padding:var(--sp-2) var(--sp-35);font-size:var(--fs-sm);color:var(--text)}
.ta-popup-linha label{display:flex;align-items:center;gap:var(--sp-2);cursor:pointer;flex:1}
/* Nome da coluna no popup de ordenar. Era <label style="flex:1"> sem campo
   nenhum pra nomear - rotulo que nao rotula so confunde leitor de tela. */
.ta-popup-nome{flex:1}
.ta-popup-rodape{padding:var(--sp-25) var(--sp-35);border-top:1px solid var(--border);display:flex;gap:var(--sp-2);justify-content:flex-end}
.ta-popup-rodape button{padding:var(--sp-15) var(--sp-35);border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--surface);cursor:pointer;font-size:var(--fs-xs);font-weight:600;font-family:inherit}
.ta-popup-rodape button:hover{background:var(--bg)}
.ta-popup-rodape .ta-aplicar{background:var(--accent);color:#fff;border-color:var(--accent)}
.ta-popup-rodape .ta-aplicar:hover{background:var(--accent-hover)}

/* Padrao_Filtro_por_Coluna: linha "contem" dentro do thead, nasce fechada */
.tr-filtro{display:none}
.tr-filtro.aberta{display:table-row}
.tr-filtro th{padding:var(--sp-15) var(--sp-3);background:var(--surface)}
.tr-filtro input{width:100%;height:30px;padding:0 var(--sp-2);border:1px solid var(--field-border);border-radius:var(--radius-sm);font-size:var(--fs-xs);font-weight:400;text-transform:none;letter-spacing:normal;color:var(--text);font-family:inherit;box-sizing:border-box}
.tr-filtro input:focus{outline:none;border-color:var(--accent)}
.tr-filtro input::placeholder{color:var(--text-dim)}

/* Ordenacao clicando no header */
.table th[data-col-key]{cursor:pointer;user-select:none}
.table th[data-col-key]:hover{color:var(--text)}
.th-sort-seta{margin-left:var(--sp-1);font-size:10px}
.th-sort-num{margin-left:var(--sp-1);font-size:9px;background:var(--accent-soft);color:var(--accent-text);border-radius:999px;padding:0 5px;font-weight:700}

/* Slot de acao indisponivel: mesmo espaco, esmaecido, nunca some (Padrao_Tabela) */
.btn.btn-disabled{opacity:.4;cursor:not-allowed}
.btn.btn-disabled:hover{border-color:var(--border)}
/* Botao travado de verdade (atributo disabled) tinha a mesma cara do liberado:
   o Confirmar da importacao parecia clicavel antes de escolher o arquivo. */
.btn:disabled{opacity:.45;cursor:not-allowed}

/* Padrao_Estado_Vazio: substitui a tabela inteira quando nao ha linha nenhuma */
.vz{flex:1;min-height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--sp-6) var(--sp-45)}
.vz .vz-icone{font-size:40px;color:var(--text-dim);line-height:1;margin-bottom:var(--sp-4)}
.vz-titulo{margin:0;font-size:var(--fs-lg);font-weight:700;color:var(--text)}
.vz-sub{margin:7px 0 0;font-size:var(--fs-sm);color:var(--text-dim);line-height:1.5;max-width:400px}
/* Paragrafo que explica uma regra do sistema (hoje so em Perfis e
   Permissoes). O limite de 70 caracteres por linha e legibilidade, nao
   enfeite: linha longa demais faz o olho perder a volta. Estava escrito
   inline em duas vezes no template. */
.texto-apoio{font-size:var(--fs-sm);color:var(--text-dim);max-width:70ch}

/* O campo nao empurra mais espaco por conta propria: quem abre o vao e a
   fileira, e o campo solto segue o MESMO ritmo dela. Antes a fileira
   pedia 12px e cada campo somava 16px por baixo, entao a distancia na
   vertical dava 28px contra 12px na horizontal. Achado A9, 25/10. */
.field{margin-bottom:var(--sp-3)}
/* Rotulo de campo. [[Padrao_Formulario]]:17 manda 13px peso 600 SEM uppercase
   e SEM letter-spacing, e :21 chama o uppercase forcado de "padrao de sistema
   legado" - uppercase moderno so em grupo de menu, cabecalho de tabela e label
   de KPI. Era exatamente o que estava aqui (11px MAIUSCULO com letter-spacing).
   O C21 pediu a mesma coisa com outras palavras: "o cabecalho poderia ser ate
   uma especie de uma letra menor em negrito, e depois o conteudo numa outra".
   DESVIO DECLARADO de um passo: a nota diz 13px, aqui fica --fs-sm (12px),
   porque ela pediu o rotulo MENOR que o conteudo e o conteudo e --fs-base
   (13px). Pela hierarquia do CLAUDE.md, pedido da sessao vence convencao da
   vault; o que a nota condena - uppercase e letter-spacing - sai inteiro. */
/* `.rotulo-leitura` entra na MESMA regra, nao numa copia: e a legenda de um
   texto so-leitura (o responsavel que vem do Lead), que tem que ser
   indistinguivel de um rotulo de campo. Duas regras iguais viram duas regras
   diferentes na primeira vez que alguem mexe numa delas. */
.field label,.field .rotulo-leitura,.field .rotulo-vazio{display:block;font-size:var(--fs-sm);font-weight:600;color:var(--text-dim);margin-bottom:var(--sp-1)}
/* Asterisco de campo obrigatorio (A1). aria-hidden no HTML: leitor de tela
   lendo "Lead estrela" nao ajuda. A trava de verdade e no servidor
   (modules/propostas/obrigatorios.py). */
/* O asterisco NAO usa o vermelho. Decisao dela em 22/10: *"o vermelho
   deste sistema e so de excluir e cancelar"* - campo obrigatorio e
   atencao, nao perigo, e os dois falando a mesma lingua apagam a
   diferenca justamente onde ela importa. Fica no escuro do texto, que
   contrasta com o cinza do rotulo ao lado sem gritar. O dourado da marca
   foi considerado e reprovado: da 2,65:1 no branco, metade do piso de
   4,5:1, e o asterisco carrega informacao, nao e enfeite.
   Achado D8, 25/10. */
.obrigatorio{color:var(--text);font-weight:700;margin-left:var(--sp-05)}
/* Fundo e borda vem dos tokens de CAMPO, nao dos do cartao: o campo era
   branco igual ao cartao, com borda de 1,25:1. Achado 10, 25/10. */
.input,.textarea,.select-native{width:100%;padding:var(--sp-2) var(--sp-3);background:var(--field-bg);border:1px solid var(--field-border);border-radius:var(--radius-sm);color:var(--text);font-family:inherit;transition:.12s}
.input:focus,.textarea:focus,.select-native:focus{outline:none;border-color:var(--accent)}
/* O campo era o UNICO controle sem anel de foco: desligava o outline e
   trocava so a cor da borda. Quem navega por TAB perdia de vista onde
   estava. Mesmo anel do .sb-display, da caixa de marcar e do olho da
   senha. Achado I4, 25/10. */
.input:focus-visible,.textarea:focus-visible,.select-native:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* UMA altura e UM tamanho de fonte por fileira de formulario (achado 1 de
   25/10). [[Padrao_Formulario]]:13 - *"Todos os controles na MESMA altura
   (40px)."* - e :104 nao deixa margem: *"Nao 38px, nao 36px. 40px."*

   Era o que ela viu e descreveu como *"a fonte de datas parece maior do que
   as dos textos (vide exemplo da data PAGR x Consultor)"*: a data nao cresceu,
   o campo do lado e que era menor - o campo de texto nasce 13px sem altura
   declarada (altura = o que o conteudo pedir) e o seletor com busca nascia
   12px com 32px de altura. Lado a lado na mesma fileira, dois tamanhos e duas
   alturas.

   box-sizing:border-box porque a altura precisa CONTER a borda e o padding;
   sem isso 40px viram 58px e a fileira desalinha pro outro lado.

   DESVIO DECLARADO: [[Sistema_de_Estilos]] poe o campo em 14px. Aqui a
   fileira se unifica em --fs-base (13px), que e a escala deste projeto;
   subir a escala inteira e o achado 17 do plano (POLIMENTO), que ela ainda
   nao escolheu, e mudar so o campo criaria um terceiro tamanho.

   A area de texto longo fica FORA: Observacoes e Descricao crescem com o
   conteudo, e altura fixa ali seria defeito novo, nao conserto.

   EFEITO COLATERAL, declarado: dois campos moram dentro de celula de tabela -
   o valor em Parametros (`parametros/index.html:28`) e a quantidade das linhas
   que o `outros-itens.js` monta. Os dois sobem de ~35px pra 40px, e a linha da
   tabela acompanha. E de proposito: sao campos que a pessoa digita, e campo
   que se digita tem a altura de campo. Vale olhar em homologacao.

   O escopo NAO pode ser `.field .input`: a barra de filtros do Dashboard e da
   Purga usa `.filtro-bar__field`, nao `.field`, e ali tem campo ao lado de
   seletor com busca - escopar no `.field` deixaria aquelas duas barras com o
   mesmo defeito que esta sendo consertado aqui. */
.input,.select-native{height:40px;box-sizing:border-box;font-size:var(--fs-base)}
.textarea{resize:vertical;min-height:80px;font-size:var(--fs-base)}
/* Campo que nao se digita aqui: o dado vem de outro cadastro. Fundo chapado
   + cor apagada e o que faz a pessoa ver que o campo nao e dela ANTES de
   clicar. O fundo estava inline em duas telas (leads/cidades.html,
   leads/importacoes.html) e virou regra em 2026-10-21, quando os quatro campos
   do Responsavel no Cliente ficaram readonly: [[Sistema_de_Estilos]] diz que
   CSS mora em static/css, nao no template. A trava de verdade e no backend,
   nao aqui - [[Padrao_Mass_Assignment]] lista "confiar em disabled no <input>"
   como anti-padrao, e readonly cai no mesmo buraco. */
/* So-leitura: mais ESCURO que o editavel. Com o editavel virando cinza, o
   --bg de antes (#f6f8f6) ficaria mais CLARO que ele e inverteria o sinal. */
.input[readonly],.textarea[readonly]{color:var(--text-dim);background:var(--field-bg-ro);cursor:default}
/* Campo que o servidor recusou. O `autofocus` leva o cursor ate aqui; esta
   regra e o que faz a pessoa VER qual e, sem precisar reler a mensagem e
   procurar. Cor por token ([[Sistema_de_Estilos]]), nunca hex no template. */
.input[aria-invalid="true"],.textarea[aria-invalid="true"]{border-color:var(--danger);background:var(--danger-soft)}
.input[aria-invalid="true"]:focus,.textarea[aria-invalid="true"]:focus{border-color:var(--danger)}
.selectbusca .sb-display[aria-invalid="true"]{border-color:var(--danger);background:var(--danger-soft)}

/* Linha de ajuda colada no campo que ela governa. [[Tela_Nao_Tem_Manual]]
   proibe paragrafo explicando a tela no topo da pagina, e manda a informacao
   pro lugar onde a duvida existe: junto do controle, no momento do clique.
   Nasce em 2026-10-21 pro campo Observacoes, que grava texto que o cliente
   nunca le, e pro bloco do Responsavel, que agora vem do Lead. */
.field-hint{font-size:var(--fs-sm);color:var(--text-dim);line-height:1.45;margin:0 0 var(--sp-3)}
.field label+.field-hint{margin-top:calc(-1 * var(--sp-1));margin-bottom:var(--sp-2)}
/* Olho de ver a senha. A caixa e criada por senha-olho.js em volta do input:
   o botao fica DENTRO do campo, sem mudar a altura dele nem a linha do form
   ([[Padrao_Formulario]]: controle nenhum muda de altura por causa de icone).
   O padding a direita abre o espaco pro olho nao cobrir o que foi digitado. */
.senha-campo{position:relative;display:block}
.senha-campo .input{padding-right:38px}
.senha-olho{position:absolute;right:1px;top:1px;bottom:1px;width:36px;
  display:flex;align-items:center;justify-content:center;
  background:none;border:0;padding:0;cursor:pointer;
  color:var(--text-dim);font-size:16px;line-height:1;
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;transition:color .12s}
.senha-olho:hover{color:var(--text)}
.senha-olho:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}

/* Larguras de coluna e alinhamento do botao que estavam inline no template
   das tabelas de Acessorios/Suprimentos. [[Sistema_de_Estilos]]: nenhuma tela
   escreve CSS proprio. */
.table th.col-qtd{width:100px}
.table th.col-acao{width:50px}
/* Mais larguras de coluna que estavam escritas dentro do <th>, em quatro
   telas (purga, assessorias, listas de opcoes). [[Sistema_de_Estilos]]:14 -
   *"o hex nunca aparece na tela, so no arquivo de tokens"* - e a mesma
   logica vale pra medida: largura de coluna e decisao de estilo. */
.table th.col-check{width:40px}
.table th.col-ordem{width:80px}
.table th.col-acoes{width:140px}
.table th.col-padrao{width:140px}
/* Botao que mora DENTRO de uma fileira de campos (o Adicionar das tabelas de
   Acessorios e de Suprimentos) ou de uma barra de filtros (o Filtrar do
   Dashboard e da Purga) entra na mesma altura dos campos ao lado.

   Escopo pelo PAI de proposito: `.btn` solto NAO pode virar 40px, porque e o
   mesmo botao da topbar e da coluna de acoes da tabela, onde 40px estouraria
   a linha. Conferido: nenhum `.btn-sm` e filho direto de campo, entao a regra
   nao atropela o botao pequeno.

CORRIGIDO EM 02/11/2026: o paragrafo acima ja prometia a barra de filtros,
mas o seletor so cobria `.filtro-bar__field>.btn` - e nas 5 telas que tem
barra de filtros o Filtrar/Limpar/Adicionar e filho DIRETO da barra, sem
campo em volta. A regra nunca pegou neles. Medido no navegador: o Filtrar
da Lista de Propostas tinha 29px ao lado de dois controles de 40px, contra
[[Padrao_Formulario]]:13 - *"Todos os controles na MESMA altura (40px)"*.
Dai o `.filtro-bar>.btn`. Conferido que nenhum `.btn-sm` e filho direto da
barra. Medido nas 5: `>` so consertou duas. As outras tres envolvem o
botao de um jeito diferente - `.filtro-bar__field` numa, `.align-end`
noutras duas - e perseguir involucro e correr atras do proprio rabo. O
escopo passou a ser A BARRA, em qualquer profundidade: botao dentro de
barra de filtros E controle da fileira. O `:not(.btn-sm)` guarda o que o
paragrafo acima protegia, e tem teste cobrando que nenhum `.btn-sm` mora
dentro de barra de filtros (hoje sao 9 botoes, nenhum pequeno).

DIVIDA PAGA EM 02/11, no mesmo dia em que foi anotada: por um tempo este
seletor nomeou DUAS classes de barra, porque o Leads usava `.filtros` e o
resto `.filtro-bar` - e o Filtrar do Leads media 31,6px ao lado de um
campo de 40px justamente porque o seletor so conhecia a segunda. A
anotacao da divida dizia "sao 15 telas" e estava ERRADA: a varredura
achou UM template usando `.filtros` (`templates/leads/lista.html`), nunca
15 - chutei o tamanho em vez de contar. A classe foi apagada e o Leads
passou a `card filtro-bar mb-4`, que e a forma que o Dashboard e a Purga
ja usavam: uma classe de barra, como a [[Padrao_Barra_de_Filtros]]:187
manda (*"Um componente, nao seis copias"*). Tem teste cobrando que
`.filtros` nao volta. */
.field>.btn,.filtro-bar .btn:not(.btn-sm){height:40px;box-sizing:border-box}
/* O campo que e SO um botao ('Adicionar' de acessorios e suprimentos).
   Sem isso ele sobe pro topo da fileira e fica na linha dos ROTULOS, nao
   na dos campos. E o truque 3 do [[Padrao_Formulario]]:119 - *"o .campo
   do botao TAMBEM tem label (com &nbsp; invisivel). Isso garante que ele
   tenha a MESMA altura total"* - com uma diferenca: a nota usa um <label>
   vazio, e rotulo vazio e defeito de acessibilidade (o leitor de tela
   anuncia um rotulo que nao rotula nada). Aqui o espaco vem de um <span>
   marcado como decorativo: mesma altura, sem mentir pro leitor de tela. */
.field .rotulo-vazio::before{content:"\00a0"}
/* A fileira alinha pelo TOPO. Pedido dela em 25/10, com print da tela:
   o Consultor e a Assessoria Ambiental saiam da linha dos vizinhos.

   Ate 25/10 isso era `end`, citando [[Padrao_Formulario]]:115: *"o .ra-bar
   precisa alinhar pela BASE (flex-end). Assim controles ficam alinhados, e
   as labels (que podem variar de altura por wrap) ficam em cima"*. A nota
   esta certa PRA O CASO DELA: na .ra-bar todo campo e rotulo + controle de
   40px e NADA embaixo, entao a unica diferenca de altura vem de cima. Tanto
   que, quando um campo destoa (o botao, que nao tem rotulo), a nota nao
   muda o alinhamento - o truque 3 IGUALA a altura da caixa.

   Nos nossos formularios tem texto EMBAIXO do controle (o telefone e o
   e-mail do consultor, a ajuda do servico de precificacao). Nesse caso o
   `end` empurra o campo inteiro pra cima e e o ROTULO que sai da linha,
   que e o que ela viu. Pelo topo os rotulos se encontram, e os controles
   tambem, porque todo controle desta fileira tem a mesma altura de 40px.

   O que o topo NAO cobre e o caso da nota: rotulo que quebra em duas
   linhas derruba so aquele controle. Medido antes de trocar: nenhum
   rotulo quebra na largura de desktop, e abaixo de 880px a fileira vira
   uma coluna so, onde nao existe vizinho pra desalinhar. */
.field-row{display:grid;gap:var(--sp-3);align-items:start;margin-bottom:var(--sp-3)}
.field-row .field{margin-bottom:0}
.field-row.cols-2{grid-template-columns:1fr 1fr}
.field-row.cols-3{grid-template-columns:1fr 1fr 1fr}
.field-row.cols-4{grid-template-columns:1fr 1fr 1fr 1fr}

/* Pastilha de situacao nao quebra linha (decisao da Claucia, 02/11). Medido:
   'Aguardando aprovacao' vinha em DUAS linhas, 37px contra 20,5px das
   outras, e era ela que esticava a altura da linha inteira da tabela.
   Situacao e rotulo curto de uma palavra ou duas; pastilha que quebra
   parece campo de texto, nao etiqueta. */
.badge{display:inline-flex;align-items:center;padding:var(--sp-05) 9px;border-radius:999px;font-size:var(--fs-xs);font-weight:600;white-space:nowrap}
.badge-success{background:var(--success-soft);color:var(--success)}
.badge-danger{background:var(--danger-soft);color:var(--danger)}
.badge-warning{background:var(--warning-soft);color:var(--warning)}
.badge-info{background:var(--gold-soft);color:var(--gold)}
.badge-neutral{background:var(--neutral-soft);color:var(--text-dim)}
/* Tipo de AGR "Ajuste" (C19). Cor propria, nao reaproveita badge de situacao:
   situacao e tipo sao campos diferentes e aparecem lado a lado. */
.badge-ajuste{background:var(--cafe-soft);color:var(--cafe)}


/* ── Mobile/tablet (Responsividade_Sempre): formulario empilha, toque maior, sem zoom do iOS ── */
@media (max-width:880px){
  .field-row.cols-2,.field-row.cols-3,.field-row.cols-4{grid-template-columns:1fr}
  .input,.textarea,.select-native{font-size:16px}
  /* No toque a fileira inteira vai pra 44px, nao pra 40px. Se o campo comum
     ficasse nos 40px do desktop, ele ficaria 4px mais baixo que o campo de
     data, que o seletor com busca e que o botao - os tres ja estao em 44px
     aqui. Seria o mesmo defeito do achado 1, mudando de tela. */
  .input,.select-native{height:44px}
  /* iOS Safari: com a aparencia NATIVA, o input[type=date] ignora o tamanho que
     definimos e nasce mais alto/largo que os demais campos, com o valor
     centralizado e cortado. -webkit-appearance:none faz ele respeitar o box como
     um campo de texto; ai min-height:44px (altura de toque, igual ao SelectBusca)
     casa com o campo Consultor. datetime-edit/value: zera padding e margem e
     alinha a esquerda. Especificidade element+attr+class vence a base .input;
     escopo so mobile, desktop intacto. */
  input[type="date"].input{-webkit-appearance:none;appearance:none;min-height:44px}
  input[type="date"].input::-webkit-datetime-edit{padding:0}
  input[type="date"].input::-webkit-date-and-time-value{text-align:left;margin:0;line-height:normal}
  /* NOTA: os overrides mobile do SelectBusca (sb-search 16px anti-zoom iOS e
     sb-display/sb-opt 44px de toque) NAO ficam aqui: as regras base do .selectbusca
     estao mais ABAIXO no arquivo e, com mesma especificidade, venceriam por ordem.
     Ficam no @media do fim do arquivo, depois da base. */
  .btn{min-height:44px;padding:var(--sp-25) var(--sp-4)}
  .btn-sm{min-height:40px;padding:var(--sp-2) var(--sp-3)}
  /* [[Padrao_Barra_de_Filtros]]:384 - no estreito os chips quebram em linha e o
     wrapper solta a altura fixa, senao a fileira de 6 vaza a tela. Chip no
     toque vai pra 40px, pela mesma razao do `.btn-sm` da linha de cima. */
  .periodo-chips{flex-wrap:wrap;height:auto}
  /* Mesma coisa na faixa do cartao de tabela: a caixa de busca de 220px ao
     lado do titulo, da contagem e do menu nao cabe em 375px, e o que sobraria
     dela era uma caixa de tres caracteres. A faixa quebra e a caixa pega a
     linha toda, e a altura vai pros 44px de toque junto com os outros
     campos - aqui escrita na mao porque o seletor da base e mais especifico
     que o `.input` daqui de cima e venceria. */
  .tabela-card__head{flex-wrap:wrap}
  .tabela-card__head .ta-busca{flex-basis:100%;width:100%;min-width:0;
    height:44px}
  .periodo-chip{height:40px}
  .periodo-vazio{height:auto}
  .flex{flex-wrap:wrap}
  .modal-overlay{padding:var(--sp-3)}
  .login-shell{padding:var(--sp-3)}
}

.flash{padding:var(--sp-3) var(--sp-4);border-radius:var(--radius-sm);margin-bottom:var(--sp-3);font-size:var(--fs-sm)}
/* `.flash-msg` e a MENSAGEM (a que vem do flash do Flask ou do erro de salvar),
   nao o painel explicativo fixo que usa a mesma caixa. So a mensagem ganha X e
   cronometro: painel de tela nao se fecha nem se apaga sozinho. */
.flash-msg{position:relative;padding-right:calc(var(--sp-4) + var(--sp-45))}
/* X do aviso que nao some sozinho (erro e aviso). `position:absolute` em vez de
   flex no `.flash`: flex no pai anularia o atributo `hidden` dos avisos de
   modal em aprovacoes.html, que nascem escondidos. */
.flash-fechar{position:absolute;top:var(--sp-2);right:var(--sp-3);background:none;border:0;padding:0;line-height:1;color:inherit;cursor:pointer;opacity:.65;font-size:var(--fs-lg)}
.flash-fechar:hover{opacity:1}
.flash-fechar:focus-visible{outline:2px solid currentColor;outline-offset:2px;border-radius:var(--radius-sm)}
/* A mesma frase do aviso, embaixo do campo que segurou o salvamento. */
.field-erro{margin-top:var(--sp-1);font-size:var(--fs-xs);color:var(--danger)}
.flash.success{background:var(--success-soft);color:var(--success);border-left:3px solid var(--success)}
.flash.error{background:var(--danger-soft);color:var(--danger);border-left:3px solid var(--danger)}
.flash.warning{background:var(--warning-soft);color:var(--warning);border-left:3px solid var(--warning)}

.modal-overlay{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);z-index:100;align-items:center;justify-content:center}
.modal-overlay.open{display:flex}
/* Tamanho do modal NAO mora aqui: fica no bloco de tamanhos mais abaixo, em
   vw/vh (Padrao_Modal). `max-width:100%` segura o modal dentro do padding do
   overlay no celular, senao 96vw + padding das duas bordas passa de 100vw e
   aparece rolagem horizontal. */
.modal{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--sp-5);max-width:100%;overflow-y:auto;box-shadow:var(--shadow-glass)}
.modal-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--sp-4);padding-bottom:var(--sp-3);border-bottom:1px solid var(--border)}
.modal-close:not(.btn){background:none;border:none;color:var(--text-dim);cursor:pointer;font-size:18px;padding:0 var(--sp-2)}
/* Rodape do modal. [[Padrao_Modal]]:76-79 - "Botao primario SEMPRE a direita.
   Botao secundario (Cancelar) a ESQUERDA do primario. Estrutura:
   display:flex; justify-content:flex-end; gap:10px". Era `flex-between`, que
   atira o Cancelar pro canto oposto: num modal de 55vw o par de acoes some em
   duas pontas da tela. No celular vira coluna, Salvar em cima. */
.modal-acoes{display:flex;justify-content:flex-end;gap:var(--sp-3);margin-top:var(--sp-4);flex-wrap:wrap}
@media (max-width:640px){
  .modal-acoes{flex-direction:column-reverse}
  .modal-acoes>.btn{width:100%;justify-content:center}
}

.divider{border:none;border-top:1px solid var(--border);margin:var(--sp-4) 0}
.text-dim{color:var(--text-dim)}
.text-sm{font-size:var(--fs-sm)}
.text-xs{font-size:var(--fs-xs)}
.text-right{text-align:right}
.mt-2{margin-top:var(--sp-2)}
.mt-3{margin-top:var(--sp-3)}
.mt-4{margin-top:var(--sp-4)}
.mb-4{margin-bottom:var(--sp-4)}
.flex{display:flex}
.flex-between{display:flex;justify-content:space-between;align-items:center}
.flex-wrap{flex-wrap:wrap}
.items-center{align-items:center}
.gap-1{gap:var(--sp-1)}
.gap-2{gap:var(--sp-2)}
.gap-3{gap:var(--sp-3)}
.wrap{flex-wrap:wrap}

.breakdown-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:var(--sp-2);font-size:var(--fs-xs)}
.breakdown-cell{background:var(--bg-elev);border-radius:var(--radius-sm);padding:var(--sp-2) var(--sp-3)}
.breakdown-cell .lbl{color:var(--text-dim);margin-bottom:var(--sp-05)}
.breakdown-cell .val{font-weight:700;font-size:var(--fs-sm)}
.breakdown-cell.pv{border:1px solid var(--accent);background:var(--accent-soft)}
.breakdown-cell.pv .val{color:var(--accent-text)}

.tab-bar{display:flex;gap:0;border-bottom:1px solid var(--border);margin-bottom:var(--sp-4)}
.tab-btn{padding:var(--sp-2) var(--sp-4);font-size:var(--fs-sm);background:none;border:none;color:var(--text-dim);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px}
.tab-btn.active{color:var(--accent-text);border-bottom-color:var(--accent);font-weight:600}
.tab-pane{display:none}
.tab-pane.active{display:block}

/* Loading (spinner + texto). Ver Padrao_Loading_Estado.md */
@keyframes spinner-rotate{to{transform:rotate(360deg)}}
.loading-inline{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-35);padding:60px var(--sp-45);background:var(--surface);border-radius:var(--radius-sm);text-align:center}
.spinner-circle{width:44px;height:44px;border:4px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spinner-rotate .8s linear infinite}
.loading-text{font-size:var(--fs-sm);font-weight:600;color:var(--text)}
.loading-inline--compacto{padding:var(--sp-45)}
.loading-inline--compacto .spinner-circle{width:24px;height:24px;border-width:3px}
.loading-inline .erro{color:var(--danger);font-weight:600}

/* Modal de confirmacao (substitui window.confirm). Ver Sem_Popup_Nativo.md */
.modal-confirm-msg{margin:0 0 var(--sp-4);color:var(--text);line-height:1.5}
.modal-confirm-acoes{display:flex;gap:var(--sp-3);justify-content:flex-end}
/* Tamanhos do modal em vw/vh, nunca em px (Padrao_Modal, regra inegociavel 1:
   "Tamanho sempre em vw/vh, nunca em px. Se calibrar em px numa tela
   especifica, quebra em qualquer outra resolucao"). Sequencia 34-55-89, razao
   aurea entre si. Modal sem classe de tamanho cai no medio, que e o default
   seguro da nota. */
.modal--w-sm{width:34vw;max-height:42vh}
.modal--w-md{width:55vw;max-height:70vh}
.modal--w-lg{width:89vw;max-height:90vh}
.modal:not(.modal--w-sm):not(.modal--w-md):not(.modal--w-lg){width:55vw;max-height:70vh}

/* Notebook (881-1280px): o medio fica intermediario. O seletor nomeia so o
   medio e o fallback de proposito: um `.modal` generico aqui venceria por
   ordem e esticaria tambem o pequeno e o grande. */
@media (max-width:1280px){
  .modal--w-md,
  .modal:not(.modal--w-sm):not(.modal--w-md):not(.modal--w-lg){width:68vw}
}

/* Celular (<=880px): tudo quase tela cheia, com margem minima. */
@media (max-width:880px){
  .modal--w-sm,
  .modal--w-md,
  .modal--w-lg,
  .modal:not(.modal--w-sm):not(.modal--w-md):not(.modal--w-lg){width:96vw;max-height:92vh}
}
.field--span2{grid-column:span 2}
.field--span3{grid-column:span 3}
/* Caixa com a largura de UMA coluna dentro de um campo que ocupa DUAS: o
   numero e curto, o texto de ajuda embaixo e que precisa da largura toda.
   Janela do Usuario, Desconto maximo (05/11/2026). */
.input--uma-coluna{width:calc((100% - var(--sp-3)) / 2)}
/* Interruptores empilhados e alinhados pela esquerda (janela do Usuario). */
.toggles-grupo{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-15)}
@media (max-width:880px){
  /* No celular a grade vira uma coluna so. Campo com span 2 ou 3 ali criava
     uma coluna fantasma e deixava o campo vizinho mais estreito (o Codigo da
     janela do Usuario saia menor que o Nome). */
  .field--span2,.field--span3{grid-column:auto}
  .input--uma-coluna{width:100%}
}

/* Utilitarios que substituem style= inline (Sistema_de_Estilos) */
.topbar-form-inline{display:inline}
.form-inline{display:inline}
.erro-page{text-align:center;padding:80px 0}
.erro-page__icon{font-size:64px;color:var(--danger);display:block;margin-bottom:var(--sp-4)}
.erro-page__msg{margin-top:var(--sp-2)}
.erro-page__voltar{margin-top:var(--sp-5);display:inline-flex}

/* Barra de filtros inline (substitui style="flex-wrap:wrap;align-items:flex-end") */
.filtro-bar{display:flex;gap:var(--sp-3);flex-wrap:wrap;align-items:flex-end}
.filtro-bar__field{margin:0}
.filtro-bar__field--grow{flex:1;min-width:160px}

/* Celula vazia em tabela (substitui style="text-align:center;padding:var(--sp-5)") */
.empty-cell{text-align:center;padding:var(--sp-5);color:var(--text-dim)}
.empty-cell--sm{padding:var(--sp-4)}

/* Field / bloco compacto (substitui style="max-width:200px", etc) */
.field--w-200{max-width:200px}
.field--w-320{max-width:320px}
.field--w-160{max-width:160px}

/* Container inline generico (substitui varios display:flex; gap; align-items) */
.row-gap-2{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap}
.row-gap-3{display:flex;gap:var(--sp-3);align-items:center;flex-wrap:wrap}
.row-gap-4{display:flex;gap:var(--sp-4);align-items:center;flex-wrap:wrap}
.grow-1{flex:1}
.mt-1{margin-top:var(--sp-1)}
.mt-2{margin-top:var(--sp-2)}
.mt-3{margin-top:var(--sp-3)}
.mt-4{margin-top:var(--sp-4)}
.mt-5{margin-top:var(--sp-5)}
.mt-6{margin-top:var(--sp-6)}
/* .mb-2 faltava na familia: `detalhe.html:139` e `:157` (os titulos
   "Acessorios e Equipamentos" e "Outros Servicos e Suprimentos") pediam a
   classe, o CSS nao tinha a regra, e os dois titulos ficavam encostados na
   tabela de baixo. Classe escrita no HTML sem regra no CSS nao da erro
   nenhum: a tela so nasce crua, e e invisivel na revisao de codigo. */
.mb-2{margin-bottom:var(--sp-2)}
.mb-3{margin-bottom:var(--sp-3)}
.text-center{text-align:center}
.text-right{text-align:right}
.vl-total-destaque{font-size:var(--fs-lg);font-weight:700;color:var(--accent-text)}
.form-acoes-rodape{flex-wrap:wrap;gap:var(--sp-3)}
.text-accent-bold{font-weight:700;color:var(--accent-text)}
.text-lg-strong{font-size:var(--fs-lg);font-weight:600}
.text-lg-accent{font-size:var(--fs-lg);font-weight:700;color:var(--accent-text)}
.text-warning{color:var(--warning)}
.text-success{color:var(--success)}
.text-danger{color:var(--danger)}
.col-w-200{width:200px}
.input-num-right{text-align:right}
/* Quantidade em linha de tabela: cabe 3 digitos e nao empurra a coluna
   de acoes pra fora. Era style="width:80px" escrito no JS. */
.input-qtd{width:80px}
.card--w-sm{max-width:420px}
.card--w-md{max-width:560px}
.card--w-lg{max-width:680px}
.filtro-bar__field--grow-lg{flex:1;min-width:240px}
/* [[Acao_Primaria_a_Direita]]:14 - *"O botao que executa a acao principal
   de um bloco fica ancorado na DIREITA daquele bloco, sempre, seja ele
   barra de filtro, formulario, rodape de modal, topbar ou linha de
   upload."*

   `.align-end` sozinho e `align-self:flex-end`, que alinha na VERTICAL e
   nao faz nada na horizontal. Ele e a opcao 1 do
   [[Padrao_Barra_de_Filtros]]:358, copiada ao pe da letra - e e exatamente
   o furo que a [[Acao_Primaria_a_Direita]] nasceu pra fechar (:129:
   *"PROIBIDO copiar bloco de CSS de nota de componente sem conferir se a
   acao primaria dele esta ancorada"*).

   Medido no Dashboard em 02/11: a barra tem 1164px, os 5 campos ocupam a
   primeira linha, e o grupo Filtrar/Limpar quebrava pra segunda linha
   ENCOSTADO NA ESQUERDA, a 995px da borda direita. E o mesmo retrato do
   caso que a nota conta na :89, dos 972px.

   `margin-left:auto` no grupo (e nao `justify-content` na barra, que
   empurraria os campos tambem) come a folga a esquerda dele, em qualquer
   linha que ele caia. E a tecnica que a propria nota lista na :55 pro
   grupo de acao. O grupo e o ULTIMO filho, entao nao cai na armadilha da
   :94 (*"o elemento com margin-*:auto vem ANTES do que deve encostar na
   borda"*).

   O `display:flex;gap` entra junto porque o grupo era `display:block`: a
   folga entre Filtrar e Limpar era de 3,6px, o espaco da quebra de linha
   do HTML, nao um vao escolhido. */
/* ── Seletor de periodo (templates/_periodo.html) ──────────────────────
   [[Padrao_Barra_de_Filtros]]:153 - *"Chips ou select: decide a largura, nao o
   gosto"*: chip em linha quando o filtro mora numa barra com a largura da
   pagina (o caso do Dashboard e da Purga), SelectBusca quando mora em popover
   ou coluna estreita (~325px). Aqui e barra larga, entao chip.

   O CSS da nota (:210-243) vem com os valores do DataEvo (`--fu-h: 38px`,
   `white`, `var(--cor-primaria)`). Traduzi pros tokens desta casa, que e o que
   a [[Sistema_de_Estilos]] manda - cor entra por token, nunca hex em arquivo
   de tela - e pra altura de controle DESTE sistema, 40px, a mesma do campo e
   do botao ao lado.

   :245 - *"sem o `height` no wrapper `.fu-presets`, a fileira de mini-botoes
   'engorda' mais que os inputs e desalinha tudo"*. Dai o `height:40px` no
   `.periodo-chips`, e nao so nos chips. */
.periodo-chips{display:inline-flex;align-items:center;gap:var(--sp-1);height:40px;padding:3px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);box-sizing:border-box}
.periodo-chip{height:32px;border:1px solid transparent;background:transparent;border-radius:var(--radius-sm);padding:0 var(--sp-25);font:inherit;font-size:var(--fs-sm);font-weight:600;color:var(--text-dim);cursor:pointer;white-space:nowrap}
.periodo-chip:hover{color:var(--accent-text)}
.periodo-chip.on{border-color:var(--accent);background:var(--accent-soft);color:var(--accent-text)}
/* O estado em que o Limpar deixa o seletor (:164). Fica na linha do campo, nao
   do rotulo, pra nao empurrar a fileira. */
.periodo-vazio{display:inline-flex;align-items:center;height:40px;margin-left:var(--sp-2);font-size:var(--fs-sm);color:var(--text-dim)}
.filtro-bar>.align-end{display:flex;gap:var(--sp-2);margin-left:auto}
.align-end{align-self:flex-end}
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:var(--sp-3);align-items:start}
.kpi-val--lg{font-size:var(--fs-xl);font-weight:800;line-height:1.1;letter-spacing:-.5px;font-variant-numeric:tabular-nums;margin-top:var(--sp-1);word-break:break-word}
.kpi-val--accent{color:var(--accent-hover,var(--accent))}
.kpi-val--warning{color:var(--warning)}
.kpi-val--success{color:var(--success)}

/* Seções do formulário grande (proposta form.html tinha bloco <style> proprio) */
/* Titulo de bloco, achado 13 (25/10). Tinha --fs-sm, o MESMO tamanho do
   rotulo do campo, em verde e em maiusculas: nada ali dizia 'isto e um
   titulo'. Agora e maior (--fs-lg) e escuro, e o verde da marca saiu da
   letra e virou um filete antes do texto - marca o bloco em vez de
   disputar a leitura com o texto.
   Maiuscula saiu por [[Padrao_Formulario]]:20 - *"uppercase forcado com
   peso 700-800 e padrao de sistema legado"* - e :25-27 so admite
   maiuscula em grupo de menu, cabecalho de tabela e rotulo de KPI. */
.section-title{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-lg);font-weight:700;color:var(--text);margin:var(--sp-5) 0 var(--sp-3);padding-bottom:var(--sp-2);border-bottom:1px solid var(--border)}
/* Filete da marca. Fica a ESQUERDA do texto, nao em border-left: com o
   border-bottom do titulo, a borda da esquerda fecharia um 'L'. */
.section-title::before{content:"";flex:0 0 auto;width:var(--sp-1);height:1em;background:var(--accent);border-radius:var(--radius-sm)}
/* Titulo verde com pipe, SO na proposta (Editar e Ver proposta), 05/11/2026.
   Pedido do cliente: o texto do titulo na MESMA cor verde do pipe. Fica numa
   classe a parte porque a Claucia decidiu que as outras telas com
   .section-title (Dashboard, Textos padrao, Listas de opcoes, Importacoes)
   continuam com o texto escuro de 25/10.
   Texto e pipe usam o MESMO token, --accent-text (6,34:1 contra o branco),
   que e o verde que tokens.css reserva pra quando o verde e LETRA.
   Vale em .section-title e em .card-title (a tela Ver proposta usa o
   segundo). Trancado em tests/aceitacao/test_janela_usuario_e_titulos_da_proposta.py. */
.titulo-marca{display:flex;align-items:center;gap:var(--sp-2);font-weight:700;color:var(--accent-text)}
/* Subtitulo dentro de um bloco (Adicionar Item, Acessorios, Outros Servicos):
   mesmo verde e mesmo pipe, um degrau menor que o titulo e sem a linha de
   baixo, pra hierarquia continuar clara. */
.subtitulo-marca{display:flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-base);font-weight:700;color:var(--accent-text)}
.titulo-marca::before,.subtitulo-marca::before{content:"";flex:0 0 auto;width:var(--sp-1);height:1em;background:var(--accent-text);border-radius:var(--radius-sm)}
/* Titulo que divide a linha com um valor (Itens do Servico + total em R$):
   o <h2> continua sendo o cabecalho da pagina pra leitor de tela, mas herda
   a letra do titulo do bloco; o valor vai pra ponta direita. */
.section-title__h{font:inherit;color:inherit;letter-spacing:inherit;margin:0}
.section-title__fim{margin-left:auto}
.itens-panel{background:var(--bg-elev,var(--surface));border:1px solid var(--border);border-radius:var(--radius);padding:var(--sp-4);margin-top:var(--sp-4)}
#breakdown{display:none;margin-top:var(--sp-3)}
.hidden{display:none!important}

/* Toast (aviso curto, sem popup nativo -- Sem_Popup_Nativo). Criado via window.toast
   em main.js, ancora no rodape e some sozinho. */
.toast-host{position:fixed;left:0;right:0;bottom:var(--sp-4);z-index:200;display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);padding:0 var(--sp-3);pointer-events:none}
.toast{max-width:440px;display:flex;align-items:center;gap:var(--sp-2);background:var(--text);color:#fff;padding:var(--sp-25) var(--sp-4);border-radius:var(--radius);font-size:var(--fs-sm);box-shadow:var(--shadow);opacity:0;transform:translateY(8px);transition:opacity .18s ease,transform .18s ease;pointer-events:auto}
.toast.show{opacity:1;transform:none}
.toast--success{background:var(--accent)}
.toast--error{background:var(--danger)}
.toast--warning{background:var(--warning)}
/* pulso no item recem-adicionado (feedback ao "Adicionar a proposta") */
@keyframes itemFlash{0%{box-shadow:0 0 0 2px var(--accent)}100%{box-shadow:0 0 0 0 rgba(0,0,0,0)}}
.item-flash{animation:itemFlash 1.4s ease-out}
.rm-label{display:none}  /* so aparece no cartao mobile (regra no @media abaixo) */

/* ── Tela de proposta no mobile (vendedor: tela mais usada no celular) ──
   A tabela de itens tem 8 colunas; no celular o vendedor arrastava de lado pra ver
   valores e pra alcancar o "X" de remover. Vira CARTAO (1 item por bloco, rotulo a
   esquerda / valor a direita) com o remover sempre a mao. Divergencia CONSCIENTE do
   scroll-com-sombra default de Padrao_Tabela/Responsividade_Sempre: aqui e lista
   EDITAVEL e a acao de remover nao pode depender de arrastar (regra "acao sempre
   acessivel ao toque"). Desktop segue tabela normal (tudo isto e mobile-only). */
@media (max-width:880px){
  .itens-cards thead{display:none}
  .itens-cards,.itens-cards tbody,.itens-cards tr{display:block;width:auto}
  .itens-cards tr{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);padding:var(--sp-3);margin-bottom:var(--sp-3)}
  .itens-cards td{display:flex;justify-content:space-between;align-items:baseline;gap:var(--sp-3);border:none;padding:var(--sp-1) 0;text-align:right}
  .itens-cards td[data-label]::before{content:attr(data-label);font-weight:600;color:var(--text-dim);text-align:left;flex:0 0 auto}
  .itens-cards td.actions{justify-content:flex-end;padding-top:var(--sp-2);margin-top:var(--sp-2);border-top:1px solid var(--border)}
  .itens-cards td.actions .rm-label{display:inline;margin-left:var(--sp-1)}
  .itens-cards td.empty-cell,.itens-cards td[colspan]{justify-content:center;text-align:center}
  /* barra de acoes fixa: Salvar sempre a mao num form longo (fica abaixo do
     z-index do painel do SelectBusca=150, entao ele aparece por cima) */
  .form-acoes-rodape{position:sticky;bottom:0;background:var(--surface);border-top:1px solid var(--border);margin:var(--sp-4) calc(-1 * var(--sp-3)) 0;padding:var(--sp-3);z-index:15;box-shadow:0 -4px 16px rgba(20,30,25,0.06)}
  .toast-host{bottom:80px}
}

/* Login (login.html tinha bloco <style> proprio) */
.login-shell{display:flex;align-items:center;justify-content:center;min-height:100vh;background:var(--bg)}
.login-box{width:100%;max-width:380px;padding:var(--sp-6);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow)}
.login-logo{text-align:center;font-size:var(--fs-2xl);font-weight:700;color:var(--accent-text);margin-bottom:var(--sp-5);display:flex;align-items:center;justify-content:center;gap:var(--sp-2)}
.login-logo small{display:block;font-size:var(--fs-sm);color:var(--text-dim);font-weight:400;margin-top:var(--sp-1)}
/* C20: com logo da empresa a marca vira COLUNA - imagem em cima, frase
   embaixo. `.login-logo` e flex em linha, e a imagem ao lado do texto
   espremeria as duas. Sem logo nada disto se aplica e a tela fica igual. */
.login-logo--empresa{flex-direction:column;gap:var(--sp-2)}
/* `contain` pelo mesmo motivo da sidebar: logo deitado nao se corta. 220px
   cabem com folga nos 316px uteis do .login-box. */
.login-logo-img{display:block;max-width:220px;max-height:64px;object-fit:contain}
/* Previa do logo na tela de Empresa. Ate 25/10 a tela so tinha o campo de
   enviar arquivo: nao havia como conferir qual logo estava valendo. */
.logo-previa{display:inline-flex;align-items:center;justify-content:center;padding:var(--sp-2);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius)}
.logo-previa img{display:block;max-width:220px;max-height:64px;object-fit:contain}
.login-btn{width:100%;justify-content:center;margin-top:var(--sp-2)}

/* Linha com toggle + rotulo (helper) */
.toggle-linha{display:inline-flex;align-items:center;gap:var(--sp-2)}
.toggle-linha--stack{display:flex;margin-bottom:var(--sp-15)}
.toggle-linha__lbl{font-size:var(--fs-sm);color:var(--text)}
/* Quando a lista e de MARCAR (checkbox, nao switch), o rotulo e um <label> e
   precisa clicar junto com o quadradinho. Ver contentores.html. */
label.toggle-linha__lbl{cursor:pointer;margin:0}
.toggle-lista{display:flex;flex-direction:column;gap:var(--sp-1)}

/* Toggle On/Off (regra Padrao_Toggle_OnOff). Trio: span.cv-sw + input + label */
.cv-sw{position:relative;width:42px;height:24px;flex:0 0 auto;display:inline-block}
.cv-sw input{display:none}
.cv-sw label{position:absolute;inset:0;background:var(--border);border-radius:999px;cursor:pointer;transition:.15s;margin:0}
.cv-sw label::after{content:'';position:absolute;top:2px;left:2px;width:20px;height:20px;background:var(--surface);border-radius:50%;transition:.15s;box-shadow:0 1px 3px rgba(0,0,0,.25)}
.cv-sw input:checked + label{background:var(--accent)}
.cv-sw input:checked + label::after{transform:translateX(18px)}
.cv-sw input:focus-visible + label{outline:2px solid var(--accent);outline-offset:2px}

/* SelectBusca (regra Componente_SelectBusca). Substitui <select> nativo */
.selectbusca{position:relative;min-width:180px}
/* O controle que a pessoa ve e clica e este div, nao o input escondido: e aqui
   que a altura e o tamanho da letra tem que casar com o .input ao lado
   (era 32px/12px contra 40px/13px). box-sizing pro min-height conter borda e
   padding, igual ao campo de texto. */
/* O MESMO contorno do .input: foi o achado 1 desta PR deixar os dois
   campos iguais; dar relevo a um so desfaria aquilo. */
.selectbusca .sb-display{padding:var(--sp-15) var(--sp-3);background:var(--field-bg);border:1px solid var(--field-border);border-radius:var(--radius-sm);cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:var(--sp-2);box-sizing:border-box;min-height:40px;font-size:var(--fs-base);color:var(--text)}
.selectbusca .sb-display:hover{border-color:var(--accent)}
.selectbusca .sb-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1 1 auto}
.selectbusca .sb-label.sb-placeholder{color:var(--text-dim)}
/* O painel e `fixed`, com `left`/`width`/`top` vindos do JS, e NAO `absolute`
   como prescreve [[Componente_SelectBusca]]:41-46. Divergencia decidida pela
   Claucia em 26/10/2026, com estes numeros na mesa:

   Caixa que rola recorta filho `absolute`. `.modal` tem `max-height:70vh` +
   `overflow-y:auto`, que e a regra 4 de [[Padrao_Modal]]:18 ("Altura limitada
   com scroll interno se conteudo longo"). Medido em 19/10: dentro do modal o
   painel de 280px passava 214px da borda e escondia 6 das 9 opcoes. Vale pros
   9 modais que tem SelectBusca dentro.

   A rota que a vault manda ([[Padrao_Modal_Popup_Centrado]]) e trocar o modal
   por `<dialog class="popup-centrado">` com `overflow:visible !important`.
   Aqui ela cobraria duas outras regras:

   1. tirar o `overflow` do modal tira a rolagem interna - a regra 4 acima. E
      medido em 26/10 num 1366x768, dois dos nove formularios ja passam do
      proprio teto: "Usuario" 683px contra 538px (70vh) e "Editar lead" 747px
      contra 691px (90vh, que e `.modal--w-lg`). Os dois perderiam o
      botao Salvar fora da tela, sem como chegar nele. Devolver a rolagem numa
      caixa interna recortaria o painel de novo: QUALQUER caixa entre a lista
      e a beira da tela que role, corta;
   2. `<dialog>.showModal()` fecha no ESC pelo navegador, e
      [[Padrao_Modal]]:22,:382 proibiu isso em 30/07/2026 ("modal de cadastro
      perde o que a pessoa digitou"). A nota do popup-centrado e de 29/06/2026
      e nunca foi reconciliada com essa regra.

   `z-index:150` fica acima do `.modal-overlay` (100) e abaixo do
   `.toast-host` (200): a lista cobre o modal, e o aviso cobre a lista. */
.selectbusca .sb-panel{position:fixed;z-index:150;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow);max-height:280px;overflow-y:auto;display:none}
.selectbusca.open .sb-panel{display:block}
.selectbusca.open .sb-display{border-color:var(--accent)}
.selectbusca .sb-search{width:100%;padding:var(--sp-2) var(--sp-3);background:var(--bg-elev,var(--surface));border:none;border-bottom:1px solid var(--border);color:var(--text);font-family:inherit;font-size:var(--fs-sm);box-sizing:border-box}
.selectbusca .sb-display:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.selectbusca .sb-search:focus{outline:none}
.selectbusca .sb-opt{padding:var(--sp-2) var(--sp-3);cursor:pointer;font-size:var(--fs-sm);color:var(--text)}
.selectbusca .sb-opt:hover{background:var(--accent-soft);color:var(--accent-text)}
.selectbusca .sb-opt.sb-selected{background:var(--accent-soft);color:var(--accent-text);font-weight:600}
.selectbusca .sb-empty{padding:var(--sp-3);color:var(--text-dim);font-size:var(--fs-sm);text-align:center}
.selectbusca[data-disabled="1"] .sb-display{background:var(--border);cursor:not-allowed;opacity:.6}

/* ── SelectBusca no mobile (vem DEPOIS da base acima pra vencer por ordem, ja que
   a especificidade e igual). Tela de proposta tem 14 desses menus. ── */
@media (max-width:880px){
  /* A) iOS da zoom no foco de input com font-size < 16px (Responsividade_Sempre).
     A busca do menu era 12px -> zoom em TODO menu aberto. */
  .selectbusca .sb-search{font-size:16px}
  /* B) Alvo de toque 44px (Responsividade_Sempre): a barra do menu ficava em 32px;
     as opcoes tambem crescem pra caber o dedo. */
  .selectbusca .sb-display{min-height:44px}
  .selectbusca .sb-opt{padding:11px var(--sp-3)}
}

/* ==========================================================================
   Matriz de permissoes (/admin/perfis)
   Um card por perfil, grade Funcionalidade x Acao.
   E checkbox e nao toggle por causa do teste do [[Padrao_Toggle_OnOff]]:
   "clicar nisso muda alguma coisa agora? Nao, so marca pra depois = checkbox"
   - aqui so grava no botao Salvar. Desenho do checkbox vem do
   [[Padrao_Selecao_em_Lote]] ("nunca o do sistema operacional").
   ========================================================================== */
.pf{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);margin-bottom:var(--sp-3);overflow:hidden}
.pf--travado{background:var(--navy-faint)}

.pf__head{width:100%;display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:none;border:0;font-family:inherit;font-size:var(--fs-base);color:var(--text);text-align:left;cursor:pointer}
.pf__head:hover{background:var(--bg-elev)}
.pf__head:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.pf__caret{flex:0 0 auto;color:var(--text-dim);transition:transform .15s}
.pf__head[aria-expanded="true"] .pf__caret{transform:rotate(90deg)}
.pf__nome{font-weight:600;flex:0 0 auto}
.pf__desc{color:var(--text-dim);font-size:var(--fs-sm);flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pf__meta{flex:0 0 auto;color:var(--text-dim);font-size:var(--fs-xs);white-space:nowrap}
.pf__tag{flex:0 0 auto;display:inline-flex;align-items:center;gap:var(--sp-1);padding:var(--sp-05) var(--sp-2);border-radius:999px;
  font-size:var(--fs-xs);font-weight:600;background:var(--gold-soft);color:var(--gold-text);white-space:nowrap}

.pf__corpo{padding:0 var(--sp-4) var(--sp-4);border-top:1px solid var(--border)}
.pf__corpo[hidden]{display:none}
/* Rodape de perfil sem usuario nenhum: nao leva o filete de cima (o bloco
   anterior ja terminou com um) nem o respiro do rodape normal. */
.pf__rodape--solto{border:0;padding-top:0;margin-top:var(--sp-2)}
.pf__aviso{display:flex;gap:var(--sp-3);align-items:flex-start;margin:var(--sp-4) 0;padding:var(--sp-3);
  border-radius:var(--radius-sm);background:var(--gold-soft);font-size:var(--fs-sm);line-height:1.5}
.pf__aviso i{color:var(--gold);flex:0 0 auto;font-size:18px}

.pf__barra{display:flex;flex-wrap:wrap;gap:var(--sp-2);align-items:center;margin:var(--sp-4) 0 var(--sp-3)}
.pf__barra-rot{font-size:var(--fs-xs);color:var(--text-dim);text-transform:uppercase;letter-spacing:.5px;font-weight:600}
.pf__rodape{display:flex;justify-content:flex-end;gap:var(--sp-2);margin-top:var(--sp-4);
  padding-top:var(--sp-3);border-top:1px solid var(--border)}

/* Grade. Primeira coluna fica fixa pra nome do menu nao sumir no scroll lateral. */
/* A grade ocupa o card inteiro: encolher ate o conteudo deixava meia tela vazia
   na direita e tudo grudado na esquerda.
   `table-layout:fixed` + porcentagem = largura decidida AQUI, nao pelo tamanho
   do texto de cada cabecalho; so assim as cinco colunas de acao saem iguais e os
   checkbox ficam numa fileira reta. Com layout automatico a coluna do nome
   engolia a folga e o primeiro Ver ia pro meio da tela.
   `min-width` segura o minimo legivel: abaixo disso a grade rola de lado. */
.pg-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-sm);
  max-width:100%}
.pg{width:100%;min-width:620px;table-layout:fixed;border-collapse:collapse;font-size:var(--fs-sm)}
.pg th,.pg td{padding:var(--sp-2) var(--sp-3);border-bottom:1px solid var(--border);text-align:center}
.pg thead th{position:sticky;top:0;background:var(--surface);color:var(--text-dim);font-size:var(--fs-xs);
  text-transform:uppercase;letter-spacing:.5px;font-weight:600;white-space:nowrap;z-index:2}
/* `.pg th` tem a mesma forca que `.pg__tela` sozinho e venceria o alinhamento:
   por isso a coluna da tela qualifica o elemento.
   30% cabe o nome mais longo do catalogo ("Assessorias Ambientais") com folga e
   ainda sobra o grosso da largura pras cinco colunas de acao. */
.pg th.pg__tela,.pg td.pg__tela{text-align:left;width:30%;
  padding-right:var(--sp-3);
  position:sticky;left:0;background:var(--surface);z-index:1}
.pg thead .pg__tela{z-index:3}
/* Coluna de acao: o checkbox tem 18px, o resto e respiro entre Ver/Criar/...
   14% x 5 = os 70% que sobram do nome, divididos em partes iguais: largura "do
   tamanho do texto" deixava Ver estreita e Importar larga, e a fileira de
   checkbox saia torta. */
.pg th.pg__col,.pg td.pg__col{width:14%;padding-left:var(--sp-2);padding-right:var(--sp-2);
  white-space:nowrap}
.pg tbody tr:hover td{background:var(--bg-elev)}
.pg tbody tr:hover .pg__tela{background:var(--bg-elev)}

.pg__grupo td{background:var(--navy-soft);text-align:left;padding:var(--sp-2) var(--sp-3)}
.pg__grupo:hover td{background:var(--navy-soft)}
.pg__grupo-linha{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.pg__grupo-nome{font-weight:700;font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.6px;color:var(--navy);min-width:110px}
/* Botao de grupo repete 7 vezes por card: discreto, pra nao competir com a grade. */
.pg__grupo .btn{padding:var(--sp-05) var(--sp-2);font-size:var(--fs-xs);color:var(--text-dim);background:transparent}
.pg__grupo .btn:hover{color:var(--text);background:var(--surface)}

/* Checkbox desenhado (Padrao_Selecao_em_Lote): o nativo muda de cara por SO. */
.chk{appearance:none;-webkit-appearance:none;width:18px;height:18px;margin:0;position:relative;
  border:1.5px solid var(--border);border-radius:5px;background:var(--surface);cursor:pointer;
  transition:background .12s,border-color .12s;vertical-align:middle}
.chk:hover{border-color:var(--accent)}
.chk:checked{background:var(--accent);border-color:var(--accent)}
.chk:checked::after{content:'';position:absolute;left:5px;top:1px;width:5px;height:10px;
  border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
.chk:indeterminate{background:var(--accent);border-color:var(--accent)}
.chk:indeterminate::after{content:'';position:absolute;left:3px;top:7px;width:10px;height:2px;
  background:#fff;border:0;transform:none}
.chk:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.chk:disabled{cursor:not-allowed;opacity:.55}
.chk:disabled:hover{border-color:var(--border)}

.pg__legenda{display:flex;align-items:center;gap:var(--sp-2);margin:var(--sp-2) 0 0;
  font-size:var(--fs-xs);color:var(--text-dim);flex-wrap:wrap}
.pg__arraste{display:none}

/* Celula que nao se aplica: apagada com tooltip, nunca vazia
   ([[Padrao_Tabela]], "slots fixos com esmaecimento"). */
.chk-na{display:inline-block;width:18px;height:18px;line-height:18px;color:var(--text-dim);
  opacity:.35;cursor:help;user-select:none;font-weight:700}

@media (max-width:720px){
  .pf__head{flex-wrap:wrap;padding:var(--sp-3)}
  .pf__desc{flex:1 1 100%;white-space:normal;order:9}
  .pf__corpo{padding:0 var(--sp-3) var(--sp-3)}
  .pg{font-size:var(--fs-base)}
  .pg th,.pg td{padding:var(--sp-3) var(--sp-2)}
  /* No celular a grade nao cabe inteira: ela vai ate o minimo e rola de lado,
     mantendo a mesma proporcao de colunas da tela grande. */
  .pg th.pg__tela,.pg td.pg__tela{padding-right:var(--sp-2)}
  /* No celular a grade so cabe rolando de lado, e sem mouse nao da pra
     descobrir isso por acidente: a legenda avisa. */
  .pg__arraste{display:inline;flex:1 1 100%}
  /* Alvo de toque (Responsividade_Sempre): 18px de desenho dentro de 24px de area. */
  .chk{width:22px;height:22px}
  .chk:checked::after{left:6px;top:2px;width:6px;height:12px}
}

/* ── Upload de arquivo (Padrao_Upload_Arquivo, prefixo im-) ─────────────────
   Arrastar e clicar no mesmo label; input de arquivo escondido fora da tela.
   Cor so por token: hex em template ou em CSS de tela e proibido
   ([[Sistema_de_Estilos]]). */
.im-lbl{display:block;font-size:var(--fs-xs);font-weight:700;text-transform:uppercase;
  letter-spacing:.5px;color:var(--text-dim);margin:var(--sp-4) 0 var(--sp-2)}

/* Pre-requisito: o que o arquivo representa. Radio de verdade escondido +
   label clicavel, pra funcionar no teclado e no leitor de tela. */
.im-opcs{display:flex;gap:var(--sp-3);flex-wrap:wrap}
.im-opc-inp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
.im-opc{flex:1 1 220px;display:block;border:1.5px solid var(--border);border-radius:var(--radius-sm);
  padding:var(--sp-3);cursor:pointer;transition:border-color .12s,background .12s}
.im-opc strong{display:block;font-size:var(--fs-sm)}
.im-opc small{display:block;color:var(--text-dim);font-size:var(--fs-xs);margin-top:var(--sp-05)}
.im-opc:hover{border-color:var(--accent)}
.im-opc-inp:checked + .im-opc{border-color:var(--accent);background:var(--accent-soft)}
.im-opc-inp:focus-visible + .im-opc{outline:2px solid var(--accent);outline-offset:2px}

.im-drop{display:block;border:2px dashed var(--border);border-radius:var(--radius-sm);
  padding:var(--sp-6) var(--sp-4);text-align:center;color:var(--text-dim);cursor:pointer;
  transition:.15s;user-select:none}
.im-drop:hover,.im-drop.over{border-style:solid;border-color:var(--accent);
  background:var(--accent-soft);color:var(--accent-text)}
.im-drop.loaded{border-style:solid;border-color:var(--accent);background:var(--accent-soft);
  color:var(--accent-text)}
/* Icone central de 36px que troca conforme o estado (regra 3 da nota). */
.im-drop i{font-size:36px;display:block;margin-bottom:var(--sp-2)}
.im-arq{display:block;margin-top:var(--sp-15);font-weight:600;color:var(--accent-text)}
/* Input nativo escondido fora da tela, nunca o visual do navegador (regra 2). */
.im-inp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}

/* Linha de acao: Confirmar ancorado a DIREITA e a mensagem a esquerda, pelo
   margin-right:auto dela (regras 6 e 6-B / [[Acao_Primaria_a_Direita]]). A
   mensagem vem ANTES do botao no HTML; depois dele, este mesmo margin
   arrastaria o grupo todo pra esquerda. */
.im-acao{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;
  justify-content:flex-end;margin-top:var(--sp-4)}
.im-acao .im-msg{margin-right:auto;font-size:var(--fs-xs);color:var(--text-dim)}
.im-acao .im-msg.ok{color:var(--accent-text);font-weight:600}
.im-acao .im-msg.erro{color:var(--danger);font-weight:600}

/* ── Fila de importacao (prefixo fj-) ──────────────────────────────────────*/
.fj{border:1px solid var(--border);border-left:3px solid var(--border);
  border-radius:var(--radius-sm);padding:var(--sp-3) var(--sp-4);margin-bottom:var(--sp-3)}
.fj--processando{border-left-color:var(--accent)}
.fj--na_fila{border-left-color:var(--gold)}
.fj--erro,.fj--interrompido{border-left-color:var(--danger)}
.fj__head{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.fj__nome{font-weight:600;font-size:var(--fs-sm)}
.fj__meta{font-size:var(--fs-xs);color:var(--text-dim);margin-left:auto}
.fj__badge{display:inline-flex;align-items:center;gap:var(--sp-1);font-size:var(--fs-xs);
  font-weight:700;text-transform:uppercase;letter-spacing:.5px;padding:var(--sp-05) var(--sp-2);
  border-radius:999px;background:var(--bg-elev);color:var(--text-dim)}
.fj__badge--processando{background:var(--accent-soft);color:var(--accent-text)}
.fj__badge--na_fila{background:var(--gold-soft);color:var(--gold)}
.fj__badge--erro,.fj__badge--interrompido{background:var(--danger-soft);color:var(--danger)}
.fj__texto{font-size:var(--fs-sm);color:var(--text-dim);margin:var(--sp-2) 0 0}
.fj__texto--erro{color:var(--danger)}
.fj__acoes{display:flex;gap:var(--sp-2);align-items:center;margin-top:var(--sp-3)}
.fj-vazio{display:flex;align-items:center;gap:var(--sp-2);color:var(--text-dim);
  font-size:var(--fs-sm);margin:0}
/* Contagem sob o spinner (Padrao_Loading_Estado, operacao longa): numero com
   largura fixa pra contagem nao tremer enquanto sobe. */
.loading-sub{font-size:var(--fs-xs);color:var(--text-dim);font-variant-numeric:tabular-nums}

@media (max-width:720px){
  .fj__meta{margin-left:0;flex:1 1 100%}
  .im-opc{flex:1 1 100%}
}

/* Senha temporaria do reset (rodada de senhas, 2026-10-18).
   Card de [[Padrao_Box_Card]]: fundo --surface, borda 1px --border, raio
   --radius, padding --sp-4, tudo por token. O destaque dourado na borda
   esquerda e o mesmo recurso do .pf__aviso logo acima: diz "leia isto agora"
   sem virar cor nova no sistema. */
.senha-temp{background:var(--surface);border:1px solid var(--border);
  border-left:3px solid var(--gold);border-radius:var(--radius);
  padding:var(--sp-4);margin-bottom:var(--sp-4)}
.senha-temp__titulo{display:flex;align-items:center;gap:var(--sp-2);
  margin:0 0 var(--sp-2);font-size:var(--fs-lg)}
.senha-temp__titulo i{color:var(--gold);font-size:18px}
.senha-temp__texto{margin:0 0 var(--sp-3);font-size:var(--fs-sm);
  color:var(--text-dim);line-height:1.5}
.senha-temp__texto:last-child{margin-bottom:0}
.senha-temp__linha{display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--sp-2);margin-bottom:var(--sp-3)}
/* A senha em si: monoespacada e grande o suficiente pra ler em voz alta sem
   trocar caractere. user-select:all faz um clique selecionar tudo, pra quem
   preferir copiar na mao em vez do botao. */
.senha-temp__valor{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  font-size:var(--fs-lg);letter-spacing:1px;background:var(--bg);
  border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:var(--sp-2) var(--sp-3);user-select:all}

/* ── Grafico de tendencia do Dashboard ──────────────────────────────────────
   As cores das barras estavam escritas como hex dentro do SVG, oito vezes
   (`fill="#1f9d55"`, `fill="#c19a2e"`...). [[Sistema_de_Estilos]] nao abre
   excecao pra SVG: *"o hex nunca aparece na tela, so no arquivo de tokens"*.
   Na pratica era a marca em DOIS lugares - trocar o verde em tokens.css
   deixava o grafico no tom velho, calado.

   Por CLASSE e nao `fill="var(--accent)"`: var() dentro de atributo de
   apresentacao do SVG nao resolve em todo navegador. Dentro de regra CSS
   resolve em todos.

   O que NAO vem pra ca: `font-size`, `x`, `y`, `width`. Aquelas medidas estao
   em unidade do viewBox, nao em pixel - sao geometria do desenho, e acompanham
   o grafico quando ele encolhe. Virar px no CSS quebraria a escala. */
.grafico-tendencia{width:100%;height:240px}
.grafico-tendencia .g-eixo{stroke:var(--border);stroke-width:1}
.grafico-tendencia .g-barra-aceitas{fill:var(--accent)}
.grafico-tendencia .g-barra-todas{fill:var(--gold);opacity:.35}
.grafico-tendencia .g-legenda{fill:var(--text)}
.grafico-tendencia .g-valor{fill:var(--text)}
.grafico-tendencia .g-rotulo{fill:var(--text-dim)}
/* Subtitulo colado no titulo do cartao: o .section-title ja reserva o respiro
   de baixo, e o paragrafo logo abaixo e continuacao do titulo, nao bloco novo. */
.grafico-sub{margin-top:calc(-1 * var(--sp-2))}
