/* =====================================================================
 * OrçaPRO — Design System
 * Identidade própria (navy/aço), dark-ready, foco visível, alvos clicáveis.
 * ===================================================================== */
:root {
  /* ⚠ diz ao NAVEGADOR em que tom desenhar o que ele mesmo desenha: a lista
     do <select>, a barra de rolagem, a marca do checkbox. Sem isto, alguns
     navegadores ignoram o fundo do <option> e voltam a pintar de branco — que
     foi o defeito do seletor de obras do Painel. */
  color-scheme: light;
  --navy: #0f2740;
  --navy-2: #15324f;
  /* TEXTO SOBRE O NAVY — faixas que ficam escuras nos DOIS temas (a barra da
     janela destacada). ⚠ Não usar --verde/--amarelo ali: são do tema e, no
     claro, somem sobre o navy. Medidos contra #0f2740: 12,19:1 · 10,80:1 ·
     10,52:1 (mínimo 4,5). O escuro não redeclara o navy, então não
     redeclara estes. */
  --sobre-navy: #dbe8f5;
  --sobre-navy-ok: #86efac;
  --sobre-navy-aviso: #fcd34d;
  /* ⚠ ESTE AZUL ESTAVA QUASE CINZA, E ISSO E MEDIVEL: o #2e6f9e anterior
     tinha croma 0,099 em OKLab — ABAIXO do piso 0,1 a partir do qual uma cor
     deixa de ser lida como cor. E ele e a tinta mais presente do sistema
     (botao principal, link, icone, foco, serie de grafico): o app inteiro
     puxava para o cinza-azulado por causa de um unico token.
     O de agora tem croma 0,147 (+48%) e contraste 5,27:1 contra o branco —
     mais vivo E mais legivel que o anterior (5,41 -> 5,27 na mesma faixa,
     ambos bem acima do minimo 4,5). Continua da familia azul-aco da marca:
     o que mudou foi a saturacao, nao o matiz. */
  --aco: #0d6ebd;
  --aco-claro: #3d92cb;
  /* ---------------------------------------------------------------
   * CORES SEMÂNTICAS — saíram dos defaults de fábrica.
   * Eram #16a34a, #dc2626 e #f59e0b: green-600, red-600 e amber-500 do
   * Tailwind, exatamente como vêm na caixa. Paleta de fábrica é um dos
   * sinais de interface gerada. Agora são tons de obra — verde mais fundo,
   * tijolo e ocre — e cada tema tem o seu valor, medido para não sumir no
   * fundo (ver tools/test-contraste.js).
   * O navy e o aço ficam: aqueles são autorais, são a marca.
   * --------------------------------------------------------------- */
  --verde: #15803d;
  --verde-claro: #1a9c4b;
  /* ⚠ MAIS VIVO ATE ONDE A LEGIBILIDADE PERMITE, e nao alem.
     De #b4232a para ca o croma sobe 19% (0,180 -> 0,214) e o contraste
     contra o branco continua em 5,14:1, acima do minimo 4,5.
     ⚠ E O AMBAR E O VERDE FICARAM COMO ESTAVAM, de proposito: medi os dois.
     Ambar #aa6200 esta em 4,71:1 — qualquer passo mais vivo (#b56800 = 4,25)
     cai abaixo do minimo. Verde #15803d idem (#0f8a3e = 4,44). Cor de alerta
     que ninguem le nao alerta ninguem; nem toda tinta tem folga para vida. */
  --vermelho: #d61f26;
  --amarelo: #aa6200;

  --bg: #f4f7fb; /* mesmo branco-azulado do site — claro puxado pro branco */
  --surface: #ffffff;
  --surface-2: #eef2f7;
  --surface-3: #e5ecf4;
  /* v1.1.121 — linhas com mais contraste (pedido: "linhas com a cor mais forte") */
  --linha: #c9d6e4;
  --linha-forte: #7e95aa;
  --texto: #111d2b;
  --texto-fraco: #516375;
  /* faixa da SUB ETAPA: --surface-2 30% rumo a --surface. No claro a superficie E branca,
     entao isto e literalmente "30% mais claro que a etapa" (#eef2f7 -> #f3f6f9). */
  --faixa-sub: #f3f6f9;
  /* fundo da faixa TOTAL GERAL da planilha. No claro e o navy da marca; nos
     tons escuros deriva da superficie do proprio tom (o navy fixo brigava
     com verde/marrom e sumia no preto). */
  --tot-fundo: var(--navy);
  /* fundos tingidos de estado do Painel novo (.pn-*): a cor semântica a
     ~12% sobre a superfície — pílula e cartão de atenção sem hex novo */
  --tinta-ok: rgba(21,128,61,.12); --tinta-aviso: rgba(170,98,0,.13); --tinta-alerta: rgba(214,31,38,.11); --tinta-aco: rgba(13,110,189,.10);

  /* ⚠ COR DE SÉRIE DE GRÁFICO É TOKEN PRÓPRIO, e não `--navy` emprestado.
     Medido em 25/08/2026: a linha "Receitas", a barra "Realizado" e a fatia
     "obra" da rosca usavam `var(--navy)` (#0f2740). No tema escuro o cartão é
     um gradiente #142433→#10202e — contraste de **1,04:1**. As três séries não
     ficavam fracas: ficavam INVISÍVEIS, e o gráfico continuava desenhando
     como se estivesse tudo certo.
     A cor da marca serve para fundo e título; para traço sobre superfície que
     inverte, ela precisa de um par claro/escuro. Daí estes tokens. */
  /* ⚠ ESTA PALETA FOI VALIDADA POR SCRIPT, NAO ESCOLHIDA A OLHO (02/09/2026).
     A anterior — navy #0f2740, ocre #b45309, verde #15803d, azul #5a9bc9 —
     REPROVOU em quatro dos seis testes: o navy caia fora da banda de
     luminosidade (L 0,27) e lia como CINZA (croma 0,056, abaixo do piso), o
     azul do "previsto" ficava a 2,94:1 da superficie (minimo 3:1) e o par
     verde/ocre separava so 6,8 de Delta-E para quem tem protanopia.
     Na pratica: grafico sem vida, e duas series que um daltonico nao
     distingue. Os valores de agora passam nos seis, com Delta-E 13,7 no pior
     par (piso 8).
     ⚠ E O VERDE SAIU DAS SERIES DE PROPOSITO. Ele e cor de ESTADO nesta base
     (saudavel, dentro do orcado, no prazo); usa-lo tambem como "saldo
     acumulado" fazia a mesma tinta dizer duas coisas no mesmo painel. O
     saldo agora e teal; o verde ficou reservado para status.
     Refazer? `node scripts/validate_palette.js "<hex,...>" --mode light`
     na skill dataviz. Nunca no olho. */
  --graf-a: #1a6ba8;   /* receitas · realizado · categoria "obra" */
  --graf-b: #c2410c;   /* despesas */
  --graf-c: #0d9488;   /* saldo acumulado */
  --graf-d: #7c3aed;   /* 4a serie, quando houver */
  /* ⚠ o PREVISTO nao e uma serie: e a REFERENCIA contra a qual se compara.
     Cor forte nele fazia a barra de referencia gritar mais que o realizado,
     que e o numero que importa. Neutro recuado, e o realizado avanca. */
  --graf-prev: #94a8bd;
  /* ⚠ AS CATEGORIAS DE CUSTO SAO UMA PALETA, NAO SETE ESCOLHAS SOLTAS.
     Estavam como hex cru dentro do js (`_CORCAT`), e duas delas eram cor de
     ESTADO usada como serie: material em verde #16a34a e impostos em
     vermelho #dc2626. No mesmo painel, verde queria dizer "saudavel" nos
     indicadores e "material" na barra empilhada; vermelho, "estouro" e
     "impostos". A tinta perdia o sentido.
     Esta ordem foi validada nos seis testes (script da skill dataviz), nos
     dois temas. O pior par — medicao x impostos — separa 6,8 de Delta-E em
     deuteranopia, no piso legal: vale porque nunca aparece so pela cor
     (legenda com nome, lista por extenso com valor e %, e titulo em cada
     segmento). Ordem FIXA: nao rotacionar, nao gerar a oitava. */
  --cat-obra: #1a6ba8;
  --cat-material: #c2410c;
  --cat-mao: #0d9488;
  --cat-equip: #a16207;
  --cat-admin: #7c3aed;
  --cat-impostos: #be185d;
  --cat-medicao: #4d7c0f;
  /* "outros" e o balde, nao uma categoria: neutro de proposito, para nao
     disputar atencao com o que tem nome */
  --cat-outros: #94a3b8;
  /* ⚠ TEXTO DE STATUS DENTRO DE GRAFICO, NAO COR DE CAIXA. O `--vermelho`
     puro (#b4232a) reprova AA em texto pequeno, e o `#dc2626`/`#ea580c` que
     estavam cravados no SVG nao viravam nada no tema escuro — medido sobre o
     cartao #142433: #dc2626 dava 3,21:1 e #ea580c dava 4,39:1, os dois abaixo
     de AA para texto pequeno. Com os tokens: 5,71:1 e 7,60:1 no escuro, 6,47:1
     e 5,02:1 no claro. Mesmo remedio ja
     usado no Last Planner (--lp-vermelho-texto): um par proprio, um valor por
     tema. Selo de 9,5px e rotulo de 11,5px leem por aqui. */
  --graf-alerta: #b91c1c;  /* estouro / vencido, em TEXTO */
  --graf-aviso: #b45309;   /* defasagem em atenção, em TEXTO */

  /* Elevação em camadas (difusa = sensação premium), não uma sombra dura só */
  --sombra-sm: 0 1px 1px rgba(15,39,64,.04), 0 1px 2px rgba(15,39,64,.06);
  --sombra: 0 1px 2px rgba(15,39,64,.04), 0 3px 8px rgba(15,39,64,.05), 0 10px 24px rgba(15,39,64,.06);
  --sombra-lg: 0 2px 4px rgba(15,39,64,.05), 0 10px 24px rgba(15,39,64,.08), 0 28px 60px rgba(15,39,64,.15);
  --sombra-navy: 0 4px 14px rgba(15,39,64,.22), 0 14px 34px rgba(15,39,64,.30);
  --realce: inset 0 1px 0 rgba(255,255,255,.65);   /* brilho sutil no topo de superfícies claras */
  --anel: 0 0 0 3px rgba(46,111,158,.16);           /* anel de foco de campo */
  --card-bg: linear-gradient(180deg, #ffffff 0%, #f8fbfe 100%);
  --bg-grad: radial-gradient(1180px 680px at 80% -12%, #f3f8fd 0%, rgba(243,248,253,0) 52%);

  /* ---------------------------------------------------------------
   * FORMA — três raios, não quatorze.
   * O CSS tinha 14 valores de arredondamento diferentes espalhados
   * (2,3,4,5,6,7,8,9,10,12…). Arredondamento improvisado é um dos tiques
   * visuais que fazem uma interface parecer gerada, não desenhada.
   * --------------------------------------------------------------- */
  --raio-sm: 6px;
  --raio: 10px;
  --raio-lg: 16px;
  /* ⚠ A RÉGUA DO CONTROLE (padrão visual, 14/09/2026 — "deixa as letras
     padronizadas, a tela está uma bagunça de padrão"). Medido na 1.2.77 só
     acima do Gantt: 16 jeitos de botão, 8 alturas (22 · 24,6 · 26 · 27 ·
     27,4 · 30 · 32,1 · 36) e 5 raios. A régua saiu do SEGMENTADO que o dono
     aprovou (as sub-abas do Cronograma): 32 px, raio 8, borda clara, sem
     sombra, o estado dito pelo preenchimento. Os números moram aqui uma vez;
     botão, segmentado, interruptor e campo compacto leem daqui.
     32 = line-height 18 + padding 6+6 + borda 1+1 — escrito, nunca derivado
     de `line-height: normal` (que é o que dava 26/27/30 conforme a fonte). */
  --raio-ctl: 8px;
  --h-ctl: 32px;

  /* ---------------------------------------------------------------
   * TIPOGRAFIA — seis degraus e três pesos.
   *
   * Antes: 27 tamanhos distintos (de 8,5px a 40px) e 7 pesos, com 700/800
   * respondendo por 50 das 76 declarações e o peso normal usado UMA vez.
   * Quando tudo está em negrito, nada fica em destaque — e nada abaixo de
   * 12px é legível numa tela de canteiro, com poeira e sol.
   *
   * O corpo subiu de 13px para 15px. É daqui que vem a maior parte do
   * ganho de leitura; a fonte responde por menos de um quinto.
   * --------------------------------------------------------------- */
  --t-micro: 12px;   /* rótulo em caixa alta, legenda */
  --t-mini:  11.5px; /* rótulo de ferramenta em área de trabalho densa (BIM): o menor tamanho de interface */
  --t-peq:   13.5px; /* apoio, meta, célula secundária */
  --t-base:  15px;   /* corpo, tabela, formulário */
  --t-med:   17px;   /* subtítulo, valor de indicador */
  --t-tit:   20px;   /* título de tela e de modal */
  --t-hero:  32px;   /* o número grande do painel e o nome da obra no palco de Obras — só os dois */
  /* ⚠ ESTE NÃO É UM TAMANHO DE DESIGN, É UM LIMIAR DO SAFARI. Campo de
     formulário com menos de 16px faz o Safari do iPhone DAR ZOOM sozinho ao
     receber foco: a tela salta, o resto do formulário sai de vista, e a
     pessoa relata que "desconfigurou" — foi uma das causas da dificuldade de
     entrar pelo celular (11/09/2026). O --t-base é 15px, meio pixel abaixo do
     que basta para disparar o zoom. Use SÓ em campo que se digita no celular;
     para texto, a régua acima continua mandando. */
  --t-campo-toque: 16px;
  /* ⚠ REGUA SEPARADA, E POR UM MOTIVO TECNICO. Dentro de um <svg> com
     viewBox, "px" nao e pixel de tela: o desenho e escalado pela largura do
     cartao. O eixo do fluxo de caixa mede 440 unidades e e desenhado em
     ~508px, entao 9,5 aqui chegam ao olho como ~11. Usar --t-micro (12px)
     no eixo daria 13,8px reais — rotulo de moldura maior que celula de
     tabela. Sao unidades de DESENHO, e ficam numa regua propria em vez de
     virarem numero solto espalhado pelo css. */
  --t-graf-eixo: 9.5px;  /* marca de eixo e leitura do hover */
  --t-graf-mes:  10px;   /* rotulo de categoria no eixo x */

  --p-normal: 400;   /* corpo */
  --p-medio:  500;   /* ênfase, rótulo, botão */
  --p-forte:  600;   /* título, total, cabeçalho de tabela */

  /* espessura de traço: um fio e um acento. Havia 1px, 1.5px, 1.6px e 1.8px
     convivendo — a borda "grossa" de um card encostando na "fina" de outro. */
  --traco: 1px;
  --traco-forte: 2px;

  /* ---------------------------------------------------------------
   * AS DUAS FAMÍLIAS (ver css/fontes.css).
   * O padrão é o IBM Plex: ele tem cara de instrumento de engenharia e
   * traz o Mono junto, e é o Mono que faz a coluna de quantidade e de
   * preço alinhar dígito embaixo de dígito — uma planilha de orçamento
   * lida com vírgula fora de prumo é uma planilha que não se confere.
   * --------------------------------------------------------------- */
  --fonte: "IBM Plex Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
  --fonte-num: "IBM Plex Mono", ui-monospace, "Consolas", monospace;
}

/* Tema tipográfico alternativo: Source Sans 3, mais humanista e macio.
   Sem Mono próprio — os números usam a mesma família, com tabular-nums. */
[data-fonte="source"] {
  --fonte: "Source Sans 3", "Segoe UI", system-ui, -apple-system, sans-serif;
  --fonte-num: "Source Sans 3", "Segoe UI", system-ui, sans-serif;
}

[data-tema="dark"] {
  color-scheme: dark;
  --bg: #0b1622;
  --surface: #11202e;
  --surface-2: #16293a;
  --surface-3: #1d3346;
  --linha: #2e455c;
  --linha-forte: #4f6c88;
  --faixa-sub: #152636;  /* --surface-2 30% rumo a --surface (mantem a hierarquia no escuro) */
  --tot-fundo: #1b3550;
  --tinta-ok: rgba(76,174,109,.16); --tinta-aviso: rgba(221,162,63,.16); --tinta-alerta: rgba(232,118,123,.16); --tinta-aco: rgba(78,143,190,.16);
  --texto: #ecf2f8;
  --texto-fraco: #9db0c2;
  --sombra-sm: 0 1px 2px rgba(0,0,0,.35);
  --sombra: 0 1px 3px rgba(0,0,0,.4), 0 4px 12px rgba(0,0,0,.3), 0 12px 30px rgba(0,0,0,.28);
  --sombra-lg: 0 4px 12px rgba(0,0,0,.4), 0 16px 40px rgba(0,0,0,.5), 0 32px 72px rgba(0,0,0,.45);
  --sombra-navy: 0 6px 20px rgba(0,0,0,.5);
  --realce: inset 0 1px 0 rgba(255,255,255,.05);
  --anel: 0 0 0 3px rgba(90,155,201,.24);
  --card-bg: linear-gradient(180deg, #142433 0%, #10202e 100%);
  --bg-grad: radial-gradient(1180px 680px at 80% -12%, #14293b 0%, rgba(20,41,59,0) 54%);
  /* as séries clareiam para sobreviver ao cartão escuro — ver o comentário no
     bloco claro. Medido depois: 1,04:1 passou para 6,4:1. */
  /* degraus PROPRIOS do escuro, validados contra a superficie escura — nao
     e o claro clareado. Os antigos reprovavam em tres dos seis testes. */
  --graf-a: #3d8fd0;
  --graf-b: #d9622a;
  --graf-c: #12a594;
  --graf-d: #8b6ce8;
  --graf-prev: #55697e;
  /* a seta do select desenhada para o fundo escuro (o SVG carrega a cor
     dentro dele; sem este degrau ela some contra o navy) */
  --seta-select: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%239db0c2' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  /* degraus proprios do escuro, validados contra a superficie escura */
  --cat-obra: #3d8fd0;
  --cat-material: #d9622a;
  --cat-mao: #12a594;
  --cat-equip: #c08a1e;
  --cat-admin: #8b6ce8;
  --cat-impostos: #dd4f8f;
  --cat-medicao: #729626;
  --cat-outros: #7e8ea1;
  --graf-alerta: #f87171;
  --graf-aviso: #e8a75c;

  /* ⚠ SEMÂNTICAS PRÓPRIAS DO ESCURO.
   * Verde de obra e tijolo são fundos por natureza — sobre fundo escuro eles
   * escurecem e o texto some. O pedido foi explícito: nada pode ficar
   * apagado por conta da cor. Aqui os mesmos papéis (positivo, negativo,
   * atenção) ganham valores CLAREADOS, medidos contra a superfície do tema
   * escuro, não contra o branco. */
  --verde: #4cae6d;
  --verde-claro: #6fd08a;
  --vermelho: #e8767b;
  --amarelo: #dda23f;
  /* o aco da marca escurece demais sobre o navy: sobre a superficie do tema
     escuro ele dava 3,06:1, abaixo do minimo de leitura. Aqui ele clareia
     mantendo o mesmo azul de aco — a marca continua reconhecivel. */
  --aco: #4e8fbe;
  --aco-claro: #7fb4da;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }
body {
  font-family: var(--fonte);
  background: var(--bg);
  color: var(--texto);
  font-size: var(--t-base);
  line-height: 1.55;
  letter-spacing: .1px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* v1.1.121 — nitidez "ultra HD": sem negrito sintético (borrado) e com as
     variantes de leitura do Inter (cv05/cv11 = l e a mais abertos em nº/tabela) */
  font-synthesis: none;
  font-optical-sizing: auto;
  font-feature-settings: "cv05" 1, "cv11" 1;
}
/* ⚠ A COR TAMBÉM SE HERDA — E ERA ELA QUE FALTAVA.
 * Esta regra passava `font-family` e `font-size` adiante e parava aí. Campo
 * de formulário NÃO herda `color` do pai: sem declaração explícita ele usa a
 * cor padrão do navegador, que é quase preta. No tema claro ninguém notou;
 * no escuro, toda coluna EDITÁVEL da planilha (quantidade e custo unitário)
 * ficava cinza-escuro sobre fundo escuro, enquanto as colunas calculadas ao
 * lado — que são <td> comum e herdam `--texto` — apareciam claras.
 * Foi assim que o orçamentista viu "letras difíceis de ler" só em duas
 * colunas, e só no escuro. Reportado na 1.1.191. */
button, input, select, textarea { font-family: inherit; font-size: inherit; color: var(--texto); }
/* ⚠ `<b>` E `<strong>` EM 600, DECLARADO (14/09/2026). O navegador os pinta em
   700, e as duas faces do app (Plex Sans e Source Sans 3) só têm 400–600: o
   700 desenha IGUAL ao 600 — medido em tinta de pixel, 4714 nos dois. Não
   muda um pixel; faz o CSS parar de mentir o peso e a régua (400/500/600)
   valer para o texto que vem em `<b>` de dentro dos componentes. */
b, strong { font-weight: var(--p-forte); }

/* ⚠ COR SEM FUNDO É COMO SE FABRICA TEXTO INVISÍVEL — e foi o que aconteceu.
 * A regra acima dava `color: var(--texto)` (quase branco, no escuro) ao
 * `<select>` e NÃO dava fundo. O campo fechado até se virava porque fica sobre
 * o card escuro, mas a LISTA que o navegador abre é desenhada por ele, com
 * fundo claro do sistema — e o texto quase branco sumia dentro dela. O
 * `<option>` não tinha regra nenhuma.
 *
 * Rogério viu isso no seletor de obras do Painel, na v1.1.192: os nomes das
 * obras ilegíveis dentro da lista aberta.
 *
 * ⚠ E O TESTE DE CONTRASTE AFIRMAVA METADE DO PAR: ele exigia que
 * `input/select/textarea` recebessem `color: var(--texto)` e nunca exigiu um
 * fundo junto. Guarda que confere só a cor aprova exatamente este defeito.
 *
 * `color-scheme` é o que faz o navegador desenhar a lista, a barra de rolagem
 * e a marca de seleção no tom certo — sem ele, alguns navegadores ignoram o
 * fundo do `<option>` e voltam a pintar de branco. */
select, option, optgroup { background-color: var(--surface); color: var(--texto); }

/* =====================================================================
 * CONTROLE FORA DO FORMULARIO — a mistura que mais datava a tela
 *
 * Os campos so ganhavam forma dentro de `.field`, que e o formulario dos
 * modais. Todo <select> de BARRA DE FILTRO — "Todas as Obras (Visao
 * Global)", "Ultimos 6 meses", "Todas as obras (18)" — ficava com a
 * aparencia NATIVA do sistema: canto reto, borda cinza do Windows e a seta
 * do sistema operacional, encostado em botoes e cartoes de canto redondo.
 * Nao e questao de gosto: controle nativo ao lado de controle desenhado e a
 * assinatura de pagina remendada, e estava no lugar mais visivel do Painel.
 *
 * ⚠ ESTA REGRA VEM ANTES DE `.field` DE PROPOSITO. As duas tem a mesma
 * especificidade (0,1,1), entao quem vem depois vence: `.field select`
 * (linha ~860) continua mandando dentro dos modais, e isto so alcanca o que
 * estava sem dono. Mover este bloco para baixo troca o dono dos dois.
 *
 * ⚠ E `.cell` FICA DE FORA. A grade do orcamento tem celula editavel com
 * estilo proprio, medida em pixel para a coluna fechar; dar a ela padding de
 * formulario desalinha a planilha inteira.
 * ===================================================================== */
select:not(.cell), input[type="search"]:not(.cell), input[type="date"]:not(.cell) {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  background-color: var(--surface);
  border: 1px solid var(--linha);
  border-radius: var(--raio-sm);
  padding: 6px 10px;
  color: var(--texto);
  line-height: 1.4;
  transition: border-color .14s var(--ease), box-shadow .14s var(--ease);
}
/* a seta e desenhada, e tem um degrau por tema: `background-image` nao
   aceita `currentColor`, entao a cor vai no proprio SVG */
select:not(.cell) {
  padding-right: 28px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%23516375' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
select:not(.cell):hover, input[type="search"]:not(.cell):hover, input[type="date"]:not(.cell):hover {
  border-color: var(--linha-forte);
}
select:not(.cell):focus-visible, input[type="search"]:not(.cell):focus-visible, input[type="date"]:not(.cell):focus-visible {
  border-color: var(--aco); outline: none; box-shadow: var(--anel);
}
select:not(.cell):disabled { color: var(--texto-fraco); background-color: var(--surface-2); }
:root[data-tema="dark"] select:not(.cell) { background-image: var(--seta-select); }

/* ⚠ TAMANHO DO ALVO NO TOQUE. Abaixo de 820px a barra de filtro e usada com
   o dedo, e 44px e o minimo para acertar sem errar o vizinho — o mesmo
   motivo pelo qual a base ja forca 16px de fonte aqui (evita o zoom
   automatico do iOS ao focar o campo). */
@media (max-width: 820px) {
  select:not(.cell), input[type="search"]:not(.cell), input[type="date"]:not(.cell) { min-height: 44px; }
}
select:disabled, option:disabled { color: var(--texto-fraco); }
/* a dica do campo continua mais fraca que o valor digitado — mas legível */
input::placeholder, textarea::placeholder { color: var(--texto-fraco); }
/* Números alinham em coluna em toda tabela/KPI/gráfico (leitura de planilha) */
table.tbl, .kpi .num, .g-pill, .cell, input[type="number"] { font-variant-numeric: tabular-nums; }
/* Ícones SVG inline (js/icones.js) herdam a cor do texto e alinham com o rótulo */
.ic-svg { display: inline-block; }
.tab .ic-svg { opacity: .72; }
.tab.ativa .ic-svg { opacity: 1; }
/* Dentro de .btn o flex-gap já separa ícone/texto — zera a margem própria do ícone */
.btn .ic-svg { margin-right: -1px !important; }
:focus-visible { outline: 2px solid var(--aco-claro); outline-offset: 2px; }
::selection { background: rgba(46,111,158,.22); }

/* Hierarquia de título de página (premium, cascateia em toda tela da Gestão/Orçamento) */
.main h1 { font-size: var(--t-hero); font-weight: var(--p-forte); letter-spacing: -.55px; line-height: 1.15; color: var(--texto); margin: 0 0 5px; }
.main h2 { font-size: var(--t-tit); font-weight: var(--p-forte); letter-spacing: -.2px; color: var(--texto); }
.main .sub, .main .subtitulo { color: var(--texto-fraco); font-size: var(--t-base); }

/* Scrollbars discretas (detalhe de acabamento) */
* { scrollbar-width: thin; scrollbar-color: var(--linha-forte) transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--linha-forte); border-radius: 999px; border: 3px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: var(--texto-fraco); background-clip: padding-box; border: 3px solid transparent; }
/* números tabulares onde há dinheiro/quantidade (padrão de ferramenta financeira) */
.kpi .num, .orc-card .valor, table.tbl td.num, table.tbl th.num, .sinapi-result .preco { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ---------- Layout app ---------- */
/* ⚠ `100vh` NO SAFARI DO IPHONE NÃO É A ALTURA VISÍVEL: ele conta a tela sem
   descontar a barra de endereço, então o rodapé fica escondido embaixo dela e
   a página ganha um pedaço que só aparece ao rolar. `100dvh` (dynamic viewport
   height) é a medida que acompanha a barra aparecendo e sumindo. A linha do
   `100vh` fica antes como reserva para navegador antigo que não conheça
   `dvh` — quem conhece usa a segunda e ignora a primeira. */
.app { display: grid; grid-template-rows: 58px 1fr; height: 100vh; height: 100dvh; }

/* ---------- ÁREA SEGURA DO IPHONE (notch e barra de gestos) ----------
   ⚠ O BLOCO MUDOU DE LUGAR — está no FIM deste arquivo, e o lugar é a
   correção. Ele morava aqui, e daqui não valia NADA: as regras-base de
   `.topbar` (logo abaixo) e de `.modal-bg` têm a MESMA especificidade e vêm
   DEPOIS, e em empate de especificidade quem ganha é a última. O reserva de
   margem existia no arquivo, estava certo, e perdia a cascata em toda
   largura — inclusive no iPhone deitado, que mede 852-956px e nem chega no
   @media de celular. Procurar "env(" no CSS dava verde; medir dava 22px.
   O que ele faz e por quê está escrito junto do bloco, no fim do arquivo. */
/* Na tela de login não há topbar: colapsa a linha e remove padding/scroll do main */
.app.tela-login { grid-template-rows: 1fr; }
.app.tela-login .main { padding: 0; overflow: hidden; }
/* ⚠ `flex-wrap: wrap` VALE EM TODA LARGURA. Ele só age quando não cabe, então
   no desktop largo não muda nada — mas estava preso dentro do
   `@media (max-width: 820px)`, e por isso o iPad em pé (834px) e o iPhone
   deitado (852–956px) caíam numa zona morta: barra que não quebra e layout
   que não encolhe. Foi a causa das capturas do dono, não o Safari. */
.topbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px;
  background: linear-gradient(180deg, #17395c 0%, var(--navy) 100%); color: #fff; padding: 0 22px;
  box-shadow: var(--sombra-navy); position: relative; z-index: 20;
  border-bottom: 1px solid rgba(255,255,255,.06);
}
/* fina linha-acento de marca na base da topbar (aço → verde) */
.topbar::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: linear-gradient(90deg, var(--aco) 0%, var(--aco-claro) 40%, var(--verde-claro) 100%); opacity: .9; }
.topbar .logo { font-weight: var(--p-forte); font-size: var(--t-tit); letter-spacing: .2px; display: flex; align-items: center; }
.topbar .logo small { font-weight: var(--p-normal); opacity: .62; font-size: var(--t-micro); display: block; line-height: 1; letter-spacing: .2px; }
/* ⚠ UM LOGO SÓ. Com o menu lateral à vista, o quadrado da marca já está no
   alto dele, colado ao nome na barra — eram dois ícones iguais lado a lado
   (visto na tela do Rogério em 11/09/2026). O do menu é o que fica: no Modo
   foco é nele que se clica para abrir o menu recolhido. No celular o menu
   vira gaveta e o ícone do topo volta. */
@media screen and (min-width: 821px) { .app.com-sidebar > .topbar .logo > svg { display: none; } }
/* =====================================================================
 * SELOS DA BARRA DE CIMA — CHAPADO, HEX FIXO, E É POR CONTRASTE.
 *
 * Eram `linear-gradient(135deg, var(--verde), var(--verde-claro))` com texto
 * branco. Dois defeitos empilhados:
 *
 * 1) GRADIENTE. O texto branco cruza o degradê inteiro, então quem manda no
 *    contraste é a parada MAIS CLARA. `--verde-claro` no claro (#1a9c4b) dá
 *    3,56:1, contra os 4,5:1 que a WCAG exige para 12px. Esta lição já estava
 *    escrita DUAS vezes neste arquivo — em `.btn.success` e em `.selo-ajuste`
 *    — e nunca tinha sido aplicada aqui.
 *
 * 2) TOKEN TEMATIZADO NUMA BARRA QUE NÃO MUDA DE TEMA. `--navy` é declarado
 *    uma única vez e nunca redefinido: a barra de cima é navy no tema claro E
 *    no escuro. Só que `--verde-claro` INVERTE (#1a9c4b → #6fd08a), então
 *    trocar para o tema escuro repintava o selo e deixava o fundo onde estava:
 *    branco sobre verde-claro, 1,90:1 — mancha colorida sem palavra legível,
 *    em toda tela, inclusive na marca do próprio produto.
 *
 * Por isso o hex é CRAVADO e não token: cor que pousa sobre a barra não pode
 * derivar do tema, senão o tema mexe em metade do par. #15803d chapado com
 * branco dá 5,02:1 (é o valor do --verde do tema claro, o mesmo que
 * `.btn.success` já usa) e o selo destaca-se do navy em 3,02:1.
 *
 * ⚠ O SELO "FREE" NÃO ERA BUG DE TEMA ESCURO — estava quebrado em produção,
 * no tema claro, para todo cliente do plano gratuito: branco sobre #fbbf24 dá
 * 1,67:1 nos dois temas. Trocar o âmbar por um marrom escuro passaria, mas
 * mataria a identidade do selo. O padrão que esta base já escolheu para esse
 * caso (ver `.selo-ajuste`) é fundo tintado + TEXTO escuro: âmbar chapado com
 * o navy da marca por cima dá 9,09:1 e o selo continua âmbar.
 * ===================================================================== */
.topbar .logo .logo-ia {
  display: inline-block; margin-left: 5px; padding: 1px 6px; border-radius: var(--raio-sm);
  background: #15803d; color: #fff;
  font-size: var(--t-micro); font-weight: var(--p-forte); letter-spacing: .5px; vertical-align: 2px;
  box-shadow: 0 2px 6px rgba(21,128,61,.4);
}
.topbar .spacer { flex: 1; }
.topbar .badge-plano {
  background: #15803d; color: #fff; font-size: var(--t-micro); font-weight: var(--p-forte);
  padding: 3px 10px; border-radius: 999px; letter-spacing: .3px; text-transform: uppercase;
  box-shadow: 0 2px 6px rgba(21,128,61,.32);
}
.topbar .badge-plano.free { background: #fbbf24; color: var(--navy); box-shadow: 0 2px 6px rgba(245,158,11,.32); }
.topbar .user { font-size: var(--t-peq); opacity: .82; }
.topbar button.linkbtn { background: none; border: none; color: #cfe0ef; cursor: pointer; font-size: var(--t-peq); font-weight: var(--p-normal); padding: 6px 9px; border-radius: var(--raio-sm); transition: .12s; }
.topbar button.linkbtn:hover { color: #fff; background: rgba(255,255,255,.09); }
.topbar-burger { display: none; align-items: center; justify-content: center; flex: none; width: 40px; height: 40px; margin-right: 2px; border: 0; border-radius: var(--raio); background: rgba(255,255,255,.14); color: #fff; font-size: var(--t-tit); line-height: 1; cursor: pointer; }
.topbar-burger:hover { background: rgba(255,255,255,.24); }
/* Menu de conta/configurações (agrupa Tabelas, Empresa, Backup, Licença, Tema, Sair) */
.topbar-conta { position: relative; flex: none; }
/* a pílula da conta: logo da empresa, nome e a foto de quem está logado com
   um anel — a pessoa se reconhece de relance no canto da tela */
.conta-btn { display: inline-flex; align-items: center; gap: 10px; max-width: 250px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.16); color: #fff; font-family: inherit; font-weight: var(--p-medio); font-size: var(--t-base); padding: 4px 8px 4px 12px; border-radius: 999px; cursor: pointer; transition: background .18s, border-color .18s, box-shadow .18s; }
.conta-btn:hover { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.3); box-shadow: 0 0 0 3px rgba(143,192,227,.14); }
.conta-btn .conta-ic { font-size: var(--t-med); flex: none; }
.conta-btn .conta-nome { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; }
.conta-btn .conta-ca { opacity: .7; font-size: var(--t-micro); flex: none; }
.conta-drop { display: none; position: absolute; top: calc(100% + 8px); right: 0; min-width: 252px; background: var(--surface); border: 1px solid var(--linha); border-radius: var(--raio); box-shadow: var(--sombra-lg); padding: 6px; z-index: 45; }
.topbar-conta.aberto .conta-drop { display: block; }
.conta-cab { padding: 8px 12px 10px; border-bottom: 1px solid var(--linha); margin-bottom: 6px; }
.conta-cab b { display: block; color: var(--texto); font-size: var(--t-base); line-height: 1.2; }
.conta-cab span { color: var(--texto-fraco); font-size: var(--t-peq); }
.conta-item { display: flex; align-items: center; gap: 11px; width: 100%; background: none; border: 0; text-align: left; color: var(--texto); font-family: inherit; font-size: var(--t-base); font-weight: var(--p-normal); padding: 10px 12px; border-radius: var(--raio); cursor: pointer; }
.conta-item:hover { background: var(--surface-2); }
.conta-item > span { width: 20px; text-align: center; flex: none; font-size: var(--t-med); }
.conta-item.alerta { color: var(--vermelho); font-weight: var(--p-forte); }
.conta-item.sair { color: var(--vermelho); }
.conta-sep { height: 1px; background: var(--linha); margin: 6px; }

.main { overflow: auto; padding: 28px 34px; background: var(--bg-grad); }

/* ---------- Sidebar de módulos (Gestão) ---------- */
/* ⚠ `minmax(0, 1fr)`, NÃO `1fr`. `1fr` é `minmax(auto, 1fr)`: a coluna nunca
   encolhe abaixo do min-content do que está dentro dela, e a barra de cima
   (que não quebrava linha acima de 820px) travava o app inteiro em ~1013px.
   No iPad Pro 11" em pé (834px) a página inteira ficava 189px maior que a
   tela, com a marca cortada no topo e os cards cortados na direita. */
/* ⚠ 138 px, NÃO 212 (24/09/2026): a coluna encolheu 35% e o que permitiu isso
   foi o ÍCONE EM CIMA DO RÓTULO (`.sb-nav > .sb-item`, abaixo) — em linha,
   "Configurações" com ícone ao lado precisa dos 212. A medida mora em
   `--sb-w` porque três lugares dependem dela: esta coluna, o `left` da aba
   lateral (`.sb-fly.aberta`) e a largura do modo foco aberto (estilo injetado
   em js/gestao.js). Mudar um só desalinha a aba. */
.app.com-sidebar { --sb-w: 138px; grid-template-columns: var(--sb-w) minmax(0, 1fr); grid-template-areas: "side top" "side main"; }
.app > .main, .app > .topbar, .app.com-sidebar > .topbar, .app.com-sidebar > .sidebar { min-width: 0; }
.app.com-sidebar > .sidebar { grid-area: side; }
.app.com-sidebar > .topbar { grid-area: top; }
.app.com-sidebar > .main { grid-area: main; }
/* A LUZ QUE SEGUE O MOUSE (24/09/2026). O navy clareia em volta do ponteiro:
   dentro da barra a luz acompanha o cursor; fora dela, encosta na borda mais
   próxima e vai apagando com a distância (js/gestao.js `menuLuz`). É a única
   coisa que se move na barra, e só responde à mão da pessoa — com
   `prefers-reduced-motion` ou sem ponteiro (toque) o JS nem liga, e o fundo
   fica o degradê de sempre.
   ⚠ MECÂNICA: a luz é a primeira camada do `background`, um círculo de raio
   `--lr` centrado em `--lx --ly`. O JS só escreve essas três variáveis; apagar
   é levar o raio a 0 (círculo de raio zero não pinta nada), então não há
   alfa em `calc()` nem `@property` — funciona em qualquer WebView que entenda
   variável CSS. `background-attachment` fica no padrão (`scroll`): num
   elemento que rola, o fundo é fixo à CAIXA e não ao conteúdo, que é o que
   se quer — a luz está onde o mouse está, não onde a lista rolou. */
.sidebar { display: none; --lx: -999px; --ly: -999px; --lr: 0px;
  background:
    radial-gradient(var(--lr) circle at var(--lx) var(--ly), rgba(255,255,255,.16) 0, rgba(61,146,203,.42) 16%, rgba(61,146,203,.16) 44%, rgba(61,146,203,0) 72%),
    linear-gradient(180deg, #143454, var(--navy));
  color: #cfe0ef; flex-direction: column; overflow-y: auto; box-shadow: 2px 0 12px rgba(15,39,64,.2); z-index: 15; }
.app.com-sidebar > .sidebar { display: flex; }
.sb-top { padding: 15px 18px 8px; }
.sb-lbl { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: 1.5px; color: rgba(255,255,255,.38); padding: 8px 20px 4px; font-weight: var(--p-forte); }
.sb-nav { display: flex; flex-direction: column; gap: 2px; padding: 2px 10px 14px; }
/* cabeçalho de grupo do menu (jornada da obra, igual à landing) */
.sb-grp { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: 1.2px; color: rgba(255,255,255,.34); padding: 13px 12px 4px; font-weight: var(--p-forte); white-space: nowrap; }
.sb-sep { height: 1px; margin: 12px 12px 4px; background: rgba(255,255,255,.1); }

/* ---------- Barra em AZULEJOS + ABA LATERAL do grupo (24/09/2026) ----------
   No desktop cada módulo é um azulejo: ícone em cima, rótulo embaixo. É o que
   deixa a coluna caber em 138 px. Clicar num GRUPO não abre sanfona nem tem
   seta: abre uma aba ao lado da barra com os módulos de dentro, e abrir outro
   grupo fecha o anterior — uma aba por vez, a tela não enche.
   ⚠ A aba (`.sb-fly`) mora DENTRO de #sidebar no DOM (os módulos continuam
   alcançáveis por `#sidebar [data-view]`, que é o que a suíte do menu enxuto
   conta) e sai da caixa com `position: fixed` — fixed escapa do
   `overflow-y: auto` da barra; a barra do desktop não tem `transform`, senão o
   fixed viraria absolute e a aba ficaria cortada. No celular a mesma aba abre
   em linha, embaixo do item (a gaveta tem transform, e lá não há lado). */
.sb-fly { display: none; }
.sb-fly.aberta { display: block; }
.sb-fly-cab { display: flex; align-items: center; gap: 7px; padding: 8px 10px 5px; color: #fff; font-size: var(--t-micro); font-weight: var(--p-forte); }
.sb-fly-cab .sb-ic { color: #9fbdda; width: 18px; height: 16px; }
.sb-fly .sb-item.sb-filho { padding: 7px 10px; font-size: var(--t-peq); gap: 9px; opacity: .88; }
.sb-fly .sb-item.sb-filho:hover, .sb-fly .sb-item.sb-filho.on { opacity: 1; }
/* o azulejo do grupo aberto fica aceso junto com a aba — os dois são uma coisa só */
.sb-item.sb-grp-bt.aberto { background: rgba(255,255,255,.11); color: #fff; }
.sb-item.sb-grp-bt.aberto .sb-ic { color: #fff; }
@media screen and (min-width: 821px) {
  .sb-top { display: flex; justify-content: center; padding: 14px 8px 4px; }
  .sb-lbl { text-align: center; padding: 6px 4px 4px; letter-spacing: 1.2px; }
  .sb-nav { padding: 2px 8px 12px; }
  .sb-nav > .sb-item {
    flex-direction: column; justify-content: center; gap: 4px;
    padding: 8px 4px 7px; text-align: center;
    font-size: var(--t-micro); line-height: 1.15; font-weight: var(--p-medio);
  }
  .sb-nav > .sb-item .sb-ic { width: 26px; height: 22px; }
  /* rótulo em até duas linhas ("Painel de vendas", "Desbloquear Gestão"); a
     terceira some em vez de empurrar o azulejo de baixo */
  .sb-nav > .sb-item > span:not(.sb-ic) { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere; }
  /* o deslize lateral do hover é gramática de LINHA; num azulejo centrado ele
     só desalinha o ícone do vizinho */
  .sb-nav > .sb-item:hover { transform: none; }
  .sb-sep { margin: 8px 6px 2px; }
  .sb-org { text-align: center; white-space: normal; line-height: 1.25; padding: 6px 4px; }
  /* o ícone da engrenagem sai no azulejo: com ele, "Organizar menu" não cabia em 138 px e quebrava em duas linhas */
  .sb-nav > .sb-org svg { display: none; }
  /* ⚠ z-index 45: acima da cena de Obras e da tela (a aba mora no <body> enquanto
     aberta, ver _menuFlyAbrir), abaixo do fundo de modal (50) e das toasts (100) */
  .sb-fly.aberta {
    position: fixed; left: var(--sb-w, 138px); top: 0; width: 216px; z-index: 45;
    padding: 4px 6px 6px; overflow-y: auto;
    background: var(--navy-2); border: 1px solid rgba(255,255,255,.12); border-left: 0;
    border-radius: 0 var(--raio) var(--raio) 0;
    box-shadow: 10px 0 30px rgba(8,18,30,.35);
  }
  .sb-fly .sb-item.sb-filho:hover { transform: none; }
}
@media screen and (max-width: 820px) {
  /* na gaveta a aba vira sanfona: entra embaixo do item, com o traço que diz
     "isto está dentro"; o cabeçalho sobra (o item de cima já é o nome) */
  .sb-fly.aberta { margin: 0 0 6px 18px; padding-left: 8px; border-left: 1px solid rgba(255,255,255,.14); }
  .sb-fly-cab { display: none; }
}
/* seletor de tema (modal) */
.tema-ops { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.tema-op { border: 2px solid var(--linha); border-radius: var(--raio); padding: 12px 12px 10px; cursor: pointer; background: var(--surface); text-align: left; transition: transform .15s, border-color .15s, box-shadow .15s; width: 100%; font: inherit; color: var(--texto); }
.tema-op:hover { transform: translateY(-2px); border-color: var(--aco-claro); box-shadow: var(--sombra); }
.tema-op.on { border-color: var(--verde); box-shadow: 0 0 0 3px rgba(21,128,61,.15); }
.tema-op .sw { display: flex; gap: 5px; margin-bottom: 8px; }
.tema-op .sw i { width: 22px; height: 22px; border-radius: var(--raio-sm); border: 1px solid rgba(0,0,0,.18); }
.tema-op b { display: block; font-size: var(--t-base); }
.tema-op small { color: var(--texto-fraco); font-size: var(--t-peq); line-height: 1.3; display: block; }
@media (max-width: 560px) { .tema-ops { grid-template-columns: repeat(2, 1fr); } }
.sb-item { display: flex; align-items: center; gap: 11px; background: none; border: 0; color: #cfe0ef; font-size: var(--t-base); font-weight: var(--p-medio); padding: 11px 12px; border-radius: var(--raio); cursor: pointer; text-align: left; transition: .12s; width: 100%; }
.sb-item:hover { background: rgba(255,255,255,.08); color: #fff; }
.sb-item.on { background: linear-gradient(90deg, rgba(46,111,158,.55), rgba(46,111,158,.18)); color: #fff; box-shadow: inset 3px 0 0 var(--verde-claro); }
.sb-item.sb-upsell { color: #ffd47e; margin-top: 10px; border: 1px dashed rgba(255,212,126,.38); }
.sb-item.sb-upsell:hover { background: rgba(255,212,126,.12); color: #ffe3a6; }
.sb-ic { width: 22px; height: 20px; flex: none; display: inline-flex; align-items: center; justify-content: center; color: #9fbdda; }
.sb-item:hover .sb-ic, .sb-item.on .sb-ic { color: #fff; }
.sb-ic svg { display: block; }
.g-ic { flex: none; }
h1 .g-ic { margin-right: 9px; vertical-align: -.14em; color: var(--aco); }
.g-pill { font-size: var(--t-micro); font-weight: var(--p-forte); padding: 2px 9px; border-radius: 999px; white-space: nowrap; }
/* ⚠ A COR DO TEXTO DO SELO VEM DAQUI, NÃO DO INLINE — ver TXTStatus em
   js/gestao.js. O `pill()` só sabe a cor de identidade do status; qual das
   duas leituras usar depende do TEMA, que estilo inline não enxerga. Sem
   estas duas linhas o par vira enfeite: o JS escreve as variáveis e ninguém
   as lê. O fallback `inherit` preserva os poucos g-pill que nunca tiveram
   cor própria. */
.g-pill { color: var(--gp-t, inherit); }
[data-tema="dark"] .g-pill { color: var(--gp-td, var(--gp-t, inherit)); }
table.tbl tr.lin:hover td { background: rgba(46,111,158,.06); }
.kpis.kpis-g { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kpis.kpis-g .num { font-size: var(--t-tit); }
@media (max-width: 720px) { .kpis.kpis-g { grid-template-columns: repeat(2, 1fr); } }

/* ---------- Botões ---------- */
/* ⚠ EXCEÇÃO PARA RÓTULO LONGO. O `white-space: nowrap` do `.btn` está certo
   para os botões curtos das barras — mas num rótulo de frase inteira ele
   trava tudo numa linha, e o `justify-content: center` derrama o excedente
   PARA OS DOIS LADOS: o usuário lê o meio da frase, sem começo nem fim.
   Marcar o botão com `longo` deixa o texto quebrar, em vez de mexer no `.btn`. */
/* ⚠ BARRA DE BOTÕES QUEBRA EM QUALQUER LARGURA. Estava dentro do media
   query de 820px, e a barra da Folha Semanal (2 selects + 8 botões) mede
   1779px FIXOS: "Entregáveis" e "Lançar no Financeiro" ficavam fora da tela
   em toda largura acima de 820px — inclusive no monitor de 1440px, onde
   sobravam 722px para fora. Só o celular mostrava esses botões.
   Quebrar linha só acontece quando não cabe, então no desktop largo nada
   muda. `.modal .flex` entra junto: o modal é anexado ao body, não ao
   `.main`, e por isso a fileira de botões dele nunca quebrava. */
.main .flex, .modal .flex { flex-wrap: wrap; }
.btn.longo { white-space: normal; text-align: center; line-height: 1.25; }
/* ⚠ N2 — O SECUNDÁRIO MORA AQUI, NA DECLARAÇÃO ORIGINAL (D3: a régua vale
   para o app inteiro, 751 `class="btn` em js/). Roteiro do defeito: os
   valores do secundário estavam em DOIS lugares que brigavam — este `.btn`
   (borda --linha-forte 3,1:1, --sombra-sm, sobe 1 px no hover) e a regra
   `.barra-acoes .btn:not(…)` (especificidade 0,6,0: borda --linha, sem
   sombra). O MESMO `class="btn sm"` desenhava dois botões conforme o avô:
   "Parâmetros" do topo e "Limpar" do cartão, lado a lado na mesma tela, não
   pareciam da mesma família. Os valores daquela regra vieram para cá e ela
   foi APAGADA — um terceiro bloco "unificado" no fim do arquivo perderia
   para as regras escritas depois (memória "regra de unificação nasce
   perdendo").
   Sem sombra e sem `translateY`: o que diz "clicável" é a borda e o cursor;
   o que diz o estado é o preenchimento. Botão que dependia da sombra para
   aparecer foi conferido em foto (Planilha, Obras, Financeiro, Medições,
   modais, nos dois temas) antes de entrar.
   ⚠ `line-height: 20px` escrito: 9+9+20+2 = 40, o mesmo alvo de toque que o
   celular já exige (@media 820px). O `.btn.sm` abaixo é o controle de 32. */
.btn {
  display: inline-flex; align-items: center; gap: 7px; justify-content: center;
  border: 1px solid var(--linha); background: var(--surface); color: var(--texto);
  padding: 9px 15px; line-height: 20px; border-radius: var(--raio-ctl); cursor: pointer; font-weight: var(--p-medio);
  transition: .14s cubic-bezier(.4,0,.2,1); white-space: nowrap; box-shadow: none;
}
.btn:hover { border-color: var(--linha-forte); background-color: var(--surface-2); }
.btn:active { transform: none; }
/* ⚠ SOLIDO, NAO GRADIENTE — e por dois motivos, nao por gosto.
   1) O gradiente vertical com brilho interno (`inset 0 1px 0 branco`) e a
      gramatica de botao de 2010: imita um plastico iluminado de cima. Nada
      mais na tela finge volume, so ele.
   2) Ele COMIA A COR. O topo era `#3d92cb` cru — um azul mais claro e mais
      lavado —, entao metade do botao nunca mostrava a tinta da marca. Ao
      deixar o token mais vivo, o ganho ficava escondido atras do degrade.
   A sombra tambem carregava o rgb do azul ANTIGO (46,111,158) escrito a
   mao: sombra colorida que nao acompanha o token e um descolamento que
   ninguem ve acontecer. */
/* ⚠ N1 SEM SOMBRA COLORIDA E COM PESO 600 AQUI (e não só dentro da
   `.barra-acoes`, que era onde o 600 morava). A sombra azul de 2 camadas era
   o que fazia o primário e o [Passar a obra] parecerem dois "ativos"
   disputando com a sub-aba ativa a 72 px deles. */
.btn.primary { background: var(--aco); border-color: var(--aco); color: #fff; box-shadow: none; font-weight: var(--p-forte); }
.btn.primary:hover { background: var(--aco-claro); border-color: var(--aco-claro); box-shadow: none; }
/* ⚠ CHAPADO, NÃO GRADIENTE — e é por contraste, não por gosto.
   Era `linear-gradient(180deg, #22b95d, var(--verde))`. O texto branco cruza o
   gradiente inteiro, então quem manda é o ponto MAIS CLARO: #22b95d dá
   2,57:1, contra o mínimo de 4,5:1 da WCAG para texto normal. Pior ainda,
   ficava abaixo do #16a34a que a loja usava — o canônico era o exemplo ruim.
   Nenhum verde da paleta passa como topo: --verde-claro #1a9c4b dá 3,56:1 e
   até o #178a43 da borda dá 4,42:1. O único que passa é o próprio --verde
   chapado: 5,02:1.
   ⚠ O HOVER TAMBÉM FICA EM --verde. Trocá-lo por --verde-claro derrubaria o
   texto para 3,56:1 — o hover é estado de texto, não só de moldura, e não
   pode reprovar. O realce do hover vem da sombra mais forte e do
   `filter: brightness(1.02)` que já existe mais abaixo neste arquivo. */
/* ⚠ HEX CRAVADO, PELO MESMO MOTIVO DO SELO DA BARRA (ver a nota lá em cima).
 * `--verde` INVERTE entre os temas: #15803d no claro e #4cae6d no escuro,
 * porque no escuro ele é cor de TEXTO (valor positivo sobre superfície
 * escura). Aqui ele era FUNDO, com texto branco por cima — e no tema escuro
 * isso dava 2,77:1. Este é o botão "Salvar": o rótulo mais importante do app
 * apagando no fundo do próprio botão.
 * #15803d com branco dá 5,02:1, e não muda com o tema — que é o ponto: quem
 * manda no par é o botão, não a superfície atrás dele. */
/* [Gerar Proposta] continua verde (D2): é a ÚNICA cor diferente da tela, e o
   hover deixa de "acender" por sombra — o realce é o `filter` lá embaixo. */
.btn.success { background: #15803d; border-color: #139345; color: #fff; box-shadow: none; font-weight: var(--p-forte); }
.btn.success:hover { background: #15803d; box-shadow: none; }
.btn.ghost { background: transparent; box-shadow: none; border-color: var(--linha); }
.btn.ghost:hover { box-shadow: none; background-color: var(--surface-2); }
.btn.danger { color: var(--vermelho); border-color: transparent; background: transparent; box-shadow: none; }
.btn.danger:hover { background: rgba(220,38,38,.08); border-color: transparent; transform: none; box-shadow: none; }
/* N2-FORTE — a ação consequente de uma faixa, que não é o primário da tela.
   Era `.barra-acoes .btn.acao-forte` (só valia dentro da barra do editor); o
   [Passar a obra para esta revisão] mora na faixa da obra do Cronograma e
   era azul cheio, colado na sub-aba ativa (D2). Ele abre confirmação e mexe
   em quantidade medida: precisa ser ACHÁVEL, não gritar igual ao estado. */
.btn.acao-forte { color: var(--texto); border-color: var(--linha-forte); font-weight: var(--p-forte); box-shadow: none; }
/* o controle de 32 px: 18 + 6 + 6 + 1 + 1 (ver --h-ctl). ⚠ O lado continua
   10 px, como era: com 12 a linha 1 da barra do editor (13 botões, 79 px de
   folga a 1366 com o menu aberto) quebrou e desceu a tela inteira 42 px. */
.btn.sm { padding: 6px 10px; line-height: 18px; font-size: var(--t-peq); }
/* N3 — AÇÃO DE APOIO SÓ COM ÍCONE: transparente em repouso, 32×32 quadrado,
   ícone 16. `title` e `aria-label` são obrigatórios no HTML (o nome da ação
   só existe neles). Hover pinta o fundo; o foco usa o anel do `.btn`.
   Usado na barra do Cronograma (Imprimir, Documentos, MS Project) e é o
   mesmo que o ⧉ "Abrir em outra janela" deve usar. */
.btn.sm.icone { width: var(--h-ctl); height: var(--h-ctl); padding: 0; background: transparent; border-color: transparent; color: var(--texto); }
.btn.sm.icone:hover { background: var(--surface-2); border-color: var(--linha); }
.btn.sm.icone .ic-svg { width: 16px; height: 16px; }
/* N3 com texto (← Voltar, ".mpp?"): mesma pele do ícone, largura do rótulo */
.btn.sm.n3 { background: transparent; border-color: transparent; }
.btn.sm.n3:hover { background: var(--surface-2); border-color: var(--linha); }
.btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; transform: none; }

/* ---------- Cards ---------- */
/* ⚠ `--raio-lg` NOS CARTÕES, e não um valor novo. O Rogério pediu o Painel com
   a cara de uma peça de divulgação; comparando as duas, medida a medida, o que
   diferia era só o arredondamento (10px contra ~16) e o respiro entre cartões.
   Fundo, sombra em camadas, realce e o hover já estavam certos.
   O 16px NÃO foi escolhido no olho: é o `--raio-lg` que a folha já define e já
   usa noutros lugares — inventar um valor aqui criaria um terceiro raio no
   sistema e a próxima pessoa não saberia qual dos três é o certo. */
.card {
  background: var(--card-bg); border: 1px solid var(--linha);
  border-radius: var(--raio-lg); box-shadow: var(--sombra), var(--realce); padding: 24px;
}
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 18px; }
.orc-card { cursor: pointer; transition: .16s cubic-bezier(.4,0,.2,1); position: relative; overflow: hidden; }
.orc-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: linear-gradient(180deg, var(--aco-claro), var(--aco)); opacity: 0; transform: scaleY(.4); transform-origin: top; transition: .18s; }
.orc-card:hover { border-color: var(--aco); transform: translateY(-3px); box-shadow: var(--sombra-lg), var(--realce); }
.orc-card:hover::before { opacity: 1; transform: scaleY(1); }
.orc-card h3 { margin: 0 0 4px; font-size: var(--t-med); font-weight: var(--p-forte); letter-spacing: -.2px; }
.orc-card .meta { color: var(--texto-fraco); font-size: var(--t-peq); }
.orc-card .valor { font-size: var(--t-tit); font-weight: var(--p-forte); color: var(--verde); margin-top: 10px; letter-spacing: -.4px; }

/* ---------- KPIs ---------- */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); gap: 18px; margin-bottom: 24px; }

/* ---------- Gráficos do Painel ----------
   ⚠ DUAS COLUNAS, E NUNCA TRÊS. São QUATRO cartões de gráfico. O
   `auto-fit,minmax(320px,1fr)` que estava aqui dava 3 colunas num monitor de
   1280px: o quarto cartão caía sozinho na segunda fileira e sobrava meia
   largura de buraco ao lado dele. E com 334px de largura a legenda da rosca
   cortava o nome das categorias — "Mão de ...", "Equipam...", numa tela que
   fala de dinheiro.
   Com duas colunas os quatro fecham 2×2 em qualquer largura, e cada cartão
   passa a ter ~508px. Um ajuste resolve o buraco e a legenda. */
.dash-graf { display: grid; gap: 18px; margin-bottom: 18px; grid-template-columns: 1fr; }

/* ⚠ DUAS COLUNAS SÓ QUANDO O CARTÃO COUBER, e 760px era cedo demais. Medido:
   alargar a janela de 759 para 780px ENCOLHIA o texto do eixo em 54% (17,9px
   → 8,2px), porque duas colunas de 364px são piores que uma de 735px para um
   gráfico de 440 unidades. A janela crescia e a leitura piorava.
   O cartão precisa de ~480px para o gráfico respirar, e a conta medida é
   `conteúdo ≈ viewport − 290`: dois cartões de 480 + 18 de gap pedem 1.268px
   de janela. */
@media (min-width: 1280px) { .dash-graf { grid-template-columns: repeat(2, 1fr); } }

/* ⚠ E O SVG TEM TETO. Sem ele o mesmo `font-size="9.5"` saía com 5,8px num
   cartão de 320 e 19,8px num de 806 — 3,4x de variação para o mesmo número, e
   no monitor grande o rótulo do eixo ficava MAIOR que o título do cartão.
   O viewBox tem 440 unidades: limitar a 560px mantém a escala entre 0,99 e
   1,27, e o texto do eixo entre 9,4 e 12px em qualquer tela. É aqui que se
   controla a legibilidade — não mexendo no font-size de dentro do SVG. */
.dash-graf svg { max-width: 560px; }
.dash-graf .card > svg { display: block; margin: 0 auto; }
.kpi { background: var(--card-bg); border: 1px solid var(--linha); border-radius: var(--raio-lg); padding: 19px 21px; box-shadow: var(--sombra), var(--realce); position: relative; overflow: hidden; transition: .18s cubic-bezier(.4,0,.2,1); }
.kpi::before { content: ""; position: absolute; left: 0; top: 0; right: 0; height: 3px; background: linear-gradient(90deg, var(--linha-forte), var(--linha)); }
.kpi:hover { transform: translateY(-3px); box-shadow: var(--sombra-lg), var(--realce); border-color: var(--linha-forte); }
/* ⚠ `.kpi-lbl` E `.kpi-val` SÃO OS MESMOS SELETORES, e não uma cópia. Eram
   usadas 9 vezes em js/gestao.js e não existiam em CSS nenhum: `grep -rn
   "kpi-lbl\|kpi-val" --include=*.css` voltava vazio. Sem estilo e sendo
   <span>, os dois ficavam INLINE e colados — "Retenção presaR$ 3.205,65" —
   e o valor, que é dinheiro do cliente, saía 25% menor que o de um cartão
   que só conta diários de obra.

   Elas entram na MESMA regra em vez de ganhar uma cópia: duas listas de
   declarações iguais divergem na primeira vez que alguém mexer numa só. O
   `display:block` é o que essas precisam a mais, porque `.rotulo` e `.num`
   são <div> e estas são <span>. */
.kpi .rotulo, .kpi .kpi-lbl { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .8px; color: var(--texto-fraco); font-weight: var(--p-forte); }
.kpi .num, .kpi .kpi-val { font-size: var(--t-tit); font-weight: var(--p-forte); margin-top: 9px; letter-spacing: -.5px; line-height: 1.1; }
.kpi .kpi-lbl, .kpi .kpi-val { display: block; }
.kpi.destaque::before { background: linear-gradient(90deg, var(--verde-claro), var(--verde)); }
.kpi.destaque .num { color: var(--verde); }
.kpi.custo::before { background: linear-gradient(90deg, var(--aco-claro), var(--aco)); }
.kpi.custo .num { color: var(--aco); }
/* brilho radial discreto atrás do número nos KPIs de destaque */
.kpi.destaque::after, .kpi.custo::after { content: ""; position: absolute; right: -30px; top: -30px; width: 120px; height: 120px; border-radius: 50%; pointer-events: none; }
.kpi.destaque::after { background: radial-gradient(circle, rgba(21,128,61,.10), transparent 70%); }
.kpi.custo::after { background: radial-gradient(circle, rgba(46,111,158,.10), transparent 70%); }

/* ---------- Abas ---------- */
/* rolagem lateral em QUALQUER largura: quando as abas cabem o navegador não
   desenha barra nenhuma, então não há custo no desktop. Preso no media query
   de 820px, as 8 abas do editor somam 1059px e as duas últimas ("Relatórios"
   e "BDI & Parâmetros") ficavam fora da tela no iPad. */
.tabs { display: flex; gap: 2px; overflow-x: auto; -webkit-overflow-scrolling: touch; border-bottom: 1px solid var(--linha); margin-bottom: 24px; }
.tabs > .tab { flex: 0 0 auto; }
.tab { position: relative; display: inline-flex; align-items: center; padding: 11px 16px; cursor: pointer; border-bottom: 2px solid transparent; color: var(--texto-fraco); font-weight: var(--p-medio); transition: .14s; border-radius: 8px 8px 0 0; white-space: nowrap; }
.tab:hover { color: var(--texto); background: var(--surface-2); }
.tab.ativa { color: var(--aco); font-weight: var(--p-forte); }
.tab.ativa::after { content: ""; position: absolute; left: 8px; right: 8px; bottom: -1px; height: 2.5px; border-radius: 3px 3px 0 0; background: linear-gradient(90deg, var(--aco), var(--aco-claro)); }

/* ---------- Tabelas ---------- */
table.tbl { width: 100%; border-collapse: collapse; font-size: var(--t-base); }
table.tbl th, table.tbl td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--linha); }
table.tbl th { background: linear-gradient(180deg, var(--surface-2), var(--surface-3)); font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .7px; color: var(--texto-fraco); font-weight: var(--p-forte); position: sticky; top: 0; z-index: 2; border-bottom: 2px solid var(--linha-forte); }
table.tbl th:first-child { border-top-left-radius: 10px; }
table.tbl th:last-child { border-top-right-radius: 10px; }
table.tbl tbody tr { transition: background .12s; }
table.tbl tbody tr:hover td { background: rgba(46,111,158,.06); }
table.tbl tbody tr:last-child td { border-bottom: none; }
table.tbl td.num, table.tbl th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.tbl tr.etapa-row td { background: var(--surface-2); font-weight: var(--p-forte); box-shadow: inset 3px 0 0 var(--aco); }
table.tbl tr.etapa-row:hover td { background: var(--surface-3); }
/* accordion da planilha: a linha continua NO DOM (o refresh de avisos e a
   numeração contam com isso) — some só da tela. A regra fica presa a .oculta,
   nunca a .etapa-row, que também é usada no sintético, no cronograma e no
   preview do importador. */
table.tbl tr.oculta { display: none; }

/* ===== PLANILHA DO ORÇAMENTO: a Descrição precisa de largura ==========
 * Em table-layout auto, a coluna de ações (vários botões) e as numéricas
 * espremiam a Descrição a ponto de o texto quebrar palavra a palavra
 * ("PISO / PODOTÁTIL / DE / ALERTA"), empilhado na vertical. Fixar uma
 * largura mínima devolve a leitura numa linha; o excedente rola de lado
 * dentro do .pl-tabela, sem empurrar a página. word-break NORMAL: quebra
 * entre palavras, nunca no meio delas. */
table.tbl-plan th:nth-child(3), table.tbl-plan tr.lin td:nth-child(3) {
  min-width: 280px; white-space: normal; overflow-wrap: break-word; word-break: normal;
}
/* a tabela não encolhe abaixo do somatório das colunas — garante o scroll
   horizontal do .pl-tabela em vez de espremer tudo */
table.tbl-plan { min-width: 760px; }
/* código e unidade não quebram; a UF/competência e os botões ficam inteiros */
table.tbl-plan tr.lin td:nth-child(2), table.tbl-plan tr.lin td:nth-child(4) { white-space: nowrap; }

/* ===== PARA ONDE VAI A LARGURA QUE SOBRA ==============================
 * A tabela ocupa 100% da área e, em `table-layout: auto`, o navegador
 * reparte a sobra ENTRE TODAS as colunas. Numa tela larga isso dava ~250px
 * para "Custo Total" e "Preço Venda" — colunas cujo conteúdo mede ~90px — e
 * o número, alinhado à direita, ficava a um palmo do próprio rótulo. Ler
 * "qual número é de qual coluna" virava trabalho justamente nas duas
 * colunas que decidem o orçamento.
 *
 * `width:1%` é o pedido "encolha até o seu conteúdo": o navegador não
 * consegue honrar 1% (o conteúdo não cabe), cai na largura mínima do
 * conteúdo, e joga TODA a sobra na única coluna sem `width` — a Descrição,
 * que é exatamente quem se beneficia de espaço.
 *
 * ⚠ `tr.lin` NÃO É ENFEITE — É A CAUSA do vão reclamado. A linha de etapa
 *   tem um `<td colspan="5">`, então ali o nth-child(3) não é a Descrição:
 *   é o Custo Total. A min-width de 280px escrita para a Descrição caía
 *   sobre a coluna do dinheiro e a inflava para 280px na tabela inteira —
 *   número alinhado à direita com 180px de vazio à esquerda. Só a linha de
 *   ITEM tem as 9 colunas; regra de coluna pertence a `tr.lin` e ao
 *   `thead`, nunca a um `td:nth-child(N)` solto.
 *
 * ⚠ Qtd (5) e Custo Unit (6) levam `width` mas NÃO `nowrap`: são
 *   `input.cell` com `width:100%` e `min-width:88px` (regra lá em cima), e
 *   o selo de ajuste mora dentro da célula de custo. A largura mínima do
 *   conteúdo já reserva o campo; travar a quebra espremeria o selo.
 * ===================================================================== */
table.tbl-plan th:nth-child(1), table.tbl-plan tr.lin td:nth-child(1),
table.tbl-plan th:nth-child(2), table.tbl-plan tr.lin td:nth-child(2),
table.tbl-plan th:nth-child(4), table.tbl-plan tr.lin td:nth-child(4),
table.tbl-plan th:nth-child(7), table.tbl-plan tr.lin td:nth-child(7),
table.tbl-plan th:nth-child(8), table.tbl-plan tr.lin td:nth-child(8),
table.tbl-plan th:nth-child(9), table.tbl-plan tr.lin td:nth-child(9) {
  width: 1%; white-space: nowrap;
}
table.tbl-plan th:nth-child(5), table.tbl-plan tr.lin td:nth-child(5),
table.tbl-plan th:nth-child(6), table.tbl-plan tr.lin td:nth-child(6) { width: 1%; }

/* ===== MODO COMPACTO DA PLANILHA ==================================
 * Obra grande tem dezenas de itens e a linha alta obriga a rolar sem parar.
 * O compacto corta o respiro vertical e desce um degrau na fonte — sem mexer
 * na largura da Descrição (que foi o conserto anterior) e sem esconder nada.
 * ⚠ Os alvos de clique dos botões da linha NÃO encolhem junto: continuam
 *   confortáveis para o dedo, senão o compacto viraria uma armadilha em tablet
 *   no canteiro. */
table.tbl-compacta th, table.tbl-compacta td { padding: 5px 10px; }
table.tbl-compacta { font-size: var(--t-peq); }
table.tbl-compacta th:nth-child(3), table.tbl-compacta tr.lin td:nth-child(3) { min-width: 240px; }
/* a descrição em 2 linhas no máximo; o resto fica no title/tooltip da célula */
table.tbl-compacta tr.lin td:nth-child(3) {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
table.tbl-compacta .pill { padding: 1px 6px; }
table.tbl-compacta tr.etapa-row td { padding-top: 7px; padding-bottom: 7px; }
table.tbl-compacta .btn.sm { padding: 3px 7px; }

/* Tabela larga no celular (triagem da nota tem 11 colunas): a coluna da
   DESCRIÇÃO fica fixa ao rolar para o lado — sem ela o usuário chega no
   seletor de obra sem saber de qual produto se trata. */
@media screen and (max-width: 820px) {
  .main div[style*="overflow-x"] table.tbl th:nth-child(3),
  .main div[style*="overflow-x"] table.tbl td:nth-child(3) {
    position: sticky; left: 0; z-index: 2;
    background: var(--surface); box-shadow: 2px 0 0 var(--linha);
    max-width: 46vw;
  }
}
table.tbl tr.etapa-row td[data-toggle-etapa] { user-select: none; }
table.tbl tr.etapa-row td[data-toggle-etapa]:hover { background: var(--surface-3); }
/* SUB ETAPA (1.1) — MESMA fonte e MESMO tamanho da etapa (pedido do dono): a
   hierarquia fica por NÚMERO (1.1 vs 1), RECUO e TOM, nunca por tipografia menor.
   Por isso não há font-size nem font-weight aqui: herdam de .etapa-row.

   O FUNDO É 30% MAIS CLARO QUE O DA ETAPA — mas medido em direção à SUPERFÍCIE
   DA TABELA, não ao branco absoluto. No tema claro a superfície É branca, então
   isto é literalmente "30% mais claro" (#eef2f7 → #f3f6f9). No tema ESCURO,
   clarear 30% rumo ao branco levaria #16293a a #5a6875: a sub etapa passaria a
   gritar MAIS que a etapa e a hierarquia se inverteria. Indo 30% rumo à
   superfície (#11202e), ela se aproxima do fundo e continua um degrau ABAIXO —
   que é a intenção. Uma fórmula, dois temas corretos.

   O número (1.1 vs 1) é o sinal que sobrevive ao aperto de tela no celular — por
   isso o item da sub etapa NÃO ganha recuo extra (a coluna já cresce de 1.1 para
   1.1.1 sozinha). */
table.tbl tr.etapa-row.subetapa td {
  background: var(--faixa-sub);
  color: var(--texto);                    /* MESMA cor de texto da etapa (pedido do dono) */
  box-shadow: inset 3px 0 0 var(--aco);   /* 4,99:1 contra a faixa no tema claro */
}
/* hover: um passo a partir do PRÓPRIO repouso da sub etapa. Pintar --surface-2 aqui
   (como estava) deixava a sub etapa com o fundo EXATO da etapa em repouso — passar o
   mouse nela a transformava visualmente numa etapa. */
table.tbl tr.etapa-row.subetapa:hover td { background: color-mix(in srgb, var(--faixa-sub) 88%, var(--aco) 12%); box-shadow: inset 3px 0 0 var(--aco); }
/* chevron e número na MESMA linha: com o recuo de 22px a célula ficava estreita e
   o "▾" caía em cima do "1.1", deixando a linha 12px mais alta que a da etapa. */
table.tbl tr.etapa-row.subetapa td:first-child { padding-left: 22px; white-space: nowrap; }
/* RODAPÉ DE TOTAIS da planilha — última linha da tabela, para a planilha fechar
   somando. O total sempre à vista fica nos cartões do topo do editor.
   Escopado nas DUAS classes (e não em "tfoot td"): outras telas do app têm tfoot
   com layout próprio e herdariam este fundo/negrito sem pedir. */
table.tbl tfoot tr.tot-linha td,
table.tbl tfoot tr.tot-geral td { background: var(--surface-2); font-weight: var(--p-forte); border-top: 2px solid var(--linha-forte); }
table.tbl tfoot tr.tot-linha td { font-weight: var(--p-medio); color: var(--texto-fraco); font-size: var(--t-peq); }
table.tbl tfoot tr.tot-geral td { background: var(--tot-fundo); color: #fff; font-size: var(--t-base); border-top: 0; }
table.tbl tfoot tr.tot-geral td .muted { color: rgba(255,255,255,.72) !important; }
table.tbl tfoot tr.tot-geral td:nth-last-child(2) { color: #7ee2a8; } /* preço de venda em destaque */
table.tbl tr.etapa-row.subetapa td:nth-child(2) { padding-left: 18px; }
/* seletor "em que grupo este item está" — discreto até o hover, para não
   competir com os números na planilha */
table.tbl select.sel-sub { max-width: 122px; font-size: var(--t-micro); padding: 3px 4px; border: 1px solid transparent; background: transparent; color: var(--texto-fraco); border-radius: var(--raio-sm); cursor: pointer; }
table.tbl select.sel-sub:hover, table.tbl select.sel-sub:focus { border-color: var(--linha-forte); background: var(--surface); color: var(--texto); }
@media screen and (max-width: 820px) { table.tbl select.sel-sub { max-width: 88px; } }
table.tbl input.cell { width: 100%; border: 1px solid transparent; background: transparent; padding: 5px 7px; border-radius: var(--raio-sm); text-align: right; transition: .1s; }
/* ⚠ COLUNA DE NÚMERO NÃO PODE SER DIMENSIONADA PELA PALAVRA DO CABEÇALHO.
   `width: 100%` num input dentro de célula de tabela não pede largura
   nenhuma: a coluna fecha no min-content, que aqui é a palavra "Qtd". Com o
   padding de 16px de cada lado da célula sobravam 23,7px para o campo — e
   "12,50" precisa de 59px. Medido: o orçamentista via literalmente "1" no
   lugar de "12,50", e "1.2" no lugar de "1.234,56". Não é estética: ele não
   consegue LER a quantidade que digitou, nem acertar um alvo de 23,7px.
   Some no monitor largo (a partir de ~1440px o campo cresce sozinho), e é
   por isso que passou despercebido — quebrava no iPhone, no iPad e em
   qualquer janela abaixo de ~1366px.
   O `min-width` fica escopado em `[data-edit]` de propósito: os outros
   `.cell` do app (coeficiente, preço de insumo, duração do cronograma) têm
   largura própria em estilo inline e não podem ser alargados por tabela. */
/* 88px = 14 de padding + 2 de borda + 72 de conteúdo. A medição do achado deu
   59px para "12,50" na coluna Qtd; "1.234,56" no Custo Unitário pede mais, e
   é a mesma regra que atende as duas. 72px de conteúdo cobre as duas com
   folga, sem alargar a tabela a ponto de estorvar no desktop. */
table.tbl input.cell[data-edit] { min-width: 88px; }
/* e a coluna aperta o padding lateral para devolver espaço ao número, em vez
   de gastá-lo em margem — só onde a tela é estreita */
@media screen and (max-width: 1100px) {
  table.tbl td.num, table.tbl th.num { padding-left: 8px; padding-right: 8px; }
}
table.tbl input.cell:hover { border-color: var(--linha-forte); background: var(--surface); }
table.tbl input.cell:focus { border-color: var(--aco); background: var(--surface); box-shadow: 0 0 0 3px rgba(46,111,158,.13); outline: none; }
table.tbl td.right { text-align: right; white-space: nowrap; }
table.tbl td.num-item { white-space: nowrap; text-align: center; font-variant-numeric: tabular-nums; color: var(--aco); font-weight: var(--p-forte); }
.acoes { display: inline-flex; align-items: center; gap: 5px; flex-wrap: nowrap; justify-content: flex-end; }
.btn.sm.ico { padding: 6px 7px; min-width: 28px; font-size: var(--t-base); }
/* =====================================================================
 * PÍLULA DE FONTE DE PREÇO (SINAPI, SEINFRA, ORSE, SUDECAP…)
 *
 * ⚠ O TOM CLARO FOI RECALIBRADO NA v1.2, E O MOTIVO IMPORTA.
 * Estas cores nasceram escolhidas contra BRANCO PURO. Só que a pílula quase
 * nunca cai sobre branco: ela mora na planilha, e ali o fundo é
 * `--surface-2` — a faixa de etapa (`table.tbl tr.etapa-row td`) e o hover do
 * resultado da busca (`.sinapi-result:hover`), que é o estado normal enquanto
 * a pessoa mira a linha que vai clicar. Sobre `--surface-2` dez das dezenove
 * reprovavam AA, as piores em 2,77:1 (sudecap) e 2,82:1 (seinfra).
 *
 * A correção mantém MATIZ e SATURAÇÃO de cada base e só escurece a
 * luminosidade até passar de 4,7:1 contra o PIOR dos dois fundos. Matiz é
 * função, não enfeite: a pílula existe para dizer DE QUAL base veio o preço,
 * e é isso que o orçamentista aponta para justificar preço em licitação —
 * colapsar duas bases na mesma cor destruiria o uso dela.
 *
 * ⚠ E foi medido nos DOIS temas, de propósito. O defeito que esta rodada
 * conserta nasceu de alguém medir só o escuro em 2025, escrever 18 correções
 * e nunca voltar ao claro — que é o tema PADRÃO do app (index.html
 * data-tema="light"). Meia proteção carimba de aprovado exatamente o buraco.
 * A régua roda em tools/test-contraste-selos.js, que deriva a lista deste
 * próprio bloco: base nova entra já coberta.
 * ===================================================================== */
/* ⚠ PILL É SANS, 24 px, SEM SOMBRA INTERNA (régua, 14/09/2026). Sem
   `font-family` a pill herdava o Mono do `td.num` onde mora: a "crítica" da
   coluna Folga pedia 700 e desenhava 500 (o Mono só tem 400–500), mais leve
   que o texto normal ao lado — hierarquia falsa. `line-height` escrito:
   18 + 3 + 3 = 24, e não 1.4 × 12 = 16,8 → 22,8. */
.pill { display: inline-block; font-family: var(--fonte); font-size: var(--t-micro); font-weight: var(--p-forte); padding: 3px 9px; border-radius: 999px; letter-spacing: .2px; line-height: 18px; box-shadow: none; }
/* ⚠ sinapi é a pílula PADRÃO (`r.cor || "sinapi"` no render do item), e era a
   única sem cor própria: usava `var(--aco)`, token tematizado, e por isso
   PARECEU resolvida nos dois lados. Reprovava nos dois — 4,41:1 no claro e
   4,10:1 no escuro. O token foi calibrado contra a SUPERFÍCIE, não contra o
   fundo azulado da própria pílula; são medições diferentes. --aco fica como
   está (passa nos usos dele); quem ganha valor próprio é a pílula. */
.pill.sinapi { background: rgba(46,111,158,.15); color: #29638c; }
.pill.proprio, .pill.propria { background: rgba(245,158,11,.18); color: #a14a08; }
/* aviso sob a composição na planilha: insumo sem preço coletado no detalhamento.
   ⚠ A cor era o hex #b45309 CRAVADO — que é, literalmente, o valor claro do
   token --graf-aviso. Não foi escolha: foi o token copiado à mão e depois
   esquecido quando o tema escuro ganhou o par dele. Sem par, no escuro esse
   marrom caía para 3,02:1 sobre o cartão. Trocando o hex pelo token, o claro
   não muda um pixel (--graf-aviso vale #b45309 lá) e o escuro passa a 7,29:1.
   --graf-aviso é o token certo: ele existe justamente para "atenção, em TEXTO". */
tr.tr-aviso-insumo td { padding: 4px 16px 8px 16px !important; border-bottom: 1px solid var(--linha); background: rgba(234,88,12,.05); font-size: var(--t-peq); color: var(--graf-aviso); }
tr.tr-aviso-insumo b { cursor: pointer; text-decoration: underline; text-underline-offset: 2px; }
.pill.sicro { background: rgba(161,98,7,.15); color: #865206; }
.pill.seinfra { background: rgba(13,148,136,.15); color: #096c63; }
.pill.setop { background: rgba(124,58,237,.15); color: #7027eb; }
.pill.sudecap { background: rgba(8,145,178,.15); color: #066981; }
.pill.orse { background: rgba(219,39,119,.15); color: #af1d5e; }
.pill.sbc { background: rgba(100,116,139,.15); color: #475569; }
.pill.emop { background: rgba(225,29,72,.13); color: #be123c; }
.pill.cpos { background: rgba(37,99,235,.13); color: #1d4ed8; }
.pill.fde { background: rgba(5,150,105,.14); color: #046e50; }
.pill.agetop { background: rgba(234,88,12,.14); color: #ac3a0b; }
.pill.sedop { background: rgba(21,128,61,.14); color: #126e35; }
.pill.cehop { background: rgba(2,132,199,.14); color: #036499; }
.pill.iopes { background: rgba(180,83,9,.14); color: #994708; }
.pill.deinfra { background: rgba(79,70,229,.14); color: #4338ca; }
.pill.der { background: rgba(71,85,105,.16); color: #334155; }
.pill.cdhu { background: rgba(147,51,234,.14); color: #7e22ce; }
.pill.outra { background: rgba(148,163,184,.18); color: #556376; } /* FASE 1.2: código de fonte desconhecida */
/* REGIME desonerado: badge verde sob o código, para o item saltar aos olhos
   (encargo social diferente). Onerado é o padrão e não recebe selo. */
/* ⚠ Este selo nasceu (1.2.42, pela linha da landing) com `font-size: 9px` e
   `color: #15803d`, e as duas coisas eram defeito: 9px fica abaixo do piso de
   12px que esta base adota para tela de canteiro, e o verde dava 4,24:1 sobre
   --surface e 3,82:1 sobre --surface-2, contra o mínimo de 4,5. O tamanho volta
   a herdar --t-micro do `.pill` (o padding apertado é que mantém o selo
   discreto sob o código), e o verde desce um degrau para #166534 — medido em
   6,03:1 e 5,43:1. O escuro já passava (7,74 e 6,96) e não muda. */
.pill.regime-des { background: rgba(22,163,74,.15); color: #166534; padding: 1px 6px; margin-top: 2px; }
[data-tema="dark"] .pill.regime-des { color: #4ade80; }
/* LICITAÇÃO: selo "acima do órgão" sob o código do item (js/ui.js). Mesmo
   molde do selo do regime, logo acima: herda --t-micro e --p-forte do `.pill`.
   ⚠ Nasceu (1.2.135) com tamanho 10px e peso 700 escritos à mão — abaixo do
   piso de 12px da tela de canteiro e fora da régua; o gate da 1.2.136 pegou
   pelo tools/test-contraste.js ("tamanho de fonte solto", "peso solto"). */
.pill.lic-alerta { background: rgba(220,38,38,.12); color: #991b1b; padding: 1px 6px; margin-top: 2px; }
[data-tema="dark"] .pill.lic-alerta { color: #fca5a5; }
/* Dark: texto claro para não sumir sobre superfície escura */
/* ⚠ `.propria` (com A) faltava aqui, e o par claro sempre teve as duas
   grafias. Conferido: hoje o render só emite `pill proprio`, então isto é
   armadilha ARMADA e não defeito à solta — no dia em que alguém escrever a
   forma feminina, ela sai marrom #b45309 sobre superfície escura, 2,15:1, o
   pior número de todo o conjunto, e sem nada acusando. É assim que se produz
   um buraco desses: lista de correção escrita à mão, uma grafia de cada vez. */
[data-tema="dark"] .pill.proprio, [data-tema="dark"] .pill.propria { color: #fbbf24; }
/* o par escuro que faltava para a pílula mais usada. Vem do token da marca
   (--aco-claro no escuro = #7fb4da): 5,82:1, e continua sendo o azul de aço. */
[data-tema="dark"] .pill.sinapi { color: var(--aco-claro); }
[data-tema="dark"] .pill.sicro { color: #d0a24a; }
[data-tema="dark"] .pill.seinfra { color: #2dd4bf; }
[data-tema="dark"] .pill.setop { color: #a78bfa; }
[data-tema="dark"] .pill.sudecap { color: #22c3e6; }
[data-tema="dark"] .pill.orse { color: #f472b6; }
[data-tema="dark"] .pill.sbc { color: #94a3b8; }
[data-tema="dark"] .pill.emop { color: #fb7185; }
[data-tema="dark"] .pill.cpos { color: #93c5fd; }
[data-tema="dark"] .pill.fde { color: #6ee7b7; }
[data-tema="dark"] .pill.agetop { color: #fdba74; }
[data-tema="dark"] .pill.sedop { color: #86efac; }
[data-tema="dark"] .pill.cehop { color: #7dd3fc; }
[data-tema="dark"] .pill.iopes { color: #fbbf24; }
[data-tema="dark"] .pill.deinfra { color: #a5b4fc; }
[data-tema="dark"] .pill.der { color: #cbd5e1; }
[data-tema="dark"] .pill.cdhu { color: #d8b4fe; }
/* era #94a3b8: passava sobre --surface (4,68) e reprovava sobre --surface-2
   (4,23), que é a faixa de etapa. --texto-fraco do escuro (#9db0c2) sobe para
   4,86 nos dois fundos — e é o token semanticamente certo: "outra" quer dizer
   fonte NÃO identificada, informação de apoio. */
[data-tema="dark"] .pill.outra { color: var(--texto-fraco); }

/* ---------- Modal ---------- */
.modal-bg { position: fixed; inset: 0; background: rgba(8,18,30,.55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); display: flex; align-items: center; justify-content: center; z-index: 50; padding: 20px; animation: fadein .15s; }
/* ⚠ LARGURA POR CONTEÚDO, e não uma medida só para tudo (09/09/2026).
 * Os 760 px valiam para um formulário de cadastro, e sufocavam as telas que
 * são o trabalho de verdade: o Mapa de Cotação com 40 itens × N fornecedores
 * abria com a descrição do material cortada em 20 caracteres ("TUBO PVC SERIE
 * NORMAL, D…" para quatro bitolas diferentes) e a coluna de preço espremida —
 * numa janela de 1500 px, com 700 px sobrando de véu escuro dos dois lados.
 * Quem precisa comparar preço item a item lia quatro linhas idênticas.
 *
 * ⚠ NÃO É "TUDO GRANDE": um "tem certeza?" de duas linhas com 1580 px de
 *   largura é pior que o problema que resolve — a frase atravessa a tela e o
 *   botão fica longe do texto. Quem decide é o conteúdo, no `UI.modal`: corpo
 *   com <table> (grade de itens, comparativos, listas longas) ganha `largo`.
 *
 * ⚠ SEM `min()`/`clamp()` DE PROPÓSITO: o produto roda em WebView de
 *   instalador antigo (ver CLAUDE.md) e função de CSS que o motor não conhece
 *   invalida a declaração inteira — o modal voltaria ao tamanho de fábrica sem
 *   ninguém entender por quê. O `padding` do `.modal-bg` já garante que o
 *   modal nunca encoste na borda, então `max-width` sozinho basta. */
.modal { background: var(--surface); border: 1px solid var(--linha); border-radius: var(--raio-lg); box-shadow: var(--sombra-lg); width: 100%; max-width: 880px; max-height: 92vh; display: flex; flex-direction: column; overflow: hidden; animation: popin .18s cubic-bezier(.16,1,.3,1); }
.modal.largo { max-width: 1580px; max-height: 94vh; }
.modal.largo .body { padding: 16px 18px; }
/* ⚠ ALARGAR O MODAL NÃO ALARGA O QUE ESTÁ DENTRO — medido na foto do headless
 * em 09/09/2026, com o Mapa já em 1560 px: os cards de fornecedor esticaram
 * junto (são `flex:1`) e os campos ficaram do tamanho de fábrica dentro deles,
 * com um vão de 300 px depois de cada um; o "Condição (ex.: 28 dias)" virou uma
 * caixinha perdida no canto. Quem olha lê isso como tela quebrada, não como
 * tela grande. O card do fornecedor é um bloco de formulário: os campos dele
 * ocupam a largura que o card tiver, seja ela qual for. */
[data-ct-forn] input:not([type="hidden"]), [data-ct-forn] select { width: 100%; }
[data-ct-forn] .row { display: flex; gap: 6px; }
[data-ct-forn] .row > input { flex: 1; min-width: 0; }
.modal header { padding: 18px 24px; border-bottom: 1px solid var(--linha); display: flex; align-items: center; background: linear-gradient(180deg, var(--surface-2), var(--surface)); }
.modal header h2 { margin: 0; font-size: var(--t-tit); font-weight: var(--p-forte); letter-spacing: -.3px; }
@keyframes fadein { from { opacity: 0; } to { opacity: 1; } }
@keyframes popin { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
.modal .body { padding: 20px; overflow: auto; }
/* wrap: com 3 botões (ex.: "Cancelar / Excluir só a obra / Excluir tudo") o rodapé
 * nowrap empurrava o Cancelar para FORA da tela no celular — ninguém conseguia
 * desistir justamente no modal mais perigoso. Quebra a linha em vez de estourar.
 * NÃO invertemos a ordem em tela pequena: o app tem modais com o botão perigoso em
 * posições diferentes (Excluir família, Limpar assinatura, ‹ Voltar do wizard), e
 * qualquer inversão global colocaria um deles debaixo do polegar. A ordem visual
 * segue a ordem do autor — que é também a ordem de foco do teclado. */
.modal footer { padding: 14px 20px; border-top: 1px solid var(--linha); display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; }
.modal footer > button { max-width: 100%; }

/* ---------- Form ---------- */
.field { margin-bottom: 14px; }
.field label { display: block; font-size: var(--t-peq); font-weight: var(--p-medio); color: var(--texto-fraco); margin-bottom: 5px; }
/* ⚠ CHECKBOX E RADIO FICAM DE FORA. Esta regra veste campo de digitação —
   largura cheia, padding e borda. Aplicada a uma caixa de marcar, ela
   transformava a checkbox num retângulo de largura total com borda, e o texto
   ao lado era empurrado para fora do container: no celular e no iPad virava
   uma caixa enorme e vazia com o texto espremido numa coluna cortada. */
/* ⚠ `background-color`, NUNCA o atalho `background` (14/09/2026). Esta regra
   tem a MESMA especificidade de `select:not(.cell)` (lá em cima, que desenha
   a seta com `background-repeat: no-repeat`) e vem depois: o atalho zerava a
   imagem e o repeat. No claro a seta do <select> sumia (o "Nenhum" do
   Paralelismo parecia caixa de texto); no escuro o `:root[data-tema="dark"]
   select:not(.cell)` devolvia só a imagem, e o `repeat` que o atalho deixou
   LADRILHAVA a seta pelo campo inteiro (medido: background-repeat: repeat).
   e2e-padrao-cronograma confere `no-repeat` + imagem nos dois temas. */
.field input:not([type="checkbox"]):not([type="radio"]), .field select, .field textarea {
  width: 100%; padding: 10px 12px; border: 1px solid var(--linha-forte);
  border-radius: var(--raio-sm); background-color: var(--surface); color: var(--texto);
  transition: border-color .14s, box-shadow .14s;
}
.field input[type="checkbox"], .field input[type="radio"] { width: auto; margin: 3px 0 0; }

/* ⚠ CAIXA DE MARCAR NÃO ESTICA — REGRA GLOBAL, e ela existe por causa do
   Safari do iPhone.
   O Chrome trava a checkbox no tamanho intrínseco e ignora `width`, então o
   defeito NÃO aparece em emulação — foi por isso que eu não consegui
   reproduzir a captura do cliente a 375px. O Safari do iOS faz o contrário:
   com padding/border aplicados a caixa sai do desenho nativo e vira um
   retângulo que estica até a largura do container, empurrando o texto ao lado
   para fora da tela. É a "caixa enorme e vazia com o texto cortado".
   `flex: 0 0 auto` fecha a porta em qualquer motor: dentro de um container
   flex — que é como TODAS as 60 linhas de opção do app são montadas — a
   caixa não cresce nem encolhe, independentemente do que outra regra tente. */
input[type="checkbox"], input[type="radio"] { flex: 0 0 auto; }

/* ---------- LINHA DE OPÇÃO: [caixa de marcar] + texto explicativo ----------
   O padrão aparece dezenas de vezes (publicar no Portal, relatórios liberados,
   consentimento, escolhas de exportação) e vinha escrito à mão em cada lugar,
   com medidas ligeiramente diferentes. Aqui vira uma classe só.
   ⚠ `min-width:0` no texto é o que impede o estouro horizontal: um item de
   flex não encolhe abaixo do próprio conteúdo por padrão (`min-width:auto`),
   e uma frase longa empurra o container para fora da tela — que é como o
   modal do Portal ganhava barra de rolagem lateral no celular. */
.opt-linha { display: flex; gap: 9px; align-items: flex-start; font-size: var(--t-base); cursor: pointer;
  border: 1px solid var(--linha); border-radius: var(--raio); padding: 11px 13px; }
.opt-linha + .opt-linha { margin-top: 6px; }
.opt-linha > span { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
/* fundo claro FIXO pede texto escuro fixo: no tema escuro o nome herdava o
   texto claro do tema e sumia (1,06:1) — é justamente o relatório que revela
   custo ao cliente, e ele precisa ser lido antes de marcar */
.opt-linha.opt-alerta { background: #fff7ed; border-color: #fdba74; color: #111d2b; }
.opt-linha.opt-alerta .muted { color: #9a3412; }
.opt-linha.opt-nu { border: 0; padding: 0; }
/* alvo de toque confortável no celular, sem mexer no desenho do desktop */
@media (max-width: 820px) {
  .opt-linha { padding: 12px; }
  .opt-linha input[type="checkbox"], .opt-linha input[type="radio"] { width: 18px; height: 18px; }
}
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--aco-claro); }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--aco); outline: none; box-shadow: var(--anel); }
.field input::placeholder, .field textarea::placeholder { color: var(--texto-fraco); opacity: .7; }
/* A grade era 1fr 1fr FIXO: toda linha de formulario tinha duas colunas,
   tivesse ela 1, 3 ou 4 campos. Das 112 linhas do sistema, 57 saiam erradas —
   as de 3 campos viravam 2 + 1 orfao (169px de altura em vez de 79, com um
   buraco de 347px ao lado) e as de 1 campo ocupavam metade da largura a toa.
   Era o "nao aproveita o espaco" que o cliente descreveu.
   Agora a linha cria quantas colunas couberem e os campos esticam para
   preencher: 2 campos continuam 2 colunas, 3 campos viram 3, e no celular
   o `min(100%, ...)` derruba tudo para uma coluna so. */
.row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 150px), 1fr)); gap: 14px; }
/* ⚠ `screen and` é obrigatorio: sem isso a regra vale no PRINT tambem, porque
   a folha A4 tem ~794px de largura — menos que o ponto de corte — e todo
   impresso do sistema sairia com os campos empilhados. Ja custou um conserto. */
@media screen and (max-width: 640px) { .row { grid-template-columns: 1fr; } }

/* ⚠ O MENU DA CONTA SAÍA PELA BORDA ESQUERDA NO CELULAR.
 * `.conta-drop` ancora em `right: 0` do CHIP (`.topbar-conta`, position:relative).
 * No desktop o chip fica na direita da tela e os 252px do menu cabem folgados.
 * No celular o chip desce para a segunda linha e vai para a ESQUERDA (x=67 num
 * aparelho de 375): `right: 0` dele jogava o menu para `left: -96`, ou seja
 * 38% dele fora da tela. "Dados da empresa", "Tabelas de preço" e "Nuvem" —
 * exatamente os itens que o cliente citou — ficavam cortados na borda.
 *
 * Conserto: o menu passa a pendurar pela ESQUERDA do chip. Quando a barra
 * quebra, o chip está encostado na borda esquerda, então o menu abre para
 * dentro da tela. Quando não quebra, o chip está na direita e o menu, com
 * seus 252px contra os 230 de largura máxima do chip, ultrapassa a borda
 * dele em no máximo 22px — que é menos que o respiro da barra.
 *
 * ⚠ E SEM MEDIA QUERY, DE PROPÓSITO. Minha primeira tentativa travou isto em
 * `max-width: 640px` e, medindo em 790px, o menu AINDA saía em `left: -10`
 * com os 10 itens cortados: a barra passa a duas linhas muito antes dos 640,
 * e o ponto exato depende do nome da empresa e dos botões que estiverem no
 * topo. Breakpoint aqui é chute que volta a quebrar quando o conteúdo muda.
 *
 * ⚠ E NÃO ancorei na `.topbar` inteira (tirando o `relative` do chip), que
 * também resolvia o vazamento: em 790px o menu ia parar em 516–790 enquanto
 * o botão ficava em 12–242, do outro lado da tela. Menu solto do botão que o
 * abriu é conserto que troca um defeito por outro. */
.conta-drop { right: auto; left: 0; max-width: calc(100vw - 20px); min-width: 0; transform-origin: top left; }

/* ---------- Busca SINAPI ---------- */
.sinapi-result { border: 1px solid var(--linha); border-radius: var(--raio); padding: 10px 12px; margin-bottom: 8px; display: flex; align-items: center; gap: 12px; }
.sinapi-result:hover { border-color: var(--aco); background: var(--surface-2); }
.sinapi-result .desc { flex: 1; }
.sinapi-result .cod { font-weight: var(--p-forte); color: var(--aco); font-size: var(--t-peq); }
.sinapi-result .preco { font-weight: var(--p-forte); color: var(--verde); white-space: nowrap; }

/* ---------- Login (split premium: marca + formulário) ---------- */
.login-wrap { display: grid; grid-template-columns: 1.05fr .95fr; height: 100%; min-height: 100%; background: var(--surface); }
.login-hero { position: relative; overflow: hidden; color: #fff; display: flex; align-items: center; padding: 56px 62px;
  background: radial-gradient(900px 620px at 72% -12%, #1c4b73 0, #0c1f33 62%, #081826 100%); }
.login-hero .lh-grid { position: absolute; inset: 0; opacity: .55;
  background-image: linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px), linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size: 46px 46px; -webkit-mask-image: radial-gradient(680px 520px at 38% 42%, #000, transparent 82%); mask-image: radial-gradient(680px 520px at 38% 42%, #000, transparent 82%); }
.login-hero::after { content: ""; position: absolute; right: -140px; top: -120px; width: 460px; height: 460px; border-radius: 50%; background: radial-gradient(circle, rgba(111,208,138,.18), transparent 70%); }
.lh-content { position: relative; z-index: 1; max-width: 470px; }
.lh-logo { display: flex; align-items: center; gap: 13px; font-size: var(--t-hero); font-weight: var(--p-forte); letter-spacing: -.6px; margin-bottom: 34px; }
.lh-logo b { background: var(--verde); color: #fff; font-size: var(--t-base); padding: 2px 8px; border-radius: var(--raio-sm); margin-left: 3px; vertical-align: 3px; box-shadow: 0 3px 10px rgba(21,128,61,.42); }
.lh-h { font-size: var(--t-hero); font-weight: var(--p-forte); line-height: 1.13; letter-spacing: -1px; margin-bottom: 28px; }
.lh-h em { font-style: normal; color: var(--verde-claro); }
.lh-feats { list-style: none; margin: 0 0 30px; padding: 0; }
.lh-feats li { position: relative; padding: 9px 0 9px 34px; color: #cfe0ee; font-size: var(--t-med); }
.lh-feats li::before { content: "✓"; position: absolute; left: 0; top: 9px; width: 22px; height: 22px; border-radius: 50%; background: rgba(111,208,138,.18); color: var(--verde-claro); font-weight: var(--p-forte); font-size: var(--t-peq); display: flex; align-items: center; justify-content: center; }
.lh-trust { font-size: var(--t-base); color: #9fb6cc; border-top: 1px solid rgba(255,255,255,.11); padding-top: 20px; }
.login-formside { display: flex; align-items: center; justify-content: center; padding: 44px; overflow: auto; background: var(--surface); }
.login-card { width: 100%; max-width: 384px; }
.login-card .brand { margin-bottom: 26px; }
.login-card .brand .lc-logo { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.login-card .brand .nome { font-size: var(--t-tit); font-weight: var(--p-forte); color: var(--texto); letter-spacing: -.3px; }
/* mesmo remédio do selo IA da barra de cima (ver o bloco em .topbar .logo-ia):
   chapado no lugar do gradiente, porque o branco cruzava o degradê e quem
   mandava era a ponta clara — 3,56:1 no tema claro e 1,90:1 no escuro. Aqui o
   selo pousa sobre --surface, não sobre o navy, mas o hex fixo vale igual: ele
   é um chip PREENCHIDO, então a superfície atrás não entra na conta do texto,
   e o próprio chip continua se destacando do fundo escuro (3,30:1). */
.login-card .brand .nome .ia { display: inline-block; margin-left: 4px; padding: 1px 6px; border-radius: var(--raio-sm); background: #15803d; color: #fff; font-size: var(--t-peq); font-weight: var(--p-forte); letter-spacing: .5px; vertical-align: 2px; }
.login-card .brand .slogan { color: var(--texto-fraco); font-size: var(--t-base); }
.login-card .field input { padding: 11px 13px; }

/* ---- Entrar pelo celular (11/09/2026) ----
   O olho da senha e a caixa de criar conta. ⚠ O campo precisa de padding à
   direita do tamanho do botão: sem isso a senha passa POR BAIXO do olho e a
   pessoa não lê justamente o que o olho existe para mostrar. */
.lg-senha-wrap { position: relative; }
.lg-senha-wrap input { width: 100%; padding-right: 44px; }
.lg-olho {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  /* ⚠ 40x40: alvo de toque de dedo. Ícone de 17px num botão de 20px é o que
     faz a pessoa errar o clique três vezes e desistir. */
  width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--texto-fraco); border-radius: var(--raio-sm);
}
.lg-olho:hover { color: var(--texto); background: var(--surface-2, rgba(127,127,127,.12)); }
.lg-olho:focus-visible { outline: 2px solid var(--aco); outline-offset: 1px; }
.lg-nova { margin-top: 14px; }
.lg-nova > summary {
  cursor: pointer; font-size: var(--t-peq); color: var(--texto-fraco);
  /* alvo de toque: no celular um <summary> de uma linha é difícil de acertar */
  padding: 8px 2px; list-style: none; text-align: center;
}
.lg-nova > summary::-webkit-details-marker { display: none; }
.lg-nova > summary:hover { color: var(--aco); }

@media (max-width: 860px) {
  .login-wrap { grid-template-columns: 1fr; }
  .login-hero { display: none; }
  .login-formside { padding: 28px 22px; align-items: flex-start; padding-top: 56px; }
  /* ⚠ 16px NO CAMPO, E NÃO É ESTÉTICA: abaixo de 16px o Safari do iPhone DÁ
     ZOOM sozinho ao focar o campo, a tela salta, e a pessoa perde de vista o
     resto do formulário. É o comportamento que faz "o site desconfigurar"
     quando se vai digitar a senha. */
  .login-card .field input { font-size: var(--t-campo-toque); padding: 13px 13px; }
  .lg-senha-wrap input { padding-right: 46px; }
}

/* ========== Mobile / Tablet (app instalável no celular) ========== */
/* ⚠ O ZOOM DO iOS É QUESTÃO DE APARELHO, NÃO DE LARGURA.
 * O Safari do iPhone e do iPad AMPLIA a página inteira ao focar qualquer
 * campo com fonte abaixo de 16px, e depois não desfaz o zoom — o usuário
 * fica com a tela deslocada e tem que reenquadrar na mão a cada digitação.
 * A regra que sobe a fonte para 17px existia, mas presa no
 * `@media (max-width: 820px)`: o iPad em pé tem 834px e ficava de fora,
 * justamente onde há mais formulário na tela. `(pointer: coarse)` pergunta
 * o que importa — se o apontador é o dedo — e pega iPhone, iPad e tablet
 * Android em qualquer largura, sem tocar no desktop.
 * (O Chrome no Android não amplia; a regra é inofensiva lá.) */
/* ⚠ E O `!important` NÃO É PREGUIÇA — SEM ELE A REGRA NÃO VALIA NADA.
 * Ela é folha de estilo; todo campo da GRADE do diário nasce com
 * `style="font-size:12px"` escrito pelo JS, e atributo `style` vence folha.
 * Medido em Chrome com emulação de toque a 375px, com a media query
 * respondendo `true`: 11 de 12 campos do diário computavam entre 9,5px e
 * 12px — quantidade do serviço, qtd/horas/extras do efetivo, horas paradas
 * da ocorrência, produção por pessoa, etapa, legenda da foto. Só o campo do
 * formulário (que não tem style inline) ficava nos 17px.
 * Ou seja: a cada toque num campo da grade o Safari ampliava a tela e o
 * encarregado reenquadrava na mão, em pé, no canteiro — no módulo feito
 * exatamente para o dedo, com a equipe achando que já estava protegido.
 * O commit que criou a regra afirmava "max(16px, ...) garante o piso"; a
 * proteção foi dada por pronta sem nunca ter sido medida.
 * `table.tbl select.sel-sub` entra junto: lá o que vence é especificidade de
 * CLASSE, não o inline — mesmo efeito, causa diferente. */
@media (hover: none) and (pointer: coarse) {
  input, select, textarea { font-size: max(16px, var(--t-med)) !important; }
}

/* =====================================================================
 * A ZONA MORTA DO IPAD — 821px a 1100px
 *
 * ⚠ TODAS as regras responsivas do app paravam em 820px. O iPad Pro 11" em
 *   pé tem 834px; o iPad de 13" em pé, 1024px; o iPhone moderno deitado, de
 *   852 a 956px. Nessa faixa não havia NEM o layout de celular NEM espaço
 *   para o de desktop: barra que não quebrava, abas que não rolavam, tabela
 *   larga saindo por fora do cartão e a página inteira deslizando de lado.
 *   Foi isto que o dono fotografou — e não é defeito do Safari: reproduz no
 *   Chrome, medido.
 *
 *   Este bloco fica SEPARADO do de 820px de propósito: lá moram as coisas de
 *   CELULAR (gaveta de menu, esconder elementos), que não valem para tablet.
 *   Aqui mora só o que é questão de LARGURA.
 * ===================================================================== */
@media screen and (max-width: 1100px) {
  /* tabela larga rola dentro do próprio cartão, em vez de empurrar a coluna */
  .main table.tbl { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* ⚠ A REGRA IRMÃ DA DE CIMA, e ela faltava havia versões.
     A de cima cobre `.main table.tbl`. Modal NÃO está dentro de `.main` (ele
     é anexado ao body) e a tabela de serviços do diário nem classe `.tbl`
     tem — nasce como `<table style="width:100%">` no render. Resultado
     medido a 375px: a grade pede 500px de largura mínima (só a coluna "Feito
     hoje" pede 230px), sobram 353px, e como a tabela não tinha rolagem
     própria quem deslizava era o CORPO DO MODAL: para alcançar a coluna
     "Situação" o formulário inteiro andava 167px para a esquerda e o seletor
     de Obra saía da tela. No canteiro, com uma mão no telefone.
     Sem `table.tbl` de propósito: pega as cinco tabelas que vivem em modal —
     serviços e equipamentos do diário, documentos, entrega de EPI e
     requisição —, sendo que duas delas TÊM a classe e mesmo assim escapavam,
     porque o problema nunca foi a classe, era o ancestral `.main`.
     O bloco logo abaixo já tinha consertado a fileira de BOTÕES do modal pelo
     mesmo motivo, e parou ali: proteção pela metade de novo. */
  .modal .body table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
  /* barras de filtro e de botões quebram em vez de sair da tela.
     ⚠ o `.main` do seletor antigo deixava os MODAIS de fora — eles são
     anexados ao body, não ao main, e por isso a fileira de botões do modal
     não quebrava nem no celular. */
  .modal .body > div[style*="display:flex"] { flex-wrap: wrap; }
}

@media screen and (max-width: 820px) {
  /* fix-raiz do "estouro" horizontal: coluna nunca passa da viewport e main não estica com tabela larga */
  html, body { overflow-x: hidden; }
  .app { grid-template-columns: minmax(0, 1fr); }
  .app > .main, .app > .topbar { min-width: 0; }
  .app.com-sidebar > .topbar, .app.com-sidebar > .sidebar { min-width: 0; }
  /* topbar cresce e quebra os botões p/ 2ª linha em vez de estourar */
  .app { grid-template-rows: auto 1fr; }
  .topbar { flex-wrap: wrap; padding: 8px 12px; gap: 6px 8px; min-height: 50px; }
  .topbar .logo { font-size: var(--t-med); }
  .topbar .user { display: none; }
  .topbar button.linkbtn { padding: 6px 9px; font-size: var(--t-peq); }
  .topbar .spacer { flex-basis: 100%; height: 0; order: 5; }
  .main { padding: 14px 12px; }
  /* barras de botões (toolbar do editor etc.) quebram linha em vez de empurrar a largura */
  /* cabeçalho: título em linha própria (nome quebra), toolbar na linha de baixo */
  .main .flex.between > div:first-child { flex: 1 1 100%; margin-bottom: 6px; }

  /* Menu de módulos da Gestão vira GAVETA (abre no botão ☰) — some do fluxo, entra deslizando */
  .app.com-sidebar { grid-template-columns: minmax(0, 1fr); grid-template-areas: "top" "main"; }
  .app.com-sidebar > .main { min-width: 0; }
  .app.com-sidebar > .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; width: 262px; max-width: 82vw; z-index: 60;
    display: flex; flex-direction: column; overflow-y: auto;
    transform: translateX(-100%); transition: transform .22s ease;
  }
  .app.com-sidebar.menu-aberto > .sidebar { transform: translateX(0); box-shadow: 6px 0 26px rgba(0,0,0,.45); }
  .app.com-sidebar.menu-aberto::after { content: ""; position: fixed; inset: 0; background: rgba(8,18,30,.5); z-index: 55; }
  .app.com-sidebar .topbar-burger { display: inline-flex; }
  .sb-item { font-size: var(--t-med); padding: 13px 14px; }  /* alvo confortável de toque na gaveta */

  /* Abas do editor rolam de lado (6 abas não cabem no celular) — some o estouro em cascata */
  .tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .tabs .tab { white-space: nowrap; flex: 0 0 auto; }

  /* Tabelas largas rolam sozinhas em vez de estourar a tela */
  .main table.tbl { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; white-space: nowrap; }

  /* KPIs: 2 colunas no tablet, números menores e sem estourar */
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .kpi { min-width: 0; padding: 13px 14px; }
  .kpis .num, .kpi .num, .kpis.kpis-g .num { font-size: var(--t-tit); }
  .kpis.kpis-g { grid-template-columns: 1fr 1fr; }
  .row, .cards3 { grid-template-columns: 1fr !important; }
  /* lista de orçamentos/obras: 1 card por linha */
  .grid-cards { grid-template-columns: 1fr !important; }
  /* cabeçalhos "título + botão" quebram em vez de estourar */
  .flex.between { flex-wrap: wrap; gap: 10px; }
  .flex.between > h1 { font-size: var(--t-tit); }
  /* modais ocupam quase a tela toda no celular */
  .modal-bg { padding: 10px; }
  .modal { max-width: 100%; max-height: 92vh; }
  /* botões e campos com alvo de toque confortável */
  .btn { min-height: 40px; }
  /* ⚠ o N3 de 32×32 vira 40×40 no dedo: sem isto a altura subia pelo
     min-height acima e a largura ficava em 32 — alvo estreito e torto */
  .btn.sm.icone { width: 40px; }
  /* login cabe na largura da tela */
  .login-formside { padding: 24px 16px; }
  .login-card { max-width: 100%; }
}
@media screen and (max-width: 520px) {
  /* celular: KPIs em 1 coluna (número sempre cabe inteiro) */
  .kpis, .kpis.kpis-g { grid-template-columns: 1fr; }
  .topbar .logo small { display: none; }
  .conta-btn .conta-nome { display: none; }
}

/* ---------- Toast ---------- */
.toasts { position: fixed; bottom: 20px; right: 20px; z-index: 100; display: flex; flex-direction: column; gap: 8px; max-width: 560px; max-width: min(560px, calc(100vw - 40px)); pointer-events: none; }
/* ⚠ RECADO LONGO NÃO TAMPA O RODAPÉ DO QUADRO. O recado da recusa fica 8 a
   20 s (App._msRecado) e, sem largura máxima, ia de x=0 a 1346 cobrindo
   Cancelar/Salvar/Avançar — justo quando manda fechar o quadro (medido na
   revisão da F2: elementFromPoint no Cancelar = DIV.toast por 14 s). Com
   quadro aberto o recado sobe para o topo, sobre o título; e o contêiner não
   pega clique (pointer-events), para nada por baixo ficar inalcançável.
   UI.toast põe a classe quando há #modal-bg no momento do recado. */
.toasts.sobre-modal { bottom: auto; top: 12px; right: 50%; transform: translateX(50%); }
.toast { background: var(--navy); color: #fff; padding: 11px 16px; border-radius: var(--raio); box-shadow: var(--sombra); font-size: var(--t-base); animation: slidein .2s; }
.toast.ok { background: var(--verde); }
.toast.erro { background: var(--vermelho); }
@keyframes slidein { from { transform: translateX(20px); opacity: 0; } to { transform: none; opacity: 1; } }

.muted { color: var(--texto-fraco); }
.vazio { text-align: center; padding: 58px 24px; color: var(--texto-fraco); font-size: var(--t-base); line-height: 1.6; }
.vazio b, .vazio strong { color: var(--texto); font-weight: var(--p-forte); }
.vazio .vazio-ic, .vazio .ic-grande { font-size: var(--t-hero); display: block; margin-bottom: 10px; opacity: .55; }

/* ===================== PROPOSTA COMERCIAL ===================== */
.proposta-overlay {
  position: fixed; inset: 0; z-index: 200; background: #5b6b7b;
  overflow: auto; padding: 64px 0 40px;
  --p-navy: #0f2740; --p-aco: #2e6f9e; --p-verde: #15803d; --p-linha: #d8e0ea;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.prop-toolbar {
  position: fixed; top: 0; left: 0; right: 0; height: 52px; z-index: 210;
  background: var(--navy); color: #fff; display: flex; align-items: center; gap: 12px; padding: 0 18px;
}
.prop-toolbar .ttl { font-weight: var(--p-forte); flex: 1; }
/* FOLHA DOS DOCUMENTOS SEM PAPEL PRÓPRIO (ver js/app.js `_abrirPrint`).
   ⚠ O RECUO É A MARGEM DO @page (10mm, l.1515): a largura útil aqui tem que
   ser a MESMA do PDF (190mm), senão a pré-visualização quebra a linha num
   lugar e o papel noutro — e aí ela deixa de servir para conferir.
   As tintas são fixas de propósito: o documento é o entregável, não segue o
   tema escuro da tela (o `@media print` faz o mesmo, l.1468). */
.doc-folha {
  width: 210mm; max-width: 100%; min-height: 297mm; box-sizing: border-box;
  margin: 0 auto; padding: 10mm; background: #fff; color: #1a2632;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .3);
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.pg {
  width: 210mm; min-height: 297mm; background: #fff; color: #1a2632; margin: 0 auto 18px;
  box-shadow: 0 6px 24px rgba(0,0,0,.3); padding: 24mm 20mm; position: relative;
  font-size: 11.5pt; line-height: 1.55; box-sizing: border-box;
}
.pg .wm {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 64pt; font-weight: var(--p-forte); color: rgba(15,39,64,.04); transform: rotate(-30deg);
  pointer-events: none; letter-spacing: 4px; z-index: 0;
}
.pg > *:not(.wm) { position: relative; z-index: 1; }
.pg h1 { font-size: 30pt; margin: 6px 0; color: var(--p-navy); }
.pg h2.pg-tit { font-size: 18pt; color: var(--p-navy); border-bottom: 3px solid var(--p-aco); padding-bottom: 8px; margin: 0 0 18px; }
.pg h3 { font-size: 12pt; color: var(--p-aco); margin: 14px 0 6px; }
.pg ul { margin: 6px 0 6px 18px; } .pg li { margin: 3px 0; }
.pg .cols { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.pg .pg-rod { position: absolute; bottom: 14mm; left: 20mm; right: 20mm; border-top: 1px solid var(--p-linha); padding-top: 6px; font-size: 8.5pt; color: #7a8a99; }
.pg .nota { font-size: 9.5pt; color: #6b7b8a; }
.pg .bloco { margin-bottom: 12px; }
/* Decorativo inspirado no logo (linhas) */
.pg.capa { background: linear-gradient(155deg, #0b1d31 0%, #143454 58%, #1c4b73 128%); color: #fff; display: flex; flex-direction: column; overflow: hidden; }
/* grade de projeto (blueprint) decorativa, com máscara suave no canto */
.pg.capa::before { content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px), linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size: 42px 42px; -webkit-mask-image: radial-gradient(560px 460px at 82% 16%, #000, transparent 74%); mask-image: radial-gradient(560px 460px at 82% 16%, #000, transparent 74%); }
.pg.capa::after { content: ""; position: absolute; right: -120px; top: -100px; width: 420px; height: 420px; border-radius: 50%; background: radial-gradient(circle, rgba(111,208,138,.16), transparent 70%); z-index: 0; }
.pg.capa > * { position: relative; z-index: 1; }
.capa .logo-ph { border: 2px dashed rgba(255,255,255,.4); padding: 14px 20px; display: inline-block; border-radius: var(--raio); color: rgba(255,255,255,.85); font-weight: var(--p-medio); }
.capa-top { margin-bottom: auto; }
.capa-mid .kicker { letter-spacing: 6px; font-size: 11pt; color: #9be7af; font-weight: var(--p-forte); }
.capa-mid .kicker::after { content: ""; display: block; width: 58px; height: 4px; background: var(--p-verde); border-radius: var(--raio-sm); margin-top: 14px; }
.capa-mid h1 { color: #fff; font-size: 29pt; font-weight: var(--p-forte); line-height: 1.12; letter-spacing: -.5px; margin: 18px 0 10px; }
.capa-obra { font-size: 13pt; color: #cfe0ef; }
.capa-info { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.13); border-radius: var(--raio); padding: 18px 22px; margin: 30px 0; }
.ci-row { display: flex; justify-content: space-between; align-items: baseline; padding: 8px 0; border-bottom: 1px solid rgba(255,255,255,.1); font-size: 11pt; }
.ci-row:last-child { border-bottom: none; padding-bottom: 0; }
.ci-row:last-child b { font-size: 15pt; }
.ci-row span { color: #a9c4dc; }
.ci-row b { font-variant-numeric: tabular-nums; }
.capa-rod { margin-top: auto; font-size: 9pt; color: rgba(255,255,255,.6); border-top: 1px solid rgba(255,255,255,.1); padding-top: 14px; }
table.prop-tbl { width: 100%; border-collapse: collapse; font-size: 10.5pt; margin: 8px 0; }
table.prop-tbl th, table.prop-tbl td { padding: 8px 10px; border-bottom: 1px solid var(--p-linha); text-align: left; }
table.prop-tbl th { background: var(--p-navy); color: #fff; font-weight: var(--p-forte); letter-spacing: .3px; }
table.prop-tbl tbody tr:nth-child(even) td { background: #f7fafd; }
/* linha de grupo (etapa) na analítica do laudo — acento à esquerda */
table.prop-tbl tbody tr.grp-lau td { background: #eaf1f8; font-weight: var(--p-forte); color: var(--p-navy); box-shadow: inset 3px 0 0 var(--p-aco); }
table.prop-tbl td.r, table.prop-tbl th.r { text-align: right; font-variant-numeric: tabular-nums; }
table.prop-tbl tfoot td { background: #eef4fa; font-weight: var(--p-forte); border-top: 2px solid var(--p-navy); }
.assinaturas { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-top: 60px; text-align: center; }
.assin { font-weight: var(--p-medio); } .assin span { color: #6b7b8a; font-weight: var(--p-normal); }
.linha-assin { border-top: 1.5px solid #1a2632; margin-bottom: 8px; }

/* ----- Relatório completo (sintético + analítico), documento que flui ----- */
.rel-doc {
  width: 210mm; max-width: 210mm; background: #fff; color: #1a2632; margin: 0 auto;
  box-shadow: 0 6px 24px rgba(0,0,0,.3); padding: 18mm 16mm; box-sizing: border-box;
  font-size: 10.5pt; --p-navy: #0f2740; --p-aco: #2e6f9e; --p-verde: #15803d; --p-linha: #d8e0ea;
  -webkit-print-color-adjust: exact; print-color-adjust: exact;
}
.rel-head { display: flex; justify-content: space-between; align-items: flex-start; border-bottom: 3px solid var(--p-aco); padding-bottom: 12px; margin-bottom: 16px; }
.rel-head h1 { font-size: 22pt; color: var(--p-navy); margin: 4px 0 0; }
.rel-emp { font-weight: var(--p-forte); color: var(--p-aco); letter-spacing: .5px; }
.rel-sub { color: #5a6b7b; font-size: 11pt; }
.rel-meta { font-size: 9.5pt; text-align: right; }
.rel-meta div { margin: 2px 0; } .rel-meta span { color: #7a8a99; }
.rel-kpis { display: grid; grid-template-columns: repeat(4,1fr); gap: 10px; margin-bottom: 18px; }
.rel-kpis div { border: 1px solid var(--p-linha); border-radius: var(--raio); padding: 8px 12px; }
.rel-kpis span { display: block; font-size: 8.5pt; text-transform: uppercase; color: #7a8a99; letter-spacing: .4px; }
.rel-kpis b { font-size: 14pt; }
.rel-kpis .dest b { color: var(--p-verde); }
.rel-tit { font-size: 13pt; color: var(--p-navy); border-left: 4px solid var(--p-aco); padding-left: 8px; margin: 22px 0 8px; }
.rel-doc table.prop-tbl tr.grp td { background: var(--p-navy); color: #fff; font-weight: var(--p-forte); }
.rel-doc table.prop-tbl tr.sub td { background: #eef4fa; font-weight: var(--p-forte); }
/* CABEÇALHO DE SUB ETAPA (1.1) nos documentos — classe PRÓPRIA, nunca ".sub":
   nesta tabela ".sub" já é a linha de SUBTOTAL da etapa e vence o ".grp" por vir
   depois; a sub etapa sairia com a cara de um subtotal e o cliente não teria
   como distinguir um do outro no PDF. Aqui ela é um degrau claro abaixo da
   etapa (navy), com recuo e o filete de acento mais fino. */
.rel-doc table.prop-tbl tr.grp.subetapa td {
  background: #dce7f2; color: var(--p-navy); font-weight: var(--p-forte);
  box-shadow: inset 6px 0 0 var(--p-aco); font-size: 9.8pt;
}
/* LAUDO — o par estava INVERTIDO: a etapa (.grp-lau) é #eaf1f8 e a sub herdava
   #dce7f2, ou seja, saía MAIS ESCURA que a mãe — o contrário da regra. Agora a
   etapa fica #dce7f2 e a sub #e7eef6, que é exatamente #dce7f2 30% rumo ao branco.
   Navy sobre as duas: 12,10:1 e 12,97:1 — a hierarquia no papel fica por filete,
   recuo e numeração, que já existem. */
table.prop-tbl tbody tr.grp-lau td { background: #dce7f2; }
table.prop-tbl tbody tr.grp-lau.subetapa td {
  background: #e7eef6; color: var(--p-navy); font-weight: var(--p-forte);
  /* filete MAIS FINO e fonte MENOR que a etapa mãe (que herda 11px e 3px). Antes
     esta regra dava 9.8pt (=13px) e 6px de filete: a sub etapa imprimia MAIOR e
     com o dobro da barra de acento do pai — hierarquia invertida no laudo. */
  box-shadow: inset 3px 0 0 var(--p-aco); font-size: var(--t-micro);
}
.rel-rod { margin-top: 20px; border-top: 1px solid var(--p-linha); padding-top: 8px; font-size: 8.5pt; color: #7a8a99; }
/* ⚠ MARCA D'ÁGUA NO DOCUMENTO QUE FLUI. Só existia `.pg .wm` (a página fixa da
   proposta/laudo). No relatório e no cronograma, que usam `.rel-doc`, o mesmo
   <div class="wm"> caía no FLUXO: o nome da empresa saía como uma linha solta
   de texto no alto da primeira página — vista na foto do PDF do cronograma, e
   impressa assim em todo relatório desde que a marca d'água entrou. */
.rel-doc { position: relative; }
.rel-doc > .wm {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 64pt; font-weight: var(--p-forte); color: rgba(15,39,64,.04); transform: rotate(-30deg);
  pointer-events: none; letter-spacing: 4px; z-index: 0;
}
.rel-doc > *:not(.wm) { position: relative; z-index: 1; }

@media print {
  /* ⚠⚠ O PAPEL É BRANCO — E ISTO AQUI FAZIA O PDF SAIR PRETO.
   * `data-tema="dark"` mora no <html> e CONTINUA valendo na hora de imprimir.
   * Todo o conteúdo do documento usa os tokens (--surface, --texto, --bg…),
   * então herdava as cores do modo escuro; e a regra `print-color-adjust:
   * exact` logo abaixo — que existe para o navy da capa sair de verdade —
   * FORÇAVA esse preto a ser impresso. Quem trabalha no tema escuro (e o
   * tema é lembrado por aparelho) recebia um PDF preto, ilegível e que come
   * o cartucho inteiro.
   * Aqui os tokens voltam aos valores claros para a impressão, independente
   * do tema da tela — que continua como o usuário gosta.
   * ⚠ E A LISTA NÃO PODE SER NOMINAL. Na primeira versão deste bloco eu
   * escrevi os tons um por um e ESQUECI o "RA Engenharia" (`data-tom="ra"`) —
   * justamente o tema com o nome da empresa. Ele tem especificidade (0,2,0) e
   * vencia o `[data-tema="dark"]` (0,1,0) daqui, então continuava escuro; e
   * como ele não declara `--texto`, o texto ERA resetado para escuro: o
   * entregável saía com letra quase preta sobre fundo navy, pior do que antes
   * do conserto. A lista continua não sendo nominal: casar por PRESENÇA do
   * atributo pega qualquer tema, inclusive os que ainda não existem.
   * (Os tons `data-tom` saíram na 1.1.188; `data-fonte` entrou no lugar. O
   * seletor antigo fica aqui de propósito, para o impresso continuar certo
   * em quem ainda não atualizou e tem o atributo velho gravado no aparelho.) */
  :root,
  [data-tema="dark"],
  [data-tema="dark"][data-tom],
  [data-tema="dark"][data-fonte] {
    --bg: #ffffff;
    --surface: #ffffff;
    --surface-2: #eef2f7;
    --surface-3: #e5ecf4;
    --linha: #c9d6e4;
    --linha-forte: #a6bdd2;
    --texto: #111d2b;
    --texto-fraco: #516375;
    --faixa-sub: #f3f6f9;
    --tot-fundo: #0f2740;
    --card-bg: #ffffff;
    --bg-grad: none;
    --sombra-sm: none; --sombra: none; --sombra-lg: none; --sombra-navy: none;
    --realce: none;
  }
  /* as tarjas do detalhamento também eram versões escuras */
  [data-tema="dark"] .tbl-analitico .lin-comp td { background: rgba(21, 128, 61, .10) !important; }
  [data-tema="dark"] .tbl-analitico .lin-sub  td { background: rgba(46, 111, 158, .10) !important; }
  [data-tema="dark"] .tbl-analitico .lin-ins  td { background: rgba(245, 158, 11, .08) !important; }

  /* CORE FIX de impressão: html/body têm height:100% (l.59) e a media mobile (max-width:820px)
     aplica overflow-x:hidden — AMBOS disparam no print (A4 ≈ 794px < 820px), viram um container
     de altura fixa e CORTAVAM o conteúdo em fluxo (.rel-doc) na 1ª página. Liberamos altura e
     overflow p/ paginar de verdade em todos os entregáveis. */
  html, body { height: auto !important; min-height: 0 !important; overflow: visible !important; background: #fff !important; }
  body > *:not(#proposta-print) { display: none !important; }
  #proposta-print { position: static; background: #fff; padding: 0; overflow: visible; height: auto; min-height: 0; }
  /* força a impressão das cores de fundo/gradientes (navy da capa, cabeçalhos, acentos) */
  #proposta-print, #proposta-print *, #proposta-print *::before, #proposta-print *::after {
    -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important;
  }
  .prop-toolbar, .no-print { display: none !important; }
  .pg { box-shadow: none; margin: 0; page-break-after: always; width: auto; min-height: auto; }
  .pg:last-child { page-break-after: auto; }
  /* Capa preenche a área imprimível (dentro da margem de 10mm) — moldura fina e uniforme */
  .pg.capa { min-height: 277mm; overflow: hidden; }
  /* Relatório: flui em várias páginas; cabeçalho de tabela repete, linhas não quebram */
  .rel-doc { box-shadow: none; margin: 0; width: auto; max-width: none; padding: 0; }
  /* ⚠ A FOLHA DA TELA NÃO PODE IR PARA O PAPEL. Ela existe para a
     pré-visualização parecer o PDF (js/app.js `_abrirPrint`); na impressão o
     recuo dela SOMARIA aos 10mm do @page — 20mm de margem, o documento
     estreitando e paginando num lugar diferente do que a tela mostrou. Aqui
     ela vira um invólucro sem efeito nenhum. */
  .doc-folha { box-shadow: none; margin: 0; width: auto; max-width: none; padding: 0; min-height: 0; background: #fff; }
  .rel-doc table.prop-tbl thead { display: table-header-group; }
  .rel-doc table.prop-tbl tr { page-break-inside: avoid; }
  /* títulos de seção não órfãos no rodapé; cabeçalho/KPIs não partem no meio */
  .rel-doc .rel-tit { page-break-after: avoid; break-after: avoid; }
  .rel-doc .rel-head, .rel-doc .rel-kpis { page-break-inside: avoid; break-inside: avoid; }
  @page { size: A4; margin: 10mm; }
}
.right { text-align: right; }
.flex { display: flex; align-items: center; gap: 10px; }
.flex.between { justify-content: space-between; }
.mt { margin-top: 16px; } .mb { margin-bottom: 18px; }

/* ---------- Topbar: busca universal + central de avisos ---------- */
.topo-ic-btn { position: relative; display: inline-flex; align-items: center; gap: 7px; background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.16); color: #fff; border-radius: var(--raio); padding: 7px 11px; cursor: pointer; font-size: var(--t-base); margin-right: 8px; transition: .14s; }
.topo-ic-btn:hover { background: rgba(255,255,255,.18); }
/* "Instalar app": verde discreto para se distinguir dos ícones neutros da
   barra sem gritar. Ele fica na tela enquanto o app não estiver instalado —
   some sozinho em modo standalone, que é o único motivo de sumir. */
.topo-instalar { background: rgba(111,208,138,.16); border-color: rgba(111,208,138,.38); }
.topo-instalar:hover { background: rgba(111,208,138,.26); }
/* no celular sobra pouca barra: fica o ícone, que o alvo de toque preserva */
@media (max-width: 760px) { .topo-instalar-txt { display: none; } }
.topo-kbd { font-size: var(--t-micro); font-weight: var(--p-forte); letter-spacing: .4px; background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.22); border-radius: var(--raio-sm); padding: 1px 6px; opacity: .85; }
.aviso-badge { position: absolute; top: -6px; right: -6px; min-width: 17px; height: 17px; border-radius: 999px; background: #dc2626; color: #fff; font-size: var(--t-micro); font-weight: var(--p-forte); display: flex; align-items: center; justify-content: center; padding: 0 4px; border: 2px solid var(--navy); }
@media (max-width: 760px) { .topo-kbd { display: none; } .topo-ic-btn { padding: 7px 9px; } }

/* ---------- Busca universal (overlay Ctrl+K) ---------- */
#busca-ov { position: fixed; inset: 0; background: rgba(8,18,30,.55); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); display: none; align-items: flex-start; justify-content: center; z-index: 70; padding: 10vh 16px 16px; animation: fadein .12s; }
.busca-caixa { width: 100%; max-width: 560px; background: var(--surface); color: var(--texto); border: 1px solid var(--linha-forte); border-radius: var(--raio-lg); box-shadow: var(--sombra-lg); overflow: hidden; }
.busca-topo { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--linha); }
.busca-lupa { font-size: var(--t-med); opacity: .7; }
#busca-inp { flex: 1; border: none; outline: none; background: transparent; color: var(--texto); font-size: var(--t-med); }
.busca-esc { font-size: var(--t-micro); font-weight: var(--p-forte); color: var(--texto-fraco); border: 1px solid var(--linha-forte); border-radius: var(--raio-sm); padding: 2px 7px; }
.busca-res { max-height: 46vh; overflow-y: auto; padding: 6px; }
.busca-item { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: var(--raio); cursor: pointer; }
.busca-item.on, .busca-item:hover { background: rgba(46,111,158,.10); }
.busca-item.on { box-shadow: inset 3px 0 0 var(--aco); }
.busca-ico { font-size: var(--t-med); width: 22px; text-align: center; flex: none; }
.busca-tit { font-weight: var(--p-medio); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.busca-sub { margin-left: auto; color: var(--texto-fraco); font-size: var(--t-peq); white-space: nowrap; flex: none; max-width: 40%; overflow: hidden; text-overflow: ellipsis; }
.busca-vazio { padding: 22px; text-align: center; color: var(--texto-fraco); font-size: var(--t-base); }
.busca-dica { padding: 9px 16px; border-top: 1px solid var(--linha); color: var(--texto-fraco); font-size: var(--t-micro); background: var(--surface-2); }

/* ---------- Central de avisos (dropdown do sino) ---------- */
#avisos-drop { position: fixed; z-index: 65; width: min(370px, calc(100vw - 16px)); max-height: 62vh; overflow-y: auto; background: var(--surface); color: var(--texto); border: 1px solid var(--linha-forte); border-radius: var(--raio); box-shadow: var(--sombra-lg); animation: fadein .12s; }
.avisos-cab { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--linha); }
.avisos-cab span { color: var(--texto-fraco); font-size: var(--t-peq); }
.avisos-zen { padding: 22px 16px; text-align: center; color: var(--texto-fraco); font-size: var(--t-base); }
.avisos-grp { padding: 10px 14px 4px; font-size: var(--t-micro); font-weight: var(--p-forte); text-transform: uppercase; letter-spacing: .6px; color: var(--texto-fraco); }
.avisos-item { padding: 9px 14px; cursor: pointer; border-radius: var(--raio); margin: 0 6px; }
.avisos-item:hover { background: rgba(46,111,158,.10); }
.avisos-item b { display: block; font-size: var(--t-base); font-weight: var(--p-medio); }
.avisos-item small { color: var(--texto-fraco); font-size: var(--t-peq); }
.avisos-mais { padding: 8px 14px 12px; color: var(--aco); font-size: var(--t-peq); font-weight: var(--p-medio); cursor: pointer; }
.watermark-hint { font-size: var(--t-micro); color: var(--texto-fraco); }

/* ===================================================================
 * Inter vendorizado (offline-first) — fonte variavel, subset latin,
 * embutida base64 no proprio CSS (zero dependencia de rede/packer).
 * Substitui o <link> do fonts.googleapis.com: identico online e offline.
 * Fonte: Google Fonts (Inter v20, OFL). unicode-range latin -> emoji e
 * demais glifos caem no fallback do sistema (comportamento desejado).
 * =================================================================== */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: var(--p-normal) 900;
  font-display: swap;
  src: url(data:font/woff2;base64,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) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* =====================================================================
 * OrçaPRO — ELEVAÇÃO PREMIUM (v2, ADITIVA sobre o Design System acima)
 * Refino de acabamento, não restruturação: easing premium, profundidade
 * em hover, números "de dinheiro" com gradiente (com @supports de
 * segurança + fallback sólido), brilho discreto varrendo botões-âncora,
 * entrada suave de menus e linha-âncora nas tabelas. 100% superset —
 * não remove nem esconde nada. Respeita prefers-reduced-motion (o guard
 * que faltava no arquivo). Tudo tematizado (claro/dark).
 * ===================================================================== */
:root {
  --ease: cubic-bezier(.2, .7, .2, 1);
  --sombra-hover: 0 2px 4px rgba(15,39,64,.05), 0 14px 34px -10px rgba(15,39,64,.18), 0 34px 62px -28px rgba(15,39,64,.22);
}
[data-tema="dark"] {
  --sombra-hover: 0 6px 16px rgba(0,0,0,.5), 0 22px 50px rgba(0,0,0,.55);
}

/* — Profundidade + easing mais finos nos elementos que já elevam — */
.orc-card, .kpi { transition: transform .28s var(--ease), box-shadow .28s var(--ease), border-color .28s var(--ease); will-change: transform; }
.orc-card:hover, .kpi:hover { box-shadow: var(--sombra-hover), var(--realce); }
.btn { transition: transform .18s var(--ease), box-shadow .18s var(--ease), background .18s, border-color .18s, filter .18s; }
/* o realce de hover ja e a troca de tinta; filtro por cima disso mexe na
   cor sem que ela mude no token, e o valor que aparece na tela deixa de ser
   o valor que esta escrito no css */
.btn.success:hover { filter: saturate(1.03) brightness(1.02); }

/* — Brilho que varre os botões-âncora no hover (premium, discreto) — */
.btn.primary, .btn.success { position: relative; overflow: hidden; }
.btn.primary::after, .btn.success::after {
  content: ""; position: absolute; top: 0; left: -60%; width: 42%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.35), transparent);
  transform: skewX(-18deg); transition: left .6s var(--ease); pointer-events: none;
}
.btn.primary:hover::after, .btn.success:hover::after { left: 135%; }

/* — Números "de dinheiro" com gradiente sutil (fallback sólido garantido) — */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .kpi .num {
    background-image: linear-gradient(180deg, #1c2c3d, #35485c);
    -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  }
  [data-tema="dark"] .kpi .num { background-image: linear-gradient(180deg, #ffffff, #bfccda); }
  .kpi.destaque .num, .orc-card .valor { background-image: linear-gradient(180deg, var(--verde-claro), var(--verde)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
  .kpi.custo .num { background-image: linear-gradient(180deg, var(--aco-claro), var(--aco)); }
}

/* — Entrada suave de menus/dropdowns (reaproveita o popin já definido) — */
.conta-drop { animation: popin .16s var(--ease); transform-origin: top right; }

/* — Linha-âncora premium ao passar o mouse nas linhas da tabela — */
table.tbl tbody tr:hover td { box-shadow: inset 2px 0 0 rgba(46,111,158,.5); }
table.tbl tr.etapa-row:hover td { box-shadow: inset 3px 0 0 var(--aco); }

/* — Sidebar: leve deslize no hover (item ativo fica firme) — */
.sb-item { transition: background .16s var(--ease), color .16s, transform .16s var(--ease), box-shadow .16s; }
.sb-item:hover { transform: translateX(2px); }
.sb-item.on, .sb-item.on:hover { transform: none; }

/* — Modal: sombra um pouco mais profunda (sensação de flutuar) — */
.modal { box-shadow: var(--sombra-lg), 0 40px 84px -40px rgba(8,18,30,.55); }

/* — Foco premium unificado (mantém acessível: anel + leve elevação) — */
.btn:focus-visible, .conta-item:focus-visible, .sb-item:focus-visible { outline: none; box-shadow: var(--anel), var(--sombra); }

/* — Respeita quem pediu menos movimento (guard de acessibilidade que faltava) — */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .orc-card:hover, .kpi:hover, .btn:hover, .sb-item:hover { transform: none !important; }
  .btn.primary::after, .btn.success::after { display: none !important; }
}

/* ===== Last Planner — Quadro Kanban (colunas derivam do estado LPS) ===== */
.lp-vtoggle { display: inline-flex; gap: 4px; }
/* Vermelho de TEXTO com contraste AA nos dois temas (o --vermelho puro reprova em texto pequeno) */
.lp-q { --lp-vermelho-texto: #b91c1c; }
[data-tema="dark"] .lp-q { --lp-vermelho-texto: #f87171; }
[data-tema="dark"] .lp-qtag { color: var(--aco-claro); background: rgba(90, 155, 201, .14); }
.lp-q {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(215px, 1fr);
  gap: 10px; overflow-x: auto; padding-bottom: 6px; align-items: start;
  scrollbar-width: thin;
}
.lp-qcol {
  background: var(--surface-2); border: 1px solid var(--linha);
  border-radius: var(--raio-sm); padding: 8px; min-height: 200px;
  transition: box-shadow .15s, border-color .15s;
}
.lp-qcol.sobre { border-color: var(--aco); box-shadow: 0 0 0 2px var(--aco) inset; }
.lp-qcol.imp { background: rgba(220, 38, 38, .06); border-color: rgba(220, 38, 38, .25); }
.lp-qcol.ok { background: rgba(21, 128, 61, .06); border-color: rgba(21, 128, 61, .22); }
.lp-qcab { display: flex; align-items: center; gap: 7px; padding: 2px 3px 8px; }
.lp-qicone { font-size: var(--t-base); color: var(--vermelho); line-height: 1; }
.lp-qicone.vd { color: var(--verde); }
.lp-qponto { width: 8px; height: 8px; border-radius: 999px; background: var(--aco); flex: 0 0 auto; }
.lp-qnome { font-size: var(--t-micro); font-weight: var(--p-forte); text-transform: uppercase; letter-spacing: .06em; color: var(--texto); line-height: 1.2; min-width: 0; }
.lp-qcol.imp .lp-qnome { color: var(--lp-vermelho-texto); }
.lp-qnome small { display: block; font-size: var(--t-micro); font-weight: var(--p-normal); text-transform: none; letter-spacing: 0; color: var(--texto-fraco); }
.lp-qn {
  margin-left: auto; font-size: var(--t-micro); font-weight: var(--p-forte); font-variant-numeric: tabular-nums;
  background: var(--surface); border: 1px solid var(--linha); color: var(--texto-fraco);
  border-radius: 999px; padding: 1px 7px;
}
.lp-qn.alerta { background: var(--vermelho); border-color: var(--vermelho); color: #fff; }
.lp-qlista { display: flex; flex-direction: column; gap: 7px; }
.lp-qcard {
  background: var(--surface); border: 1px solid var(--linha); border-radius: var(--raio-sm);
  padding: 8px 9px; cursor: grab; box-shadow: var(--sombra-sm); user-select: none;
  transition: box-shadow .15s, transform .15s;
}
.lp-qcard:hover { box-shadow: var(--sombra); transform: translateY(-1px); }
.lp-qcard:active { cursor: grabbing; }
.lp-qcard.arrastando { opacity: .45; }
.lp-qcol.imp .lp-qcard { border-left: 3px solid var(--vermelho); }
.lp-qcol.ok .lp-qcard { opacity: .85; }
.lp-qtags { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 5px; }
.lp-qtag {
  font-size: var(--t-micro); font-weight: var(--p-forte); color: var(--aco);
  background: rgba(46, 111, 158, .1); border-radius: var(--raio-sm); padding: 1px 6px;
}
.lp-qtag.crono { color: var(--texto-fraco); background: var(--surface-2); }

/* O MIOLO DO PREVISTO × REALIZADO COMPLETO (redesenho pedido pelo Rogério em
   08/10/2026: "tá muito feio, principalmente a parte de cronograma — coisa
   repetida, mal organizada, poluindo demais: fora").
   O HTML é do js/cronoexecui.js (painelPR completo → _prCompleto) e já sai com
   as peças do kit (mod-aviso, mod-kpis, mod-sec): vale igual no módulo
   "Cronograma da obra" e na sub-aba Previsto × Realizado do orçamento. Aqui só
   o que é do painel: a barra de origem (a "barra de filtros" — é onde mora a
   data de corte e as ações da linha de base), o segundo número do indicador
   (IDP), a lista de observações recolhível e o corpo das seções.
   ⚠ Seletor `.cx-pr.cx-pr-full`: o <style> do painel (CSS_PR) vem DEPOIS do
   app.css, e com especificidade igual ele venceria. */
.cx-pr.cx-pr-full { font-size: var(--t-peq); }
.cx-pr.cx-pr-full .cx-pr-origem { display: flex; align-items: center; justify-content: space-between; gap: 10px 20px; flex-wrap: wrap; padding: 10px 14px; margin: 0 0 16px; background: var(--card-bg); border: 1px solid var(--linha); border-radius: var(--raio-lg); font-size: var(--t-peq); }
.cx-pr.cx-pr-full .cx-pr-orig { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; color: var(--texto-fraco); min-width: 0; }
.cx-pr.cx-pr-full .cx-pr-orig b { color: var(--texto); font-weight: var(--p-forte); }
.cx-pr.cx-pr-full .cx-pr-sep { font-style: normal; color: var(--linha-forte); }
.cx-pr.cx-pr-full .cx-pr-sembase { color: var(--amarelo); font-weight: var(--p-medio); }
.cx-pr.cx-pr-full .cx-pr-orig-dir { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; margin-left: auto; }
.cx-pr.cx-pr-full .cx-pr-corte { display: inline-flex; align-items: center; gap: 8px; margin: 0; color: var(--texto-fraco); font-weight: var(--p-normal); white-space: nowrap; }
.cx-pr.cx-pr-full .cx-pr-corte input { width: 150px; }
.cx-pr.cx-pr-full .cx-pr-fc { font-size: var(--t-micro); }
.cx-pr.cx-pr-full .cx-pr-origem .cx-pr-acoes { margin: 0; gap: 8px; }
/* o segundo número do indicador "Previsto na data" (IDP, só com linha de base) */
.cx-pr.cx-pr-full .mod-kpi .cx-kpi-idp { display: inline; white-space: nowrap; }
.cx-pr.cx-pr-full .mod-kpi .cx-kpi-idp .cx-kpi-rot { font-size: inherit; text-transform: none; letter-spacing: 0; font-weight: var(--p-normal); color: inherit; }
.cx-pr.cx-pr-full .mod-kpi .cx-kpi-idp .cx-kpi-v { font-size: inherit; font-weight: var(--p-forte); color: var(--texto); }
.cx-pr.cx-pr-full .mod-kpi .cx-sit { font-size: var(--t-micro); padding: 0 7px; }
.cx-pr.cx-pr-full .mod-kpi .cx-kpi-acao { margin-top: 8px; }
/* as observações sobre a conta: UM aviso, a lista abre no clique */
.cx-pr.cx-pr-full .mod-aviso .cx-obs > summary { cursor: pointer; font-weight: var(--p-forte); color: var(--texto); }
.cx-pr.cx-pr-full .mod-aviso .cx-obs > summary:focus-visible { outline: 2px solid var(--aco-claro); outline-offset: 2px; border-radius: var(--raio-sm); }
.cx-pr.cx-pr-full .mod-aviso .cx-obs .cx-lista { margin: 8px 0 2px; font-size: var(--t-peq); line-height: 1.55; color: var(--texto-fraco); }
/* a leitura executiva (só na sub-aba do orçamento) como um bloco do kit */
.cx-pr.cx-pr-full .cx-pr-leitura { margin: 0 0 18px; }
.cx-pr.cx-pr-full .cx-pr-leitura .nr { margin: 0 0 10px; padding: 14px 18px; border: 1px solid var(--linha); border-left: 3px solid var(--aco); border-radius: var(--raio-lg); background: var(--card-bg); }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-cab { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .7px; color: var(--texto-fraco); margin-bottom: 6px; }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-cab .muted { text-transform: none; letter-spacing: 0; font-weight: var(--p-normal); }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-txt { font-size: var(--t-peq); }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-ress { padding: 10px 18px; border-left-color: var(--linha-forte); }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-ress .nr-falta { margin: 0; }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-ress summary { cursor: pointer; color: var(--texto-fraco); }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-ress summary:focus-visible { outline: 2px solid var(--aco-claro); outline-offset: 2px; border-radius: var(--raio-sm); }
.cx-pr.cx-pr-full .cx-pr-leitura .nr-ress .cx-lista { font-size: var(--t-micro); margin-top: 6px; }
/* o corpo das seções */
.cx-pr.cx-pr-full .cx-pr-curva .cx-curva { border: 0; border-radius: 0; }
.cx-pr.cx-pr-full .cx-pr-gantt .cx-gantt { border-radius: var(--raio); }
.cx-pr.cx-pr-full .cx-pr-nos .cx-tabela { margin: 0 -18px -16px; }
.cx-pr.cx-pr-full .cx-pr-nos table.tbl.cx-pr-tab { margin: 0; width: 100%; }
.cx-pr.cx-pr-full .cx-pr-fora { margin: 0; padding-left: 18px; line-height: 1.5; }
.cx-pr.cx-pr-full .cx-pr-fora li + li { margin-top: 8px; }
.cx-pr.cx-pr-full .cx-fora-it { margin-top: 2px; color: var(--texto-fraco); font-size: var(--t-micro); }
.cx-pr.cx-pr-full .cx-fora-it .cx-pr-sep { margin: 0 6px; font-style: normal; color: var(--linha-forte); }
.cx-pr.cx-pr-full .cx-pr-nada { margin: 0 0 18px; font-size: var(--t-micro); color: var(--texto-fraco); }
@media (max-width: 720px) {
  .cx-pr.cx-pr-full .cx-pr-orig-dir { margin-left: 0; width: 100%; }
  .cx-pr.cx-pr-full .cx-pr-corte input { width: auto; flex: 1 1 auto; }
  /* a curva desenhada em 1000 de largura, espremida em 350 px, deixava a letra
     dos eixos com 3 px: no celular ela guarda 560 px e rola no corpo da seção */
  .cx-pr.cx-pr-full .cx-pr-curva .cx-curva { min-width: 560px; }
}

.lp-qtit { font-size: var(--t-peq); font-weight: var(--p-medio); line-height: 1.35; color: var(--texto); }
.lp-qmotivo {
  font-size: var(--t-micro); font-weight: var(--p-medio); color: var(--lp-vermelho-texto);
  background: rgba(220, 38, 38, .07); border: 1px solid rgba(220, 38, 38, .2);
  border-radius: var(--raio-sm); padding: 3px 6px; margin-top: 5px;
}
.lp-qpe { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-top: 7px; }
.lp-qresp { display: inline-flex; align-items: center; gap: 5px; font-size: var(--t-micro); color: var(--texto-fraco); min-width: 0; }
.lp-qresp > span + * { min-width: 0; }
.lp-qav {
  width: 20px; height: 20px; border-radius: 999px; background: var(--navy); color: #fff;
  font-size: var(--t-micro); font-weight: var(--p-forte); display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
[data-tema="dark"] .lp-qav { background: var(--aco); }
.lp-qchip {
  font-size: var(--t-micro); font-weight: var(--p-medio); white-space: nowrap; color: var(--texto-fraco);
  background: var(--surface-2); border: 1px solid var(--linha); border-radius: var(--raio-sm); padding: 1px 6px;
}
.lp-qchip.vence { color: var(--lp-vermelho-texto); background: rgba(220, 38, 38, .08); border-color: rgba(220, 38, 38, .25); font-weight: var(--p-forte); }
.lp-qchip.ok { color: var(--verde); background: rgba(21, 128, 61, .09); border-color: rgba(21, 128, 61, .25); }
.lp-qvazio {
  font-size: var(--t-micro); color: var(--texto-fraco); text-align: center; padding: 18px 6px;
  border: 1px dashed var(--linha-forte); border-radius: var(--raio-sm);
}
.lp-qcol.imp .lp-qvazio { border-color: rgba(220, 38, 38, .3); color: var(--lp-vermelho-texto); }
@keyframes lpQPulso { 0%, 100% { opacity: 1; } 50% { opacity: .4; } }
.lp-qicone.pulso { animation: lpQPulso 2.2s ease-in-out infinite; }
.lp-qcard:focus-visible { outline: none; box-shadow: var(--anel); }
@media (prefers-reduced-motion: reduce) {
  .lp-qicone.pulso { animation: none; }
  .lp-qcard:hover { transform: none; }
}
@media (max-width: 900px) { .lp-q { grid-auto-columns: minmax(190px, 230px); } }

/* ---- Detalhamento analítico (composição → insumos), cores por tipo ---- */
.tbl-analitico .lin-comp td { background: rgba(21, 128, 61, .14); font-weight: var(--p-medio); }
.tbl-analitico .lin-sub  td { background: rgba(46, 111, 158, .10); }
.tbl-analitico .lin-ins  td { background: rgba(245, 158, 11, .08); }
[data-tema="dark"] .tbl-analitico .lin-comp td { background: rgba(21, 128, 61, .20); }
[data-tema="dark"] .tbl-analitico .lin-sub  td { background: rgba(46, 111, 158, .18); }
[data-tema="dark"] .tbl-analitico .lin-ins  td { background: rgba(245, 158, 11, .12); }
.tag-tipo { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: var(--raio-sm); font-size: var(--t-micro); font-weight: var(--p-forte); color: #fff; }
.tag-c { background: #15803d; }  /* composição — branco por cima: 5,02:1 */
.tag-s { background: #2e6f9e; }  /* serviço    — branco por cima: 5,41:1 */
/* ⚠ era #d97706, e com a letra branca dava 3,19:1 nos DOIS temas (a tag é
   chapada, então o tema não a socorre). #aa6200 é o valor claro do token
   --amarelo — mesmo âmbar da paleta, um degrau mais fundo — e sobe para
   4,71:1. Hex fixo e não `var(--amarelo)` de propósito: no escuro o token vira
   #dda23f e a letra branca cairia para 2,1:1. */
.tag-i { background: #aa6200; }  /* insumo     — branco por cima: 4,71:1 */
.cod-link { color: var(--aco); font-weight: var(--p-forte); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.cod-link:hover { color: var(--navy, #0f2740); }
/* código do item na planilha: clicável quando tem composição para abrir */
.pill.cod-click { cursor: pointer; box-shadow: inset 0 0 0 1px rgba(46,111,158,.45); }
.pill.cod-click:hover { filter: brightness(.92); text-decoration: underline; }

/* ---- 🗑 excluir orçamento no card da lista ---- */
.orc-card { position: relative; }
.orc-card .orc-del { position: absolute; top: 10px; right: 10px; opacity: .35; transition: opacity .15s; }
.orc-card:hover .orc-del { opacity: 1; }
/* sem hover no toque: fica sempre visível e com alvo de dedo (44px é o mínimo confortável) */
@media (max-width: 900px) { .orc-card .orc-del { opacity: .8; min-width: 44px; min-height: 44px; } }

/* ---- pendência de preço (insumo não coletado / item zerado) ---- */
.preco-user { width: 92px; text-align: right; padding: 4px 8px; border-radius: var(--raio-sm); border: 1px solid rgba(46,111,158,.4); background: #fffdf5; font: inherit; font-size: var(--t-peq); }
.preco-user.pendente { border-color: #dc2626; background: rgba(220,38,38,.06); }
.preco-user.pendente::placeholder { color: #dc2626; font-weight: var(--p-medio); }
[data-tema="dark"] .preco-user { background: rgba(255,255,255,.06); color: inherit; }
.txt-pendente { color: #dc2626; font-weight: var(--p-forte); font-size: var(--t-peq); white-space: nowrap; }
.selo-user { font-size: var(--t-micro); cursor: help; }
.tbl-analitico .lin-pendente td { background: rgba(220,38,38,.07) !important; }
input.cell.cell-erro { border-color: #dc2626 !important; background: rgba(220,38,38,.08) !important; box-shadow: 0 0 0 2px rgba(220,38,38,.15); }

/* ---------- Foto da obra, logo da empresa e foto de perfil (v1.1.148) ----------
   A capa da obra tem altura FIXA e `object-fit:cover`: foto de celular vem em
   qualquer proporção, e sem isso cada card ficaria de um tamanho, com a lista
   toda desalinhada. O espaço já nasce reservado porque a imagem chega depois
   (ela mora no IndexedDB) — sem isso o card "pula" quando ela carrega. */
/* ⚠ o recuo negativo tem que ser o padding REAL do card (24px). Eu tinha
   escrito -19/-21 de cabeca e sobrava uma moldura de 4px nas laterais e 6px no
   topo — a foto ficava "solta" dentro do card em vez de ser a capa dele.
   O raio fica por conta do proprio card, que ja tem overflow:hidden. */
.orc-card .obra-capa { margin: -24px -24px 14px; height: 132px; overflow: hidden; background: var(--surface-2); }
.orc-card .obra-capa img { width: 100%; height: 100%; object-fit: cover; display: block; }
@media screen and (max-width: 820px) { .orc-card .obra-capa { height: 152px; } }

/* pré-visualização no formulário da obra */
.obra-foto-prev { width: 132px; height: 88px; border: 1.5px dashed var(--linha-forte); border-radius: var(--raio); background: var(--surface-2); display: flex; align-items: center; justify-content: center; overflow: hidden; flex: none; }
.obra-foto-prev img { width: 100%; height: 100%; object-fit: cover; }
.obra-foto-vazia { font-size: var(--t-peq); color: var(--texto-fraco); }

/* barra do topo: logo da empresa + foto de quem está logado */
.conta-logo { height: 22px; max-width: 84px; object-fit: contain; border-radius: var(--raio-sm); background: rgba(255,255,255,.92); padding: 1px 3px; flex: none; }
.conta-foto { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; flex: none; border: 2px solid rgba(8,20,33,.9); box-shadow: 0 0 0 2px rgba(111,208,138,.75); }
.conta-foto.ini { display: inline-flex; align-items: center; justify-content: center; background: rgba(255,255,255,.18); font-size: var(--t-micro); font-weight: var(--p-forte); letter-spacing: .3px; color: #fff; }
@media screen and (max-width: 620px) { .conta-logo { display: none; } }   /* no celular a barra é curta: fica a foto, que identifica a pessoa */

/* pré-visualização em "Minha foto de perfil" */
.perfil-prev { width: 96px; height: 96px; border-radius: 50%; overflow: hidden; background: var(--surface-2); border: 2px solid var(--linha-forte); display: flex; align-items: center; justify-content: center; flex: none; }
.perfil-prev img { width: 100%; height: 100%; object-fit: cover; }
.perfil-prev .ini { font-size: var(--t-hero); font-weight: var(--p-forte); color: var(--texto-fraco); }

/* no papel a capa não entra: o impresso tem cabeçalho próprio */
@media print { .orc-card .obra-capa, .conta-logo, .conta-foto { display: none !important; } }

/* ---------- Cena da lista de Obras (js/obravitrine.js) ----------
   A tela de Obras é uma CENA: a foto da obra em destaque cobre a área de
   conteúdo inteira, atrás de tudo (o CENÁRIO), com um zoom lento contínuo; o
   título, o palco (os números da obra) e a grade de cards vêm por cima.
   Trocar de obra desliza a foto de lado, na direção do card na grade.
   ⚠ A CENA É ESCURA NOS DOIS TEMAS, de propósito: é foto com texto por
   cima, e texto só lê sobre foto com véu escuro — um véu claro lavaria a
   foto. Por isso as tintas daqui são próprias (--ov-*), escolhidas contra o
   navy, e não os tokens do tema: o --verde do tema claro (#15803d) some. */
.ov-cena {
  --ov-fundo: #081421;
  --ov-texto: #ffffff;
  --ov-fraco: #b9c9d9;
  --ov-verde: #6fd08a;
  --ov-ambar: #e8b04f;
  --ov-alerta: #f4999d;
  --ov-aco: #8fc0e3;
  /* a cena encosta nas bordas da área de rolagem: desfaz o respiro do .main
     com margem negativa e o devolve como padding — o conteúdo fica onde era.
     ⚠ estes dois números SÃO o padding do .main (e o do celular, abaixo). */
  --ov-py: 28px;
  --ov-px: 34px;
  position: relative; isolation: isolate;
  margin: calc(-1 * var(--ov-py)) calc(-1 * var(--ov-px));
  /* sem padding em cima: o cenário nasce colado no topo da cena, e quem
     devolve o respiro de cima ao conteúdo é a margem de baixo dele */
  padding: 0 var(--ov-px) var(--ov-py);
  min-height: var(--ov-alt, 100vh);
}
.ov-cena > :not(.ov-cenario):not(.ov-aura) { position: relative; z-index: 1; }
/* ---------- A cena passa por trás do topo e do menu lateral ----------
   A AURA é a foto da obra muito desfocada, fixa atrás da janela inteira.
   O topo e o menu lateral viram vidro SÓ quando a tela tem a cena
   (`.app:has(.ov-cena)`): nas outras telas nada muda, e não há estado em
   JS para ficar ligado por engano ao sair de Obras. Navegador sem `:has`
   fica com o topo e o menu de sempre.
   ⚠ o topo (z 20) e o menu (z 15) pintam POR CIMA da aura, que mora dentro
   da cena — por isso ela aparece através deles, e não sobre eles. */
.ov-aura { display: block !important; position: fixed; inset: 0; z-index: -1; pointer-events: none; background: var(--ov-fundo); }
/* ⚠ O QUANTO A FOTO APARECE É UMA CONTA, NÃO UM GOSTO. Com brilho .55 e vidro
   a .66–.8 o menu saía igual ao azul de sempre e a "transição entre a cena e
   os botões" não se via. Aí subi para brilho .72 e vidro .42 — e a revisão da
   1.2.70 mediu o pior caso (céu branco no alto da foto, o normal em foto de
   canteiro): item do menu 3,55:1, legenda do topo 2,38:1. Abaixo de 4,5.
   Os números de agora (brilho .66, vidro ≥ .58 no topo e ≥ .62 no menu,
   legenda a .86) dão ≥ 4,5 com a foto BRANCA; quem conta é
   tools/test-obravitrine.js, que lê estes valores daqui e refaz a conta. */
.ov-aura img { width: 100%; height: 100%; object-fit: cover; filter: blur(30px) saturate(1.3) brightness(.66); transform: scale(1.15); opacity: 0; transition: opacity .8s var(--ease); }
.ov-aura img.on { opacity: 1; }
.app:has(.ov-cena) > .topbar {
  background: linear-gradient(180deg, rgba(8,20,33,.62), rgba(8,20,33,.58));
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: 0 1px 0 rgba(255,255,255,.08);
}
.app:has(.ov-cena) > .topbar::after { opacity: .45; }
.app:has(.ov-cena) > .topbar .logo small { opacity: .86; }
.app:has(.ov-cena) > .sidebar {
  background: linear-gradient(180deg, rgba(8,20,33,.62) 0%, rgba(8,20,33,.68) 45%, rgba(8,20,33,.76) 100%);
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: 1px 0 0 rgba(255,255,255,.08);
}
/* ⚠ `.ov-cena .tela-head h1`: `.main h1` (0,1,1) pinta o título com a cor
   do TEXTO do tema — escuro sobre a cena escura. Mesmo tropeço do nome da
   obra (ver .ov-palco .ov-nome). */
.ov-cena .tela-head h1 { color: var(--ov-texto); }
/* o cabeçalho do kit de módulo (roteiro de 08/10/2026) sobre a cena: as
   tintas da cena, não as do tema — a cena é escura nos dois temas */
.ov-cena .mod-cab h1 { color: var(--ov-texto); }
.ov-cena .mod-cab .mod-sub { color: var(--ov-fraco); }
.ov-cena .mod-cab .mod-ic { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.16); color: var(--ov-aco); }
/* O CENÁRIO: preso no topo da área de rolagem (sticky), da altura dela
   (--ov-alt, medida pelo JS em #main), e sem ocupar lugar no fluxo (a
   margem de baixo devolve a altura). Rolar a grade não leva a foto embora.
   ⚠ o !important VENCE o style="display:none" do HTML (ver
   ObraVitrine.cenario): folha velha em cache = sem cenário, e não uma foto
   de 1600 px empurrando a lista. */
.ov-cenario {
  display: block !important;
  /* ⚠ `top` NEGATIVO, igual ao respiro do .main. O sticky conta o topo a
     partir do padding da área de rolagem, não da borda: com `top: 0` o
     cenário ficava preso 28px ABAIXO do topo, parado e rolando (medido pela
     tools/e2e-obras-vitrine.js, seção 8b — e a primeira explicação que eu
     escrevi aqui para isso estava errada: mexer na margem não mudou nada). */
  position: sticky; top: calc(-1 * var(--ov-py)); z-index: 0;
  height: var(--ov-alt, 100vh);
  margin: 0 calc(-1 * var(--ov-px)) calc(var(--ov-py) - var(--ov-alt, 100vh));
  overflow: hidden; pointer-events: none;
  background: var(--ov-fundo);
}
/* duas camadas que se revezam: a CAMADA desliza na troca de obra, a FOTO
   dentro dela faz o zoom lento. Na mesma peça, um transform apagaria o outro. */
.ov-camada { position: absolute; inset: 0; opacity: 0; will-change: transform, opacity; }
.ov-camada.on { opacity: 1; }
.ov-cenario.carregando .ov-camada.on { opacity: .35; transition: opacity .3s; }
.ov-camada .ov-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 40%;
  will-change: transform;
  animation-duration: 26s; animation-timing-function: ease-in-out;
  animation-iteration-count: infinite; animation-direction: alternate; animation-fill-mode: both;
}
/* os cinco movimentos de câmera (ObraVitrine.MOVIMENTOS): lentos o bastante
   para parecer vídeo e não enjoar; o `alternate` volta pelo mesmo caminho,
   sem o salto de recomeçar */
.ov-img.kb-aproxima { animation-name: ov-kb-aproxima; }
.ov-img.kb-direita  { animation-name: ov-kb-direita; }
.ov-img.kb-sobe     { animation-name: ov-kb-sobe; }
.ov-img.kb-afasta   { animation-name: ov-kb-afasta; }
.ov-img.kb-diagonal { animation-name: ov-kb-diagonal; }
@keyframes ov-kb-aproxima { from { transform: scale(1.02); } to { transform: scale(1.15); } }
@keyframes ov-kb-direita  { from { transform: scale(1.14) translateX(-3.5%); } to { transform: scale(1.14) translateX(3.5%); } }
@keyframes ov-kb-sobe     { from { transform: scale(1.14) translateY(3%); } to { transform: scale(1.14) translateY(-3%); } }
@keyframes ov-kb-afasta   { from { transform: scale(1.17); } to { transform: scale(1.03); } }
@keyframes ov-kb-diagonal { from { transform: scale(1.06) translate(2.5%, 2%); } to { transform: scale(1.16) translate(-2.5%, -2%); } }
/* a troca de obra: a nova entra pelo lado do card (direita = card mais
   adiante na grade) e a antiga sai pelo lado oposto, as duas esmaecendo.
   1s aqui = ObraVitrine.TROCA_MS no JS. */
.ov-camada.entra-direita, .ov-camada.entra-esquerda, .ov-camada.entra-fade { z-index: 1; }
.ov-camada.entra-direita  { animation: ov-entra-direita 1s var(--ease) both; }
.ov-camada.entra-esquerda { animation: ov-entra-esquerda 1s var(--ease) both; }
.ov-camada.entra-fade     { animation: ov-entra-fade .8s ease both; }
.ov-camada.sai-esquerda   { animation: ov-sai-esquerda 1s var(--ease) both; }
.ov-camada.sai-direita    { animation: ov-sai-direita 1s var(--ease) both; }
.ov-camada.sai-fade       { animation: ov-sai-fade .8s ease both; }
@keyframes ov-entra-direita  { from { opacity: 0; transform: translateX(9%); } to { opacity: 1; transform: none; } }
@keyframes ov-entra-esquerda { from { opacity: 0; transform: translateX(-9%); } to { opacity: 1; transform: none; } }
@keyframes ov-entra-fade     { from { opacity: 0; } to { opacity: 1; } }
@keyframes ov-sai-esquerda   { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(-9%); } }
@keyframes ov-sai-direita    { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(9%); } }
@keyframes ov-sai-fade       { from { opacity: 1; } to { opacity: 0; } }
/* o véu: escuro à esquerda, onde mora o texto do palco; mais claro no meio
   de cima, onde a foto aparece; e escurecendo para baixo, onde está a grade */
.ov-veu {
  position: absolute; inset: 0; z-index: 2;
  background:
    linear-gradient(90deg, rgba(8,20,33,.9) 0%, rgba(8,20,33,.72) 28%, rgba(8,20,33,.26) 58%, rgba(8,20,33,.16) 100%),
    linear-gradient(180deg, rgba(8,20,33,.34) 0%, rgba(8,20,33,0) 20%, rgba(8,20,33,.18) 40%, rgba(8,20,33,.76) 62%, rgba(8,20,33,.9) 100%);
}
/* ⚠ COM A FICHA ABERTA, O VÉU GANHA UM PISO (.4). O véu de cima é fino à
   direita (.16) e some a 20% da altura — é por ali que a foto aparece no
   palco. Com a ficha por cima, esse vão passava através do vidro dela: sobre
   foto clara, o link "Abrir no Google Maps" e o texto fraco da ficha caíam
   abaixo de 4,5:1 (revisão da 1.2.70; medido nos pixels com foto branca:
   link 4,21:1, aba inativa 4,42:1; na conta do pior ponto, 3,14:1).
   O piso escurece a cena só enquanto a ficha está aberta, como o fundo de um
   diálogo; o palco continua com a foto clara. A conta é refeita a partir
   destes números em tools/test-obravitrine.js (seção 11), e a medida nos
   pixels mora em tools/e2e-obras-vitrine.js (seção 8h). */
.ov-veu::after { content: ""; position: absolute; inset: 0; background: rgba(8,20,33,.4); opacity: 0; transition: opacity .5s var(--ease); }
.ov-cena.ficha-aberta .ov-veu::after { opacity: 1; }
/* sem foto: papel milimetrado de prancha, andando devagar. A obra ainda não
   tem imagem, mas a cena continua sendo de engenharia — e não o cinza de
   "imagem faltando" */
.ov-cenario.sem-foto {
  background-image:
    linear-gradient(rgba(143,192,227,.13) 1px, transparent 1px),
    linear-gradient(90deg, rgba(143,192,227,.13) 1px, transparent 1px),
    linear-gradient(rgba(143,192,227,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(143,192,227,.05) 1px, transparent 1px);
  background-size: 80px 80px, 80px 80px, 16px 16px, 16px 16px;
  background-position: -1px -1px;
  animation: ov-prancha 60s linear infinite;
}
@keyframes ov-prancha { to { background-position: 79px 79px, 79px 79px, 15px 15px, 15px 15px; } }
/* O PALCO: só o texto da obra em destaque, sobre o cenário.
   ⚠ o !important VENCE o style="display:none" do HTML (ver ObraVitrine.palco). */
.ov-palco {
  display: grid !important;
  position: relative;
  min-height: 360px; margin: 0 0 26px;
  color: var(--ov-texto);
}
.ov-texto { position: relative; align-self: end; max-width: 680px; padding: 36px 0 24px; }
.ov-linha1 { display: flex; flex-wrap: wrap; gap: 6px 16px; align-items: center; margin: 0 0 8px; font-size: var(--t-peq); color: var(--ov-fraco); }
.ov-st { display: inline-flex; align-items: center; gap: 7px; color: var(--ov-texto); font-weight: var(--p-medio); }
.ov-st::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ov-st, var(--ov-aco)); }
.ov-st[data-st="andamento"] { --ov-st: var(--ov-verde); }
.ov-st[data-st="pausada"] { --ov-st: var(--ov-ambar); }
.ov-st[data-st="concluida"] { --ov-st: var(--ov-fraco); }
/* ⚠ `.ov-palco .ov-nome`, e não `.ov-nome` sozinho: `.main h2` (0,1,1)
   vencia (0,1,0) e pintava o nome com a cor do TEXTO do tema — escuro sobre
   o palco escuro, invisível no tema claro — e ainda o encolhia para 20px.
   Só a foto da tela mostrou; tools/e2e-obras-vitrine.js agora mede cor,
   tamanho e contraste. */
.ov-palco .ov-nome { margin: 0; font-size: var(--t-hero); line-height: 1.12; font-weight: var(--p-forte); letter-spacing: -.5px; color: var(--ov-texto); text-wrap: balance; }
.ov-onde { display: flex; flex-wrap: wrap; gap: 2px 18px; margin: 6px 0 0; font-size: var(--t-base); color: var(--ov-fraco); }
.ov-numeros { display: flex; flex-wrap: wrap; gap: 12px 40px; margin: 22px 0 14px; }
.ov-numeros dt { display: flex; align-items: center; gap: 7px; font-size: var(--t-peq); color: var(--ov-fraco); }
.ov-numeros dd { margin: 2px 0 0; font-size: var(--t-tit); font-weight: var(--p-forte); line-height: 1.25; font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; color: var(--ov-texto); }
.ov-numeros dd.ov-nota { margin: 1px 0 0; font-size: var(--t-micro); font-weight: var(--p-normal); color: var(--ov-fraco); }
.ov-numeros dd.ov-alerta { color: var(--ov-alerta); }
.ov-sw { display: inline-block; flex: none; }
.ov-sw-med { width: 12px; height: 8px; border-radius: 2px; background: var(--ov-verde); }
.ov-sw-hoje { width: 2px; height: 13px; background: var(--ov-texto); }
/* a trena: medido (barra) e calendário (traço) na mesma fita, com as marcas
   de 10 em 10% de uma trena de obra */
.ov-trena {
  position: relative; height: 10px; max-width: 460px; margin: 4px 0 0;
  border-radius: 2px; background-color: rgba(255,255,255,.10);
  background-image: repeating-linear-gradient(90deg, rgba(255,255,255,.30) 0, rgba(255,255,255,.30) 1px, transparent 1px, transparent 10%);
  box-shadow: inset -1px 0 0 rgba(255,255,255,.30);
}
.ov-trena-med { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 2px; background: var(--ov-verde); transform-origin: left center; }
.ov-trena-hoje { position: absolute; top: -5px; bottom: -5px; width: 2px; margin-left: -1px; background: var(--ov-texto); box-shadow: 0 0 0 1px rgba(11,27,44,.6); }
.ov-diario { margin: 14px 0 0; font-size: var(--t-peq); color: var(--ov-fraco); }
.ov-acoes { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.ov-palco .btn.ov-sec { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.3); color: var(--ov-texto); }
.ov-palco .btn.ov-sec:hover { background: rgba(255,255,255,.2); }
.ov-credito { position: absolute; right: 0; bottom: 6px; z-index: 1; margin: 0; font-size: var(--t-micro); color: rgba(255,255,255,.8); text-shadow: 0 1px 2px rgba(0,0,0,.7); }
/* a entrada curta quando o palco TROCA de obra — resposta ao gesto; na
   primeira pintura não roda (a classe só entra em _ovMostrar) */
.ov-texto.entra > * { animation: ov-entra .3s var(--ease) both; }
.ov-texto.entra .ov-trena-med { animation: ov-cresce .55s var(--ease) both; }
@keyframes ov-entra { from { opacity: 0; transform: translateX(-8px); } to { opacity: 1; transform: none; } }
@keyframes ov-cresce { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* ---------- A FICHA DA OBRA — o painel de vidro sobre a cena ----------
   No lugar do formulário branco que o "Abrir obra" abria (pedido de
   11/09/2026). A foto grande continua atrás, vista através do vidro; a grade
   das outras obras sai de cena e volta ao fechar. */
/* atalhos do palco: Mapa, Diário, Medições, Fotos */
.ov-atalhos { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.ov-chip {
  display: inline-flex; align-items: center; gap: 6px; min-height: 34px; padding: 6px 14px;
  border-radius: 999px; border: 1px solid rgba(255,255,255,.22); background: rgba(255,255,255,.08);
  color: var(--ov-texto); font: inherit; font-size: var(--t-peq); font-weight: var(--p-medio); cursor: pointer;
  transition: background .18s, border-color .18s, transform .18s var(--ease);
}
.ov-chip:hover { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.4); transform: translateY(-1px); }
.ov-chip.on { background: var(--ov-texto); border-color: var(--ov-texto); color: var(--ov-fundo); }
.ov-chip:focus-visible, .ov-aba:focus-visible, .ov-ficha-fechar:focus-visible, .ov-linha:focus-visible, .ov-thumb:focus-visible { outline: 2px solid var(--ov-aco); outline-offset: 2px; }
/* ⚠ (0,3,0) + !important: vence o `display: grid !important` do palco */
.ov-cena.ficha-aberta .ov-palco, .ov-cena.ficha-aberta .ov-grade { display: none !important; }
.ov-cena.ficha-voltando .ov-palco, .ov-cena.ficha-voltando .ov-grade { animation: ov-volta .5s var(--ease) both; }
@keyframes ov-volta { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
/* ⚠ o !important VENCE o style="display:none" do HTML (ver ObraVitrine.fichaHtml) */
.ov-ficha {
  display: flex !important; flex-direction: column;
  position: relative; margin: 6px 0 26px;
  min-height: calc(var(--ov-alt, 100vh) - 150px);
  border-radius: var(--raio-lg); overflow: hidden;
  background: linear-gradient(180deg, rgba(8,20,33,.6), rgba(8,20,33,.74));
  -webkit-backdrop-filter: blur(20px) saturate(1.3); backdrop-filter: blur(20px) saturate(1.3);
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 30px 80px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.08);
  color: var(--ov-texto);
  animation: ov-ficha-entra .5s var(--ease) both;
}
@keyframes ov-ficha-entra { from { opacity: 0; transform: translateY(24px) scale(.985); } to { opacity: 1; transform: none; } }
.ov-ficha-cab { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 26px 28px 14px; }
/* ⚠ duas classes pelo mesmo motivo do palco: `.main h2` (0,1,1) pintaria o nome escuro */
.ov-ficha .ov-nome { margin: 0; font-size: var(--t-hero); line-height: 1.12; font-weight: var(--p-forte); letter-spacing: -.5px; color: var(--ov-texto); text-wrap: balance; }
.ov-ficha-fechar {
  flex: none; min-height: 40px; padding: 8px 16px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,.25); background: rgba(255,255,255,.1); color: var(--ov-texto);
  font: inherit; font-weight: var(--p-medio); cursor: pointer; transition: background .15s;
}
.ov-ficha-fechar:hover { background: rgba(255,255,255,.2); }
.ov-abas { display: flex; gap: 2px; padding: 0 20px; border-bottom: 1px solid rgba(255,255,255,.12); overflow-x: auto; scrollbar-width: none; }
.ov-aba {
  flex: none; background: none; border: 0; border-bottom: 2px solid transparent; color: var(--ov-fraco);
  font: inherit; font-weight: var(--p-medio); padding: 12px 14px 11px; cursor: pointer; transition: color .15s, border-color .2s;
}
.ov-aba:hover { color: var(--ov-texto); }
/* o contorno de foco vai POR DENTRO: a barra de abas rola na horizontal e
   cortava o de fora em cima e embaixo — sobravam dois traços soltos */
.ov-aba:focus-visible { outline-offset: -3px; border-radius: 8px; }
.ov-aba.on { color: var(--ov-texto); border-bottom-color: var(--ov-aco); }
.ov-ficha-corpo { flex: 1; padding: 24px 28px; }
.ov-ficha-corpo.entra > * { animation: ov-entra .3s var(--ease) both; }
.ov-ficha-rodape { display: flex; flex-wrap: wrap; gap: 10px; justify-content: flex-end; padding: 16px 28px 22px; border-top: 1px solid rgba(255,255,255,.1); }
.ov-ficha .btn.ov-sec { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.3); color: var(--ov-texto); }
.ov-ficha .btn.ov-sec:hover { background: rgba(255,255,255,.2); }
/* Resumo: os números da obra e os dados do cadastro */
.ov-dados { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px 28px; margin: 26px 0 0; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.1); }
.ov-dados dt { font-size: var(--t-peq); color: var(--ov-fraco); }
.ov-dados dd { margin: 2px 0 0; color: var(--ov-texto); overflow-wrap: anywhere; }
/* Diário, Medições, Documentos */
.ov-lista { display: flex; flex-direction: column; gap: 8px; }
.ov-linha {
  display: flex; align-items: center; gap: 16px; width: 100%; text-align: left; padding: 12px 16px;
  border-radius: var(--raio); border: 1px solid rgba(255,255,255,.1); background: rgba(255,255,255,.05);
  color: var(--ov-texto); font: inherit; cursor: pointer;
  transition: background .15s, border-color .15s, transform .18s var(--ease);
}
.ov-linha:hover { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.22); transform: translateX(3px); }
.ov-linha-fixa { cursor: default; }
.ov-linha-fixa:hover { transform: none; }
.ov-linha-data { flex: none; width: 92px; font-variant-numeric: tabular-nums; color: var(--ov-fraco); font-size: var(--t-peq); }
.ov-linha-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ov-linha-corpo b { font-weight: var(--p-medio); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ov-linha-corpo small { color: var(--ov-fraco); font-size: var(--t-micro); }
.ov-linha-num { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 1px; text-align: right; font-weight: var(--p-forte); font-variant-numeric: tabular-nums; }
.ov-linha-num b { font-weight: inherit; }
/* o valor em R$ embaixo do % da medição */
.ov-linha-num small { font-weight: var(--p-normal); font-size: var(--t-micro); color: var(--ov-fraco); }
.ov-marca { font-style: normal; color: var(--ov-ambar); }
.ov-mais { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 16px; }
.ov-vazio { padding: 28px 0; color: var(--ov-fraco); }
.ov-vazio p { margin: 0 0 14px; max-width: 540px; }
/* Mapa: escurecido e um pouco transparente, para ser parte da cena e não um
   quadro branco colado nela. O filtro inverte as cores do mapa claro do
   Google (sem chave não há estilo escuro); satélite fica natural. */
.ov-mapa-barra { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; }
.ov-seg { display: inline-flex; gap: 6px; }
.ov-link { color: var(--ov-aco); font-size: var(--t-peq); }
.ov-mapa-frame {
  display: block; width: 100%; height: min(56vh, 520px);
  border: 1px solid rgba(255,255,255,.14); border-radius: var(--raio-lg); background: rgba(8,20,33,.4);
  opacity: .88; filter: invert(.9) hue-rotate(180deg) saturate(.75) contrast(.92);
  transition: opacity .3s;
  animation: ov-mapa-entra .7s var(--ease) both;
}
.ov-mapa-frame.satelite { filter: saturate(1.05); opacity: .92; }
.ov-mapa-frame:hover { opacity: 1; }
@keyframes ov-mapa-entra { from { opacity: 0; transform: scale(.975); } to { transform: none; } }
.ov-nota { margin: 10px 0 0; color: var(--ov-fraco); font-size: var(--t-micro); }
/* o aviso de que o endereço vai ao Google fica ACIMA do mapa: embaixo de um
   quadro de 520 px, num notebook, ele caía fora da tela */
.ov-aviso-mapa { margin: 0 0 12px; font-size: var(--t-peq); }
/* Fotos: a miniatura clicada vai para o fundo da cena */
.ov-galeria { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.ov-thumb {
  position: relative; padding: 0; aspect-ratio: 4 / 3; overflow: hidden; cursor: pointer;
  border: 1px solid rgba(255,255,255,.12); border-radius: var(--raio); background: rgba(255,255,255,.06);
}
.ov-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s var(--ease); }
.ov-thumb:hover img { transform: scale(1.06); }
.ov-thumb span { position: absolute; left: 0; right: 0; bottom: 0; padding: 18px 8px 6px; font-size: var(--t-micro); color: #fff; text-align: left; background: linear-gradient(0deg, rgba(0,0,0,.72), rgba(0,0,0,0)); }
.ov-thumb.on { outline: 2px solid var(--ov-aco); outline-offset: 2px; }
.ov-thumb.sem { display: none; }
@media screen and (max-width: 820px) {
  .ov-ficha-cab { flex-direction: column; padding: 18px 16px 10px; }
  .ov-ficha .ov-nome { font-size: calc(var(--t-hero) * .8); }
  .ov-abas { padding: 0 6px; }
  .ov-ficha-corpo { padding: 18px 16px; }
  .ov-ficha-rodape { padding: 14px 16px 18px; }
  .ov-linha-data { width: 74px; }
  .ov-mapa-frame { height: 50vh; }
}
/* ---------- Os cards da grade de Obras: vidro sobre a cena ----------
   ⚠ SÓ dentro de `.ov-grade`: o `.orc-card` também é o card da lista de
   Orçamentos, que não tem cena atrás e continua como era.
   ⚠ A ALTURA DA CAPA (132/152 px) e o padding de 24px NÃO mudam aqui:
   tools/e2e-imagem-sem-css.js confere a altura exata, e o piso de
   UI.chaoDeEstilo() conta com a margem -24px. O que muda é pele, não caixa. */
/* ---------- A FILEIRA: um trilho só, no pé da cena, que anda para os lados ----------
   Pedido de 11/09/2026: a grade rolando para baixo poluía a tela. A cena
   vira coluna — o palco em cima, a fileira colada embaixo (margin-top:
   auto) — e o card é só a foto e o nome.
   ⚠ A ALTURA da capa continua a das regras de cima (132 / 152 px no
   celular): não se escreve `height` aqui, senão o 152 do celular perde. */
.ov-cena { display: flex; flex-direction: column; }
/* a fileira vai de ponta a ponta da cena (como no Netflix) e as setas moram
   na calha das pontas.
   ⚠ --ov-calha tem de ser MAIOR que a largura da seta (76 px): é até ali
   que a seta, a rodinha e o Tab trazem o card (Gestao._ovAlinhar e o
   scroll-padding). Com 64 px o card parava 12 px embaixo da seta, e o
   mouse na beira dele caía na seta (revisão da 1.2.71). */
.ov-fila { position: relative; margin: auto calc(-1 * var(--ov-px)) 0; padding-top: 22px; --ov-calha: 84px; }
.ov-cena.ficha-aberta .ov-fila { display: none !important; }
.ov-cena.ficha-voltando .ov-fila { animation: ov-volta .5s var(--ease) both; }
/* ⚠ UMA regra só para o trilho. Havia duas com a mesma especificidade, e a
   de baixo (padding e scroll-padding de 2 px) anulava a da calha — visto
   pela revisão da 1.2.71. position: relative faz o offsetLeft dos cards
   ser contado a partir do trilho (é o que o Gestao._ovAlinhar usa). */
.ov-fila .ov-grade {
  display: flex; gap: 16px; margin: 0; padding: 8px var(--ov-px) 14px; position: relative;
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity; scroll-padding-inline: var(--ov-calha);
  scrollbar-width: none;
}
.ov-fila .ov-grade::-webkit-scrollbar { display: none; }
/* o card deixa de ser caixa: sem fundo, sem borda, sem padding — quem tem
   corpo é a foto. (0,2,0) vence o `.card`/`.orc-card` do resto do app. */
.ov-grade .orc-card {
  flex: 0 0 236px; scroll-snap-align: start; position: relative;
  padding: 0; margin: 0; background: none; border: 0; border-radius: 0; box-shadow: none;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  color: var(--ov-texto); cursor: pointer; outline: none; transform: none;
}
.ov-grade .orc-card::before, .ov-grade .orc-card::after { display: none; }
.ov-grade .orc-card:hover { transform: none; box-shadow: none; border-color: transparent; background: none; }
.ov-grade .orc-card .obra-capa {
  position: relative; margin: 0; border-radius: 12px;
  background: linear-gradient(135deg, #163a5c 0%, #0b1a2a 100%);
  box-shadow: 0 10px 26px rgba(0,0,0,.36), 0 0 0 1px rgba(255,255,255,.1);
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.ov-grade .orc-card .obra-capa::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: linear-gradient(0deg, rgba(8,20,33,.35) 0%, rgba(8,20,33,0) 45%); pointer-events: none; }
.ov-grade .orc-card .obra-capa img { transition: transform .6s var(--ease); }
.ov-grade .orc-card:hover .obra-capa { transform: translateY(-4px); box-shadow: 0 18px 38px rgba(0,0,0,.46), 0 0 0 1px rgba(255,255,255,.34); }
.ov-grade .orc-card:hover .obra-capa img { transform: scale(1.06); }
/* o card que está no palco: o elo entre a fileira e o topo */
.ov-grade .orc-card.em-cena .obra-capa { box-shadow: 0 0 0 2px var(--ov-aco), 0 18px 40px rgba(0,0,0,.46), 0 0 30px rgba(143,192,227,.28); }
.ov-grade .orc-card:focus-visible .obra-capa { box-shadow: 0 0 0 3px #fff, 0 0 0 6px var(--ov-aco), 0 18px 40px rgba(0,0,0,.46); }
/* ⚠ (0,2,1) vence o `.main h3` (0,1,1) — ver a nota do .main h2 no palco */
.ov-grade .orc-card h3 {
  margin: 10px 2px 0; font-size: var(--t-base); line-height: 1.3; font-weight: var(--p-forte); color: var(--ov-fraco);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  transition: color .2s;
}
.ov-grade .orc-card:hover h3, .ov-grade .orc-card.em-cena h3, .ov-grade .orc-card:focus-visible h3 { color: var(--ov-texto); }
/* obra sem foto nenhuma: a marca no lugar da foto, apagada */
.ov-grade .orc-card .obra-capa.sem-foto { display: flex; align-items: center; justify-content: center; }
.ov-grade .orc-card .obra-capa.sem-foto svg { width: 54px; height: 54px; opacity: .5; }
.ov-grade .obra-capa.sem-foto .ov-marca-fundo { fill: rgba(255,255,255,.08); }
.ov-grade .obra-capa.sem-foto .ov-b1 { fill: rgba(255,255,255,.5); }
.ov-grade .obra-capa.sem-foto .ov-b2 { fill: rgba(255,255,255,.8); }
.ov-grade .obra-capa.sem-foto .ov-b3 { fill: var(--ov-verde); }

/* AS SETAS — o logo da OrçaPRO. As barras sobem para a direita, então ele
   aponta para a frente; espelhado (scaleX(-1)), para trás. Faixa da altura
   da fileira, com o degradê do fundo, como no Netflix.
   ⚠ o !important do .on vence o style="display:none" (ver ObraVitrine.fila) */
.ov-seta {
  position: absolute; top: 22px; bottom: 14px; z-index: 3; width: 76px;
  align-items: center; justify-content: center;
  margin: 0; padding: 0; border: 0; cursor: pointer; color: #fff;
  opacity: .85; transition: opacity .25s var(--ease);
}
.ov-seta.on { display: flex !important; }
.ov-fila:hover .ov-seta, .ov-seta:focus-visible { opacity: 1; }
.ov-seta.esq { left: 0; padding-right: 12px; background: linear-gradient(90deg, rgba(8,20,33,.94) 0%, rgba(8,20,33,.6) 55%, rgba(8,20,33,0) 100%); }
.ov-seta.dir { right: 0; padding-left: 12px; background: linear-gradient(270deg, rgba(8,20,33,.94) 0%, rgba(8,20,33,.6) 55%, rgba(8,20,33,0) 100%); }
.ov-seta svg { width: 46px; height: 46px; overflow: visible; filter: drop-shadow(0 8px 18px rgba(0,0,0,.55)); transition: transform .25s var(--ease); }
.ov-seta.esq svg { transform: scaleX(-1); }
.ov-seta:hover svg { transform: scale(1.14); }
.ov-seta.esq:hover svg { transform: scaleX(-1) scale(1.14); }
.ov-seta .ov-marca-fundo { fill: #163a5c; stroke: rgba(255,255,255,.4); stroke-width: 2.5; transition: stroke .2s; }
.ov-seta .ov-b1 { fill: rgba(255,255,255,.55); }
.ov-seta .ov-b2 { fill: rgba(255,255,255,.92); }
.ov-seta .ov-b3 { fill: var(--ov-verde); }
.ov-seta:focus-visible { outline: none; }
.ov-seta:focus-visible .ov-marca-fundo { stroke: var(--ov-aco); stroke-width: 7; }
/* ao passar o mouse as barras sobem em onda, da menor para a maior: o
   movimento corre no sentido da seta */
.ov-seta rect { transform-box: fill-box; transform-origin: 50% 100%; }
.ov-seta:hover .ov-b1 { animation: ov-barra .9s var(--ease) infinite; }
.ov-seta:hover .ov-b2 { animation: ov-barra .9s var(--ease) .12s infinite; }
.ov-seta:hover .ov-b3 { animation: ov-barra .9s var(--ease) .24s infinite; }
@keyframes ov-barra { 0%, 100% { transform: scaleY(1); } 45% { transform: scaleY(1.22); } }
@media (prefers-reduced-motion: reduce) {
  :root:not([data-movimento="sempre"]) .ov-seta:hover rect { animation: none; }
}
@media screen and (max-width: 820px) {
  /* no celular a fileira anda com o dedo; seta em cima de card de 210 px
     tampa metade dele */
  .ov-seta.on { display: none !important; }
  .ov-grade .orc-card { flex-basis: 210px; }
}

/* ---------- O rodapé da ficha ganhou as ações do card ---------- */
.ov-ficha-rodape .ov-rodape-vao { flex: 1 1 auto; }
.ov-ficha-rodape .btn.ov-perigo { color: var(--ov-alerta); }
.ov-ficha-rodape .btn.ov-perigo:hover { border-color: var(--ov-alerta); background: rgba(244,153,157,.14); }

/* ---------- O Portal do cliente com a cara da ficha ----------
   Pedido de 11/09/2026: "o painel da obra e o do portal do cliente com a
   mesma configuração de layout". O modal do Portal ganha o vidro da ficha,
   no tema de quem usa (ver abaixo). Caixa com fundo claro fixo no style=
   tem de fixar também a cor do texto — senão, no escuro, herda o texto
   claro e some. Só o do Portal leva o vidro — os outros ~140 UI.modal do
   app continuam como são. */
.modal-bg.ov-modal-vidro { background: rgba(3,9,16,.55); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
/* ⚠ O TEMA É O DE QUEM USA. A primeira versão punha data-tema="dark" no
   #modal-bg sempre — e o formulário do Portal tem caixas com fundo claro
   fixo (o resultado da publicação, as linhas que revelam custo, avisos com
   cor no style=): no escuro forçado o texto delas ficou em 1,08:1 a 2,1:1
   (revisão da 1.2.71). No tema claro, o padrão, o vidro é CLARO e tudo se
   lê como até a 1.2.70; quem escolheu o escuro ganha o vidro escuro. */
.modal-bg.ov-modal-vidro > .modal {
  background: rgba(255,255,255,.9);
  -webkit-backdrop-filter: blur(22px) saturate(1.3); backdrop-filter: blur(22px) saturate(1.3);
  border: 1px solid rgba(255,255,255,.7); border-radius: 18px;
  box-shadow: 0 30px 80px rgba(0,0,0,.45), inset 0 1px 0 rgba(255,255,255,.6);
}
.modal-bg.ov-modal-vidro > .modal > header { background: transparent; border-bottom: 1px solid var(--linha); }
.modal-bg.ov-modal-vidro > .modal > .body { background: transparent; }
.modal-bg.ov-modal-vidro > .modal > footer { background: rgba(15,39,64,.04); border-top: 1px solid var(--linha); }
[data-tema="dark"] .modal-bg.ov-modal-vidro > .modal {
  background: linear-gradient(180deg, rgba(12,27,42,.8), rgba(8,20,33,.9));
  border-color: rgba(255,255,255,.14); color: var(--texto);
  box-shadow: 0 30px 80px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.06);
}
[data-tema="dark"] .modal-bg.ov-modal-vidro > .modal > header { border-bottom-color: rgba(255,255,255,.1); }
[data-tema="dark"] .modal-bg.ov-modal-vidro > .modal > footer { background: rgba(0,0,0,.16); border-top-color: rgba(255,255,255,.1); }
/* as duas caixas de aviso do Portal têm a cor no style= (o tema claro não
   as alcança); a classe ov-pt-caixa, posta pelo portalObra, deixa o vidro
   pintá-las. ⚠ !important porque vence o style= da própria caixa. */
[data-tema="dark"] .modal-bg.ov-modal-vidro .ov-pt-caixa { background: rgba(61,143,208,.14) !important; border-color: rgba(143,192,227,.34) !important; color: #dcebf8 !important; }
[data-tema="dark"] .modal-bg.ov-modal-vidro .ov-pt-caixa.ov-pt-atencao { background: rgba(232,176,79,.13) !important; border-color: rgba(232,176,79,.42) !important; color: #f6dcae !important; }
[data-tema="dark"] .modal-bg.ov-modal-vidro .ov-pt-caixa b { color: #fff; }
@media screen and (max-width: 820px) {
  /* ⚠ o padding do .main no celular (14px 12px, na regra de 820px acima) */
  .ov-cena { --ov-py: 14px; --ov-px: 12px; }
  .ov-palco { min-height: 300px; }
  .ov-texto { padding: 18px 0 16px; }
  .ov-palco .ov-nome { font-size: calc(var(--t-hero) * .8); }
  .ov-numeros { gap: 10px 26px; }
  /* ⚠ no celular o texto cobre a foto de cima a baixo, então o véu é quase
     uniforme. A 1ª versão clareava para .4 no topo e a linha de status caiu
     em cima da parte clara da foto (visto na captura a 390 px). */
  .ov-veu { background: linear-gradient(180deg, rgba(8,20,33,.8) 0%, rgba(8,20,33,.86) 50%, rgba(8,20,33,.93) 100%); }
}
/* quem pediu menos movimento vê a foto parada e a troca sem deslize — o
   guarda geral do arquivo encurtaria as animações, mas deixaria a foto
   presa no fim do zoom; aqui ela fica no enquadramento de repouso */
/* ⚠ A MENOS QUE a pessoa tenha escolhido "Sempre ligado" em Aparência
   (App.aplicarMovimento → <html data-movimento="sempre">): aí a escolha dela
   passa na frente da do sistema. As três primeiras regras param a cena; as
   de baixo DEVOLVEM as durações, porque o guarda geral do arquivo
   (* { animation-duration: .001ms !important }) as zeraria mesmo assim.
   Medido em 11/09/2026: a máquina da RA tem as animações do Windows
   desligadas — sem esta porta, quem pediu o efeito nunca o via. */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-movimento="sempre"]) .ov-camada .ov-img { animation: none !important; transform: scale(1.04); }
  :root:not([data-movimento="sempre"]) .ov-camada.entra-direita, :root:not([data-movimento="sempre"]) .ov-camada.entra-esquerda, :root:not([data-movimento="sempre"]) .ov-camada.entra-fade,
  :root:not([data-movimento="sempre"]) .ov-camada.sai-direita, :root:not([data-movimento="sempre"]) .ov-camada.sai-esquerda, :root:not([data-movimento="sempre"]) .ov-camada.sai-fade { animation: none !important; }
  :root:not([data-movimento="sempre"]) .ov-cenario.sem-foto { animation: none !important; }
  :root[data-movimento="sempre"] .ov-camada .ov-img { animation-duration: 26s !important; animation-iteration-count: infinite !important; }
  :root[data-movimento="sempre"] .ov-camada.entra-direita, :root[data-movimento="sempre"] .ov-camada.entra-esquerda,
  :root[data-movimento="sempre"] .ov-camada.sai-direita, :root[data-movimento="sempre"] .ov-camada.sai-esquerda { animation-duration: 1s !important; }
  :root[data-movimento="sempre"] .ov-camada.entra-fade, :root[data-movimento="sempre"] .ov-camada.sai-fade { animation-duration: .8s !important; }
  :root[data-movimento="sempre"] .ov-cenario.sem-foto { animation-duration: 60s !important; animation-iteration-count: infinite !important; }
  :root[data-movimento="sempre"] .ov-texto.entra > * { animation-duration: .3s !important; }
  :root[data-movimento="sempre"] .ov-texto.entra .ov-trena-med { animation-duration: .55s !important; }
}
/* ⚠ A AURA TAMBÉM SAI DO PAPEL. Ela é fixa, cobre a janela e o
   `display: block !important` dela vale na impressão — sem esta linha, a
   foto desfocada se repetiria atrás de cada folha. Medido em 11/09/2026
   (tools/e2e-obras-vitrine.js, 8i): hoje ela não chega à folha porque o
   `body > *:not(#proposta-print)` do bloco de impressão já tira o .app
   inteiro; esta linha é a que segura no dia em que a lista for impressa. */
@media print { .ov-palco, .ov-cenario, .ov-ficha, .ov-aura { display: none !important; } .ov-cena { margin: 0; padding: 0; min-height: 0; } }

/* =====================================================================
 * APARÊNCIA — o seletor de dois eixos (v1.1.188)
 * ===================================================================== */
.tema-grupo { margin-top: 16px; }
.tema-grupo:first-of-type { margin-top: 10px; }
.tema-rot { display: block; font-size: var(--t-micro); font-weight: var(--p-medio);
  letter-spacing: .08em; text-transform: uppercase; color: var(--texto-fraco); margin-bottom: 8px; }
/* duas opções por eixo, não seis num cardápio só */
.tema-grupo .tema-ops { grid-template-columns: repeat(2, 1fr); }
/* amostra da LETRA: o número é a prova. No Plex os dígitos têm largura fixa
   e a vírgula fica no prumo; na Source, não. Mostrar a diferença vale mais
   que descrevê-la. */
.tema-op .sw-txt { display: block; font-size: var(--t-tit); font-variant-numeric: tabular-nums;
  color: var(--texto); margin-bottom: 8px; letter-spacing: -.01em; }
.tema-op:focus-visible { outline: 2px solid var(--aco); outline-offset: 2px; }

/* =====================================================================
 * NÚMERO EM COLUNA usa a família numérica.
 * Numa planilha de orçamento a conferência é visual: o olho desce a coluna
 * e procura a vírgula fora do prumo. Com dígito de largura variável isso é
 * impossível — e é por isso que o Plex traz o Mono junto.
 * ===================================================================== */
.tbl td.num, .tbl th.num, td.num, .num.tnum, .kpi .num,
.tnum, [class*="tnum"] { font-family: var(--fonte-num); font-variant-numeric: tabular-nums; }

/* =====================================================================
 * SELO "ALTERADO POR VOCÊ" — desvio em cima do preço da base
 *
 * Cor por DIREÇÃO, não por juízo de valor: acima da base é âmbar (chama
 * atenção porque é o que a fiscalização questiona), abaixo é azul-esverdeado
 * (informativo, não "bom"). Vermelho ficaria para erro, e alterar preço não
 * é erro — é decisão do orçamentista.
 * ===================================================================== */
.selo-ajuste {
  display: inline-block; margin: 3px 0 0 0; padding: 1px 6px;
  border: 1px solid transparent; border-radius: var(--raio-sm);
  font-size: var(--t-micro); font-weight: var(--p-medio);
  font-variant-numeric: tabular-nums; line-height: 1.5;
  cursor: pointer; background: var(--surface-2); color: var(--texto);
}
.selo-ajuste + .selo-ajuste { margin-left: 4px; }
.selo-ajuste:hover { border-color: var(--linha-forte); }
.selo-ajuste:focus-visible { outline: 2px solid var(--linha-forte); outline-offset: 1px; }
/* ⚠ CORES PRÓPRIAS, não os tokens --amarelo/--verde-claro: medidos sobre o
   fundo tintado do próprio selo, aqueles davam 3,67 e 2,90 de contraste — o
   selo saía apagado no tema claro, o mesmo defeito da v1.1.192 (que era no
   escuro). Estes dão 5,18 e 5,77, acima do mínimo de 4,5:1 da WCAG AA. */
.selo-ajuste.sobe  { background: rgba(170, 98, 0, .14);  color: #8f5200; border-color: rgba(170, 98, 0, .30); }
.selo-ajuste.desce { background: rgba(26, 156, 75, .12); color: #0f6b33; border-color: rgba(26, 156, 75, .28); }
.selo-ajuste.novo  { background: rgba(46, 111, 158, .14); color: var(--texto); border-color: rgba(46, 111, 158, .30); }
.selo-ajuste.coef  { background: var(--surface-3); color: var(--texto-fraco); border-color: var(--linha); }
.aj-sobe  { color: #8f5200; font-weight: var(--p-medio); }
.aj-desce { color: #0f6b33; font-weight: var(--p-medio); }
/* ⚠ O par escuro destes quatro NÃO mora aqui — mora perto do fim do arquivo,
   junto das regras do comparativo (`[data-tema="dark"] .selo-ajuste.sobe`,
   com #f0b429 / #4ade80 e um fundo mais opaco). Medido: 7,10:1 e 7,33:1, os
   dois acima de AA. Está anotado aqui porque este é o lugar onde se procura:
   um par escuro duplicado neste ponto seria código morto — a regra de lá vem
   depois, com a mesma especificidade, e ganharia de qualquer jeito. */

/* campo de coeficiente ajustado: a borda marca sem gritar */
input.coef-edit.mexido { border-color: var(--amarelo); background: rgba(170, 98, 0, .06); }

/* faixa de resumo no alto da planilha */
.faixa-ajustes {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 10px; padding: 8px 12px;
  border: 1px solid rgba(170, 98, 0, .28); border-left: 3px solid var(--amarelo);
  border-radius: var(--raio); background: rgba(170, 98, 0, .07);
  font-size: var(--t-peq); color: var(--texto);
}
.faixa-ajustes .fa-ico { display: flex; color: var(--amarelo); }
.faixa-ajustes .fa-txt { flex: 1 1 260px; }

/* comparativo base × seu valor, dentro do modal */
.cmp-ajuste {
  border: 1px solid var(--linha); border-radius: var(--raio);
  padding: 12px; margin-bottom: 12px; background: var(--surface-2);
}
.cmp-linha { margin-bottom: 8px; }
.cmp-rot { font-weight: var(--p-forte); font-size: var(--t-peq); color: var(--texto); }
.cmp-nums { display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap; }
.cmp-cel {
  flex: 1 1 110px; padding: 8px 10px; border-radius: var(--raio-sm);
  background: var(--surface); border: 1px solid var(--linha);
  display: flex; flex-direction: column; gap: 2px;
}
.cmp-cel b { font-size: var(--t-med); font-variant-numeric: tabular-nums; color: var(--texto); }
.cmp-lbl { font-size: var(--t-micro); color: var(--texto-fraco); text-transform: uppercase; letter-spacing: .04em; }
.cmp-sub { font-size: var(--t-micro); color: var(--texto-fraco); }
.cmp-cel.sobe  { border-color: rgba(170, 98, 0, .38);  background: rgba(170, 98, 0, .08); }
.cmp-cel.sobe b, .cmp-cel.sobe .cmp-sub { color: #8f5200; }
.cmp-cel.desce { border-color: rgba(26, 156, 75, .34); background: rgba(26, 156, 75, .07); }
.cmp-cel.desce b, .cmp-cel.desce .cmp-sub { color: #0f6b33; }
.cmp-seta { display: flex; align-items: center; color: var(--texto-fraco); font-size: var(--t-med); }
.cmp-impacto { margin-top: 8px; font-size: var(--t-peq); color: var(--texto); }
.cmp-meta { margin: 8px 0; font-size: var(--t-micro); color: var(--texto-fraco); }
.cmp-alerta {
  margin-top: 8px; padding: 8px 10px; border-radius: var(--raio-sm);
  background: rgba(170, 98, 0, .10); border: 1px solid rgba(170, 98, 0, .26);
  font-size: var(--t-peq); color: var(--texto);
}
.cmp-just { display: block; margin-top: 12px; font-size: var(--t-peq); color: var(--texto); }
.cmp-just > span { display: block; margin-bottom: 4px; font-weight: var(--p-medio); }

/* no tema escuro os fundos translúcidos precisam de mais opacidade para
   não sumirem contra a superfície escura (a lição da v1.1.192) */
[data-tema="dark"] .selo-ajuste.sobe,
[data-tema="dark"] .faixa-ajustes { background: rgba(245, 158, 11, .16); }
[data-tema="dark"] .selo-ajuste.sobe, [data-tema="dark"] .faixa-ajustes .fa-ico,
[data-tema="dark"] .cmp-cel.sobe b, [data-tema="dark"] .cmp-cel.sobe .cmp-sub,
[data-tema="dark"] .aj-sobe { color: #f0b429; }
[data-tema="dark"] .selo-ajuste.desce, [data-tema="dark"] .cmp-cel.desce b,
[data-tema="dark"] .cmp-cel.desce .cmp-sub, [data-tema="dark"] .aj-desce { color: #4ade80; }
[data-tema="dark"] .cmp-alerta { background: rgba(245, 158, 11, .14); }
[data-tema="dark"] input.coef-edit.mexido { border-color: #f0b429; background: rgba(245, 158, 11, .10); }

/* =====================================================================
 * FAIXA DE TOTAIS DO FINANCEIRO — o recorte e os números DELE
 *
 * O primeiro bloco é o rótulo do recorte, e não um KPI: quem olha precisa
 * ler "estou vendo a obra X" ANTES de ler os valores, senão o saldo de uma
 * obra passa por saldo da empresa.
 * ===================================================================== */
.fin-faixa {
  display: flex; align-items: stretch; gap: 10px; flex-wrap: wrap;
  margin-bottom: 14px; padding: 10px 12px;
  border: 1px solid var(--linha); border-left: 3px solid var(--navy);
  border-radius: var(--raio); background: var(--surface-2);
}
.fin-faixa .fin-rec, .fin-faixa .fin-kpi {
  display: flex; flex-direction: column; gap: 1px; min-width: 118px;
  padding-right: 12px; border-right: 1px solid var(--linha);
}
.fin-faixa .fin-kpi:last-of-type { border-right: 0; }
.fin-faixa .fin-lbl {
  font-size: var(--t-micro); color: var(--texto-fraco);
  text-transform: uppercase; letter-spacing: .05em; font-weight: var(--p-medio);
}
.fin-faixa b { font-size: var(--t-med); font-variant-numeric: tabular-nums; color: var(--texto); }
.fin-faixa .fin-rec b { font-size: var(--t-base); }
.fin-faixa .fin-sub { font-size: var(--t-micro); color: var(--texto-fraco); font-variant-numeric: tabular-nums; }
@media (max-width: 700px) {
  .fin-faixa .fin-rec, .fin-faixa .fin-kpi { border-right: 0; min-width: 46%; }
}

/* =====================================================================
 * UMA LINGUAGEM SO PARA CABECALHO, INDICADOR E ACAO DE LINHA
 *
 * Tres inconsistencias medidas em 02/09/2026, olhando as telas lado a lado:
 *
 * 1) HIERARQUIA DE BOTAO. O cabecalho do Financeiro tinha quatro botoes de
 *    peso parecido — "Lancar de documento (IA)" (com fundo navy solido
 *    inline), "CSV", "Gasto rapido" e "+ Novo lancamento". Quando tudo pesa
 *    igual, nada e o proximo passo. So o `.primary` que o `_head` desenha e
 *    a acao principal; o resto e secundario POR DEFINICAO.
 *
 * 2) INDICADOR EM DOIS DIALETOS. O Painel usa cartoes brancos com sombra
 *    (.kpi); Financeiro e Compras usam uma faixa cinza chapada
 *    (.fin-faixa). Mesma informacao, dois pesos visuais. A faixa passa a
 *    falar a lingua do cartao — mesma superficie, mesma borda, mesma sombra
 *    — e a diferenca fica sendo so a DENSIDADE, que e deliberada: cartao na
 *    tela de analise, faixa no topo de uma lista.
 *
 * 3) ACAO DE LINHA COMPETINDO COM O DADO. "Estornar" repetido em toda linha
 *    paga formava uma coluna de botoes que puxava o olho mais que os
 *    valores — e valor e o que a pessoa foi ali ler.
 *
 * ⚠ DISCRETO NAO E ESCONDIDO. A cor do texto continua `--texto-fraco`
 * (5,9:1 sobre a superficie, acima do AA), a borda continua visivel e o
 * hover/foco devolve o contraste inteiro. Botao de dinheiro que some e
 * trava sem porta: quem nao acha o "Estornar" resolve marcando o documento
 * de outro jeito, e isso vai parar no Portal do cliente.
 * ===================================================================== */

/* --- 1) o cabecalho de tela: um principal, o resto secundario --- */
.tela-acoes { gap: 8px; align-items: center; flex-wrap: wrap; }
/* ⚠ `!important` aqui e deliberado, e e o unico jeito honesto: as 37 telas
   carregam `margin-right` INLINE nos botoes de acao ("margin-right:10px;
   align-self:center", repetido tela a tela), e inline so perde para
   important. Com o `gap` do flex fazendo o espacamento, a margem antiga
   soma e abre um vao de 18px entre botoes. A alternativa era editar 37
   trechos a mao e torcer para a proxima tela lembrar do padrao. */
.tela-acoes .btn { margin-right: 0 !important; align-self: center !important; }
/* ⚠ O SECUNDÁRIO DO CABEÇALHO DE TELA NÃO TEM MAIS REGRA PRÓPRIA (14/09/2026).
   Aqui morava um `.tela-acoes .btn:not(.primary):not(.success):not(.danger)`
   (0,4,0) com a pele do secundário — superfície, borda --linha, sem sombra,
   texto --texto-fraco — e um hover com --sombra-sm. Era a mesma pele que o
   `.btn` passou a ter na declaração original (a régua N2), escrita uma
   segunda vez com especificidade que vence qualquer componente. Duas
   declarações do mesmo botão é o defeito que a régua conserta; o texto
   volta a --texto (N2), e a hierarquia continua dita pelo preenchimento do
   `.primary`, que é o único cheio da área. */

/* A BARRA DO EDITOR DE ORÇAMENTO (duas linhas de 16 botões, separadores,
   rótulos encurtados abaixo de 1440 px) e as FAIXAS DE PENDÊNCIA saíram em
   08/10/2026: o editor monta com o kit do padrão de tela (js/modulo.js,
   a seção do padrão de tela no fim deste arquivo) — 2 ações à vista,
   o resto no "Mais", um aviso só. Ver js/ui.js renderEditor. */

/* =====================================================================
 * GRAFICOS — MARCAS FINAS, MOLDURA RECUADA, LEITURA NO HOVER
 *
 * A regra que organiza tudo aqui: a moldura (grade, eixo, rotulo) NAO pode
 * ter o mesmo peso do dado. Antes a grade usava `--linha-forte`, a mesma
 * tinta de uma borda de tabela, e as linhas de grade competiam com as
 * proprias linhas do fluxo de caixa.
 *
 * ⚠ A CAMADA DE LEITURA E CSS PURO. O painel redesenha o SVG inteiro a cada
 * filtro; listener aqui teria de ser reatado a cada render, e o que nao e
 * reatado vira recurso morto que ninguem percebe. `:hover` num <g> nao
 * precisa de reatamento nenhum.
 * ===================================================================== */
.g-grade { stroke: var(--linha); stroke-width: 1; }
.g-zero  { stroke: var(--linha-forte); stroke-width: 1.4; }
.g-eixo  { font-size: var(--t-graf-eixo); font-weight: var(--p-forte); fill: var(--texto-fraco); }
.g-mes   { font-size: var(--t-graf-mes); font-weight: var(--p-forte); fill: var(--texto-fraco); }
/* o ultimo mes e o que a pessoa procura primeiro */
.g-mes.atual { fill: var(--texto); }

/* marca de 2px: fina o bastante para duas linhas proximas nao virarem uma */
.g-linha { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
/* ⚠ o tracejado NAO e enfeite: e a codificacao secundaria que mantem as
   series distinguiveis para quem nao separa as duas tintas. O par mais
   dificil desta paleta separa 13,7 de Delta-E em daltonismo, acima do piso
   8 — mas o tracejado e a legenda existem para o caso de impressao em
   preto e branco, onde a cor nao existe. */
.g-linha.tracejada { stroke-dasharray: 7 4; }
/* anel da cor da superficie: separa o ponto da linha que passa por baixo */
.g-fim { stroke: var(--surface); stroke-width: 2; }

/* ⚠ `.g-bar` TAMBÉM (24/09/2026). A camada de leitura foi copiada do fluxo
   (.g-col) para as barras do Previsto × Realizado (.g-bar) sem copiar este
   seletor: as N leituras nasciam visíveis, empilhadas no mesmo canto, e a
   última cobria as outras — o "rótulo sobreposto" das capturas. E o hover
   das barras não existia. */
.g-col .g-guia, .g-col .g-pt, .g-col .g-ler, .g-bar .g-ler { opacity: 0; transition: opacity .12s ease; }
.g-col:hover .g-guia, .g-col:hover .g-pt, .g-col:hover .g-ler, .g-bar:hover .g-ler { opacity: 1; }
.g-hit { fill: transparent; }
.g-guia { stroke: var(--linha-forte); stroke-width: 1; stroke-dasharray: 3 3; pointer-events: none; }
.g-pt { stroke: var(--surface); stroke-width: 2; pointer-events: none; }
.g-ler { pointer-events: none; }
.g-ler-fundo { fill: var(--surface); opacity: .94; }
.g-ler-txt { font-size: var(--t-graf-eixo); font-weight: var(--p-forte); }
.g-ler-mes { fill: var(--texto); }
/* ⚠ o texto usa TINTA DE TEXTO, e a cor fica na palavra que nomeia a serie.
   Numero pintado da cor da serie perde contraste e vira decoracao — a
   identidade quem carrega e a marca ao lado, nao o algarismo. */
.g-ler-a { fill: var(--texto-fraco); }
.g-ler-b { fill: var(--texto-fraco); }
.g-ler-c { fill: var(--texto-fraco); }

.g-b-prev { fill: var(--graf-prev); }
.g-b-real { fill: var(--graf-a); }
/* estouro e ESTADO, nao serie: usa a tinta de alerta reservada e vem sempre
   com a palavra junto (legenda + leitura), nunca so pela cor */
.g-b-real.estourou { fill: var(--graf-alerta); }
.g-bar-nome { pointer-events: none; }
.g-ler-est { fill: var(--graf-alerta); }
.g-leg-cx { width: 11px; height: 11px; border-radius: 3px; flex: none; }
/* =====================================================================
 * ÍNDICE DE ETAPAS — a estrutura do orçamento sempre à vista
 * O painel e a tabela dividem a largura; abaixo de 1100px o indice vira uma
 * FITA HORIZONTAL em vez de sumir: em tablet a lista de etapas continua
 * valendo, so nao cabe em coluna.
 * ===================================================================== */
/* ⚠ a largura do índice é a variável `--idx-w` (padrão 232px), que a alça da
   borda (js/paineisui.js) muda em linha. Variável, e não
   `grid-template-columns` no atributo style: o atributo venceria a media query
   de 1100px abaixo e o índice deixaria de virar fita no tablet. O
   `position:relative` é a âncora da alça, que é absoluta para não entrar no
   grid (como filho comum ela tomaria a 2ª coluna e empurraria a tabela). */
.pl-com-indice { --idx-w: 232px; position: relative; display: grid; grid-template-columns: var(--idx-w) minmax(0, 1fr); gap: 14px; align-items: start; }
.pl-tabela { min-width: 0; overflow-x: auto; }
.idx-etapas { display: flex; flex-direction: column; gap: 2px; position: sticky; top: 8px;
  max-height: calc(100vh - 120px); overflow-y: auto;
  background: var(--card-bg); border: 1px solid var(--linha); border-radius: var(--raio); padding: 6px; }
/* ⚠ O NOME GANHA A LINHA INTEIRA. Com numero, nome e valor lado a lado em
   232px, "3 - TERRAPLANAGEM" virava "3 - TERRAPL..." — e etapa truncada num
   indice cujo trabalho e justamente dizer o que ha no orcamento nao serve
   para nada. O valor desce para a segunda linha, ao lado da barra. */
.idx-item { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 3px 8px; align-items: baseline;
  width: 100%; text-align: left; background: none; border: 0; border-radius: var(--raio-sm);
  padding: 7px 8px; cursor: pointer; color: var(--texto); font: inherit;
  transition: background .12s var(--ease); }
.idx-item:hover { background: var(--surface-2); }
.idx-item.on { background: var(--surface-2); box-shadow: inset 2px 0 0 var(--aco); }
.idx-num { font-size: var(--t-micro); font-weight: var(--p-forte); color: var(--texto-fraco); min-width: 14px; }
/* ⚠ QUEBRA EM ATE DUAS LINHAS EM VEZ DE CORTAR. Com `nowrap`, 22 dos 23
   nomes saiam com reticencias em 232px — e um indice que existe para dizer
   o que ha no orcamento nao pode esconder o nome das etapas. Duas linhas
   ainda deixam ~14 etapas visiveis sem rolar; a terceira linha e que
   comecaria a custar caro. */
.idx-nome { font-size: var(--t-peq); line-height: 1.25; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.idx-item.on .idx-nome { font-weight: var(--p-forte); }
.idx-val { grid-column: 2; font-size: var(--t-micro); color: var(--texto-fraco); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* a barrinha diz qual etapa leva o dinheiro — a mesma leitura da curva ABC,
   por etapa em vez de por insumo */
.idx-barra { grid-column: 2; height: 3px; margin-top: 1px; border-radius: 2px; background: var(--surface-3); overflow: hidden; }
.idx-barra i { display: block; height: 100%; background: var(--aco); }
.pl-foco { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  background: var(--surface-2); border: 1px solid var(--linha); border-radius: var(--raio-sm);
  padding: 7px 10px; margin-bottom: 10px; font-size: var(--t-peq); }

@media (max-width: 1100px) {
  .pl-com-indice { grid-template-columns: minmax(0, 1fr); }
  .idx-etapas { position: static; max-height: none; flex-direction: row; overflow-x: auto; padding: 6px; }
  .idx-item { width: auto; flex: none; grid-template-columns: auto auto; }
  .idx-barra, .idx-val { display: none; }
}

/* selo da curva ABC: A = os poucos que levam 80% do dinheiro.
   ⚠ a LETRA carrega o significado, a cor so reforca — quem nao separa as
   tintas continua lendo "A", "B", "C". */
.ins-abc { display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: var(--raio-sm);
  font-size: var(--t-micro); font-weight: var(--p-forte); color: #fff; }
.ins-A { background: var(--graf-a); }
.ins-B { background: var(--graf-prev); }
.ins-C { background: var(--surface-3); color: var(--texto-fraco); }

.g-nota { font-size: var(--t-micro); color: var(--texto-fraco); margin: 6px 0 0; line-height: 1.4; }

.g-legenda { display: flex; gap: 16px; margin-top: 8px; flex-wrap: wrap; font-size: var(--t-peq); color: var(--texto-fraco); }
.g-leg { display: inline-flex; align-items: center; gap: 6px; }
.g-leg b { color: var(--texto); font-variant-numeric: tabular-nums; font-weight: var(--p-forte); }
.g-leg-cor { width: 14px; height: 3px; border-radius: 2px; flex: none; }
/* a legenda repete o tracejado da linha: a amostra tem de parecer com o que
   esta desenhado, senao ela nomeia outra coisa */
.g-leg-cor.tracejada { background-image: linear-gradient(90deg, currentColor 0 5px, transparent 5px 8px); }

@media (prefers-reduced-motion: reduce) {
  .g-col .g-guia, .g-col .g-pt, .g-col .g-ler, .g-bar .g-ler { transition: none; }
}

/* --- 1b) o indicador: UM componente, duas densidades ---
   Havia QUATRO jeitos de desenhar um indicador nesta base:
     .kpi (css), `_lpKpi` (tudo inline, e o que o Painel usa de verdade),
     a .fin-faixa, e um helper proprio dentro de js/ui.js que punha o numero
     em cima e centralizado.
   Quatro leituras diferentes da mesma coisa, e a pessoa reaprendendo a ler
   a cada tela. Agora todos usam `.kpi` com rotulo / numero / explicacao; o
   que muda e so a DENSIDADE, e ela e escolhida: `kpi-compacto` onde o
   indicador encima uma tabela, o normal na tela de analise. */
.kpi .kpi-sub { font-size: var(--t-micro); color: var(--texto-fraco); margin-top: 3px; line-height: 1.35; }
.kpi.kpi-compacto { padding: 12px 14px; }
/* a faixa colorida do topo e o destaque da tela de analise; na versao
   compacta ela vira listra decorativa em cima de uma tabela */
.kpi.kpi-compacto::before { display: none; }
/* ⚠ era `26px` cru no `_lpKpi` inline — um tamanho que nao existe na
   regua da casa (12 / 13,5 / 15 / 17 / 20 / 32). O gate reprova valor solto
   no css justamente para a escala nao virar sugestao, e reprovou este. */
.kpi.kpi-compacto .num { font-size: var(--t-tit); margin-top: 2px; }
.kpi.kpi-compacto:hover { transform: none; }

/* --- 2) a faixa de indicadores falando a lingua do cartao --- */
.fin-faixa {
  background: var(--card-bg);
  box-shadow: var(--sombra-sm);
  padding: 12px 14px;
}
.fin-faixa .fin-lbl { letter-spacing: .8px; font-weight: var(--p-forte); }
/* o numero da faixa e menor que o do cartao DE PROPOSITO: ali ele encima
   uma tabela e nao pode roubar a leitura dela. Mesma familia, densidade
   diferente. */
.fin-faixa b { letter-spacing: -.3px; }

/* --- 3) acao dentro de tabela: o dado primeiro --- */
table.tbl .btn:not(.primary):not(.success):not(.danger) {
  background: transparent;
  border-color: var(--linha);
  color: var(--texto-fraco);
  box-shadow: none;
}
table.tbl .btn:not(.primary):not(.success):not(.danger):hover,
table.tbl .btn:not(.primary):not(.success):not(.danger):focus-visible {
  background: var(--surface);
  border-color: var(--linha-forte);
  color: var(--texto);
  box-shadow: var(--sombra-sm);
}
/* ⚠ a linha inteira acende junto: sem isto, o alvo so aparece quando o
   ponteiro encosta exatamente no botao, e em tabela longa isso e cacada */
table.tbl tbody tr:hover .btn:not(.primary):not(.success):not(.danger) {
  border-color: var(--linha-forte);
  color: var(--texto);
}


/* ⚠ Base declarada do orçamento (⚙ Dados) — era campo de texto livre e virou
   leitura quando há item lançado: o documento tem de declarar a base dos
   preços que ele imprime. Ver App._edBaseCampos. */
.ed-base-fixa{padding:10px 12px;border-radius:9px;background:rgba(46,111,158,.08);box-shadow:inset 0 0 0 1px var(--linha,#c9d6e4)}
.ed-base-fixa b{font-size:var(--t-base);display:block}
.ed-base-fixa small{display:block;font-size:var(--t-micro);opacity:.72;line-height:1.45;margin-top:4px}
.ed-base-fixa .ed-base-alerta{color:var(--amarelo);opacity:1;font-weight:var(--p-medio)}

/* =====================================================================
 * ÁREA SEGURA DO IPHONE — POR ÚLTIMO, E É POR ISSO QUE FUNCIONA.
 *
 * `index.html` liga `viewport-fit=cover`. Quem liga o `cover` assume a
 * obrigação de reservar as margens: sem `env(safe-area-inset-*)`, o app
 * desenha POR BAIXO da ilha dinâmica e da barra de gestos. Dá para ver, não
 * dá para tocar.
 *
 * ⚠ ESTE BLOCO EXISTIA DESDE SEMPRE, LÁ EM CIMA, E ESTAVA INERTE.
 * Ele vinha ANTES das regras-base de `.topbar` e `.modal-bg`, com a MESMA
 * especificidade (0,1,0 contra 0,1,0). Empate de especificidade decide pela
 * ORDEM, e a ordem era contra ele. Depois disso o atalho `padding: 8px 12px`
 * do @media de celular ainda reescrevia os quatro lados de novo. Medido: no
 * iPhone deitado, `padding-left` da barra dava 22px onde o recorte pede 59px.
 *
 * ⚠ E POR QUE ESTAR NO FIM RESOLVE, EM VEZ DE EDITAR CADA REGRA NO LUGAR:
 * o `@supports` continua sendo a rede de segurança. Navegador que não conhece
 * `max()` (Safari 11.0, Chrome antigo) descarta a declaração inteira — se as
 * regras-base carregassem `max()` direto, esses navegadores ficariam com
 * padding ZERO na barra. Aqui a base segue com valor simples e este bloco só
 * a substitui em quem sabe calcular. O @media interno repete os valores
 * menores do celular pelo mesmo motivo: o de fora reserva, o de dentro não
 * pode desfazer.
 *
 * Cinco lugares, não dois — foi o levantamento que corrigiu o diagnóstico:
 *   · a LINHA da grade cresce com o recorte de topo (senão a barra de 58px
 *     não tem para onde crescer e o conteúdo continua sob a ilha);
 *   · a barra de cima: topo, esquerda e direita;
 *   · o menu lateral de módulos, que é quem ocupa o x=0 no iPhone DEITADO —
 *     e deitado o aparelho mede 852-956px, ou seja NEM ENTRA no @media de
 *     celular. Consertar só o media query de 820px não tocaria nele;
 *   · o modal, nos quatro lados;
 *   · e o topo, que nunca existiu em lugar nenhum deste arquivo.
 *
 * Sem recorte (`env()` = 0) tudo isto vira o valor de sempre: `max(22px, 0)`
 * é 22px. Desktop não muda um pixel — a suíte tools/test-area-segura.js
 * trava isso com a mesma régua com que mede o iPhone.
 * ===================================================================== */
@supports (padding: max(0px)) {
  .app { grid-template-rows: calc(58px + env(safe-area-inset-top, 0px)) 1fr; }
  .topbar {
    padding-top: env(safe-area-inset-top, 0px);
    padding-left: max(22px, env(safe-area-inset-left));
    padding-right: max(22px, env(safe-area-inset-right));
  }
  /* deitado, é a coluna do menu que encosta no recorte da esquerda */
  .app.com-sidebar > .sidebar { padding-left: env(safe-area-inset-left, 0px); }
  .modal-bg {
    padding-bottom: max(20px, env(safe-area-inset-bottom));
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
  }
  @media screen and (max-width: 820px) {
    /* no celular a barra quebra em duas linhas: a linha da grade volta a ser
       `auto` (senão a altura fixa corta a segunda linha de botões) e quem
       reserva o topo é o padding da própria barra. */
    .app { grid-template-rows: auto 1fr; }
    .topbar {
      padding-top: calc(8px + env(safe-area-inset-top, 0px));
      padding-left: max(12px, env(safe-area-inset-left));
      padding-right: max(12px, env(safe-area-inset-right));
    }
    .modal-bg {
      padding-bottom: max(10px, env(safe-area-inset-bottom));
      padding-left: max(10px, env(safe-area-inset-left));
      padding-right: max(10px, env(safe-area-inset-right));
    }
  }
}

/* ---- Janela destacada (js/janelas.js): só o orçamento, sem menu e sem topo ---- */
/* o ⧉ "Abrir em outra janela" mora no menu "Mais" do cabeçalho do editor
   (padrão de tela, 08/10/2026); o nome do botão não quebra */
.jan-abrir { white-space: nowrap; }
body.modo-janela #sidebar, body.modo-janela #topbar { display: none !important; }
body.modo-janela .app, body.modo-janela .app.com-sidebar { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); grid-template-areas: "main"; height: calc(100vh - 34px); height: calc(100dvh - 34px); }
body.modo-janela .main { grid-area: main; padding: 14px 18px; }
/* ⚠ tamanhos e pesos pela régua (--t-*, --p-*) e cores pelos tokens: o
   13px/12px/600 crus deste bloco deixaram o test-contraste vermelho desde a
   1.2.79 — e o gate padrão (sem --e2e) junto */
#jan-cab { display: flex; align-items: center; gap: 12px; height: 34px; padding: 0 14px; background: var(--navy); color: var(--sobre-navy); font-size: var(--t-peq); }
#jan-cab .jan-t { font-weight: var(--p-forte); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
#jan-cab .jan-vivo { color: var(--sobre-navy-ok); font-size: var(--t-micro); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#jan-cab .jan-atu { color: var(--sobre-navy); font-size: var(--t-micro); font-weight: var(--p-normal); font-variant-numeric: tabular-nums; white-space: nowrap; }
#jan-cab.jan-orfa .jan-vivo { color: var(--sobre-navy-aviso); }
#jan-cab .btn { margin-left: auto; }
#jan-recado { margin: 24px; max-width: 640px; }

/* ---- Foco no cronograma: a aba Cronograma sem as ações e os KPIs do orçamento ---- */
/* ⚠ SÓ O QUE É DO EDITOR (`.orc-cab`, ui.js renderEditor). A regra era
   `#main > .kpis`, e com a classe do body vazando para fora do editor (1.2.80)
   ela apagava os cartões da lista e o bloco OPERAÇÃO do Painel. Duas travas:
   o App.render tira a classe no topo, e esta regra não alcança KPI de outra tela. */
body.foco-crono #main > .orc-cab { display: none !important; }
/* o cabeçalho do editor (Modulo.cab) FICA no foco: é nele que moram a
   primária [Gerar Proposta] e o "Mais" (Apresentar, Excel…) — sem botão em
   dobro. Só encosta mais nas abas para o Gantt ganhar a altura. */
body.foco-crono #main > .mod-cab { margin-bottom: 12px; }
/* ---- Janela destacada: só o painel (sem título, ações, KPIs nem abas) ---- */
/* ⚠ o recado (#jan-recado) é a exceção: escondido por esta regra, orçamento
   excluído e endereço inválido viravam janela EM BRANCO (ver App._janelaRecado) */
body.modo-janela #main > :not(#aba-conteudo):not(#jan-recado) { display: none !important; }

/* =====================================================================
   PLANEJADOR — BLOCOS DAS FATIAS (Onda 0, T13). Um bloco por fatia, no FIM
   do arquivo: cada fatia escreve só no seu, e as três linhas de comentário
   entre eles mantêm as mudanças de fatias diferentes longe uma da outra (o
   merge não se atropela). ⚠ Tamanho, peso e cor pelos tokens (--t-*, --p-*,
   cores do tema): o test-contraste reprova valor cru, e o bloco que padroniza
   perde para regra escrita depois dele (memória "regra de unificação nasce
   perdendo").
   ===================================================================== */
/* ===== PLANEJADOR: rede (2A) ===== */
/* ⚠ O DESENHO É PAPEL BRANCO NOS DOIS TEMAS (regra 4 do cabeçalho do
   js/cronoexecui.js): o que é pintado DENTRO do SVG do Gantt usa tinta
   cravada, como o resto dele. O que é HTML em volta (chip, menu, faixa) usa
   os tokens do tema. Tamanho e peso sempre por token — o test-contraste
   reprova valor cru, e o bloco que padroniza perde para a regra escrita
   depois dele. */
/* o marcador da restrição que o APP escreveu (⧗) e o da que não é cumprida
   (⚠). #6d28d9 sobre o papel branco = 7,4:1; #b91c1c = 6,9:1. */
.cx-td-restr .cx-restr-mat-tx { color: #6d28d9; white-space: nowrap; }
.cx-td-restr .cx-restr-nok-tx { color: var(--graf-alerta, #b91c1c); font-weight: var(--p-forte); white-space: nowrap; }
.cx-folga-neg-tx { color: var(--graf-alerta, #b91c1c); font-weight: var(--p-forte); white-space: nowrap; }
/* o ⋯ da linha (tabela). Alvo de 28 px: menor que isso não se acerta no
   toque, e a coluna do nome é justamente onde o dedo já está. */
.cx-menu-bt { border: 0; background: none; color: var(--muted, #64748b); font: inherit; font-size: var(--t-peq); line-height: 1; padding: 2px 7px; min-width: 28px; min-height: 24px; border-radius: var(--raio-ctl, 8px); cursor: pointer; }
.cx-menu-bt:hover { background: var(--linha, #e2e8f0); color: var(--texto, #0f172a); }
.cx-menu-bt:focus-visible { outline: 2px solid var(--aco, #0d6ebd); outline-offset: 1px; }
.cx-menu-lista { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
/* ⚠ o item que NÃO se aplica continua na lista, com o motivo — item que some
   não ensina nada, e a pessoa vai procurar a função em outro lugar */
.cx-menu-off { color: var(--muted, #64748b); font-size: var(--t-peq); padding: 4px 0; }
/* o chip "Compatibilidade (N)" da linha do prazo e a faixa que ele abre */
/* ⚠ o registro [Calendários] da linha do prazo é PILL clicável: a régua do
   cronograma (e2e-padrao-cronograma) mede todo clicável acima do Gantt, e o
   gx-uso-link que ele usava saía com 18,6 px e raio 0 contra 24/999 da pill.
   Herda o tamanho da classe .pill; aqui vem só o que faz dela um botão. */
.cx-pill-cal-bt { border: 1px dashed var(--linha-forte, #94a3b8); background: none; color: var(--aco, #0d6ebd); cursor: pointer; padding: 2px 9px; }
.cx-pill-cal-bt:hover { border-style: solid; border-color: var(--aco, #0d6ebd); }
.cx-pill-cal-bt:focus-visible { outline: 2px solid var(--aco, #0d6ebd); outline-offset: 1px; }
.cx-chip-compat { border: 1px dashed var(--linha-forte, #94a3b8); background: none; color: var(--muted, #64748b); font: inherit; font-size: var(--t-micro); font-weight: var(--p-medio); padding: 2px 9px; border-radius: 999px; cursor: pointer; }
.cx-chip-compat:hover { border-color: var(--aco, #0d6ebd); color: var(--aco, #0d6ebd); }
.cx-chip-compat:focus-visible { outline: 2px solid var(--aco, #0d6ebd); outline-offset: 1px; }
.cx-chip-compat.cx-chip-on { border-style: solid; border-color: var(--aco, #0d6ebd); color: var(--aco, #0d6ebd); }
.cx-compat-faixa { margin: 4px 0 8px; padding: 8px 10px; border: 1px solid var(--linha, #e2e8f0); border-radius: var(--raio-ctl, 8px); background: var(--card, transparent); font-size: var(--t-peq); }
.cx-compat-faixa b { font-weight: var(--p-forte); }
/* a faixa D-PENDENTE fica sempre à vista: ela muda o que o OUTRO aparelho
   desenha, e a porta ([Fixar início]) não pode ficar escondida atrás de um
   chip */
.cx-aviso.cx-pendente { background: rgba(245, 158, 11, .14); border-color: rgba(245, 158, 11, .55); }
/*
 * ↑ setas TT/IT/cruzado, rótulos das ligações, restrições.
 */
/* ===== PLANEJADOR: extras (2A) ===== */
/* a linha T: o número em roxo (a mesma tinta da barra tracejada) é o que
   diz, sem ler, que aquela linha não é serviço do orçamento */
.cx-eap tr.cx-t > td { background: rgba(109, 40, 217, .045); }
.cx-eap .cx-n-t { color: #6d28d9; font-weight: var(--p-forte); }
.cx-eap .cx-in-nome { width: min(320px, 46vw); text-align: left; }
.cx-eap .pill.cx-pill-t { background: rgba(109, 40, 217, .12); color: #5b21b6; }
/* as camadas: o botão e a caixa */
.cx-cam { position: relative; display: inline-block; }
.cx-cam > summary { list-style: none; cursor: pointer; }
.cx-cam > summary::-webkit-details-marker { display: none; }
.cx-cam > summary.cx-cam-ap { border-color: #b45309; color: #78350f; background: #fef3c7; }
.cx-cam-caixa { position: absolute; z-index: 20; top: 100%; left: 0; margin-top: 4px; width: 300px; max-width: calc(100vw - 32px); box-sizing: border-box; padding: 8px 10px; background: var(--card, #fff); color: var(--texto, #0f172a); border: 1px solid var(--linha, #cbd5e1); border-radius: var(--raio-ctl, 8px); box-shadow: 0 6px 22px rgba(15, 23, 42, .22); }
.cx-cam-lin { display: flex; align-items: center; gap: 6px; padding: 3px 0; font-size: var(--t-peq); cursor: pointer; }
.cx-cam-ap-lin { margin-top: 6px; padding-top: 7px; border-top: 1px solid var(--linha, #e2e8f0); font-weight: var(--p-forte); }
.cx-cam-nota { margin: 6px 0 0; font-size: var(--t-micro); color: var(--muted, #64748b); }
/*
 * ↑ linhas e barras das tarefas sem preço.
 */
/* ===== PLANEJADOR: cal-gantt (2A) ===== */
/* o sombreado dos dias parados é desenhado NO SVG (fill-opacity .10 sobre o
   papel branco): aqui só a pílula das frentes, que é HTML */
.cx-pill-cal { background: rgba(13, 110, 189, .12); color: #0b5384; }
/*
 * ↑ sombreamento dos dias parados de cada frente no Gantt.
 */
/* ===== PLANEJADOR: avanco-gantt (2A) ===== */
.cx-pill-av { background: rgba(180, 83, 9, .14); color: #78350f; }
/* ⚠ o par escuro faltava: medido em 1,81:1 sobre o fundo composto da linha
   do prazo (o pior número do conjunto), e é a pílula que a 6B copiou. Ver o
   bloco MEDCC: avanco-med mais abaixo. */
[data-tema="dark"] .cx-pill-av { color: #fdba74; }
/* o seletor Planejar | Avançar e a faixa do modo */
.cx-modo-bt { display: inline-flex; gap: 4px; }
.cx-modo-av { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 6px; padding: 5px 10px; font-size: var(--t-peq); color: #78350f; background: #fef3c7; border: 1px solid #f59e0b; border-radius: var(--raio-ctl, 8px); }
.cx-modo-av .muted { color: #78350f; }
/*
 * ↑ os três trechos da barra, a linha do corte, o modo Avançar.
 */
/* ===== PLANEJADOR: cal-painel (2B) ===== */
/* Cartão e modal dos calendários das frentes. A primeira linha da tabela é a
   régua da OBRA e é só leitura: ela fica em cinza para não parecer editável —
   clicar nela e nada acontecer é o tipo de porta que não abre. */
.cx-cal-painel .cx-cal-tab { width: 100%; }
/* a coluna FRENTES nao quebra: "as demais" em duas linhas fazia a linha
   da obra parecer dois registros (medido a 1366) */
.cx-cal-painel .cx-cal-tab th:nth-child(3), .cx-cal-painel .cx-cal-tab td:nth-child(3) { white-space: nowrap; }
.cx-cal-painel .cx-cal-tab td:last-child { width: 46%; }
.cx-cal-painel .cx-cal-lead, .cx-cal-modal .cx-cal-lead { font-size: var(--t-peq); color: var(--texto-fraco); }
.cx-cal-tab .cx-cal-obra > td { color: var(--texto-fraco); background: var(--surface-2, var(--surface)); }
.cx-cal-modal .cx-cal-tit { font-size: var(--t-med); font-weight: var(--p-forte); color: var(--texto); margin: 0 0 8px; }
.cx-cal-modal .cx-cal-dia { display: flex; flex-direction: column; font-weight: var(--p-normal); font-size: var(--t-micro); color: var(--texto-fraco); }
.cx-cal-modal .cx-cal-dia input { width: 56px; }
.cx-cal-modal .cx-cal-nota, .cx-cal-modal .cx-cal-vazio { font-size: var(--t-micro); color: var(--texto-fraco); }
/* o seletor de lote nunca encolhe a ponto de esconder o número da frente: a
   pessoa escolhe pelo número, e "7.3" cortado vira escolha errada */
.cx-cal-modal .cx-cal-lote { min-width: 220px; }
/*
 * ↑ cartão e modal dos calendários das frentes.
 */
/* ===== PLANEJADOR: avanco-painel (2B) ===== */
/* Modal do avanço, sugestões por fonte, card "Término previsto" e o cartão
   "Compatibilidade". */
.cx-avanco-painel .cx-av-nota, .cx-avanco-painel .cx-av-ctx, .cx-avanco-painel .cx-av-semsug { font-size: var(--t-peq); color: var(--texto-fraco); }
/* uma tabela por FONTE (E-MC5): o título de cada uma precisa ficar colado na
   tabela dela, senão duas fontes viram uma lista só na leitura */
.cx-avanco-painel .cx-av-fonte { margin-top: 10px; }
.cx-avanco-painel .cx-av-sug { width: 100%; }
.cx-avanco-painel .cx-av-sug th:last-child, .cx-avanco-painel .cx-av-sug td:last-child { text-align: center; width: 56px; }
.cx-avanco-painel .cx-av-diff { margin-top: 10px; }
/* ⚠ o card do término leva a AÇÃO dentro (memória "ação mora no card do
   número"): o botão fica no rodapé do card, não numa barra longe dele */
.cx-kpi-termino .cx-kpi-acao { margin-top: 6px; }
.cx-pr-org { font-size: var(--t-micro); }
/* o cartão "Compatibilidade": o que um aparelho antigo vê de diferente.
   ⚠ O vermelho é só para o que NÃO foi possível garantir (código fora do
   catálogo, função desligada) — divergência declarada é informativa, e
   pintar as duas de vermelho ensina a ignorar as duas. */
.cx-compat .cx-compat-lead, .cx-compat .cx-compat-nada, .cx-compat .cx-compat-em { font-size: var(--t-peq); color: var(--texto-fraco); margin: 0 0 6px; }
.cx-compat .cx-compat-em { font-size: var(--t-micro); margin: 6px 0 0; }
/* ⚠ --graf-alerta, e NÃO --vermelho: este é TEXTO pequeno sobre o cartão, e
   o vermelho puro reprova AA nos dois temas (medido em css/app.css:122). */
.cx-compat .cx-compat-ruim { color: var(--graf-alerta); font-weight: var(--p-medio); }
.cx-compat .cx-compat-pend { font-size: var(--t-peq); color: var(--texto); margin: 0 0 8px; }
/*
 * ↑ modal do avanço, sugestões dos diários, cartão "Compatibilidade".
 */
/* ===== PLANEJADOR: bases (1B) ===== */
/* A sub-aba "Linhas de base" (CronoExecUI.basesPainel). Usa a largura toda
   da janela (memória "tela usa o máximo da janela"): cartões em grade que
   quebra, barra que quebra, tabela que rola na horizontal dentro do próprio
   contêiner — a página nunca rola de lado. */
.cxb { display: flex; flex-direction: column; gap: 10px; padding: 8px 0 16px; }
.cxb-topo { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; }
.cxb-tit { font-size: var(--t-med); color: var(--texto); }
.cxb-acoes { display: flex; flex-wrap: wrap; gap: 6px; }
.cxb-vazio { font-size: var(--t-peq); color: var(--texto-fraco); margin: 4px 0; }
.cxb-versoes { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }
.cxb-card { border: 1px solid var(--linha); border-left: 4px solid var(--linha-forte); border-radius: var(--raio); background: var(--surface); padding: 8px 10px; display: flex; flex-direction: column; gap: 3px; font-size: var(--t-peq); color: var(--texto); }
.cxb-card.cxb-contratual { border-left-color: var(--navy); }
.cxb-card.cxb-aprovada { border-left-color: var(--verde); }
.cxb-card.cxb-interna { border-left-color: var(--amarelo); }
.cxb-card.cxb-anulada { border-left-color: var(--texto-fraco); }
.cxb-card.cxb-ativa { box-shadow: var(--anel); }
.cxb-card.cxb-gemea { opacity: .82; }
.cxb-card-cab { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: var(--t-base); }
.cxb-est { font-size: var(--t-micro); font-weight: var(--p-medio); letter-spacing: .02em; color: var(--texto-fraco); }
.cxb-selo-ativa { font-size: var(--t-micro); font-weight: var(--p-medio); border-radius: 999px; padding: 0 8px; background: var(--aco); color: #fff; }
.cxb-card-l { line-height: 1.35; }
.cxb-selo-txt { color: var(--texto-fraco); }
.cxb-aviso-linha { color: var(--graf-aviso); }
.cxb-card-bt { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.cxb-card-bt .btn.on { background: var(--surface-3); border-color: var(--aco); }
.cxb-barra { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding: 8px 10px; border: 1px solid var(--linha); border-radius: var(--raio); background: var(--surface-2); font-size: var(--t-peq); }
.cxb-barra label { display: inline-flex; align-items: center; gap: 6px; }
.cxb-barra select { max-width: 280px; }
.cxb-grupo { display: inline-flex; align-items: center; gap: 6px; }
.cxb-busca input { width: 180px; }
.cxb-resumo { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 8px; }
.cxb-kpi { border: 1px solid var(--linha); border-radius: var(--raio); background: var(--surface); padding: 8px 10px; }
.cxb-kpi-rot { font-size: var(--t-micro); font-weight: var(--p-medio); color: var(--texto-fraco); text-transform: uppercase; letter-spacing: .03em; }
.cxb-kpi-v { font-size: var(--t-peq); color: var(--texto); line-height: 1.45; margin-top: 2px; }
.cxb-sec { font-size: var(--t-peq); color: var(--texto); margin-top: 4px; }
.cxb-gantt { overflow-x: auto; }
.cxb-leg { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: var(--t-micro); color: var(--texto-fraco); margin-top: 4px; }
.cxb-leg i { display: inline-block; width: 18px; height: 3px; vertical-align: middle; margin-right: 5px; }
.cxb-leg .cxb-leg-a { background: #334155; }
.cxb-leg .cxb-leg-b { background: #0d6ebd; }
.cxb-tabela { overflow-x: auto; }
table.tbl.cxb-tab { width: 100%; font-size: var(--t-peq); }
table.tbl.cxb-tab th, table.tbl.cxb-tab td { padding: 4px 8px; white-space: nowrap; vertical-align: top; }
table.tbl.cxb-tab td.cx-nome { white-space: normal; min-width: 220px; width: 100%; }
table.tbl.cxb-tab tr.cxb-l-etapa td { font-weight: var(--p-medio); }
table.tbl.cxb-tab tr.cxb-mudou td.num { color: var(--graf-aviso); }
.cxb-rec { display: inline-block; width: 14px; }
.cxb-rec2 { display: inline-block; width: 28px; }
.cxb-fora { font-size: var(--t-peq); margin: 0; }
.cxb-rodape { font-size: var(--t-micro); margin: 2px 0 0; }
.cxb-f-linha { display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 6px; }
.cxb-f-linha label { display: inline-flex; flex-direction: column; gap: 3px; font-weight: var(--p-normal); }
/*
 * ↑ sub-aba "Linhas de base", comparação e selo.
 */
/* ===== PLANEJADOR: uso (1C) ===== */
/* A BARRA DE USO mora DENTRO do papel do Gantt (.gx), que é branco nos DOIS
   temas (regra 4 do cabeçalho do js/cronoexecui.js): as tintas aqui são
   cravadas pelo mesmo motivo — um token de tema escuro sumiria no papel
   branco. Tamanho e peso pelos tokens (test-contraste). Altura: 40 px
   (CronoExecUI.GX_USO), controles de 28 px como os do canto. */
.gx-uso { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 40px; box-sizing: border-box; padding: 6px 8px; border-bottom: 1px solid #e2e8f0; background: #fff; color: #0f172a; border-radius: 7px 7px 0 0; position: relative; }
/* com a barra em cima, o cabeçalho de datas deixa de ser a borda arredondada da moldura */
.gx > .gx-uso ~ .gx-cab { border-radius: 0; }
.gx-uso-busca { display: inline-flex; align-items: center; gap: 4px; flex: 1 1 320px; min-width: 0; }
.gx .gx-uso-in { flex: 1 1 auto; min-width: 120px; max-width: 360px; height: 28px; min-height: 0; box-sizing: border-box; border: 1px solid #94a3b8; border-radius: var(--raio-ctl, 8px); padding: 0 8px; background-color: #fff; color: #0f172a; font: inherit; font-size: var(--t-micro); }
.gx .gx-uso-in::placeholder { color: #64748b; }
.gx .gx-uso-in:focus-visible { outline: 2px solid #0d6ebd; outline-offset: 1px; }
.gx-uso-cont { font-size: var(--t-micro); color: #334155; min-width: 44px; white-space: nowrap; }
.gx-uso-so { display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-micro); color: #0f172a; white-space: nowrap; cursor: pointer; }
.gx-uso-so input { color: #0f172a; background-color: #fff; }
/* ⚠ SEM position aqui: o painel do filtro se ancora na BARRA (.gx-uso), à
   direita. Ancorado neste botão, que fica no meio-direita da barra, ele
   passava da borda da janela a 1366 e as contagens saíam cortadas (foto da
   e2e-crono-busca, 17/09/2026). */
.gx-uso-filtro { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.gx-uso-dir { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }
.gx-uso-bt { height: 28px; box-sizing: border-box; border: 1px solid #cbd5e1; border-radius: var(--raio-ctl, 8px); background: #fff; color: #0f172a; padding: 0 10px; font: inherit; font-size: var(--t-micro); font-weight: var(--p-medio); cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; }
.gx-uso-bt:hover { background: #f1f5f9; border-color: #7e95aa; }
.gx-uso-bt:focus-visible, .gx-uso-chip:focus-visible, .gx-uso-link:focus-visible, .gx-uso-pilha:focus-visible { outline: 2px solid #0d6ebd; outline-offset: 1px; }
.gx-uso-pilha[aria-disabled="true"] { color: #94a3b8; cursor: not-allowed; }
.gx-uso-chip { height: 24px; box-sizing: border-box; border: 1px solid #b45309; border-radius: 999px; background: #fef3c7; color: #78350f; padding: 0 10px; font: inherit; font-size: var(--t-micro); cursor: pointer; white-space: nowrap; }
.gx-uso-chip-ind { border-style: dashed; background: #fff; color: #475569; border-color: #94a3b8; }
.gx-uso-link { border: 0; background: none; color: #0d6ebd; padding: 0; font: inherit; font-size: var(--t-micro); text-decoration: underline; cursor: pointer; }
.gx-uso-recado { padding: 4px 10px; font-size: var(--t-micro); color: #334155; background: #f8fafc; border-bottom: 1px solid #e2e8f0; }
/* a faixa âmbar do filtro (acima do Gantt e da tabela): #78350f sobre #fef3c7 = 8,6:1 */
.gx-faixa-filtro { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 5px 10px; font-size: var(--t-micro); color: #78350f; background: #fef3c7; border-bottom: 1px solid #f59e0b; }
.cx-tabela + .gx-faixa-filtro, .gx-faixa-filtro[data-gx-faixa="tabela"] { border: 1px solid #f59e0b; border-radius: var(--raio-ctl, 8px); margin: 10px 0 0; }
.gx-faixa-filtro span { flex: 1 1 280px; }
/* o painel do filtro: ancorado no botão, NÃO é modal */
.gx-fp { position: absolute; top: 100%; right: 8px; left: auto; margin-top: 2px; z-index: 20; width: 380px; max-width: calc(100% - 16px); max-height: min(70vh, 560px); overflow: auto; box-sizing: border-box; padding: 10px 12px 0; background: #fff; color: #0f172a; border: 1px solid #cbd5e1; border-radius: var(--raio-ctl, 8px); box-shadow: 0 6px 22px rgba(15, 23, 42, .22); }
.gx-fp-tit { font-size: var(--t-micro); font-weight: var(--p-forte); color: #334155; text-transform: uppercase; letter-spacing: .3px; margin: 8px 0 4px; }
.gx-fp-tit:first-child { margin-top: 0; }
.gx-fp-lin { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; padding: 3px 0; font-size: var(--t-peq); color: #0f172a; cursor: pointer; }
.gx-fp-lin input { color: #0f172a; background-color: #fff; }
.gx-fp-lin span:nth-child(2) { flex: 1 1 150px; }
/* o motivo de uma opção desligada é frase ("nenhum neste cronograma"): quebra
   dentro do painel em vez de sair por ele */
.gx-fp-n, .gx-fp-dica { font-size: var(--t-micro); color: #475569; }
.gx-fp-n { margin-left: auto; text-align: right; }
.gx-fp-dica { flex-basis: 100%; padding-left: 22px; }
.gx-fp-off { color: #64748b; cursor: not-allowed; }
.gx-fp-cats { max-height: 160px; overflow: auto; }
/* ⚠ [Limpar filtro] e [Fechar] SEMPRE à vista: com muitas categorias o painel
   rola, e as ações no fim da rolagem ficavam fora do alcance */
.gx-fp-acoes { position: sticky; bottom: 0; display: flex; justify-content: flex-end; gap: 6px; margin-top: 8px; padding: 8px 0 10px; background: #fff; border-top: 1px solid #e2e8f0; }
.gx-vazio { padding: 0 0 12px; }
.gx-vazio-txt { padding: 16px 12px 4px; font-size: var(--t-peq); color: #0f172a; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* o HISTÓRICO (modal largo) */
.cx-alt td { vertical-align: top; }
.cx-alt-m { margin: 4px 0 0; }
.cx-alt-lac td { background: var(--surface-2, #eef2f7); }
.cx-alt-rodape, .cx-alt-vazio, .cx-alt-so { font-size: var(--t-micro); }
/* os ALERTAS DO CRONOGRAMA no sino (tema do app, não o papel do Gantt) */
.avisos-crono { position: relative; }
/* numa linha própria, embaixo do detalhe: inline, ele encostava no fim do
   texto ("corte 11/09[Dispensar…]", foto da e2e-sino-crono) */
.avisos-dispensar { display: table; margin-top: 6px; border: 1px solid var(--linha, #c9d6e4); border-radius: 999px; background: transparent; color: var(--texto); padding: 1px 10px; font: inherit; font-size: var(--t-micro); cursor: pointer; }
.avisos-dispensar:hover { background: var(--surface-2, #eef2f7); }
.avisos-rodape { padding: 8px 12px; font-size: var(--t-micro); color: var(--texto-fraco); border-top: 1px solid var(--linha, #e2e8f0); }
@media (max-width: 760px) {
  /* o campo na linha inteira e o contador, ‹ › e "Só os achados" embaixo: a
     400 px o "3 de 4 · 2 fora do filtro" passava por cima dos botões */
  .gx-uso-busca { flex-basis: 100%; flex-wrap: wrap; }
  .gx .gx-uso-in { max-width: none; flex-basis: 100%; }
}
/*
 * ↑ busca, filtro, desfazer/refazer, sino e histórico.
 */

/* ===== MEDCC: avanco-med (6B) ===== */
/* As faixas da medição na linha do prazo. ⚠ Elas convivem, na MESMA linha,
   com a pílula do avanço (.cx-pill-av) e a dos calendários: por isso são
   pílula, e não botão — a régua do cronograma (e2e-padrao-cronograma) mede
   todo clicável acima do Gantt e aceita 24 px/raio 999 para pílula.
   ⚠ Cor DECLARADA, não herdada do .pill genérico: as três faixas dizem
   coisas diferentes (há número novo · os números discordam · o boletim caiu)
   e uma cor só faria a pessoa ler "aviso" três vezes sem distinguir qual.
   O contraste é o de test-contraste (4.5:1 sobre o papel claro).
   ⚠ E O PAR ESCURO EXISTE — ele faltava (achado da revisão da Onda 6,
     22/09/2026). Medido nos PIXELS, na página real em `data-tema="dark"`,
     com o fundo COMPOSTO (as pílulas são rgba sobre superfície escura, então
     medir contra o token do fundo mente): sugere 2,02:1 · conflito 1,81:1 ·
     sem lastro 2,18:1 · diário 2,98:1 — e a `.cx-pill-av` da 2A, de onde
     este bloco copiou o padrão, já estava em 1,81:1. O mínimo é 4,5:1. Toda
     a família `.pill` deste arquivo tem par escuro; esta nasceu sem, e
     nenhuma suíte media pílula no escuro (o `test-contraste` mede no claro).
     Quem confere: `tools/e2e-crono-medicao-sugere.js`, bloco [13] — na
     página real, compondo o fundo por alfa. */
.cx-pill-med { background: rgba(13, 110, 189, .12); color: #0b5384; }
.cx-med-conflito { background: rgba(180, 83, 9, .14); color: #78350f; }
.cx-med-semlastro { background: rgba(190, 18, 60, .12); color: #9f1239; }
.cx-med-diario { background: rgba(15, 118, 110, .13); color: #0f766e; }
/* "não consegui perguntar aos diários": cinza de propósito — não é alarme
   nem novidade, é ausência de resposta */
.cx-med-ilegivel { background: rgba(71, 85, 105, .14); color: #334155; }
[data-tema="dark"] .cx-pill-med { color: #7dd3fc; }
[data-tema="dark"] .cx-med-conflito { color: #fdba74; }
[data-tema="dark"] .cx-med-semlastro { color: #fda4af; }
[data-tema="dark"] .cx-med-diario { color: #5eead4; }
[data-tema="dark"] .cx-med-ilegivel { color: #cbd5e1; }
/* a tabela do [Rever]: a coluna das três decisões não quebra linha, e a
   primeira coluna é a que encolhe (o nome da tarefa é o que dá para cortar) */
.cx-av-rever td:last-child { white-space: nowrap; text-align: right; }
.cx-av-rever td:first-child { word-break: break-word; }
@media (max-width: 760px) {
  /* a 400 px as três decisões empilham em vez de sair da tela: porta
     prometida precisa existir, inclusive no celular */
  .cx-av-rever td:last-child { white-space: normal; }
}
/*
 * ↑ faixas da medição na linha do prazo e a tabela do [Rever].
 */


/* =====================================================================
 * PAINEL DE GESTÃO NOVO (.pn-*) — 24/09/2026, atrás da chave
 * `orcapro:tela:painel:v1` (ver js/painel.js). Só tokens: tamanho e peso
 * saem da régua (tools/test-contraste.js reprova px cru), cor sai do :root
 * e do par escuro. Duas superfícies apenas — plano (sem cartão) e .pn-card —
 * porque o Painel antigo tinha um cartão igual para filtro, indicador,
 * gráfico, tabela e aviso, e nada dizia o que era primário.
 * ⚠ Prefixo .pn- é exclusivo desta tela; nada aqui toca regra existente.
 * ===================================================================== */
.pn { max-width: 1240px; }
.pn h1, .pn h2, .pn h3, .pn p, .pn ul, .pn ol, .pn dl, .pn dd { margin: 0; }
.pn ul, .pn ol { padding: 0; list-style: none; }
.pn small { font-size: var(--t-peq); font-weight: var(--p-normal); color: var(--texto-fraco); }
.pn-tn { font-variant-numeric: tabular-nums; }
.pn-vazio { color: var(--texto-fraco); font-size: var(--t-peq); padding: 8px 0; }
.pn-fraco { color: var(--texto-fraco) !important; font-weight: var(--p-normal) !important; }
.pn-ok { color: var(--verde); }
.pn-ruim { color: var(--graf-aviso); }
.pn-neg { color: var(--vermelho); }

/* cabeçalho + filtros */
.pn-cab { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 14px 24px; margin-bottom: 22px; }
.pn-cab h1 { font-size: var(--t-hero); font-weight: var(--p-forte); letter-spacing: -.5px; line-height: 1.1; }
.pn-cab-sub { color: var(--texto-fraco); font-size: var(--t-peq); margin-top: 6px; }
.pn-filtros { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pn-ctl { height: var(--h-ctl); border: 1px solid var(--linha); background: var(--surface); border-radius: var(--raio-ctl); padding: 0 12px; font-size: var(--t-peq); font-weight: var(--p-medio); color: var(--texto); display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-family: inherit; }
.pn-ctl select { border: 0; background: transparent; color: inherit; font: inherit; font-weight: var(--p-medio); max-width: 240px; }
.pn-ctl select[multiple] { height: auto; max-width: 260px; }
.pn-ctl.pn-ctl-ghost { background: transparent; }
/* os <select> ficam com o estilo nativo do app (seta, borda, tema): o rótulo é só texto */
.pn-filtro { display: inline-flex; align-items: center; gap: 8px; font-size: var(--t-peq); font-weight: var(--p-medio); color: var(--texto-fraco); }
.pn-filtro select { max-width: 240px; }
/* o recorte do Painel mora no slot de obra do cabeçalho do kit (08/10/2026):
   o período é curto e não herda a largura mínima do seletor de obra */
.mod-obra .pn-filtros { flex-wrap: wrap; }
.mod-obra .pn-filtro select[data-gacao="dash-periodo"] { min-width: 0; }
.pn-ctl:hover { border-color: var(--linha-forte); }

/* superfícies e títulos de seção */
.pn-card { background: var(--surface); border: 1px solid var(--linha); border-radius: var(--raio-lg); box-shadow: var(--sombra); }
.pn-sec { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.pn-sec h2 { font-size: var(--t-med); font-weight: var(--p-forte); letter-spacing: -.2px; text-transform: none; }
.pn-sec p { color: var(--texto-fraco); font-size: var(--t-peq); text-align: right; }
.pn-sec-solta { margin-top: 26px; }

/* primeira dobra */
.pn-dobra { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 28px; margin-bottom: 30px; }
/* uma coluna: o extrato (3 colunas, número grande à direita) não cabia ao lado
   dos dois quadros — os valores ficavam escondidos atrás deles (2ª foto) */
.pn-caixa { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.pn-extrato { display: grid; grid-template-columns: max-content minmax(0, 1fr) max-content; column-gap: 14px; align-items: baseline; min-width: 0; }
.pn-extrato > * { padding: 7px 0; border-bottom: 1px solid var(--linha); }
.pn-extrato .pn-rot { font-size: var(--t-peq); color: var(--texto-fraco); }
.pn-extrato .pn-reg { font-size: var(--t-micro); color: var(--texto-fraco); }
.pn-extrato .pn-val { font-size: var(--t-med); font-weight: var(--p-medio); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.pn-extrato .pn-soma { border-bottom: 0; border-top: 2px solid var(--texto); padding-top: 10px; }
.pn-extrato .pn-rot.pn-soma { font-size: var(--t-base); color: var(--texto); font-weight: var(--p-medio); }
.pn-extrato .pn-val.pn-soma { font-size: var(--t-hero); font-weight: var(--p-forte); letter-spacing: -.6px; line-height: 1; font-variant-numeric: normal; }
.pn-delta { display: inline-block; margin-left: 6px; color: var(--verde); font-weight: var(--p-medio); }
.pn-delta-neg { color: var(--graf-aviso); }
.pn-lado { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.pn-mini { display: grid; gap: 2px; padding: 10px 12px; border-radius: var(--raio); background: var(--surface-2); }
.pn-mini .pn-rot { font-size: var(--t-micro); color: var(--texto-fraco); }
.pn-mini .pn-val { font-size: var(--t-med); font-weight: var(--p-forte); font-variant-numeric: tabular-nums; }
.pn-mini .pn-sub { font-size: var(--t-micro); color: var(--texto-fraco); line-height: 1.35; }
.pn-mini .pn-sub-alerta { color: var(--graf-alerta); font-weight: var(--p-medio); }
.pn-mini-aviso { background: var(--tinta-aviso); }
.pn-mini-aviso .pn-val { color: var(--graf-aviso); }

/* a fila de decisões */
.pn-hoje { padding: 18px 20px 12px; }
.pn-hoje .pn-sec { margin-bottom: 6px; }
/* ⚠ COLUNA E LINHA EXPLÍCITAS EM CADA CÉLULA. O grid coloca primeiro os itens
   com LINHA fixa e coluna automática — o botão (grid-row: 1 / span 2) era
   posicionado antes do valor e caía na 1ª coluna, empurrando o texto para uma
   coluna de largura mínima (uma palavra por linha). Medido na 1ª foto. */
.pn-decisao { display: grid; grid-template-columns: 104px minmax(0, 1fr) auto; grid-template-rows: auto auto; gap: 4px 14px; align-items: center; padding: 11px 0; border-top: 1px solid var(--linha); }
.pn-hoje ol > .pn-decisao:first-child { border-top: 0; }
.pn-quanto { grid-column: 1; grid-row: 1; font-size: var(--t-med); font-weight: var(--p-forte); font-variant-numeric: tabular-nums; white-space: nowrap; display: flex; align-items: center; gap: 8px; }
.pn-quanto i { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--linha-forte); }
.pn-critico .pn-quanto i { background: var(--vermelho); }
.pn-atencao .pn-quanto i { background: var(--amarelo); }
.pn-info .pn-quanto i { background: var(--aco); }
.pn-oque { grid-column: 2; grid-row: 1; font-weight: var(--p-medio); line-height: 1.3; min-width: 0; }
.pn-onde { grid-column: 2; grid-row: 2; font-size: var(--t-peq); color: var(--texto-fraco); min-width: 0; }
.pn-onde b { font-weight: var(--p-medio); color: var(--texto); }
.pn-porque-t, .pn-porque-a { display: block; margin-top: 2px; }
.pn-porque-a::before { content: "\2192\00a0"; }
.pn-acao { grid-column: 3; grid-row: 1 / span 2; }
.pn-btn { height: 30px; padding: 0 12px; border-radius: var(--raio-ctl); border: 1px solid var(--linha); background: var(--surface); color: var(--texto); font-size: var(--t-peq); font-weight: var(--p-medio); font-family: inherit; cursor: pointer; white-space: nowrap; }
.pn-btn:hover { border-color: var(--aco); color: var(--aco); }
.pn-btn-p { background: var(--aco); border-color: var(--aco); color: #fff; }
.pn-btn-p:hover { background: var(--navy-2); border-color: var(--navy-2); color: #fff; }
.pn-mais { border-top: 1px solid var(--linha); padding-top: 10px; margin-top: 2px; }
.pn-mais summary, .pn-sem-mov summary { cursor: pointer; font-size: var(--t-peq); color: var(--aco); font-weight: var(--p-medio); list-style: none; }
.pn-mais summary::-webkit-details-marker, .pn-sem-mov summary::-webkit-details-marker { display: none; }

/* obras */
.pn-obras { padding: 18px 20px 8px; margin-bottom: 30px; }
.pn-obra { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 6px 28px; padding: 14px 0; border-top: 1px solid var(--linha); }
.pn-obras > ul > .pn-obra:first-child { border-top: 0; }
.pn-obra-cab { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; grid-column: 1; }
.pn-obra-cab h3 { font-size: var(--t-base); font-weight: var(--p-forte); }
.pn-pill { font-size: var(--t-micro); font-weight: var(--p-medio); padding: 1px 9px; border-radius: 99px; background: var(--surface-2); color: var(--texto-fraco); }
.pn-pill-and { background: var(--tinta-aco); color: var(--aco); }
.pn-pill-conc { background: var(--tinta-ok); color: var(--verde); }
.pn-pill-dup { background: var(--tinta-aviso); color: var(--graf-aviso); }
.pn-quando { font-size: var(--t-peq); color: var(--texto-fraco); margin-left: auto; white-space: nowrap; }
.pn-q-alerta { color: var(--graf-alerta); font-weight: var(--p-medio); }
.pn-q-aviso { color: var(--graf-aviso); font-weight: var(--p-medio); }
/* a barra dupla: calendário em cima, medido embaixo, no mesmo eixo */
.pn-dupla { grid-column: 1; display: grid; gap: 4px; }
.pn-trilhos { position: relative; display: grid; gap: 3px; margin-top: 14px; }
.pn-trilho { height: 7px; border-radius: 3px; background: var(--surface-3); position: relative; overflow: hidden; }
.pn-trilho i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; }
.pn-trilho .pn-prazo { background: var(--linha-forte); }
.pn-trilho .pn-medido { background: var(--aco); }
.pn-trilho .pn-defas { border-radius: 0; background: repeating-linear-gradient(135deg, var(--graf-aviso) 0 3px, transparent 3px 6px); opacity: .55; }
.pn-trilho .pn-defas.pn-grave { background: repeating-linear-gradient(135deg, var(--graf-alerta) 0 3px, transparent 3px 6px); }
.pn-hoje-marca { position: absolute; top: -3px; bottom: -3px; width: 2px; background: var(--texto); border-radius: 1px; }
.pn-hoje-marca::after { content: "hoje"; position: absolute; top: -15px; left: -12px; font-size: var(--t-micro); color: var(--texto-fraco); }
.pn-dupla-leg { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: var(--t-micro); color: var(--texto-fraco); }
.pn-dupla-leg b { color: var(--texto); font-weight: var(--p-medio); }
.pn-d-aviso { color: var(--graf-aviso); font-weight: var(--p-medio); }
.pn-d-alerta { color: var(--graf-alerta); font-weight: var(--p-medio); }
.pn-d-ok { color: var(--verde); font-weight: var(--p-medio); }
.pn-d-fraco { color: var(--texto-fraco); }
.pn-obra-num { grid-column: 2; grid-row: 1 / span 2; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px 12px; align-content: start; }
.pn-obra-num div { display: grid; gap: 1px; }
.pn-obra-num dt { font-size: var(--t-micro); color: var(--texto-fraco); }
.pn-obra-num dd { font-size: var(--t-peq); font-weight: var(--p-medio); white-space: nowrap; }
.pn-obra-nota { grid-column: 1 / -1; font-size: var(--t-peq); color: var(--graf-aviso); }
.pn-obra-nota.pn-ok { color: var(--verde); }
.pn-sem-mov { border-top: 1px solid var(--linha); padding: 12px 0 8px; }
.pn-sem-mov ul { margin-top: 8px; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 6px 20px; font-size: var(--t-peq); }
.pn-sem-mov li { display: flex; justify-content: space-between; gap: 10px; color: var(--texto-fraco); }
.pn-sem-mov li b { color: var(--texto); font-weight: var(--p-medio); }

/* gráficos */
.pn-grafs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; margin-bottom: 8px; }
.pn-graf { padding: 18px 20px 16px; }
.pn-graf .pn-sec { margin-bottom: 4px; }
.pn-graf svg { max-width: 560px; width: 100%; height: auto; display: block; }
.pn-cats { display: grid; gap: 9px; margin-top: 10px; }
.pn-cat { display: grid; grid-template-columns: 112px minmax(0, 1fr) 96px 44px; align-items: center; gap: 12px; font-size: var(--t-peq); }
.pn-cat-nome { font-weight: var(--p-medio); }
.pn-cat-barra { height: 10px; border-radius: 0 4px 4px 0; background: var(--surface-3); position: relative; overflow: hidden; }
.pn-cat-barra i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 0 4px 4px 0; }
.pn-cat-val { text-align: right; font-variant-numeric: tabular-nums; }
.pn-cat-pct { text-align: right; color: var(--texto-fraco); font-variant-numeric: tabular-nums; }
.pn-rodape { font-size: var(--t-micro); color: var(--texto-fraco); margin-top: 12px; }

/* operação: contadores, não cartões */
.pn-op { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); border-top: 1px solid var(--linha); border-bottom: 1px solid var(--linha); margin-bottom: 26px; }
.pn-op-item { display: grid; gap: 2px; padding: 14px 16px 14px 0; border: 0; border-left: 1px solid var(--linha); padding-left: 16px; background: none; color: inherit; text-align: left; font-family: inherit; cursor: pointer; }
.pn-op-item:first-child { border-left: 0; padding-left: 0; }
.pn-op-item:hover .pn-op-rot { color: var(--aco); }
.pn-op-rot { font-size: var(--t-peq); color: var(--texto-fraco); }
.pn-op-val { font-size: var(--t-tit); font-weight: var(--p-forte); letter-spacing: -.3px; line-height: 1.15; }
.pn-op-sub { font-size: var(--t-micro); color: var(--texto-fraco); }
.pn-op-sub.pn-op-alerta { color: var(--graf-alerta); font-weight: var(--p-medio); }
.pn-op-sub.pn-op-aviso { color: var(--graf-aviso); font-weight: var(--p-medio); }
.pn-fim { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px 20px; font-size: var(--t-peq); color: var(--texto-fraco); margin-bottom: 14px; }
.pn-fim b { color: var(--texto); font-weight: var(--p-medio); }

@media (max-width: 1100px) { .pn-dobra, .pn-grafs { grid-template-columns: 1fr; } .pn-obra { grid-template-columns: 1fr; } .pn-obra-num { grid-column: 1; grid-row: auto; } }
@media (max-width: 820px) {
  .pn-lado { grid-template-columns: 1fr; }
  .pn-decisao { grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto auto auto; }
  .pn-decisao .pn-quanto { grid-column: 1; grid-row: 1; }
  .pn-decisao .pn-oque { grid-column: 1; grid-row: 2; }
  .pn-decisao .pn-onde { grid-column: 1; grid-row: 3; }
  .pn-decisao .pn-acao { grid-column: 2; grid-row: 1 / span 3; }
  .pn-cat { grid-template-columns: 96px minmax(0, 1fr) 80px; }
  .pn-cat-pct { display: none; }
  .pn-obra-num { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pn-sec p { text-align: left; }
}

/* --- Painel novo, 2ª leva (24/09/2026): lucratividade mensal, dois números
   com o mesmo peso, filtro de status, detalhes que abrem, rótulo curto --- */
.pn-dois { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 14px; align-items: start; }
.pn-dois > div { display: grid; gap: 1px; }
.pn-dois .pn-val { font-size: var(--t-med); font-weight: var(--p-forte); font-variant-numeric: tabular-nums; }
.pn-tag { display: inline-block; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--t-micro); font-weight: var(--p-medio); color: var(--texto-fraco); background: var(--surface-2); border-radius: 99px; padding: 2px 9px; }
.pn-sec-obras { align-items: flex-start; flex-wrap: wrap; }
.pn-sec-obras p { text-align: left; margin-top: 2px; }
.pn-seg { display: inline-flex; border: 1px solid var(--linha); border-radius: var(--raio-ctl); overflow: hidden; flex: none; }
.pn-seg-b { height: 30px; padding: 0 12px; border: 0; border-left: 1px solid var(--linha); background: var(--surface); color: var(--texto-fraco); font-size: var(--t-peq); font-weight: var(--p-medio); font-family: inherit; cursor: pointer; }
.pn-seg-b:first-child { border-left: 0; }
.pn-seg-b:hover { color: var(--texto); }
.pn-seg-b.on { background: var(--navy); color: #fff; }
.pn-detalhes { display: grid; gap: 8px; margin: -14px 0 26px; }
.pn-detalhe { border: 1px solid var(--linha); border-radius: var(--raio); background: var(--surface); }
.pn-detalhe summary { cursor: pointer; padding: 10px 14px; font-size: var(--t-peq); font-weight: var(--p-medio); color: var(--aco); list-style: none; }
.pn-detalhe summary::-webkit-details-marker { display: none; }
.pn-detalhe-c { padding: 4px 14px 14px; display: grid; gap: 12px; justify-items: start; }
.pn-detalhe-c .pn-obra-num { grid-column: auto; grid-row: auto; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); width: 100%; }
.pn-obra-num { grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); }
@media (max-width: 820px) {
  .pn-lucro { gap: 4px; }
  .pn-lucro-m span { display: none; }
  .pn-dois { grid-template-columns: 1fr; }
  .pn-seg-b { padding: 0 8px; }
}

/* --- Painel novo, 3ª leva (24/09/2026): cartões de indicador coloridos com
   mini-barras, fluxo em barras + linha, roscas, medidores em arco, grade --- */
.pn-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 22px; }
.pn-tile { position: relative; border-radius: 14px; padding: 14px 16px 12px; border: 1px solid var(--linha); background: var(--surface); box-shadow: var(--sombra); display: grid; gap: 4px; align-content: start; min-width: 0; }
.pn-tile::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 5px; border-radius: 14px 0 0 14px; background: var(--linha-forte); }
.pn-t-ok { background: linear-gradient(180deg, var(--tinta-ok), var(--surface) 70%); }
.pn-t-ok::before { background: var(--verde); }
.pn-t-ok .pn-tile-val { color: var(--verde); }
.pn-t-alerta { background: linear-gradient(180deg, var(--tinta-alerta), var(--surface) 70%); }
.pn-t-alerta::before { background: var(--vermelho); }
.pn-t-alerta .pn-tile-val { color: var(--vermelho); }
.pn-t-aco { background: linear-gradient(180deg, var(--tinta-aco), var(--surface) 70%); }
.pn-t-aco::before { background: var(--aco); }
.pn-t-aco .pn-tile-val { color: var(--aco); }
.pn-t-neutro::before { background: var(--linha-forte); }
.pn-tile-cab { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.pn-tile-cab-2 { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--linha); }
.pn-tile-rot { font-size: var(--t-peq); font-weight: var(--p-medio); color: var(--texto-fraco); }
.pn-tile-val { font-size: var(--t-hero); font-weight: var(--p-forte); letter-spacing: -.6px; line-height: 1.05; white-space: nowrap; }
.pn-tile-val-m { font-size: var(--t-med); letter-spacing: -.2px; font-variant-numeric: tabular-nums; }
.pn-tile-sub { font-size: var(--t-micro); color: var(--texto-fraco); line-height: 1.35; }
.pn-tile .pn-delta { margin-left: 0; font-size: var(--t-micro); }
.pn-tile-mini { margin-top: 4px; }
.pn-mini { width: 100%; height: 40px; display: block; }
.pn-tile .pn-dois { gap: 2px 10px; }
.pn-tile .pn-dois > div { display: grid; gap: 0; }
.pn-grid { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 22px; margin-bottom: 30px; align-items: start; }
.pn-grid-esq { display: grid; gap: 22px; min-width: 0; }
.pn-grid-dir { min-width: 0; }
.pn-tres { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
.pn-larga { margin-bottom: 30px; }
.pn-graf .g-legenda { margin-top: 8px; }
.pn-combo, .pn-lucro-svg { width: 100%; height: auto; display: block; max-width: none; }
.pn-barra { transition: opacity .12s; }
.g-col:hover ~ .pn-barra { opacity: .8; }
.pn-meta-linha { stroke: var(--graf-aviso); stroke-width: 1.4; stroke-dasharray: 6 4; }
.pn-meta-txt { font-size: var(--t-graf-eixo); fill: var(--graf-aviso); font-weight: var(--p-medio); }
.pn-ponto { stroke: var(--surface); stroke-width: 2; }
.pn-ponto.pn-p-ok { fill: var(--verde); }
.pn-ponto.pn-p-atencao { fill: var(--graf-aviso); }
.pn-ponto.pn-p-alerta { fill: var(--graf-alerta); }
.pn-ponto-txt { font-size: var(--t-graf-mes); fill: var(--texto); font-weight: var(--p-forte); }
.pn-gauges { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px 18px; }
.pn-gauge { display: grid; justify-items: center; gap: 2px; }
.pn-gauge svg { width: 100%; max-width: 200px; height: auto; display: block; }
.pn-g-trilho { fill: none; stroke: var(--surface-3); stroke-width: 14; stroke-linecap: round; }
.pn-g-fill { fill: none; stroke: var(--linha-forte); stroke-width: 14; stroke-linecap: round; }
.pn-g-ok .pn-g-fill { stroke: var(--verde); }
.pn-g-atencao .pn-g-fill { stroke: var(--graf-aviso); }
.pn-g-alerta .pn-g-fill { stroke: var(--graf-alerta); }
.pn-g-vazio .pn-g-fill { stroke: transparent; }
.pn-g-meta { stroke: var(--texto); stroke-width: 2; }
.pn-g-val { font-size: var(--t-tit); font-weight: var(--p-forte); fill: var(--texto); }
.pn-g-rot { font-size: var(--t-peq); font-weight: var(--p-medio); text-align: center; }
.pn-g-rot span { display: block; font-size: var(--t-micro); font-weight: var(--p-normal); color: var(--texto-fraco); }
.pn-donut { display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 12px; align-items: center; }
.pn-donut svg { width: 104px; height: 104px; }
.pn-fatia { transition: opacity .12s; }
.pn-donut:hover .pn-fatia { opacity: .85; }
.pn-donut .pn-fatia:hover { opacity: 1; }
.pn-d-val { font-size: var(--t-peq); font-weight: var(--p-forte); fill: var(--texto); }
.pn-d-rot { font-size: var(--t-graf-eixo); fill: var(--texto-fraco); }
.pn-dl { display: grid; gap: 4px; font-size: var(--t-micro); min-width: 0; }
.pn-dl li { display: grid; grid-template-columns: 10px minmax(0, 1fr) auto auto; gap: 6px; align-items: center; }
.pn-dl i { width: 10px; height: 10px; border-radius: 2px; }
.pn-dl-nome { line-height: 1.2; }
.pn-dl-val { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pn-dl-pct { color: var(--texto-fraco); font-variant-numeric: tabular-nums; min-width: 32px; text-align: right; }
@media (max-width: 1280px) { .pn-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) { .pn-tres { grid-template-columns: 1fr; } }
@media (max-width: 1100px) { .pn-grid { grid-template-columns: 1fr; } }
@media (max-width: 820px) { .pn-tiles { grid-template-columns: 1fr; } .pn-donut { grid-template-columns: 1fr; justify-items: center; } }

/* --- Painel novo, 4ª leva (24/09/2026): posição de hoje, agenda, previsão de
   caixa, fila em grupos com adiar, organizar painel, relatório impresso --- */
.pn-bloco { min-width: 0; }
.pn-bloco + .pn-bloco { margin-top: 22px; }
.pn-grid-esq > .pn-bloco + .pn-bloco { margin-top: 0; }
.pn-tiles { margin-bottom: 0; }
.pn-delta-neutro { color: var(--texto-fraco); font-weight: var(--p-normal); }
.pn-ctl-mini { height: 26px; padding: 0 10px; font-size: var(--t-micro); margin-bottom: 6px; }
.pn-ctl-mini.on { background: var(--tinta-aco); border-color: var(--aco); color: var(--aco); }
/* posição de hoje: faixa fina, quatro células */
.pn-posicao, .pn-agenda { display: grid; grid-template-columns: max-content repeat(4, minmax(0, 1fr)); gap: 0 18px; align-items: start; padding: 10px 14px; border: 1px solid var(--linha); border-radius: var(--raio); background: var(--surface-2); }
.pn-pos-t { font-size: var(--t-peq); font-weight: var(--p-medio); color: var(--texto-fraco); padding-top: 2px; white-space: nowrap; }
.pn-pos-c { display: grid; gap: 1px; min-width: 0; }
.pn-pos-rot { font-size: var(--t-micro); color: var(--texto-fraco); }
.pn-pos-val { font-size: var(--t-med); font-weight: var(--p-forte); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pn-pos-sub { font-size: var(--t-micro); color: var(--texto-fraco); line-height: 1.3; }
.pn-pos-aviso .pn-pos-val { color: var(--graf-aviso); }
.pn-pos-alerta .pn-pos-val { color: var(--graf-alerta); }
/* agenda: fichas clicáveis */
.pn-agenda { grid-template-columns: max-content minmax(0, 1fr); }
.pn-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.pn-chip { border: 1px solid var(--linha); background: var(--surface); border-radius: 99px; padding: 5px 12px; font-size: var(--t-peq); font-family: inherit; color: var(--texto); cursor: pointer; text-align: left; }
.pn-chip b { font-weight: var(--p-forte); }
.pn-chip:hover { border-color: var(--aco); }
.pn-chip-ok { border-color: var(--verde); }
.pn-chip-aviso { border-color: var(--graf-aviso); background: var(--tinta-aviso); }
.pn-chip-alerta { border-color: var(--graf-alerta); background: var(--tinta-alerta); }
/* fila em grupos */
.pn-grupo { border-top: 1px solid var(--linha); }
.pn-grupo summary { cursor: pointer; display: flex; justify-content: space-between; gap: 10px; padding: 10px 0 6px; list-style: none; }
.pn-grupo summary::-webkit-details-marker { display: none; }
.pn-grupo-nome { font-weight: var(--p-forte); font-size: var(--t-base); }
.pn-grupo-nome::before { content: "\25B8"; display: inline-block; width: 14px; color: var(--texto-fraco); transition: transform .12s; }
.pn-grupo[open] .pn-grupo-nome::before { transform: rotate(90deg); }
.pn-grupo-n { font-size: var(--t-peq); color: var(--texto-fraco); white-space: nowrap; }
.pn-grupo ol > .pn-decisao:first-child { border-top: 0; }
.pn-grupo-adiados .pn-decisao { opacity: .7; }
.pn-acao { display: grid; gap: 4px; justify-items: stretch; }
.pn-btn-mini { height: 24px; padding: 0 8px; font-size: var(--t-micro); color: var(--texto-fraco); }
/* organizar painel (modal) */
.pn-org-sub { font-size: var(--t-peq); color: var(--texto-fraco); margin: 0 0 10px; }
.pn-org { display: grid; gap: 4px; }
.pn-org-row { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto 30px 30px; align-items: center; gap: 8px; padding: 6px 8px; border: 1px solid var(--linha); border-radius: var(--raio-sm); background: var(--surface); }
.pn-org-row.off { opacity: .55; }
.pn-org-chk { width: 24px; height: 24px; border: 1px solid var(--linha-forte); border-radius: var(--raio-sm); background: var(--surface); color: var(--verde); font-weight: var(--p-forte); cursor: pointer; font-family: inherit; }
.pn-org-chk[aria-pressed="true"] { border-color: var(--verde); background: var(--tinta-ok); }
.pn-org-nome { font-size: var(--t-peq); font-weight: var(--p-medio); }
.pn-org-col { font-size: var(--t-micro); color: var(--texto-fraco); white-space: nowrap; }
.pn-org-mv { width: 28px; height: 26px; border: 1px solid var(--linha); border-radius: var(--raio-sm); background: var(--surface); color: var(--texto); cursor: pointer; font-family: inherit; }
.pn-org-mv:disabled { opacity: .35; cursor: default; }
/* relatório impresso: a janela abre com o app.css e esta classe no body */
.pn-impresso .main { padding: 18px 22px; }
.pn-imp-cab { font-size: var(--t-peq); color: var(--texto-fraco); border-bottom: 1px solid var(--linha); padding-bottom: 8px; margin-bottom: 14px; }
.pn-impresso .pn-filtros, .pn-impresso .pn-acao, .pn-impresso .pn-seg, .pn-impresso .pn-ctl, .pn-impresso .pn-fim, .pn-impresso .pn-chip { pointer-events: none; }
.pn-impresso .pn-filtros, .pn-impresso .pn-acao, .pn-impresso .pn-fim, .pn-impresso .pn-ctl-mini, .pn-impresso .mod-lado { display: none !important; }
@media print {
  .pn-filtros, .pn-acao, .pn-seg, .pn-fim, .pn-ctl-mini, .pn-btn, .pn .mod-lado { display: none !important; }
  .pn-grid { grid-template-columns: 1fr; }
  .pn-card, .pn-tile { break-inside: avoid; box-shadow: none; }
  .pn-grupo, .pn-sem-mov, .pn-detalhe { break-inside: avoid; }
}
@media (max-width: 1100px) { .pn-posicao { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 18px; } .pn-pos-t { grid-column: 1 / -1; } .pn-agenda { grid-template-columns: 1fr; } }
@media (max-width: 820px) { .pn-posicao { grid-template-columns: 1fr; } .pn-org-row { grid-template-columns: 28px minmax(0, 1fr) 30px 30px; } .pn-org-col { display: none; } }
/* 4 cartões na coluna dos gráficos (60% da largura) não cabem o valor
   grande abaixo de ~1500px: viram 2×2. Acima disso, os 4 em linha. */
@media (max-width: 1500px) { .pn-grid-esq .pn-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 820px) { .pn-grid-esq .pn-tiles { grid-template-columns: 1fr; } }
/* rosca em cartão de meia largura: a legenda ao lado ficava com ~180px e o
   nome invadia o valor; a rosca sobe e a legenda ocupa a largura inteira */
.pn-tres .pn-donut { grid-template-columns: 1fr; justify-items: center; gap: 10px; }
.pn-tres .pn-dl { width: 100%; }
.pn-dl-nome { overflow-wrap: anywhere; }
/* lista de barras em cartão de meia largura: as 4 colunas fixas (112+96+44
   e os vãos) não deixavam largura nenhuma para a barra. Nome em cima, barra
   na linha de baixo. */
.pn-tres .pn-cat { grid-template-columns: minmax(0, 1fr) auto 40px; grid-template-areas: "nome val pct" "barra barra barra"; gap: 4px 8px; }
.pn-tres .pn-cat-nome { grid-area: nome; overflow-wrap: anywhere; }
.pn-tres .pn-cat-barra { grid-area: barra; }
.pn-tres .pn-cat-val { grid-area: val; }
.pn-tres .pn-cat-pct { grid-area: pct; }

/* =====================================================================
   SIMULAÇÃO 4D DO BIM — painel estilo TimeLiner (Gestao._b4*, motor
   js/bim4dsim.js) e a JANELA DO 3D (#bim3d=v1/<obra>, body.modo-bim3d).
   ⚠ Tamanhos e pesos pela régua (--t-*, --p-*): o test-contraste cobra.
   ⚠ As cores de ESTADO são as mesmas do motor (BIM4DSim.COR): âmbar em
     execução, roxo crítica, vermelho atrasada. Trocar uma aqui sem trocar
     lá faz a lista dizer uma cor e o 3D mostrar outra.
   ===================================================================== */
.b4 { color: var(--texto); }
.b4-cab { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.b4-cab h3 { margin: 0; display: flex; align-items: center; gap: 6px; font-size: var(--t-med); }
.b4-sub { font-size: var(--t-micro); font-weight: var(--p-normal); color: var(--texto-fraco); }
.b4-cab-acoes { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.b4-chip-vivo { font-size: var(--t-micro); color: var(--verde); background: var(--tinta-ok); border-radius: 99px; padding: 3px 10px; font-weight: var(--p-medio); }
/* o selo do 3D destacado: "sincronizado" só com o eco da outra janela (js/bim4dsim.js, seloPainel) */
.b4-chip-espera { font-size: var(--t-micro); color: var(--texto-fraco); background: var(--tinta-aco); border-radius: 99px; padding: 3px 10px; font-weight: var(--p-medio); }
.b4-chip-aviso { font-size: var(--t-micro); color: var(--graf-aviso); background: var(--tinta-aviso); border-radius: 99px; padding: 3px 10px; font-weight: var(--p-medio); }
/* 4D exato: N/M carimbados (OrcaPRO_Etapa) */
.b4-selo-car { display: inline-block; margin: 0 0 8px; font-size: var(--t-micro); font-weight: var(--p-medio); color: var(--verde); background: var(--tinta-ok); border-radius: 99px; padding: 2px 10px; }
.b4-selo-car.b4-selo-est { color: var(--texto-fraco); background: var(--tinta-aco); border-radius: var(--raio-sm); }
.b4-corpo { display: flex; flex-direction: column; gap: 10px; }
.b4-col-a, .b4-col-b { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.b4-largo .b4-corpo { display: grid; grid-template-columns: minmax(0, 1.8fr) minmax(300px, 1fr); align-items: start; gap: 14px; }

/* ---- janela do 3D (espelho): "de onde veio" e a tela cheia ---- */
.b3-foco { position: absolute; left: 50%; transform: translateX(-50%); top: 14px; z-index: 5; max-width: min(760px, 80%); background: rgba(15, 39, 64, .9); color: #fff; border-radius: 10px; padding: 7px 14px; font-size: var(--t-peq); box-shadow: 0 6px 18px rgba(0, 0, 0, .3); pointer-events: none; text-align: center; }
/* embaixo à direita, acima do selo da janela: o canto de cima é da barra do visualizador */
.b3-tela { position: absolute; right: 14px; bottom: 50px; z-index: 6; display: inline-flex; align-items: center; gap: 6px; border: 1px solid rgba(255, 255, 255, .25); background: rgba(15, 39, 64, .82); color: #dbe8f5; border-radius: 8px; padding: 6px 11px; font: inherit; font-size: var(--t-peq); cursor: pointer; }
.b3-tela:hover { background: rgba(15, 39, 64, .95); color: #fff; }
.b3-tela:focus-visible { outline: 2px solid #93c5fd; outline-offset: 2px; }
:fullscreen .b3-tela { opacity: .55; }
:fullscreen .b3-tela:hover { opacity: 1; }

/* ---- abas do painel (Simulação · Prazo × Custo · Elo do modelo) ---- */
.b4-abas { display: flex; gap: 4px; flex-wrap: wrap; border-bottom: 1px solid var(--linha); padding-bottom: 6px; }
.b4-largo .b4-abas { grid-column: 1 / -1; }
.b4-aba { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--linha); background: var(--surface); color: var(--texto); font: inherit; font-size: var(--t-peq); padding: 6px 12px; border-radius: var(--raio-sm); cursor: pointer; min-height: 32px; }
.b4-aba:hover { background: var(--tinta-aco); }
.b4-aba.on { background: var(--aco); border-color: var(--aco); color: #fff; font-weight: var(--p-medio); }
.b4-aba:focus-visible { outline: 2px solid var(--aco); outline-offset: 2px; }
.b4-aba-n { display: inline-block; min-width: 18px; padding: 0 5px; border-radius: 99px; background: var(--graf-aviso); color: #fff; font-size: var(--t-micro); line-height: 18px; text-align: center; }

/* ---- lista: etapa → tarefas do plano executivo ---- */
.b4-grade tr.b4-filha td { background: var(--faixa-sub); }
.b4-grade tr.b4-filha td.b4-c-nome { padding-left: 26px; }
.b4-grade tr.b4-filha .b4-nome { font-weight: var(--p-normal); }
.b4-num-eap { display: inline-block; margin-right: 6px; font-size: var(--t-micro); color: var(--texto-fraco); font-variant-numeric: tabular-nums; }
.b4-tog { border: 0; background: transparent; color: var(--texto-fraco); cursor: pointer; font-size: var(--t-peq); width: 20px; height: 20px; padding: 0; margin-right: 2px; border-radius: 4px; vertical-align: middle; }
.b4-tog:hover { background: var(--tinta-aco); color: var(--texto); }
.b4-tog:focus-visible { outline: 2px solid var(--aco); }
.b4-tog-todas { margin-left: 8px; text-transform: none; letter-spacing: 0; }

/* ---- a peça clicada no 3D (em cima, em qualquer aba) ---- */
.b4-peca { font-size: var(--t-peq); color: var(--texto); margin: -4px 0 8px; line-height: 1.5; }
.b4-peca:empty { display: none; }
.b4-peca-t { color: var(--texto-fraco); }
.b4-peca-f { font-size: var(--t-micro); color: var(--aco); background: var(--tinta-aco); border-radius: 99px; padding: 0 7px; white-space: nowrap; }
.b4-ficha { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; margin: 0; font-size: var(--t-peq); }
.b4-ficha dt { color: var(--texto-fraco); }
.b4-ficha dd { margin: 0; }

/* ---- Prazo × Custo ---- */
.b4-cd-l { display: grid; grid-template-columns: 78px 1fr auto 52px; align-items: center; gap: 8px; font-size: var(--t-peq); margin: 4px 0; }
.b4-cd-l b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.b4-cd-l em { font-style: normal; color: var(--texto-fraco); text-align: right; font-variant-numeric: tabular-nums; }
.b4-cd-b { display: block; height: 10px; border-radius: 5px; background: var(--faixa-sub); overflow: hidden; }
.b4-cd-b i, .b4-desemb-bar i { display: block; height: 100%; border-radius: 5px; }
.b4-db-p { background: #64748b; }
.b4-db-r { background: var(--verde); }
.b4-cd-at { margin-top: 8px; font-size: var(--t-peq); }
.b4-cd-at ul { margin: 4px 0 0; padding-left: 18px; }
.b4-desemb { width: 100%; border-collapse: collapse; font-size: var(--t-peq); }
.b4-desemb th { text-align: left; font-size: var(--t-micro); color: var(--texto-fraco); font-weight: var(--p-forte); padding: 4px 6px; border-bottom: 1px solid var(--linha); }
.b4-desemb td { padding: 4px 6px; border-bottom: 1px solid var(--linha); }
.b4-desemb-bar { width: 32%; }
.b4-desemb-bar i { height: 6px; margin: 1px 0; }

/* ---- Elo do modelo ---- */
.b4-elo-l { display: grid; grid-template-columns: 140px 1fr 56px; align-items: center; gap: 8px; font-size: var(--t-peq); margin: 4px 0; }
.b4-elo-l b { text-align: right; font-variant-numeric: tabular-nums; }
.b4-elo-b { display: block; height: 10px; border-radius: 5px; background: var(--faixa-sub); overflow: hidden; }
.b4-elo-b i { display: block; height: 100%; }
.b4-elo-tar { background: var(--verde); }
.b4-elo-et { background: var(--graf-aviso); }
.b4-elo-est { background: #94a3b8; }
.b4-elo-ex { background: #cbd5e1; }
.b4-elo-tab { width: 100%; border-collapse: collapse; font-size: var(--t-peq); }
.b4-elo-tab th { text-align: left; font-size: var(--t-micro); color: var(--texto-fraco); padding: 4px 6px; border-bottom: 1px solid var(--linha); }
.b4-elo-tab td { padding: 4px 6px; border-bottom: 1px solid var(--linha); vertical-align: top; }
.b4-passos { margin: 0; padding-left: 20px; font-size: var(--t-peq); line-height: 1.5; }
.b4-passos li + li { margin-top: 4px; }
.b4-sec { border: 1px solid var(--linha); border-radius: var(--raio); padding: 10px 12px; background: var(--card-bg); }
.b4-sec-t { display: flex; align-items: center; gap: 6px; font-size: var(--t-micro); font-weight: var(--p-forte); text-transform: uppercase; letter-spacing: .04em; color: var(--texto-fraco); margin: 0 0 8px; }
details.b4-sec > summary.b4-sec-t { cursor: pointer; margin: 0; }
details.b4-sec[open] > summary.b4-sec-t { margin-bottom: 8px; }
.b4-sec-n { font-weight: var(--p-normal); text-transform: none; letter-spacing: 0; }
.b4-sec-aux { margin-left: auto; font-weight: var(--p-normal); text-transform: none; letter-spacing: 0; text-align: right; }
.b4-nota { font-size: var(--t-micro); color: var(--texto-fraco); margin: 6px 0 0; line-height: 1.4; }
.b4-aviso { color: var(--graf-aviso); }
.b4-vazio { margin: 6px 0; }

/* ---- tempo ---- */
.b4-data { display: flex; flex-direction: column; gap: 2px; margin-bottom: 6px; }
.b4-data-l { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
#b4-data-txt { font-size: var(--t-tit); font-weight: var(--p-forte); font-variant-numeric: tabular-nums; color: var(--texto); }
.b4-dow { font-size: var(--t-base); color: var(--texto-fraco); }
.b4-dia-info { font-size: var(--t-peq); color: var(--texto-fraco); min-height: 1.2em; }
.b4-dia-info.b4-nao-util { color: var(--graf-aviso); }
.b4-kpis { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 10px; }
.b4-kpi { display: flex; flex-direction: column; min-width: 78px; padding: 4px 9px; border: 1px solid var(--linha); border-radius: var(--raio-sm); background: var(--surface); }
.b4-kpi span { font-size: var(--t-micro); color: var(--texto-fraco); white-space: nowrap; }
.b4-kpi b { font-size: var(--t-med); font-weight: var(--p-forte); font-variant-numeric: tabular-nums; white-space: nowrap; }
.b4-kpi-exe b { color: var(--graf-aviso); }
.b4-kpi-atr b { color: var(--graf-alerta); }
.b4-kpi-ok b { color: var(--verde); }
.b4-kpi-custo span { white-space: normal; max-width: 150px; }
.b4-regua { position: relative; padding-top: 11px; }
.b4-regua input[type=range] { width: 100%; margin: 0; accent-color: var(--aco); }
.b4-marcas { position: absolute; left: 8px; right: 8px; top: 0; height: 11px; pointer-events: none; }
.b4-m { position: absolute; top: 0; width: 2px; height: 10px; margin-left: -1px; border-radius: 1px; }
.b4-m-hoje { background: var(--aco); }
.b4-m-corte { background: var(--verde); }
.b4-m-marco { background: var(--texto); width: 7px; height: 7px; margin-left: -3px; top: 2px; transform: rotate(45deg); border-radius: 1px; }
.b4-regua-rot { display: flex; justify-content: space-between; gap: 8px; font-size: var(--t-micro); color: var(--texto-fraco); margin-top: 3px; font-variant-numeric: tabular-nums; }
.b4-regua-leg { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.b4-regua-leg i { display: inline-block; vertical-align: middle; margin-right: 4px; width: 2px; height: 9px; position: static; }
.b4-regua-leg i.b4-m-marco { width: 6px; height: 6px; margin: 0 5px 0 1px; transform: rotate(45deg); }
.b4-ctl { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; margin-top: 10px; }
.b4-ctl-g { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.b4-play { min-width: 104px; }
.b4-campo { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-peq); color: var(--texto-fraco); }
.b4-campo select, .b4-campo input { height: 30px; font-size: var(--t-peq); color: var(--texto); }

/* ---- aparência e filtros ---- */
.b4-linha { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.b4-rot { font-size: var(--t-peq); color: var(--texto-fraco); min-width: 92px; }
.b4-seg { display: inline-flex; border: 1px solid var(--linha-forte); border-radius: var(--raio-sm); overflow: hidden; }
.b4-seg button { border: 0; background: var(--surface); color: var(--texto); font: inherit; font-size: var(--t-peq); padding: 5px 11px; cursor: pointer; }
.b4-seg button + button { border-left: 1px solid var(--linha); }
.b4-seg button.on { background: var(--aco); color: #fff; font-weight: var(--p-medio); }
.b4-seg button:focus-visible { outline: 2px solid var(--aco); outline-offset: -2px; }
.b4-ck { display: flex; align-items: center; gap: 7px; font-size: var(--t-peq); margin: 4px 0; cursor: pointer; color: var(--texto); }
.b4-fonte { width: 100%; height: 32px; font-size: var(--t-peq); color: var(--texto); }

/* ---- atividades: Gantt compacto ---- */
.b4-grade-wrap { max-height: 340px; overflow: auto; border: 1px solid var(--linha); border-radius: var(--raio-sm); background: var(--surface); }
.b4-largo .b4-grade-wrap { max-height: calc(100vh - 360px); min-height: 280px; }
.b4-grade { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--t-peq); --b4-x: 100%; }
.b4-grade thead th { position: sticky; top: 0; z-index: 1; background: var(--faixa-sub); color: var(--texto-fraco); font-weight: var(--p-forte); font-size: var(--t-micro); text-align: left; padding: 6px; border-bottom: 1px solid var(--linha); white-space: nowrap; }
.b4-grade td { padding: 5px 6px; border-bottom: 1px solid var(--linha); vertical-align: middle; white-space: nowrap; }
.b4-lin { cursor: pointer; }
.b4-lin:hover td { background: var(--tinta-aco); }
.b4-c-ck { width: 22px; text-align: center; }
.b4-c-n { width: 24px; color: var(--texto-fraco); text-align: right; font-variant-numeric: tabular-nums; }
.b4-grade td.b4-c-nome { white-space: normal; min-width: 160px; max-width: 300px; }
.b4-nome { font-weight: var(--p-medio); }
.b4-cor { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 6px; vertical-align: 1px; }
.b4-pecas { display: block; font-size: var(--t-micro); color: var(--texto-fraco); }
.b4-tag { display: inline-block; margin-left: 6px; font-size: var(--t-micro); padding: 0 6px; border-radius: 99px; border: 1px solid var(--linha); color: var(--texto-fraco); line-height: 16px; }
.b4-tag-crit { color: var(--graf-alerta); border-color: currentColor; font-weight: var(--p-medio); }
.b4-tag-marco { color: var(--texto); }
.b4-tag-rep { color: var(--graf-aviso); border-color: currentColor; }
.b4-c-dt { font-variant-numeric: tabular-nums; }
.b4-c-num { text-align: right; font-variant-numeric: tabular-nums; }
.b4-crit-txt { color: var(--graf-alerta); font-weight: var(--p-medio); }
.b4-est { display: inline-block; font-size: var(--t-micro); font-weight: var(--p-medio); padding: 1px 8px; border-radius: 99px; background: var(--faixa-sub); color: var(--texto-fraco); }
.b4-e-execucao .b4-est { background: var(--tinta-aviso); color: var(--graf-aviso); }
.b4-e-crit .b4-est { background: rgba(124, 58, 237, .14); color: #7c3aed; }
.b4-e-atrasado .b4-est { background: var(--tinta-alerta); color: var(--graf-alerta); }
.b4-e-concluido .b4-est { background: var(--tinta-ok); color: var(--verde); }
.b4-e-execucao td, .b4-e-atrasado td { background: rgba(245, 158, 11, .07); }
.b4-e-futuro .b4-nome { color: var(--texto-fraco); }
.b4-grade tr.b4-sel td { background: var(--tinta-aco); box-shadow: inset 0 1px 0 var(--aco), inset 0 -1px 0 var(--aco); }
.b4-grade tr.b4-pick td { box-shadow: inset 0 2px 0 var(--aco), inset 0 -2px 0 var(--aco); }
.b4-c-gantt { width: 36%; min-width: 150px; }
.b4-trilho { position: relative; height: 18px; }
/* a linha da DATA atravessa a coluna inteira: a variável mora na tabela e
   cada célula a herda — uma escrita por passo, não uma por linha */
.b4-trilho::after { content: ""; position: absolute; top: -6px; bottom: -6px; left: var(--b4-x); border-left: 2px solid var(--texto); opacity: .75; pointer-events: none; }
.b4-bar { position: absolute; top: 3px; height: 11px; border-radius: 3px; border: 1px solid var(--b4-cor, var(--aco)); background: var(--surface); overflow: hidden; box-sizing: border-box; }
.b4-bar-f { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--b4-cor, var(--aco)); }
.b4-bar-crit { border-width: 2px; }
.b4-bar-marco { width: 10px !important; height: 10px; margin-left: -5px; top: 4px; transform: rotate(45deg); border-radius: 2px; }
.b4-bar-marco .b4-bar-f { width: 100% !important; opacity: .25; }
.b4-e-concluido .b4-bar-marco .b4-bar-f { opacity: 1; }
.b4-bar-base { position: absolute; top: 15px; height: 3px; border-radius: 2px; background: var(--texto-fraco); opacity: .55; }
.b4:not(.b4-largo) .b4-c-dur, .b4:not(.b4-largo) .b4-c-folga, .b4:not(.b4-largo) .b4-c-n, .b4:not(.b4-largo) .b4-sec-aux { display: none; }

/* ---- legenda e curva S ---- */
.b4-legenda { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: var(--t-peq); }
.b4-leg-i { display: inline-flex; align-items: center; gap: 6px; }
.b4-leg-i i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
.b4-sw-nat { background: linear-gradient(135deg, #e2e8f0 0 50%, #94a3b8 50% 100%); border: 1px solid var(--linha-forte); }
.b4-cv { width: 100%; height: auto; display: block; background: var(--surface); border: 1px solid var(--linha); border-radius: var(--raio-sm); }
.b4-cv-grade { stroke: var(--linha); stroke-width: 1; }
.b4-cv-tx { fill: var(--texto-fraco); font-size: var(--t-graf-eixo); }
.b4-cv-plan { fill: none; stroke: #64748b; stroke-width: 2; }
.b4-cv-real { fill: none; stroke: var(--verde); stroke-width: 2.4; }
.b4-cv-proj { fill: none; stroke: #ea580c; stroke-width: 2; stroke-dasharray: 5 3; }
.b4-cv-corte { stroke: var(--verde); stroke-width: 1; stroke-dasharray: 2 2; }
.b4-cv-agora { stroke: var(--texto); stroke-width: 1.5; }
.b4-cv-pto { fill: var(--texto); }
.b4-cv-leg { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: var(--t-micro); color: var(--texto-fraco); margin-top: 5px; }
.b4-cv-leg i { display: inline-block; width: 16px; height: 0; border-top: 2px solid #64748b; vertical-align: middle; margin-right: 5px; }
.b4-cv-leg i.b4-cv-l-real { border-top-color: var(--verde); }
.b4-cv-leg i.b4-cv-l-proj { border-top: 2px dashed #ea580c; }
.b4-cv-leg i.b4-cv-l-data { width: 0; height: 10px; border-top: 0; border-left: 2px solid var(--texto); }

/* ---- o carimbo da data sobre o 3D (é o que a reunião lê) ---- */
.b4-hud { position: absolute; left: 64px; bottom: 16px; z-index: 5; pointer-events: none; background: rgba(15, 39, 64, .9); color: #fff; border-radius: 10px; padding: 8px 14px; box-shadow: 0 6px 18px rgba(0, 0, 0, .3); max-width: min(460px, 55%); }
.b4h-d { font-size: var(--t-med); font-weight: var(--p-forte); font-variant-numeric: tabular-nums; }
.b4h-nu { font-size: var(--t-micro); font-weight: var(--p-normal); color: #fcd34d; margin-left: 6px; }
.b4h-s { font-size: var(--t-peq); color: #dbe8f5; margin-top: 2px; }
.b4h-a { font-size: var(--t-micro); color: #bcd0e3; margin-top: 4px; line-height: 1.35; }

/* ---- a JANELA DO 3D: só o visualizador, a tela inteira ---- */
body.modo-bim3d #sidebar, body.modo-bim3d #topbar { display: none !important; }
body.modo-bim3d .app, body.modo-bim3d .app.com-sidebar { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 1fr); grid-template-areas: "main"; height: 100vh; height: 100dvh; }
body.modo-bim3d .main { grid-area: main; padding: 0; }
/* ⚠ o recado (#jan-recado) é a exceção, como na janela do orçamento: sem ela,
   obra não encontrada virava janela EM BRANCO */
body.modo-bim3d #main > :not(.b4-j3d):not(#jan-recado) { display: none !important; }
body.modo-bim3d .b4-j3d .bim-revit { height: 100vh; height: 100dvh; border: 0; border-radius: 0; }
body.modo-bim3d .b4-hud { left: 24px; bottom: 24px; padding: 12px 20px; max-width: 50%; }
body.modo-bim3d .b4h-d { font-size: var(--t-hero); }
body.modo-bim3d .b4h-s { font-size: var(--t-med); }
body.modo-bim3d .b4h-a { font-size: var(--t-base); }
.b4-j3d-status { position: absolute; right: 14px; bottom: 14px; z-index: 5; font-size: var(--t-micro); background: rgba(15, 39, 64, .82); color: #dbe8f5; padding: 5px 11px; border-radius: 99px; pointer-events: none; max-width: 46%; }
.b4-j3d-status.b4-vivo { color: #86efac; }
.b4-j3d-status.b4-aviso { color: #fcd34d; border-radius: 10px; }

/* =====================================================================
 * DISCIPLINAS E ETAPAS (filtro do 3D) e PROJETO ESTRUTURAL NO CANTEIRO
 * (js/estrutui.js). Tokens da régua: nada de tamanho/peso cru.
 * ===================================================================== */
.edisc-atalhos { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.edisc-abas, .est-abas { display: flex; gap: 6px; flex-wrap: wrap; margin: 4px 0 10px; }
.edisc-lista { border: 1px solid var(--linha); border-radius: 10px; overflow: hidden; }
.edisc-lin { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-bottom: 1px solid var(--linha); }
.edisc-lin:last-child { border-bottom: 0; }
.edisc-ck { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; cursor: pointer; }
.edisc-cor { width: 14px; height: 14px; border-radius: 4px; flex: 0 0 auto; border: 1px solid var(--linha-forte); }
.edisc-nome { font-weight: var(--p-forte); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.edisc-n { font-size: var(--t-micro); white-space: nowrap; }
.edisc-acoes, .est-acoes, .est-cab { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; align-items: center; }
.edisc-nota, .edisc-vazio { font-size: var(--t-micro); margin: 8px 0 0; }
.est-vazio p { margin: 0 0 8px; }
.est-resumo { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin: 4px 0 8px; }
.est-selo { display: inline-flex; align-items: center; gap: 4px; font-size: var(--t-micro); font-weight: var(--p-forte); padding: 2px 9px; border-radius: 99px; }
.est-selo.bom { background: rgba(21, 128, 61, .14); color: var(--verde); }
.est-selo.ruim { background: rgba(214, 31, 38, .12); color: var(--vermelho); }
.est-aviso { color: var(--amarelo); font-size: var(--t-peq); margin: 6px 0; }
.est-sec { margin: 12px 0 4px; }
.est-sec h4 { margin: 0 0 8px; font-size: var(--t-base); }
.est-grade { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px; }
.est-card { display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding: 6px; text-align: left; background: var(--surface); color: var(--texto); border: 1px solid var(--linha); border-radius: 10px; cursor: pointer; }
.est-card:hover, .est-card:focus-visible { border-color: var(--linha-forte); outline: 2px solid transparent; }
.est-thumb { width: 100%; height: auto; min-height: 60px; background: #fff; border-radius: 6px; border: 1px solid var(--linha); }
.est-thumb.sem-pdf { background: var(--surface-2); }
.est-card-tit { font-size: var(--t-peq); }
.est-card-sub { font-size: var(--t-micro); }
.est-tab { width: 100%; border-collapse: collapse; margin: 6px 0 12px; }
.est-tab th, .est-tab td { padding: 5px 7px; border-bottom: 1px solid var(--linha); text-align: left; font-size: var(--t-peq); }
.est-tab th { font-weight: var(--p-forte); background: var(--surface-2); }
.est-tab .n { text-align: right; white-space: nowrap; }
.est-tab tfoot td { font-weight: var(--p-forte); }
.est-conf tr.ruim td { color: var(--vermelho); }
.est-det { display: flex; flex-direction: column; gap: 10px; }
.est-crop-wrap { overflow: auto; max-height: 62vh; background: #fff; border: 1px solid var(--linha); border-radius: 8px; }
.est-crop { display: block; width: 100%; height: auto; background: #fff; }
.est-crop-legenda { font-size: var(--t-micro); margin: 4px 8px 6px; color: #516375; }
.est-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.est-chip { font-size: var(--t-micro); padding: 2px 9px; border-radius: 99px; background: var(--surface-2); border: 1px solid var(--linha); }
.est-dim { margin: 0; }

/* =====================================================================
   PADRÃO DE TELA DE MÓDULO (js/modulo.js + ROTEIRO-MODULO.md, 08/10/2026)
   Uma ordem só em todo módulo: cabeçalho → aviso → filtros → indicadores →
   abas → seções/tabela. Só tokens: nenhum hex solto aqui.
   ===================================================================== */
.mod-cab { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px 24px; flex-wrap: wrap; margin: 0 0 20px; }
.mod-tit { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1 1 260px; }
/* título e contexto ENCOLHEM com reticências em vez de empurrar as ações para
   baixo (a 1280 px o editor de orçamento quebrava o cabeçalho em 2 faixas) */
.mod-tit > div { min-width: 0; }
.mod-tit h1 { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* a linha de contexto NÃO corta: ela leva botão ("← Orçamentos") e o
   overflow escondido cortava o anel de foco dele (e2e-crono-foco-sai) */
.mod-ic { flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--raio); display: inline-grid; place-items: center; background: var(--surface-2); color: var(--aco); border: 1px solid var(--linha); }
.mod-ic svg { width: 22px; height: 22px; }
.mod-tit h1 { margin: 0; font-size: var(--t-tit); line-height: 1.2; font-weight: var(--p-forte); letter-spacing: -.2px; }
.mod-sub { margin: 3px 0 0; color: var(--texto-fraco); font-size: var(--t-peq); line-height: 1.4; }
.mod-lado { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; }
.mod-obra select { min-width: 200px; max-width: 280px; }
.mod-acoes { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mod-mais { position: relative; }
.mod-mais-seta { margin-left: 6px; font-size: var(--t-micro); opacity: .7; }
.mod-mais-menu { position: absolute; right: 0; top: calc(100% + 6px); z-index: 60; min-width: 220px; padding: 6px; background: var(--surface); border: 1px solid var(--linha); border-radius: var(--raio); box-shadow: var(--sombra-lg); display: flex; flex-direction: column; gap: 2px; }
.mod-mais-menu[hidden] { display: none; }
.mod-mais-item > .btn, .mod-mais-item > button, .mod-mais-item > a { width: 100%; justify-content: flex-start; text-align: left; border-color: transparent; background: transparent; box-shadow: none; }
.mod-mais-item > .btn:hover, .mod-mais-item > button:hover { background: var(--surface-2); }
.mod-mais-sep { height: 1px; margin: 4px 6px; background: var(--linha); }

.mod-filtros { display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap; padding: 10px 12px; margin: 0 0 16px; background: var(--card-bg); border: 1px solid var(--linha); border-radius: var(--raio-lg); }
/* max-width: com um seletor só na barra (Semana, Situação, Mês) o campo
   esticava por 1.200 px — um select do tamanho da tela. A busca, que pede
   espaço, usa `.mod-busca`. */
.mod-filtros .field { margin: 0; min-width: 160px; flex: 1 1 180px; max-width: 340px; }
.mod-filtros .field.mod-busca { flex: 2 1 320px; max-width: 640px; }
.mod-filtros-dir { margin-left: auto; display: flex; gap: 8px; align-items: center; }

.mod-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 0; margin: 0 0 20px; background: var(--card-bg); border: 1px solid var(--linha); border-radius: var(--raio-lg); overflow: hidden; }
.mod-kpi { display: flex; flex-direction: column; gap: 4px; padding: 14px 18px; border-left: 1px solid var(--linha); min-width: 0; }
.mod-kpi:first-child { border-left: 0; }
.mod-kpi-r { font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .7px; color: var(--texto-fraco); font-weight: var(--p-forte); }
.mod-kpi-v { font-size: var(--t-med); font-weight: var(--p-forte); color: var(--texto); font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mod-kpi-s { font-size: var(--t-micro); color: var(--texto-fraco); line-height: 1.35; }
.mod-kpi-pos .mod-kpi-v { color: var(--verde); }
.mod-kpi-neg .mod-kpi-v { color: var(--vermelho); }
.mod-kpi-alerta .mod-kpi-v { color: var(--amarelo); }
.mod-kpi-info .mod-kpi-v { color: var(--aco); }

.mod-abas { margin-bottom: 18px; }
.mod-abas .tab:focus-visible { outline: 2px solid var(--aco-claro); outline-offset: -2px; }

.mod-sec { background: var(--card-bg); border: 1px solid var(--linha); border-radius: var(--raio-lg); margin: 0 0 18px; overflow: hidden; }
.mod-sec-cab { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 14px 18px 0; }
.mod-sec-cab h2 { margin: 0; font-size: var(--t-med); font-weight: var(--p-forte); }
.mod-sec-acoes { display: flex; gap: 8px; flex-wrap: wrap; }
/* overflow-x: a seção é `overflow:hidden` (cantos), e tabela larga — a Folha
   Semanal tem 12 colunas — era CORTADA entre 720 e ~1200 px, sem rolagem.
   A rolagem fica no corpo; a margem negativa da tabela cabe no padding. */
.mod-sec-corpo { padding: 14px 18px 16px; overflow-x: auto; }
.mod-sec-corpo > table.tbl { margin: 0 -18px -16px; width: calc(100% + 36px); }
/* Número de tabela DENTRO do kit: a letra do texto, com algarismos tabulares
   (a vírgula continua no prumo — o Plex e a Source têm `tnum`). O Mono da
   regra "NÚMERO EM COLUNA" é da planilha do orçamento, onde a conferência é
   dígito a dígito; numa lista de lançamentos ele deixava a tabela com cara de
   terminal (queixa do Rogério, 08/10/2026). */
.mod-sec table.tbl td.num, .mod-sec table.tbl th.num { font-family: inherit; white-space: nowrap; }
/* Ação de LINHA (ROTEIRO §4): coluna própria, à direita, sem quebrar — nunca
   embaixo da pílula de status, que dobrava a altura de toda linha. */
.mod-sec table.tbl th.mod-lin-acoes, .mod-sec table.tbl td.mod-lin-acoes { width: 1%; text-align: right; white-space: nowrap; }
.mod-sec table.tbl td.mod-lin-acoes .btn + .btn { margin-left: 4px; }

.mod-aviso { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; margin: 0 0 16px; border-radius: var(--raio); border: 1px solid var(--linha); border-left-width: 4px; background: var(--card-bg); font-size: var(--t-peq); }
.mod-aviso-txt { display: flex; flex-direction: column; gap: 2px; }
.mod-aviso-info { border-left-color: var(--aco); }
.mod-aviso-alerta { border-left-color: var(--amarelo); }
.mod-aviso-erro { border-left-color: var(--vermelho); }
.mod-aviso-ok { border-left-color: var(--verde); }

/* pílula de status (Modulo.pilula): tons fixos pelos tokens */
.mod-pil { display: inline-block; padding: 2px 9px; border-radius: 99px; font-size: var(--t-micro); font-weight: var(--p-forte); line-height: 18px; white-space: nowrap; }
.mod-pil-ok { color: var(--verde); background: color-mix(in srgb, var(--verde) 13%, transparent); }
.mod-pil-alerta { color: var(--amarelo); background: color-mix(in srgb, var(--amarelo) 15%, transparent); }
.mod-pil-erro { color: var(--vermelho); background: color-mix(in srgb, var(--vermelho) 12%, transparent); }
.mod-pil-info { color: var(--aco); background: color-mix(in srgb, var(--aco) 13%, transparent); }
.mod-pil-neutro { color: var(--texto-fraco); background: var(--surface-2); }

.mod-vazio { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 40px 20px; color: var(--texto-fraco); }
.mod-vazio b { color: var(--texto); font-size: var(--t-med); font-weight: var(--p-forte); }
.mod-vazio p { margin: 0; max-width: 460px; font-size: var(--t-peq); }
.mod-vazio-ic { width: 52px; height: 52px; border-radius: 50%; display: inline-grid; place-items: center; background: var(--surface-2); color: var(--aco); }

@media (max-width: 720px) {
  .mod-cab { align-items: stretch; }
  .mod-lado { justify-content: flex-start; width: 100%; }
  .mod-obra, .mod-obra select { width: 100%; max-width: none; }
  .mod-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mod-kpi:nth-child(odd) { border-left: 0; }
  .mod-kpi:nth-child(n+3) { border-top: 1px solid var(--linha); }
}
