/* ============================================================================
   TEMA PRISMA — a identidade visual da LUMISET (manual de 09/2026) numa
   estrutura de SISTEMA PROFISSIONAL (12/09/2026): barra azul-marinho no topo
   com as seções, abas de segundo nível, tabelas densas, uma cor de acento e
   cores semânticas só em status. Referências: 7 telas de SaaS de obra, agenda
   e ponto reunidas pelo Samuel em img-exemplos/ (o que elas têm em comum está
   descrito no HANDOFF-FRONT.md).

   A PALETA vem do manual (p. 2): Azul noturno #0E2A47 · Azul profundo #1D4ED8 ·
   Verde profundo #0E8F66 · Vermelho #C42A25 · Gelo #EEF3F9.

   O CLARO É O PADRÃO (desde 12/09): fundo no Gelo — branco só nas superfícies
   (tabelas, cards, campos), para não "estourar o olho" — e texto em azul
   noturno. A barra do topo é o noturno nos DOIS temas: por isso o texto sobre
   ela tem tokens próprios (--barra-*), que não mudam com o tema.
   O ESCURO fica sob `:root[data-tema="escuro"]`, construído a partir do azul
   noturno: o fundo É o noturno, a barra um tom abaixo, os cards um tom acima.

   CONTRASTE (WCAG 2, medido — não no olho; scratchpad/paleta.py, 11/09):
     claro   ink #0e2a47 14,6:1 · muted 6,9:1 · faint 5,4:1   (sobre branco)
             brand #1d4ed8 6,7:1 · brand-2 #1841b4 8,6:1
             ok #0c7956 5,4:1 · crit #c42a25 5,7:1 · warn #9a4a0b 6,3:1
     escuro  ink #eef3f9 11,0:1 · muted 7,1:1 · faint 5,0:1   (sobre o card)
             brand #7897ed 4,4:1 (linha) · brand-2 #8fa8f0 5,3:1 (texto)
             ok #12ba85 4,9:1 · crit #e7827e 4,6:1 · warn #f0b13c 6,5:1
     barra   ink #eef3f9 13,1:1 · muted #b4c7da 8,4:1 sobre o noturno #0e2a47
             (medido de novo em 14/09 — a tabela de 11/09 dizia 13,9 e 8,9)
             SELEÇÃO #c42a25 (14/09): 2,57:1 na barra do claro · 2,97:1 na do
             escuro · 5,67:1 nas abas do claro · 2,17:1 nas do escuro — abaixo
             de 3:1, então: traço de 3px + rótulo ativo em branco (#fff 14,6:1)
     cartão do gráfico (o noturno, nos dois temas): texto 13,1:1 · rótulo
             8,4:1 · física #7897ed 5,2:1 · risco #e7827e 5,5:1 (escuro:
             15,1 · 9,7 · 6,0 · 6,3)
   (o verde profundo puro dá 4,1:1 sobre branco — abaixo do 4,5 exigido para
   texto; por isso o --ok claro é o mesmo verde um tom abaixo.)

   TIPOGRAFIA do manual: Poppins (marca, títulos e destaques) e Work Sans
   (texto corrido e sistema). NADA vem de CDN: as pilhas começam pela fonte da
   identidade e caem em system-ui quando ela não está na máquina — o app
   continua 100% offline.

   O QUE NÃO MUDOU, DE PROPÓSITO: os NOMES das variáveis. `app.py` e
   `piloto/relatorio.py` usam --ground, --panel, --ink, --muted, --faint,
   --line, --brand, --crit/--warn/--ok, --cost etc. Trocar valor e estrutura
   mantendo o nome é o que faz a troca ser segura.

   TODA cor vive numa variável aqui embaixo. Cor literal em qualquer outro lugar
   quebra um dos dois modos (verificar.py confere).

   --cliente: a cor da construtora CONTRATANTE. O app a injeta num <style>
   (`:root{--cliente:#rrggbb}`) só quando a empresa definiu uma; quem a usa
   escreve `var(--cliente, var(--brand))` — sem cliente, vale a marca. Nunca
   em texto (o contraste seria imprevisível): só tinta do fundo da entrada e
   o ícone da marca na barra.
   ============================================================================ */

:root{
  /* ---------- MODO CLARO (padrão) — Gelo com texto em azul noturno ---------- */
  --ground:#eef3f9;            /* fundo da tela: o gelo da identidade */
  --panel:#ffffff;             /* superfícies: tabelas, cards, campos */
  --panel-2:#dee5ed;           /* trilhos de barra, chips neutros, hover forte */
  --sidebar:#0e2a47;           /* A BARRA DO TOPO (nome histórico): o azul noturno */
  --sup:#ffffff;               /* campos de formulário */
  --elevado:#ffffff;           /* o que FLUTUA: menu, painel, balão, tutorial, popup, toast */
  --ink:#0e2a47;--muted:#465c74;--faint:#586c82;--desab:#586c82;
  --line:rgba(14,42,71,.14);
  --nav-on:rgba(14,42,71,.06); /* linha em hover, item ativo de menu */
  --brand:#1d4ed8;             /* o acento: curva física, sublinhado da aba, foco */
  --brand-2:#1841b4;           /* texto na marca, links */
  --brand-suave:#e2e8fa;       /* tinta da marca */
  --brand-solido:#1d4ed8;--brand-borda:#1d4ed8;      /* preenchimento do botão principal */
  --sobre-solido:#ffffff;      /* texto sobre o sólido (6,7:1) — igual nos dois temas */
  /* o PAPEL (28/09/2026): o quadro do QR code do segundo fator e a folha impressa
     dos códigos de recuperação são claros nos DOIS temas — o escuro NÃO redefine
     estes dois. A câmera não lê QR invertido (claro sobre escuro), e texto branco
     some no papel. Preto sobre branco: 21:1. (Bloco SEGURANÇA, no fim.) */
  --papel:#ffffff;--papel-tinta:#000000;
  --crit:#c42a25;--crit-suave:rgba(196,42,37,.10);--crit-texto:#a3231f;--crit-solido:#c42a25;
  --warn:#9a4a0b;--warn-suave:rgba(240,177,60,.18);--warn-texto:#7f3d09;
  /* a rosca de 'para onde foi o dinheiro' (09/10): a fatia 1 é o --crit; as outras mudam de TOM
     (laranja, rosado, vinho, âmbar) — o feedback: "os vermelhos estão muito parecidos" */
  --rosca-2:#e5793a;--rosca-3:#ee9c95;--rosca-4:#6e1f1c;--rosca-5:#e8b04d;
  --ok:#0c7956;--ok-suave:rgba(14,143,102,.12);--ok-texto:#0b6a4c;--ok-solido:#0c7956;
  --cost:#687a8e;              /* curva do custo: cinza-azulado neutro */
  /* GRÁFICOS (14/09, pedido do Samuel a partir de um gráfico de faturamento que
     ele gostou: "a sombra embaixo um pouco mais forte, a linha um pouco mais
     fina, bolinhas nos pontos"). A espessura é a mesma nos dois temas (vale
     daqui); a força da área sob a física e a do gap mudam com o fundo — no
     escuro a mesma opacidade quase some. ANTES: física 2,2px (carteira) e
     2,4px (ficha), custo 1,8–2px, projeção 2 e 1,8px, área .30 → .03, gap .22.
     26/09 (duas referências do Samuel: "esse estilo de linha fina, e as
     bolinhas por mês serem menores"): 1,75/1,5px → 1,25/1px, e a bolinha de
     7px → 5px (.graf-pt), crescendo com anel só quando é lida. A linha da
     minilinha dos Indicadores (.rel-spark-gap) lê o mesmo token. */
  --graf-traco:1.25px;--graf-traco-sec:1px;
  /* (11/10/2026, o Miguel) a linha do ORÇAMENTO VIGENTE no gráfico da carteira em R$: "mais grossa, num azul
     bonitão, bem chamativo, pra destacar" — o traço dela e o azul vivo (no escuro, um tom mais claro dele) */
  --graf-traco-orcado:2.5px;--graf-orcado:#2563eb;
  --graf-area-topo:.40;--graf-area-base:.06;--graf-area-custo-topo:.15;--graf-area-custo-base:.012;--graf-gap:.26;
  /* FALTA INFORMAÇÃO (02/10/2026, v0.61.0): o quanto o EXEMPLO da demo some por
     baixo do aviso — o bastante para nenhum número ser lido (medido no retrato,
     nos dois temas), pouco o bastante para a forma do gráfico continuar à vista.
     O escuro pede menos opacidade: o mesmo .5 sobre o grafite brilha demais. */
  --falta-desfoque:3px;--falta-opacidade:.75;
  /* classes de causa das OCORRÊNCIAS (o porquê, 12/09): uma cor por classe —
     fora do controle · suprimentos · execução · projeto/escopo · gestão · outra.
     Escuras o bastante para um losango de 9px sobre o branco. */
  --oc-externa:#0f7b8a;--oc-suprimento:#6d4fc2;--oc-execucao:#b8660f;
  --oc-escopo:#b0338a;--oc-gestao:#3b5f8f;--oc-outra:#687a8e;
  --sombra:0 1px 2px rgba(14,42,71,.06);
  --sombra-alta:0 1px 2px rgba(14,42,71,.08),0 10px 30px rgba(14,42,71,.14);
  --veu:rgba(14,42,71,.45);    /* o escurecido atrás do tutorial e do painel */
  --anel:rgba(29,78,216,.35);  /* anel de foco e de realce: a marca com transparência */
  /* a barra do topo é noturna nos dois temas — o que vai sobre ela também */
  --barra-ink:#eef3f9;--barra-muted:#b4c7da;
  --barra-on:rgba(238,243,249,.10);--barra-linha:rgba(238,243,249,.12);
  --barra-acento:#7897ed;      /* ícone da marca, avatar, barra de progresso e a física no cartão do gráfico: azul profundo com mais luz (o puro some no noturno) */
  --barra-crit:#e7827e;        /* risco SOBRE o noturno (cartão do gráfico): 5,5:1 — o #c42a25 puro dá 2,6:1 ali */
  /* A MARCA DA SELEÇÃO (14/09, pedido do Samuel: "não estou conseguindo ver que
     foi selecionado"): o traço sob a seção ativa da barra, sob a aba ativa da
     seção e sob a aba ativa da ficha é o VERMELHO do manual, exato, e vale nos
     dois temas (o escuro não o redefine). Antes: --barra-acento (#7897ed) na
     barra e --brand nas abas, com 2px. Medido (WCAG 2): 2,57:1 sobre a barra
     do claro, 2,97:1 sobre a do escuro, 5,67:1 nas abas do claro e 2,17:1 nas
     do escuro — abaixo dos 3:1 que a WCAG 1.4.11 pede a um indicador de
     estado. Compensado SEM trocar a cor: traço de 3px (era 2px) e o rótulo da
     seção ativa em branco pleno (14,6:1; as abas já usam a tinta cheia, --ink).
     Token separado de --crit DE PROPÓSITO: seleção não é risco — o contador
     do Radar é pílula cheia em --crit; a seleção é traço. */
  --selecao:#c42a25;--sel-traco:3px;--barra-ink-sel:#ffffff;
  /* AS CORES DA TELA PLANO (11/10/2026, pedido do Miguel: "uma brincadeira de cor, a
     progressão no tom — claro e ir escurecendo"). Cada opção tem a SUA cor, num degradê
     do canto de cima (o tom claro, -a) ao de baixo (o escuro, -b): as três faixas são a
     MESMA família azul que aprofunda com o tamanho (3 → 5 → 10 obras); a Lumina é o verde
     da economia (o verde profundo do manual); o personalizado, o VERMELHO da Lumiset (o
     Miguel, 11/10: "pra ficar na identidade visual da empresa" — o #c42a25 do manual dá
     4,4:1 no texto de apoio, então o tom claro é um passo abaixo, #b02a25). O botão é um
     tom CLARO da mesma cor, com o texto no escuro dela. São iguais nos dois temas (o bloco
     é a mesma peça escura com texto branco no claro e no escuro — o escuro NÃO redefine).
     Medido (WCAG 2, scratchpad contraste_planos.py): branco sobre o tom claro 6,5 · 7,4 ·
     11,5 · 6,5 · 6,6:1; o texto de apoio (branco a 84%) ≥ 5,0:1; o texto do botão ≥ 10,7:1;
     o botão contra o tom claro do bloco ≥ 5:1 (ele salta do fundo). */
  --pl-3-a:#25609a;--pl-3-b:#162945;--pl-3-botao:#cfe3fb;--pl-3-tinta:#10294a;
  --pl-5-a:#2f4fae;--pl-5-b:#151c42;--pl-5-botao:#d6defd;--pl-5-tinta:#141d48;
  --pl-10-a:#2b2f80;--pl-10-b:#0e1029;--pl-10-botao:#ddd9ff;--pl-10-tinta:#17154a;
  --pl-lu-a:#196a55;--pl-lu-b:#0a2826;--pl-lu-botao:#c8f1e1;--pl-lu-tinta:#0a3329;
  --pl-pe-a:#b02a25;--pl-pe-b:#350d0c;--pl-pe-botao:#fde0dc;--pl-pe-tinta:#5c1513;
  --pl-texto:#ffffff;--pl-texto-2:rgba(255,255,255,.84);--pl-borda:rgba(255,255,255,.3);
  --pl-vidro:rgba(255,255,255,.08);--pl-vidro-on:rgba(255,255,255,.16);--pl-quadro:rgba(4,8,20,.3);
  /* tipografia da identidade, com a pilha do sistema atrás (sem CDN) */
  --titulo:"Poppins",system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --sans:"Work Sans",system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --serif:var(--titulo);       /* nome antigo, mantido: quem pedia --serif pedia "fonte de título" */
  --mono:ui-monospace,"Cascadia Mono",Consolas,monospace;
  /* pontes para o Bootstrap */
  --bs-body-bg:var(--ground);--bs-body-color:var(--ink);
  --bs-body-font-family:var(--sans);
  --bs-border-color:var(--line);--bs-border-radius:6px;
  --bs-link-color-rgb:24,65,180;--bs-link-hover-color-rgb:29,78,216;
  --bs-secondary-color:var(--muted);
  --bs-font-monospace:ui-monospace,Consolas,monospace;
  --bs-primary:#1d4ed8;--bs-primary-rgb:29,78,216;
  --bs-emphasis-color:var(--ink);--bs-code-color:var(--brand-2);
  color-scheme:light;
}

:root[data-tema="escuro"]{
  /* ---------- MODO ESCURO — grafite com temperatura ----------
     O Samuel achou o escuro "sem vida" (23/09). A causa NÃO era claridade: os
     cinzas tinham 7% de saturação (cinza morto) e tudo mais estava rebaixado
     junto — superfície, texto, botão e status. A correção segue a mesma linha
     de cor, em três movimentos:
       1. TEMPERATURA nos neutros: a matiz do azul da marca (H≈220) com
          saturação baixa, ~7%. Cinza com temperatura faz o branco parecer
          limpo e o azul assentar; cinza puro achata tudo. Uma rodada com 12%
          foi descartada: acima de ~10% o neutro deixa de ser cinza e vira azul
          aos olhos (docs/TEMA-ESCURO.md, decisão 4).
       2. CROMA de volta onde um painel respira: gráfico e status. Sinal não é
          decoração — é o que a pessoa procura na tela.
       3. INTERAÇÃO com cor: o hover deixa de ser branco transparente e passa a
          ser a marca transparente. É o que dá sensação de resposta viva.
     O que NÃO mudou: a claridade das superfícies (o grafite que ele aprovou) e
     o azul do botão continua longe do vibrante. */
  --ground:#1b1d20;            /* fundo da tela */
  /* 23/09, 2ª rodada de "dar vida": a escala inteira desceu (o topo era L13%,
     agora é L8%). Não é escurecer por escurecer — com o fundo mais fundo, o
     MESMO texto e os MESMOS acentos ganham 2 a 3 pontos de contraste, e é isso
     que tira o ar apagado. De quebra, o traço vermelho da seleção passa a dar
     3,3:1 sozinho sobre o topo (era 2,9:1), sem mexer na cor do manual. */
  --sidebar:#131315;           /* A BARRA DO TOPO (nome histórico) e o balão do gráfico */
  --sup:#191a1d;               /* campos de formulário: afundados no card */
  --panel:#26282c;             /* superfícies: tabelas, cards, campos */
  --panel-2:#323439;           /* hover forte, trilhos, chips */
  --elevado:#323439;           /* o que FLUTUA: menu, painel, balão, tutorial, popup, toast */
  --ink:#ffffff;--muted:#dcdfe3;--faint:#cdd0d5;--desab:#9ea3ac;
  --line:#40434a;              /* a borda é o que desenha o card aqui */
  --nav-on:rgba(110,150,220,.16);  /* hover e item ativo: a MARCA transparente, não branco */
  --brand:#9db8e0;--brand-2:#afc6ec;--brand-suave:rgba(64,105,184,.30);--brand-solido:#4069b8;
  --brand-borda:#7a9bd9;       /* o contorno é o que dá FORMA ao botão */
  --crit:#ff8c85;--crit-suave:rgba(196,42,37,.26);--crit-texto:#ff8c85;--crit-solido:#c42a25;
  --warn:#f0b93f;--warn-suave:rgba(240,185,63,.20);--warn-texto:#f0b93f;
  --rosca-2:#f0882e;--rosca-3:#c2453f;--rosca-4:#f3c969;--rosca-5:#8a4b47;
  --ok:#3ed9a0;--ok-suave:rgba(14,143,102,.26);--ok-texto:#3ed9a0;
  --ok-solido:#0c7956;         /* o MESMO do claro: com #0e8f66 o branco do botão dava 4,09:1
                                  (abaixo de 4,5); com este, 5,4:1 — e o botão ainda se destaca
                                  do fundo (3,1:1) (24/09) */
  --cost:#cdd0d5;              /* curva do custo: o neutro, para o azul do avanço saltar */
  /* o gráfico é onde a cor trabalha: área e gap mais presentes */
  --graf-area-topo:.55;--graf-area-base:.10;--graf-area-custo-topo:.22;--graf-area-custo-base:.035;--graf-gap:.34;
  --falta-opacidade:.6;        /* o exemplo desfocado do "Falta …" (v0.61.0) */
  --oc-externa:#4fd0e3;--oc-suprimento:#b9a5e8;--oc-execucao:#f5a94f;
  --oc-escopo:#f58cd2;--oc-gestao:#8fb9ef;--oc-outra:#a2a9b6;
  /* a barra no escuro é neutra com a mesma temperatura; o acento do gráfico é
     mais vivo de propósito: ali é DADO, e o fundo quase preto aguenta */
  --barra-ink:#ffffff;--barra-muted:#d6d9dd;
  --graf-orcado:#4d8dff;       /* o azul da linha do orçamento vigente (o vivo do claro, mais aceso no escuro) */
  --barra-on:rgba(110,150,220,.18);--barra-linha:rgba(255,255,255,.14);
  --barra-acento:#7fa5f2;
  --barra-crit:#ff8c85;
  /* no escuro, elevação é BORDA — sem sombra empilhada */
  --sombra:0 0 0 1px #40434a;
  --sombra-alta:0 0 0 1px #40434a,0 10px 28px rgba(0,0,0,.6);
  --veu:rgba(6,8,12,.76);
  --anel:rgba(157,184,224,.5);
  --bs-link-color-rgb:175,198,236;--bs-link-hover-color-rgb:205,221,246;
  --bs-primary:#9db8e0;--bs-primary-rgb:157,184,224;
  color-scheme:dark;
}
/* O AZUL NOTURNO (09/10/2026, feedback: "deixar de fundo o azul mais escuro, o da
   paleta da empresa"): o TERCEIRO tema, uma variação do escuro (data-tom="azul") —
   os painéis, a tinta e os sinais do escuro continuam; o fundo da página vira o
   azul noturno da marca (#0E2A47), com o fundo em vídeo dele. */
:root[data-tema="escuro"][data-tom="azul"]{
  --ground:#0e2a47;
  --fundo-forca:.9;--fundo-imagem:url("/static/fundo/azul.jpg");
}

:root{
  /* ---------- MOVIMENTO (igual nos dois temas) ----------
     Uma fonte só para TODA transição e animação do app: três durações e
     duas curvas. Quem entra na tela usa --curva-saida (ease-out: parte
     rápido e assenta); quem sai usa --curva-entrada (ease-in: parte devagar
     e some). Teto de ~400 ms — acima disso a pessoa está esperando o
     sistema, não vendo uma resposta. As exceções, conscientes: a contagem
     dos KPIs (600 ms), o destaque da linha nova (1,5 s), a barra de tempo do
     aviso de retorno (6 s) e o rastejo da barra de progresso (é espera de
     rede, não animação de interface). Só se anima o que o navegador compõe
     sem relayout: transform, opacity, cor de fundo/borda/texto e sombra. */
  --dur-rapida:120ms;--dur-media:220ms;--dur-lenta:360ms;
  --curva-saida:cubic-bezier(.2,.8,.2,1);--curva-entrada:cubic-bezier(.4,0,1,1);
  /* (11/10/2026) a MOLA: passa um tico do ponto e volta — o "salto" dos blocos da tela
     Plano quando o mouse passa por cima (pedido do Miguel) */
  --curva-mola:cubic-bezier(.34,1.56,.64,1);
  /* a troca de uma leitura para outra na MESMA tela (28/09): o conteúdo velho
     cruza com o novo — curto, porque quem clicou quer ver o número novo, não
     esperar a animação (bloco A TROCA DE VISÃO SEM SOLAVANCO, no fim) */
  --dur-troca:180ms;
}

/* --------------------------------- base ---------------------------------- */
body{background:var(--ground);color:var(--ink);-webkit-font-smoothing:antialiased;
 font-family:var(--sans);font-size:13.5px;line-height:1.45}
/* Poppins (manual: "marca, títulos e destaques") nos títulos, na marca e nos
   números grandes; o texto corrido fica em Work Sans (--sans). Sem a fonte na
   máquina, as duas pilhas caem na MESMA fonte do sistema — nada desalinha. */
.pg-head h1,.entrada-card h1,.card-t,.card-title,.tour-titulo,.marca,.entrada-nome,
.foot-marca,.kpi-item .val,.faixa-mid .v,.bandval,.prazo-val,.painel-nome,.vazio h3{font-family:var(--titulo)}
/* números: algarismos tabulares da própria fonte (o desenho não usa mono) */
.num,td.n,th.n,.kpi-item .val,.delta,.brl,.fact .v,.mem-row .r{font-variant-numeric:tabular-nums}
/* os centavos em expoente (`_brl_sup`): o `smaller` do navegador dava 9,75 px no
   texto de 13 — o piso de 11 px (06/10) vale; no número grande segue o 75% */
.brl sup{font-size:max(11px,.75em)}
.titulo-serif{font-family:var(--serif);font-weight:500;letter-spacing:-.015em;color:var(--ink)}
.text-secondary{color:var(--muted)!important}
a{color:var(--brand-2)}
:focus-visible{outline:2px solid var(--brand);outline-offset:2px}
b,strong,.fw-semibold{font-weight:600}

/* --------------------- botão de alternar claro/escuro --------------------- */
/* dois ícones em SVG; o CSS mostra um por vez conforme o tema */
#btn-tema .sol{display:none}
:root[data-tema="escuro"] .top{box-shadow:inset 0 -1px 0 var(--line)}
[data-tema="escuro"] #btn-tema .lua{display:none}
[data-tema="escuro"] #btn-tema .sol{display:flex}

/* =============================== A CASCA ==================================
   Barra do topo (azul-marinho, fixa) com a marca, as seções e os botões de
   canto; abaixo, quando a seção tem subitens, a barra branca de abas; e o
   conteúdo numa coluna de largura limitada. Sem barra lateral.
   ========================================================================= */
.top{position:sticky;top:0;z-index:50;background:var(--sidebar);color:var(--barra-ink);
 min-height:52px;display:flex;align-items:stretch;padding:0 20px;gap:18px}
.marca{display:flex;align-items:center;gap:9px;text-decoration:none;color:var(--barra-ink);
 font-weight:600;font-size:16px;letter-spacing:-.01em;flex:none}
.marca:hover{color:var(--barra-ink)}
.marca .logo{display:grid;place-items:center;color:var(--cliente,var(--barra-acento))}
.marca .by{font-family:var(--sans);font-weight:400;font-size:11px;color:var(--barra-muted);margin-left:2px}
.nav-main{display:flex;align-items:stretch;gap:2px;min-width:0;position:relative}
.nav-item{display:inline-flex;align-items:center;gap:7px;padding:0 11px;font-size:13.5px;font-weight:500;
 color:var(--barra-muted);text-decoration:none;white-space:nowrap;
 border-top:var(--sel-traco) solid transparent;border-bottom:var(--sel-traco) solid transparent;
 transition:color var(--dur-rapida),background-color var(--dur-rapida)}
.nav-item:hover{color:var(--barra-ink)}
.nav-item:active{color:var(--barra-ink);background:var(--barra-on)}
/* a seção ativa: rótulo em BRANCO PLENO + o traço VERMELHO da seleção
   (--selecao, 3px). O vermelho sobre o noturno fica abaixo de 3:1 (ver os
   tokens): o branco do rótulo é a outra metade do sinal, não enfeite. */
.nav-item.on{color:var(--barra-ink-sel);border-bottom-color:var(--selecao)}
/* O INDICADOR QUE DESLIZA: um traço só por barra (seções, abas da seção,
   abas da ficha), criado pelo JS e posicionado por transform sob o item
   ativo — com JS o traço substitui a borda do item (.js), sem JS a borda
   fica. Ao trocar de tela, ele parte de onde a pessoa clicou e desliza até
   a seção nova: é o que mostra "de onde vim, para onde fui". */
.ind{position:absolute;left:0;bottom:0;height:var(--sel-traco);width:1px;background:var(--selecao);transform-origin:left;
 opacity:0;pointer-events:none;transition:transform var(--dur-media) var(--curva-saida),opacity var(--dur-rapida)}
.ind.on{opacity:1}
/* a borda do item só some enquanto o traço está LIGADO (:has): se o JS o
   desliga — menu vertical, aba na linha de cima — a borda volta sozinha */
.nav-main:has(.ind.on) .nav-item.on{border-bottom-color:transparent}
/* contador de obras em risco: sólido, porque é o único número da barra */
/* (06/10) piso de 11 px para texto que é informação — a auditoria pegou 10–10,5 px
   no crachá, nos eixos, no seletor de obra, nas etiquetas; a exceção declarada é
   só o avatar (as iniciais repetem o nome que está ao lado) */
.nav-item .conta{background:var(--crit-solido);color:var(--sobre-solido);font-size:11px;font-weight:600;
 border-radius:9px;padding:1px 6px;line-height:1.35;min-width:18px;text-align:center}
.top-dir{margin-left:auto;display:flex;align-items:center;gap:2px;flex:none}
.tb-btn{width:32px;height:32px;border:0;background:transparent;color:var(--barra-muted);display:grid;
 place-items:center;border-radius:6px;text-decoration:none;cursor:pointer;padding:0;
 transition:background-color var(--dur-rapida),color var(--dur-rapida),transform var(--dur-rapida)}
.tb-btn:hover{background:var(--barra-on);color:var(--barra-ink)}
.tb-btn:active{transform:scale(.92)}
/* empresa + quem está logado: um chip que abre o menu (conta, usuários, sair) */
details.menu-conta{position:relative;margin-left:8px}
details.menu-conta>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:8px;
 padding:4px 8px 4px 5px;border-radius:6px;color:var(--barra-ink);font-size:13px;font-weight:500;
 background:var(--barra-on);line-height:1.15;transition:background-color var(--dur-rapida)}
details.menu-conta>summary::-webkit-details-marker{display:none}
details.menu-conta>summary:hover{background:var(--barra-linha)}
.menu-conta .txt{display:flex;flex-direction:column;min-width:0;text-align:left}
.menu-conta .nome{max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.menu-conta .sub{font-size:11px;font-weight:400;color:var(--barra-muted)}
.menu-conta .chev{color:var(--barra-muted);display:flex;transition:transform var(--dur-media) var(--curva-saida)}
details.menu-conta[open] .chev{transform:rotate(180deg)}
/* os menus suspensos descem com fade (o <details> só anima o abrir: ao
   fechar, o navegador some com o conteúdo na hora) */
@keyframes menu-abrir{from{opacity:0;transform:translateY(-6px)}}
details.menu-conta[open] .menu-lista,details.acao-menu[open] .acao-lista{animation:menu-abrir var(--dur-media) var(--curva-saida)}
.chip-empresa{display:flex;align-items:center;gap:8px;margin-left:8px;padding:4px 10px 4px 5px;border-radius:6px;
 color:var(--barra-ink);font-size:13px;font-weight:500;background:var(--barra-on)}
.av{width:28px;height:28px;border-radius:50%;background:var(--panel-2);color:var(--muted);font-size:10.5px;
 font-weight:600;display:inline-grid;place-items:center;flex:none;letter-spacing:.02em}
/* o avatar é a EXCEÇÃO ao piso de 11 px (06/10): as iniciais são decoração — o
   nome da pessoa ou da empresa está escrito ao lado (ou no menu); num círculo de
   24 px, 10,5 é o maior que deixa duas letras largas ("MW") com respiro */
.top .av{width:24px;height:24px;font-size:10.5px;background:var(--barra-acento);color:var(--sidebar)}
.menu-lista{position:absolute;right:0;top:calc(100% + 6px);min-width:220px;background:var(--elevado);color:var(--ink);
 border:1px solid var(--line);border-radius:8px;box-shadow:var(--sombra-alta);padding:6px;z-index:60;
 display:flex;flex-direction:column;gap:2px}
.menu-lista .cab{padding:6px 10px 8px;font-size:12px;color:var(--faint);border-bottom:1px solid var(--line);
 margin-bottom:4px;line-height:1.4}
.menu-lista .cab b{color:var(--ink);font-weight:600;display:block}
.menu-lista a,.menu-lista button{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:6px;
 text-decoration:none;color:var(--ink);font:inherit;font-size:13.5px;border:0;background:transparent;
 width:100%;text-align:left;cursor:pointer}
.menu-lista a,.menu-lista button{transition:background-color var(--dur-rapida)}
.menu-lista a:hover,.menu-lista button:hover{background:var(--nav-on);color:var(--ink)}
.menu-lista svg{color:var(--faint);flex:none}
.nav-burger{display:none;width:36px;height:36px;border:0;background:transparent;color:var(--barra-ink);
 border-radius:6px;place-items:center;cursor:pointer;padding:0;align-self:center;
 transition:background-color var(--dur-rapida),transform var(--dur-rapida)}
.nav-burger:hover{background:var(--barra-on)}
.nav-burger:active{transform:scale(.92)}

/* abas de segundo nível (Financeiro: Lançamentos · Conciliação · Relatórios) */
.abas-bar{background:var(--panel);border-bottom:1px solid var(--line)}
.abas-in{max-width:1360px;margin:0 auto;padding:0 28px;display:flex;align-items:center;gap:16px;min-height:44px}
/* a seção a que as abas pertencem, em caixa alta e apagada, antes delas:
   "FINANCEIRO  Lançamentos · Conciliação · Relatórios" — sem isso as abas
   pareciam filtros soltos (queixa de 12/09: "meio confuso") */
.abas-secao{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);font-weight:500;
 white-space:nowrap;padding-right:14px;border-right:1px solid var(--line);line-height:1}
.abas{display:flex;flex-wrap:wrap;gap:0 18px;min-width:0;position:relative}
.aba{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 2px;font-size:13.5px;font-weight:500;
 color:var(--muted);text-decoration:none;border:0;background:transparent;font-family:inherit;
 border-bottom:var(--sel-traco) solid transparent;white-space:nowrap;cursor:pointer;
 transition:color var(--dur-rapida),transform var(--dur-rapida)}
.aba:hover{color:var(--ink)}
.aba:active{transform:translateY(1px)}
/* a aba ativa usa a MESMA marca da barra do topo (14/09; antes era --brand):
   o traço vermelho da seleção, 3px. Uma marca só para "você está aqui" — nas
   seções, nas abas da seção e nas abas da ficha. O .ind herda a cor da regra
   dele (não há mais cor própria para as abas). */
.aba.on{color:var(--ink);border-bottom-color:var(--selecao)}
.abas:has(.ind.on) .aba.on,.abas-pg:has(.ind.on) .aba.on{border-bottom-color:transparent}
.aba .n{font-size:11.5px;color:var(--faint);font-weight:500}
.abas-dir{margin-left:auto;display:flex;gap:6px;align-items:center;flex:none}
/* abas DENTRO da página (ficha da obra): mesmo desenho, sem a barra cheia */
.abas-pg{border-bottom:1px solid var(--line);display:flex;align-items:center;gap:16px;flex-wrap:wrap;position:relative}
.abas-pg .aba{min-height:40px}
.aba-pane[hidden]{display:none}
/* o painel da aba entra com fade + 8px (a mesma entrada da página; ao trocar
   de aba o JS marca .troca para não esperar a cascata da página) */
.content-col>.aba-pane.troca{animation-delay:0s}

.content-col{max-width:1360px;margin:0 auto;width:100%;padding:18px 28px 32px;
 display:flex;flex-direction:column;gap:16px}

/* cabeçalho da página: título pequeno + linha de apoio à esquerda, ações à direita */
.pg-head{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap}
.pg-head h1{margin:0;font-size:20px;font-weight:600;letter-spacing:-.015em;color:var(--ink);line-height:1.25}
.pg-head .sub{color:var(--faint);margin-top:2px;font-size:12.5px}
.pg-head .crumb{font-size:12px;color:var(--faint);margin-bottom:2px}
.pg-head .crumb a{color:var(--faint);text-decoration:none}
.pg-head .crumb a:hover{color:var(--ink)}
.pg-acoes{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.chip-h1{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
/* menu de ações que lista as obras (Registrar medição ▾, Aditivo ▾) */
details.acao-menu{position:relative}
details.acao-menu>summary{list-style:none;cursor:pointer}
details.acao-menu>summary::-webkit-details-marker{display:none}
details.acao-menu:not([open]) .acao-lista{display:none}  /* fechado não pode criar rolagem lateral (13/09) */
.pg-acoes .acao-lista{left:auto;right:0}                     /* na barra de ações, abre para dentro da tela */
.acao-lista{position:absolute;top:calc(100% + 6px);left:0;min-width:260px;max-height:320px;overflow:auto;
 background:var(--elevado);border:1px solid var(--line);border-radius:8px;box-shadow:var(--sombra-alta);
 padding:6px;z-index:50;display:flex;flex-direction:column;gap:2px}
.acao-lista a{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:7px 10px;
 border-radius:6px;text-decoration:none;color:var(--ink);font-size:13px;white-space:nowrap}
.acao-lista a:hover{background:var(--nav-on);color:var(--ink)}
.acao-lista .sub{color:var(--faint);font-size:11.5px}

/* ===================== OBRA EM FOCO (26/09/2026) =====================
   O seletor da barra do topo: um details.acao-menu DENTRO da nav de seções,
   encostado à direita (margin-left:auto). Desktop: chip de duas linhas (o
   nome da obra / "obra em foco"), lista suspensa abrindo para dentro da tela.
   Tela que NÃO filtra por obra (Radar, Tarefas, Comercial, Conciliação):
   .mudo — sem fundo, borda fina, texto apagado e a nota no lugar do rótulo;
   continua abrindo, porque trocar a obra vale para as outras telas. Abaixo de
   992px a nav vira o menu ☰ vertical: o seletor é a PRIMEIRA linha dele e a
   lista abre em acordeão, sem caixa flutuante — nada rola de lado. Cor só por
   token da barra (o fundo é noturno nos dois temas). */
.nav-main .foco-obra{margin-left:auto;display:flex;align-items:center;flex:none;padding-left:8px}
.foco-obra>summary{display:flex;align-items:center;gap:7px;padding:4px 8px 4px 7px;border-radius:6px;
 color:var(--barra-ink);font-size:12.5px;font-weight:500;line-height:1.15;background:var(--barra-on);
 border:1px solid transparent;transition:background-color var(--dur-rapida)}
.foco-obra>summary:hover{background:var(--barra-linha)}
.foco-obra>summary:focus-visible{outline:0;box-shadow:var(--anel)}
.foco-obra .ic{display:flex;color:var(--barra-acento)}
/* o texto tem TETO de 130px (elipse): medido a 1366 px numa tela com tutorial, a
   barra da direita começa em 1048 e o seletor sem teto ia a 1064 — por baixo do
   botão. O nome inteiro fica no title/aria-label do summary. */
.foco-obra .txt{display:flex;flex-direction:column;min-width:0;max-width:130px;text-align:left}
.foco-obra .rot,.foco-obra .sub{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.foco-obra .sub{font-size:11px;font-weight:400;color:var(--barra-muted)}
.foco-obra .chev{color:var(--barra-muted);display:flex;transition:transform var(--dur-media) var(--curva-saida)}
.foco-obra[open] .chev{transform:rotate(180deg)}
.foco-obra .acao-lista{left:auto;right:0;min-width:250px}
.foco-obra .acao-lista a[aria-current]{background:var(--brand-suave);color:var(--brand-2)}
.foco-obra .acao-lista a.entregue{color:var(--muted)}
.foco-obra .acao-vazio{padding:8px 10px;font-size:12.5px;color:var(--faint)}
.foco-obra.mudo>summary{background:transparent;border-color:var(--barra-linha);color:var(--barra-muted)}
.foco-obra.mudo .ic{color:var(--barra-muted)}
.foco-obra.mudo>summary:hover{background:var(--barra-on)}
/* a barra do topo com o seletor (medido no Chrome sem janela, 26/09): a 1366 px
   sobra 36 px SEM o "by Lumiset" e a 1280 só cabe sem o nome da empresa (fica
   o avatar de iniciais; o nome inteiro segue no menu). Abaixo de ~1130 px a nav
   de 8 seções já não cabia antes do seletor — o ☰ entra em 992 (pré-existente).
   (27/09: 7 seções — o Cronograma virou aba de Obras. Medido de novo, logado,
   numa tela COM tutorial e com um nome de empresa comprido: as seções terminam
   em 729 px em qualquer largura acima de 992, e o seletor em 906; a 1366 os
   botões começam em 984 — 78 px de folga, onde a v0.50.0 passava 22 px POR
   BAIXO deles —; a 1440, 90 px.) (29/09: medido de novo com o nome da empresa
   no teto de 200 px e o tutorial: a 1400 px o seletor ficava a 3 px dos botões
   — e com o item "Plano" do diretor, 55 px POR BAIXO deles. O "by Lumiset" some
   até 1439 px, não mais até 1399: +62 px nessa faixa, para todo mundo. O resto
   do Plano na barra está no bloco O PLANO DO PRISMA, no fim.) (01/10: o SINO das
   novidades soma 34 px à barra da direita, para todo mundo — medido de novo no
   pior caso, .tmp/v058-sino/banca.py barra: os pontos de quebra abaixo mudaram.) */
@media(max-width:1439.98px){.marca .by{display:none}}
@media(max-width:1299.98px){
 .menu-conta .txt,.chip-empresa .txt{display:none}
 details.menu-conta>summary,.chip-empresa{padding:4px}
}
/* de 1280 a 1365 px o nome da empresa volta, e um nome comprido (teto de 200 px)
   passava 8 px por baixo do seletor a 1280 (seletor até 906, botões desde 898;
   na v0.50.0, com 8 seções, eram 108 px): nessa faixa o teto do nome é 120 px
   (medido a 1280: 25 px de folga com o seletor) — o nome inteiro segue no menu.
   O chip sem login ganha o mesmo teto. (29/09: com um nome de OBRA comprido o
   seletor chega ao teto dele, 130 px, e fica 20 px mais largo que o medido em
   27/09: a 1280 a folga caía a 5 px. O teto do nome nessa faixa passou a 104 px —
   folga de 21 px sem o item "Plano" e de 27 com ele.) (01/10, com o sino: a
   1280 o seletor passava 7 px por baixo dos botões e a 1366 — a largura mais
   comum dos notebooks —, com o nome no teto de 200 px, 17 px. Agora o nome só
   volta a 1300 px, com teto de 96 px até 1365 (a 1300: 21 px de folga); de 1366
   a 1479 o teto é 160 px (a 1366: 23 px; a 1440, onde o "by Lumiset" volta,
   35 px); de 1480 em diante, os 200 px de sempre (35 px).) */
.chip-empresa .nome{display:block;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(min-width:1300px) and (max-width:1365.98px){.menu-conta .nome,.chip-empresa .nome{max-width:96px}}
@media(min-width:1366px) and (max-width:1479.98px){.menu-conta .nome,.chip-empresa .nome{max-width:160px}}
/* entre 992 e 1160 px o seletor desce para logo ABAIXO da barra, pendurado no
   fim das seções, em vez de ficar por baixo dos botões da direita. Fundo da
   própria barra, para ler como uma aba dela. (26/09, com 8 seções: a 1024 a nav
   terminava em 830 e, logado com tutorial, os botões começavam em 808 — as
   seções passavam por baixo deles. 27/09, com 7: terminam em 729, e os botões
   começam em 776 a 992 px e em 923 a 1139 px; o seletor precisa de ~175 px e só
   caberia na barra a partir de ~1123 px — ele continua pendurado até 1140.
   29/09: com um nome de obra comprido o seletor tem 187 px e, a 1140, passava
   2 px POR BAIXO dos botões — pendurado até 1159 px; a 1160, 18 px de folga.
   01/10, com o sino: a 1160 ele passava 10 px por baixo dos botões e a 1180
   ficava a 10 px deles — pendurado até 1199 px; a 1200, 30 px de folga.) */
@media(min-width:992px) and (max-width:1199.98px){
 .nav-main .foco-obra{position:absolute;top:100%;right:0;margin:0;padding:0;z-index:56}
 .foco-obra>summary,.foco-obra.mudo>summary{border-radius:0 0 6px 6px;box-shadow:var(--sombra-alta);
  background:var(--sidebar);border-color:var(--barra-linha)}
}
/* o chip "obra em foco: X · ver todas" na linha de apoio do cabeçalho das telas que filtram */
.foco-chip{display:inline-flex;align-items:center;gap:4px;margin-left:8px;padding:1px 8px;border-radius:999px;
 background:var(--brand-suave);color:var(--brand-2);font-size:11.5px;white-space:nowrap;vertical-align:middle}
.foco-chip b{font-weight:600}
.foco-chip a{color:inherit}
/* "Escolha a obra" (cadastros sem foco): a lista das obras como links ?foco= */
.escolha-obra{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:6px}
.escolha-obra-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--line);
 border-radius:8px;text-decoration:none;color:var(--ink);
 transition:background-color var(--dur-rapida),border-color var(--dur-rapida)}
.escolha-obra-item:hover{background:var(--nav-on);border-color:var(--brand);color:var(--ink)}
.escolha-obra-item .txt{display:flex;flex-direction:column;min-width:0}
.escolha-obra-item .txt b{font-weight:600;font-size:13.5px}
.escolha-obra-item .sub{font-size:11.5px;color:var(--faint)}
.escolha-obra-item .chev{margin-left:auto;color:var(--faint);display:flex}
.escolha-obra-item.entregue{color:var(--muted)}
.nota-modelo{font-size:12.5px;color:var(--muted)}
.mudo{color:var(--faint)}
/* o aviso dos itens sem obra: o texto e a ação de copiar, lado a lado */
.modelo-aviso{display:flex;gap:14px;align-items:center;justify-content:space-between;flex-wrap:wrap}
.copiar-form{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.copiar-form .nota{font-size:11.5px;color:var(--faint)}
/* rodapé de tabela (previsto por cadastro, adicionar etapa, copiar de…) */
.tabela-pe{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
 padding:10px 14px;border-top:1px solid var(--fio);font-size:12.5px;color:var(--muted)}
.tabela-pe b{color:var(--ink)}
/* ficha › Insumos: as etapas (um formulário por linha) e os insumos agrupados por etapa */
.etapas-tab td .form-control-sm{min-width:150px}
.etapas-tab td.n .form-control-sm{max-width:150px;margin-left:auto;text-align:right}
.etapa-add{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.etapa-add .form-control-sm{width:auto;min-width:200px}
.etapas-soltas{display:flex;gap:6px;align-items:center;flex-wrap:wrap;padding:10px 14px;
 border-top:1px solid var(--fio);font-size:12.5px;color:var(--muted)}
.ins-tab tr.ins-grupo td{background:var(--nav-on);padding-top:8px;padding-bottom:8px;font-size:12.5px}
.ins-tab tr.ins-grupo .sub{color:var(--faint);font-weight:400}
@media(max-width:991.98px){
 .nav-main .foco-obra{margin:2px 0 6px;padding:0 0 6px;order:-1;display:block;border-bottom:1px solid var(--barra-linha)}
 .foco-obra>summary{width:100%;min-height:42px;padding:6px 12px;font-size:14px}
 .foco-obra .rot{max-width:none}
 .foco-obra .chev{margin-left:auto}
 .foco-obra .acao-lista{position:static;min-width:0;max-height:none;background:transparent;border:0;box-shadow:none;
  padding:4px 4px 0}
 .foco-obra .acao-lista a{color:var(--barra-ink);white-space:normal}
 .foco-obra .acao-lista a:hover{background:var(--barra-on);color:var(--barra-ink)}
 .foco-obra .acao-lista a[aria-current]{background:var(--barra-on);color:var(--barra-ink-sel);
  box-shadow:inset var(--sel-traco) 0 0 var(--selecao)}
 .foco-obra .acao-lista a.entregue,.foco-obra .acao-lista .sub,.foco-obra .acao-vazio{color:var(--barra-muted)}
 .foco-obra .acao-vazio a{color:var(--barra-ink)}
 .escolha-obra{grid-template-columns:1fr}
}

/* rodapé: o produto assina, com a versão */
.rodape{display:flex;gap:18px;align-items:center;flex-wrap:wrap;padding-top:8px;margin-top:auto;
 font-size:11.5px;color:var(--faint);border-top:1px solid var(--line)}
.rodape>span{display:inline-flex;align-items:center;gap:6px}
.foot-marca{font-size:12px;font-weight:500;color:var(--muted);letter-spacing:.01em}
.foot-marca svg{color:var(--cliente,var(--brand))}
.foot-marca .by{font-weight:400;color:var(--faint)}

/* --------------------------------- cards --------------------------------- */
.card{--bs-card-bg:var(--panel);--bs-card-border-color:var(--line);--bs-card-spacer-y:14px;--bs-card-spacer-x:16px;
 --bs-card-color:var(--ink);--bs-card-border-radius:8px;box-shadow:var(--sombra)}
.card-title{font-weight:600;font-size:14px;letter-spacing:-.005em;color:var(--ink);margin-bottom:4px}
.card-title.h5{font-size:14px}
.card-t{font-size:14px;font-weight:600;color:var(--ink)}
.card-h{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}
.card-h .st{font-size:12px;white-space:nowrap}
.card-sub{font-size:12px;color:var(--faint)}

/* --------------------------------- botões -------------------------------- */
/* UMA cor de acento: o botão principal é sólido; o resto é contornado */
.btn{--bs-btn-border-radius:6px;--bs-btn-font-size:13px;font-weight:500;--bs-btn-padding-y:.36rem;--bs-btn-padding-x:.75rem;
 white-space:nowrap;--bs-btn-focus-box-shadow:0 0 0 3px var(--anel);
 transition:background-color var(--dur-rapida),border-color var(--dur-rapida),color var(--dur-rapida),
  box-shadow var(--dur-rapida),transform var(--dur-rapida),filter var(--dur-rapida)}
/* resposta ao toque: sobe 1px no hover, encolhe ao pressionar, anel no foco */
.btn:hover{transform:translateY(-1px);box-shadow:var(--sombra)}
.btn:active,.btn.active:active{transform:scale(.97);box-shadow:none}
.btn-sm{--bs-btn-font-size:12.5px;--bs-btn-padding-y:.26rem;--bs-btn-padding-x:.6rem}
.btn-primary{--bs-btn-bg:var(--brand-solido);--bs-btn-border-color:var(--brand-borda);--bs-btn-color:var(--sobre-solido);
 --bs-btn-hover-bg:var(--brand-solido);--bs-btn-hover-border-color:var(--brand-solido);--bs-btn-hover-color:var(--sobre-solido);
 --bs-btn-active-bg:var(--brand-solido);--bs-btn-active-border-color:var(--brand-solido);--bs-btn-active-color:var(--sobre-solido);
 --bs-btn-disabled-bg:var(--panel-2);--bs-btn-disabled-border-color:var(--panel-2);--bs-btn-disabled-color:var(--desab)}
.btn-primary:hover{filter:brightness(1.1)}
.btn-outline-primary{--bs-btn-color:var(--brand-2);--bs-btn-border-color:var(--brand);--bs-btn-bg:var(--panel);
 --bs-btn-hover-bg:var(--brand-suave);--bs-btn-hover-color:var(--brand-2);--bs-btn-hover-border-color:var(--brand);
 --bs-btn-active-bg:var(--brand-suave);--bs-btn-active-border-color:var(--brand-2);--bs-btn-active-color:var(--ink)}
.btn-outline-secondary{--bs-btn-color:var(--ink);--bs-btn-border-color:var(--line);--bs-btn-bg:var(--panel);
 --bs-btn-hover-bg:var(--panel-2);--bs-btn-hover-color:var(--ink);--bs-btn-hover-border-color:var(--faint);
 --bs-btn-active-bg:var(--panel-2);--bs-btn-active-border-color:var(--faint);--bs-btn-active-color:var(--ink)}
.btn-outline-danger{--bs-btn-color:var(--crit);--bs-btn-border-color:var(--line);--bs-btn-bg:var(--panel);
 --bs-btn-hover-bg:var(--crit-suave);--bs-btn-hover-color:var(--crit);--bs-btn-hover-border-color:var(--crit);
 --bs-btn-active-bg:var(--crit-suave);--bs-btn-active-border-color:var(--crit);--bs-btn-active-color:var(--crit)}
/* os sólidos semânticos do Bootstrap também lêem o tema (nada de vermelho literal) */
.btn-danger{--bs-btn-bg:var(--crit-solido);--bs-btn-border-color:var(--crit-solido);--bs-btn-color:var(--sobre-solido);
 --bs-btn-hover-bg:var(--crit);--bs-btn-hover-border-color:var(--crit);--bs-btn-hover-color:var(--sobre-solido);
 --bs-btn-active-bg:var(--crit);--bs-btn-active-border-color:var(--crit);--bs-btn-active-color:var(--sobre-solido)}
.btn-success{--bs-btn-bg:var(--ok-solido);--bs-btn-border-color:var(--ok-solido);--bs-btn-color:var(--sobre-solido);
 --bs-btn-hover-bg:var(--ok);--bs-btn-hover-border-color:var(--ok);--bs-btn-hover-color:var(--sobre-solido);
 --bs-btn-active-bg:var(--ok);--bs-btn-active-border-color:var(--ok);--bs-btn-active-color:var(--sobre-solido)}
.btn-warning{--bs-btn-bg:var(--warn-suave);--bs-btn-border-color:var(--warn);--bs-btn-color:var(--warn-texto);
 --bs-btn-hover-bg:var(--warn-suave);--bs-btn-hover-border-color:var(--warn);--bs-btn-hover-color:var(--warn-texto);
 --bs-btn-active-bg:var(--warn-suave);--bs-btn-active-border-color:var(--warn);--bs-btn-active-color:var(--warn-texto)}
.btn-group>.btn{--bs-btn-padding-x:.65rem}
.btn-mini{font:inherit;font-size:12.5px;padding:4px 10px;border-radius:6px;border:1px solid var(--line);
 background:var(--panel);color:var(--ink);cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;gap:6px;
 transition:border-color var(--dur-rapida),background-color var(--dur-rapida),transform var(--dur-rapida)}
.btn-mini:hover{border-color:var(--faint);color:var(--ink)}
.btn-mini:active{transform:scale(.97)}
.link-suave{font-size:13px;color:var(--brand-2);text-decoration:none}
.link-suave:hover{text-decoration:underline}
/* ESTADO "ENVIANDO" (JS da casca): o botão que disparou o POST trava, ganha
   o spinner e diz "Enviando…" — evita o envio duplo e responde ao clique.
   O giro é o único loop além do fundo do login e do pulso do crítico, e só
   vive enquanto a resposta não chega. */
.enviando{position:relative;pointer-events:none;opacity:.8;cursor:progress}
.enviando::before{content:"";width:12px;height:12px;border-radius:50%;border:2px solid currentColor;
 border-right-color:transparent;display:inline-block;vertical-align:-2px;margin-right:7px;animation:girar .7s linear infinite}
@keyframes girar{to{transform:rotate(360deg)}}

/* ------------------------------- formulários ------------------------------ */
/* compactos e alinhados: rótulo pequeno em cima, campo de 36px */
.form-label{display:block;font-size:12px;color:var(--muted);font-weight:500;margin-bottom:4px;
 white-space:nowrap;line-height:16px;min-height:16px}
.form-control,.form-select{min-height:36px;height:auto;padding:.3rem .6rem;background-color:var(--sup);border-color:var(--line);
 border-radius:6px;color:var(--ink);font-size:13.5px;
 transition:border-color var(--dur-rapida),box-shadow var(--dur-rapida),background-color var(--dur-rapida)}
/* campo inválido treme uma vez (JS marca .invalido no evento `invalid`);
   a máscara de dinheiro, ao inserir um ponto de milhar, dá um realce curto */
@keyframes tremer{10%,90%{transform:translateX(-1px)}20%,80%{transform:translateX(2px)}
 30%,50%,70%{transform:translateX(-3px)}40%,60%{transform:translateX(3px)}}
.invalido{animation:tremer var(--dur-lenta) var(--curva-saida)}
@keyframes realce{from{box-shadow:0 0 0 4px var(--anel)}}
.dinheiro.realce{animation:realce var(--dur-media) var(--curva-entrada)}
.form-control-sm,.form-select-sm{min-height:30px;font-size:12.5px;padding:.2rem .5rem}
/* O EXEMPLO dentro do campo usa --desab (24/09): no escuro grafite o --faint ficou
   quase branco (#cdd0d5) e o exemplo lia como valor já digitado — o branco do valor
   era só 1,5 vez mais claro. Com --desab: 6,9:1 sobre o campo e 2,5 vezes abaixo do
   valor. No claro --desab é o próprio --faint, então lá nada muda. */
.form-control::placeholder{color:var(--desab)}
input[type=file].form-control{min-height:36px;padding-top:5px}
.form-control:focus,.form-select:focus{background-color:var(--sup);border-color:var(--brand);
 box-shadow:0 0 0 3px var(--brand-suave);color:var(--ink)}
.form-text{font-size:11.5px;color:var(--faint);min-height:14px;line-height:1.35}
input[type=number].form-control{font-variant-numeric:tabular-nums;text-align:right}
form .row .btn{min-height:36px}
.row.g-3{--bs-gutter-x:.9rem;--bs-gutter-y:.7rem}
.navsec-form{color:var(--faint);font-size:11px;letter-spacing:.06em;text-transform:uppercase;
 border-bottom:1px solid var(--line);padding-bottom:5px;margin-top:4px}
/* filtros compactos em linha ("Régua: Vencimento ▾ · de … até …") */
.filtros{display:flex;flex-wrap:wrap;gap:6px 12px;align-items:center;margin:0}
.filtro{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted);margin:0}
.filtro>span{white-space:nowrap}
.filtro .form-select,.filtro .form-control{width:auto;min-height:30px;font-size:12.5px;padding:.2rem 1.6rem .2rem .5rem}
.filtro .form-control{padding-right:.5rem}
.filtros .nota{font-size:12px;color:var(--faint);margin-left:auto}
.filtros .btn-group .btn{--bs-btn-font-size:12.5px;--bs-btn-padding-y:.22rem;--bs-btn-padding-x:.55rem}

/* --------------------------------- alertas -------------------------------- */
/* borda na cor do estado + tinta do estado; texto na cor da tela (legível nos dois temas) */
.alert{border-radius:6px;font-size:13px;border-width:1px;color:var(--ink);padding:9px 12px;margin-bottom:0}
.alert b,.alert strong{font-weight:600}
.alert-warning{--bs-alert-bg:var(--warn-suave);--bs-alert-border-color:var(--warn);--bs-alert-color:var(--ink)}
.alert-danger{--bs-alert-bg:var(--crit-suave);--bs-alert-border-color:var(--crit);--bs-alert-color:var(--ink)}
.alert-success{--bs-alert-bg:var(--ok-suave);--bs-alert-border-color:var(--ok);--bs-alert-color:var(--ink)}
.alert-info{--bs-alert-bg:var(--brand-suave);--bs-alert-border-color:var(--brand);--bs-alert-color:var(--ink)}
/* AVISO DE RETORNO de um POST (`?ok=`, classe .flash): desce com fade, uma
   barra fina de tempo corre embaixo e, dentro da casca, o JS recolhe o aviso
   (altura via grid-template-rows 1fr→0fr — o único jeito de animar "auto")
   quando a barra acaba. Erros não têm barra nem somem: precisam ser lidos. */
.flash-wrap{display:grid;grid-template-rows:1fr;
 transition:grid-template-rows var(--dur-media) var(--curva-entrada),opacity var(--dur-media) var(--curva-entrada)}
.flash-wrap>.alert{min-height:0;overflow:hidden}
.flash-wrap.sumindo{grid-template-rows:0fr;opacity:0}
@keyframes flash-entrar{from{opacity:0;transform:translateY(-8px)}}
.alert.flash{position:relative;animation:flash-entrar var(--dur-lenta) var(--curva-saida) backwards}
@keyframes tempo{to{transform:scaleX(0)}}
.content-col .alert.flash::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
 background:var(--bs-alert-border-color);opacity:.6;transform-origin:left;animation:tempo 6s linear forwards}

/* --------------------------------- tabelas -------------------------------- */
/* densas: cabeçalho pequeno em caixa alta, linhas de ~40px, números à direita */
.table{--bs-table-bg:transparent;--bs-table-color:var(--ink);
 --bs-table-hover-bg:var(--nav-on);--bs-table-hover-color:var(--ink);
 --bs-table-border-color:var(--line);font-size:13px;color:var(--ink);font-variant-numeric:tabular-nums;margin-bottom:0}
.table>:not(caption)>*>*{padding:8px 10px;color:inherit;
 transition:background-color var(--dur-rapida),box-shadow var(--dur-rapida)}
.table thead th{font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);
 font-weight:500;border-bottom:1px solid var(--line);padding:7px 10px;white-space:nowrap;vertical-align:bottom}
.table tbody tr:last-child>*{border-bottom:0}
td.n,th.n{text-align:right}
.table .principal{font-weight:500}
.table .principal a{color:var(--ink);text-decoration:none}
.table .principal a:hover{color:var(--brand-2);text-decoration:underline}
.td-sub,.table .small{font-size:12px;color:var(--faint);font-weight:400}
/* linha clicável: cursor, hover e um chevron na ponta que avança no hover —
   a afordância de "esta linha abre alguma coisa" (queixa de 12/09) */
.linha-clic{cursor:pointer}
td.chev{width:30px;padding-left:0!important;color:var(--faint)}
td.chev svg{transition:transform var(--dur-rapida),color var(--dur-rapida);display:block;margin-left:auto}
/* (06/10) o chevron virou <button> — o alvo do leitor de tela ("Ver o resumo de …",
   abre diálogo); o desenho é o mesmo: sem fundo, sem borda, a cor da célula */
.linha-abrir{display:block;margin-left:auto;padding:0;border:0;background:none;color:inherit;cursor:pointer}
.linha-clic:hover td.chev svg{transform:translateX(3px);color:var(--brand-2)}
.linha-clic:hover .cel-obra .nome{color:var(--brand-2)}
.tabela-rolavel{overflow-x:auto}
.tabela-rolavel table{min-width:100%}
/* a caixa da tabela: superfície branca com cabeçalho (título · contagem · ações) */
.tabela-box{background:var(--panel);border:1px solid var(--line);border-radius:8px;box-shadow:var(--sombra)}
.tabela-head{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.tabela-head .t{font-size:14px;font-weight:600;color:var(--ink)}
.tabela-head .n{font-size:12.5px;color:var(--faint);font-weight:400}
.tabela-head .dir{margin-left:auto;display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.tabela-head .sub{font-size:12px;color:var(--faint);width:100%;margin-top:-4px}
.tabela-box .vazio{padding:32px 20px}
.tabela-box>.table,.tabela-box .tabela-rolavel>.table{border-bottom-left-radius:8px;border-bottom-right-radius:8px}
/* célula "obra": avatar de iniciais + nome + linha de apoio */
.cel-obra{display:flex;align-items:center;gap:10px;min-width:0}
.cel-obra .txt{min-width:0}
.cel-obra .nome{font-weight:500;color:var(--ink);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}
.cel-obra .nome:hover{color:var(--brand-2);text-decoration:underline}
/* barra fina de progresso na linha */
.barra{display:inline-flex;align-items:center;gap:8px;justify-content:flex-end}
.barra .trilho{width:64px;height:4px;border-radius:2px;background:var(--panel-2);position:relative;overflow:hidden;flex:none}
.barra .fill{position:absolute;inset:0 auto 0 0;border-radius:2px;background:var(--brand)}
/* barras preenchendo ao entrar (scaleX a partir da esquerda: não mexe no layout) */
@keyframes encher{from{transform:scaleX(0)}}
.barra .fill,.rb-trilho>i,.bala i,.rel-pilha i{transform-origin:left;animation:encher var(--dur-lenta) var(--curva-saida) 160ms backwards}
.barra .fill.custo{background:var(--cost)}
.barra .v{min-width:44px;text-align:right}

/* ----------------------------------- KPIs --------------------------------- */
/* faixa de indicadores: um bloco só, dividido por linhas; número + variação */
.kpis{display:flex;flex-wrap:wrap;background:var(--panel);border:1px solid var(--line);border-radius:8px;box-shadow:var(--sombra)}
.kpi-item{flex:1 1 150px;padding:11px 16px 10px;border-right:1px solid var(--line);min-width:0;
 animation:entrar var(--dur-lenta) var(--curva-saida) backwards}
.kpi-item:nth-child(2){animation-delay:40ms}.kpi-item:nth-child(3){animation-delay:80ms}
.kpi-item:nth-child(4){animation-delay:120ms}.kpi-item:nth-child(5){animation-delay:160ms}
.kpi-item:nth-child(n+6){animation-delay:200ms}
.kpi-item:last-child{border-right:0}
.kpi-item .lab{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kpi-item .val{font-size:22px;font-weight:600;letter-spacing:-.015em;line-height:1.2;color:var(--ink);margin-top:1px;white-space:nowrap}
.kpi-item .val small{font-size:13px;font-weight:500;color:var(--faint);margin-left:2px}
.delta{font-size:12px;color:var(--faint);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.delta.bom{color:var(--ok)}.delta.ruim{color:var(--crit)}
.v-crit{color:var(--crit)!important}.v-warn{color:var(--warn)!important}
.v-ok{color:var(--ok)!important}.v-brand{color:var(--brand-2)!important}

/* os "badge text-bg-*" do Bootstrap (usados pela importação livre) lêem o tema
   em vez das cores literais do Bootstrap — mesma família dos chips de estado */
.badge{font-weight:500;border-radius:6px;padding:3px 8px;font-size:11.5px}
.badge.text-bg-primary{background:var(--brand-solido)!important;color:var(--sobre-solido)!important}
.badge.text-bg-success{background:var(--ok-suave)!important;color:var(--ok-texto)!important}
.badge.text-bg-danger{background:var(--crit-suave)!important;color:var(--crit-texto)!important}
.badge.text-bg-warning{background:var(--warn-suave)!important;color:var(--warn-texto)!important}
.badge.text-bg-secondary,.badge.text-bg-light{background:var(--panel-2)!important;color:var(--muted)!important}
.table-sm>:not(caption)>*>*{padding:5px 8px}

/* ----------------------------- estados / chips ---------------------------- */
/* status = pontinho + texto, sem caixa (é o que as referências fazem) */
.estado{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:500;
 white-space:nowrap;text-transform:none;letter-spacing:0;line-height:1.3}
.estado::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
/* só o ponto do CRÍTICO pulsa: um anel que se abre e some a cada 2 s */
@keyframes pulso{0%{box-shadow:0 0 0 0 var(--crit)}70%,100%{box-shadow:0 0 0 6px transparent}}
.estado.b-crit::before{animation:pulso 2s var(--curva-saida) infinite}
.b-crit{color:var(--crit)}
.b-warn{color:var(--warn)}
.b-ok{color:var(--ok)}
.b-novo{color:var(--muted)}
.estado .sub{font-weight:400;color:var(--faint);font-size:11.5px}

/* ------------------------- análise / faixa / memória ----------------------- */
.dcols{display:grid;grid-template-columns:1.5fr 1fr;gap:16px;align-items:start}
.legend{display:flex;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--muted);margin-top:8px}
.legend i{width:14px;height:2px;display:inline-block;vertical-align:middle;margin-right:6px}
.band{background:var(--ground);border:1px solid var(--line);border-radius:6px;padding:12px 14px;margin-bottom:12px}
.bandval{font-size:24px;font-weight:500;letter-spacing:-.01em;line-height:1.1}
.bandsub{font-size:12.5px;color:var(--muted);margin-top:5px;line-height:1.5}
.src{font-size:12px;color:var(--faint);margin-top:10px;line-height:1.5}
.fact{display:flex;justify-content:space-between;gap:12px;padding:6px 0;
 border-bottom:1px solid var(--line);font-size:13px}
.fact:last-child{border-bottom:none}.fact .k{color:var(--muted)}
.fact .v{font-weight:500;text-align:right}

/* a FAIXA: piso · mais provável · teto, sempre nesta ordem — compacta */
.faixa{background:var(--ground);border:1px solid var(--line);border-radius:6px;padding:12px 14px;margin-bottom:12px}
.faixa-lab{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);margin-bottom:6px}
.faixa-grid{display:grid;grid-template-columns:1fr auto 1fr;align-items:end;gap:14px;font-variant-numeric:tabular-nums}
.faixa-grid .k{font-size:11px;color:var(--faint)}
.faixa-piso .v,.faixa-teto .v{font-size:17px;color:var(--muted)}
.faixa-teto{text-align:right}
.faixa-mid{text-align:center}
.faixa-mid .v{font-size:26px;line-height:1.05;font-weight:600}
.faixa-mid .sub{font-size:12px;color:var(--muted);margin-top:2px}
.faixa-bar{position:relative;height:5px;border-radius:3px;background:var(--panel-2);margin:10px 0 7px}
.faixa-span{position:absolute;top:0;bottom:0;border-radius:3px;opacity:.3}
.faixa-mark{position:absolute;top:-3px;width:2px;height:11px}
.faixa-base{font-size:12px;color:var(--faint);line-height:1.5}
/* sem faixa: caixa tracejada, honesta */
.faixa-vazia{border:1px dashed var(--line);border-radius:6px;padding:12px 14px;margin-bottom:12px;color:var(--muted);font-size:12.5px;line-height:1.5}
.faixa-vazia .t{font-size:14px;font-weight:600;color:var(--ink);margin-bottom:3px}
.faixa-vazia .faixa-lab{margin-bottom:5px}

/* ------------------------------ estado vazio ------------------------------ */
.vazio{text-align:center;padding:44px 20px;color:var(--muted)}
.vazio .ic{font-size:26px;margin-bottom:10px;color:var(--brand)}
.vazio h3{font-weight:600;font-size:17px;letter-spacing:-.01em;color:var(--ink);margin-bottom:6px}
.vazio p{margin:0 0 16px;font-size:13px}

/* ------------------------ financeiro: lançamentos -------------------------- */
.fin-tots{display:flex;flex-wrap:wrap;gap:8px 26px;justify-content:flex-end;
 border-top:1px solid var(--line);padding:12px 14px}
.fin-t .lab{font-size:11.5px;color:var(--faint)}
.fin-t .val{font-size:14px;font-weight:600;letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.fin-saldo td{background:var(--ground)!important}

/* -------------------- relatórios: analítico (modo livre) ------------------- */
.col-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:6px 14px}
.col-chk{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink);cursor:pointer;user-select:none}
.col-chk input{accent-color:var(--brand)}

/* ---------------------- conciliação bancária (OFX) ------------------------- */
.ofx-linha{display:flex;gap:14px;align-items:center;justify-content:space-between;flex-wrap:wrap;
 border-bottom:1px solid var(--line);padding:10px 14px}
.ofx-linha:last-child{border-bottom:0}
.ofx-linha:hover{background:var(--nav-on)}
.ofx-info{min-width:240px;flex:1}
.ofx-acoes{display:flex;gap:6px;align-items:center;flex-wrap:wrap}

/* ---------------------- orçamentos: cards de entrada ----------------------- */
.entrada-card{transition:border-color var(--dur-rapida),box-shadow var(--dur-rapida);border-radius:8px}
.entrada-card:hover{border-color:var(--brand);box-shadow:var(--sombra-alta)}
.ic-quad{width:36px;height:36px;flex:none;border-radius:6px;background:var(--brand-suave);
 display:grid;place-items:center;font-size:16px;color:var(--brand-2)}

/* --------------------------- tarefas (kanban) ------------------------------ */
.kb-board{display:flex;gap:14px;align-items:flex-start;overflow-x:auto;padding-bottom:10px}
.kb-col{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:12px;width:272px;flex:none;box-shadow:var(--sombra)}
.kb-col.kb-over{outline:2px dashed var(--brand);outline-offset:2px}
.kb-col.kb-nova{background:transparent;border-style:dashed;box-shadow:none}
.kb-head{display:flex;align-items:center;justify-content:space-between;gap:8px;font-weight:600;font-size:13.5px;color:var(--ink);padding:2px 2px 10px}
.kb-n{display:inline-block;background:var(--panel-2);color:var(--muted);border-radius:6px;font-size:11px;padding:1px 7px;margin-left:7px;vertical-align:1px;font-variant-numeric:tabular-nums}
.kb-add summary{list-style:none;cursor:pointer;color:var(--muted);font-size:12.5px;border:1px dashed var(--line);border-radius:6px;padding:7px 10px;user-select:none}
.kb-add summary::-webkit-details-marker{display:none}
.kb-add summary:hover{background:var(--nav-on);color:var(--brand-2);border-color:var(--brand)}
.kb-lista{display:flex;flex-direction:column;gap:8px;margin-top:10px;min-height:34px}
.kb-card{background:var(--ground);border:1px solid var(--line);border-radius:6px;padding:10px 12px;cursor:grab}
.kb-card:hover{box-shadow:var(--sombra-alta)}
.kb-card:active{cursor:grabbing}
.kb-titulo{font-size:13px;color:var(--ink);line-height:1.4;overflow-wrap:anywhere}
.kb-acoes{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:8px}
.kb-mover{border:none;background:transparent;color:var(--faint);font-size:11.5px;cursor:pointer;padding:0;max-width:120px}
.kb-mover:hover{color:var(--brand-2)}
.kb-x{border:none;background:transparent;color:var(--faint);cursor:pointer;font-size:12px;line-height:1;padding:3px 5px;border-radius:6px}
.kb-x:hover{color:var(--crit);background:var(--crit-suave)}
.kb-vazio{text-align:center;color:var(--faint);font-size:12px;padding:16px 6px}

/* =============================== GRÁFICOS ================================
   Eixo Y em HTML (fora do SVG, para não esticar), SVG sem proporção fixa e
   `vector-effect` para a linha manter a espessura. Área preenchida no que
   foi executado, tracejado na projeção, linha vertical na última medição
   (o "hoje" do dado) — como no gráfico de referência.
   ========================================================================= */
.graf{position:relative;margin-top:8px;padding:0 0 18px 36px}
.graf-y{position:absolute;left:0;top:0;bottom:18px;width:30px;font-size:11px;color:var(--faint);
 font-variant-numeric:tabular-nums;text-align:right}
.graf-y span{position:absolute;right:0;transform:translateY(-50%)}
.graf svg{display:block;width:100%;height:240px;overflow:hidden}  /* fora do viewBox não pinta por cima da página (13/09) */
.graf-carteira svg{height:220px}
.graf-x{position:absolute;left:36px;right:0;bottom:0;height:16px;font-size:11px;color:var(--faint);font-variant-numeric:tabular-nums}
.graf-x span{position:absolute;white-space:nowrap}
.graf-x .hoje{color:var(--ink);font-weight:600}
/* (06/10) com o eixo em 11 px (o piso), um rótulo de mês ocupa ~28 px; na FICHA, dois
   meses vizinhos do medido ficam a 1/19 do eixo — no computador de 992 a 1.099 px a
   coluna do gráfico encolhe a ~470–580 px e "06/26" encostava em "07/26" (e o 1º
   mês, alinhado à esquerda, no 2º). A regra olha a largura do PRÓPRIO gráfico
   (container query), não a da tela: abaixo de 600 px ficam o primeiro mês, a
   última medição e a borda — a mesma escolha do celular (lá embaixo, no bloco de
   700 px). O mês de cada ponto segue no cartão. */
.graf-ficha{container:graf-ficha/inline-size}
@container graf-ficha (max-width:599.98px){
 .graf-ficha .graf-x span:not(:first-child):not(:last-child):not(.hoje){display:none}
}
.graf-tag{position:absolute;font-size:11px;font-variant-numeric:tabular-nums;white-space:nowrap;line-height:1.2}
/* A ÁREA DE DESENHO (14/09): o SVG e tudo o que se posiciona sobre ele em %
   — rótulos, bolinhas, linha-guia e cartão — ficam numa caixa do tamanho
   exato do SVG. Antes o ponto da última medição usava o .graf inteiro (SVG +
   a faixa do eixo do tempo embaixo) como 100% da altura e caía até 14px
   abaixo da linha. */
.graf-plot{position:relative}
.graf-plot:focus-visible{outline-offset:4px;border-radius:2px}
/* AS LINHAS: espessura por token (14/09, "um pouco mais fina"). A física é a
   principal; o custo e a projeção do custo, secundários. */
.graf-linha,.graf-proj path{stroke-width:var(--graf-traco)}
.graf-linha.custo,.graf-proj path.custo{stroke-width:var(--graf-traco-sec)}
.graf-gap{opacity:var(--graf-gap)}
/* as linhas se DESENHAM da esquerda para a direita (pathLength="1" no <path>
   deixa o traço valer 1 unidade, qualquer que seja o comprimento; o
   dashoffset vai de 1 a 0). A área, a projeção, as bolinhas e os rótulos
   aparecem depois. O estado "escondido" vive só dentro dos keyframes: sem
   animação (navegador antigo, menos movimento) a linha está lá desde o
   início. */
@keyframes desenhar{from{stroke-dasharray:1;stroke-dashoffset:1}to{stroke-dasharray:1;stroke-dashoffset:0}}
@keyframes surgir{from{opacity:0}}
.graf-linha{animation:desenhar var(--dur-lenta) var(--curva-saida) 80ms backwards}
.graf-area,.graf-proj,.graf-tag{animation:surgir var(--dur-media) var(--curva-saida) 400ms backwards}
/* AS BOLINHAS (14/09): uma em cada ponto medido, na cor da linha, com um anel
   da cor do card que as separa da linha e da área. Entram DEPOIS de a linha
   terminar de se desenhar (80 ms + --dur-lenta = 440 ms). Não capturam o
   ponteiro: quem responde é a área de desenho (o cartão do mês).
   A PONTA DA PROJEÇÃO (14/09, tarde — "na ponta do gráfico não dá pra ver
   porque fica em cima da linha"): os rótulos "custo 113% em ago/28" saíram.
   No fim de cada reta tracejada — na borda, quando a janela corta, ou no
   término, quando cabe — fica uma bolinha APAGADA, vazada e tracejada, que
   acende quando é lida (mouse, toque ou a última parada das setas) e abre o
   cartão "Projeção (mais provável)". Projeção nunca se parece com medição. */
@keyframes pt-entrar{from{opacity:0;transform:scale(.3)}}
/* 26/09 ("as bolinhas por mês serem menores", referência de linha fina do
   Samuel): 7px → 5px. Só a bolinha LIDA cresce (1,6×) e ganha um anel na
   própria cor a 28% — o halo da referência; color-mix mantém a regra de cor só
   por token (o anel nasce do --pt do ponto, não de um hex novo). */
.graf-pt{position:absolute;width:5px;height:5px;margin:-2.5px 0 0 -2.5px;border-radius:50%;background:var(--pt);
 box-shadow:0 0 0 1.5px var(--panel);pointer-events:none;
 transition:transform var(--dur-rapida) var(--curva-saida),opacity var(--dur-rapida),box-shadow var(--dur-rapida);
 animation:pt-entrar var(--dur-media) var(--curva-saida) 460ms backwards}
.graf-pt.fis{--pt:var(--brand)}
.graf-pt.custo{--pt:var(--cost)}
.graf-pt.crit{--pt:var(--crit)}
/* (2px de borda: com 1,5px o Chrome arredonda para 1px e o tracejado some num círculo pequeno;
   8px é o menor círculo em que o tracejado de 2px ainda se lê — medido no retrato de 26/09) */
.graf-pt.proj{width:8px;height:8px;margin:-4px 0 0 -4px;background:var(--panel);border:2px dashed var(--pt);
 box-shadow:none;opacity:.55;animation-delay:400ms}
.graf-pt.on{transform:scale(1.6);box-shadow:0 0 0 1.5px var(--panel),0 0 0 4px color-mix(in srgb,var(--pt) 28%,transparent)}
.graf-pt.proj.on{opacity:1;box-shadow:0 0 0 3px color-mix(in srgb,var(--pt) 28%,transparent)}
/* A LINHA DA ÚLTIMA MEDIÇÃO (14/09, tarde): clara e fina, sem texto por cima
   — separa o medido da projeção. O mês dela vai em negrito no eixo
   (.graf-x .hoje) e a legenda do card diz "medido | projeção". */
.graf-hoje{stroke:var(--ink);stroke-width:1px;stroke-opacity:.24}
/* A LINHA-GUIA E O CARTÃO DO MÊS (JS da casca, _grafDica): passar o mouse,
   tocar ou chegar pelo teclado acende a coluna do ponto mais próximo. O
   cartão é escuro nos DOIS temas (o noturno da barra), por isso as amostras
   e o risco lá dentro usam os tokens --barra-* (as cores do gráfico somem
   sobre o noturno). Escondido é display:none — visibility:hidden ainda
   contaria na largura rolável. Só transform e opacity transicionam. */
.graf-guia{position:absolute;left:0;top:0;bottom:0;width:1px;margin-left:-.5px;background:var(--ink);opacity:0;
 pointer-events:none;transition:opacity var(--dur-rapida),transform var(--dur-rapida) var(--curva-saida)}
.graf-guia.on{opacity:.32}
.graf-tip{position:absolute;left:0;top:0;z-index:6;min-width:150px;max-width:260px;padding:8px 11px 7px;border-radius:8px;
 background:var(--sidebar);color:var(--barra-ink);box-shadow:var(--sombra-alta);font-size:12px;line-height:1.45;
 pointer-events:none;transition:transform var(--dur-rapida) var(--curva-saida);
 animation:surgir var(--dur-rapida) var(--curva-saida)}
.graf-tip[hidden]{display:none}
.graf-tip b{display:block;font-weight:600;margin-bottom:3px}
.graf-tip .r{display:flex;justify-content:space-between;align-items:baseline;gap:16px}
.graf-tip .l{color:var(--barra-muted);white-space:nowrap}
.graf-tip .v{font-variant-numeric:tabular-nums;font-weight:500;white-space:nowrap}
.graf-tip .v.crit{color:var(--barra-crit)}
.graf-tip .sw{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:7px;vertical-align:1px;
 background:var(--sw,transparent)}
.graf-tip .sw.fis{--sw:var(--barra-acento)}
.graf-tip .sw.custo{--sw:var(--barra-muted)}
.graf-tip .sw.crit{--sw:var(--barra-crit)}
.graf-tip.proj .sw{background:transparent;box-shadow:inset 0 0 0 1.5px var(--sw,transparent)}
/* no cartão, a NOTA da ponta ("o término fica além da janela do gráfico") e a
   LISTA DO MÊS (14/09, tarde): momentos-chave (anel) e ocorrências (losango),
   em português do dia a dia. Sobre o noturno do cartão as cores do gráfico
   somem: o anel usa --barra-crit (risco) ou --barra-ink, e o losango leva a
   cor da causa com um contorno claro. Anel da projeção: tracejado. */
.graf-tip .nt{display:block;margin-top:3px;color:var(--barra-muted);font-size:11.5px;line-height:1.4}
.graf-tip .evs{display:block;margin-top:6px;padding-top:6px;border-top:1px solid var(--barra-linha)}
.graf-tip b+.evs{margin-top:0;padding-top:0;border-top:0}
.graf-tip .ev{display:flex;align-items:flex-start;gap:7px;line-height:1.4}
.graf-tip .ev+.ev{margin-top:5px}
.graf-tip .ev i{flex:none;width:9px;height:9px;margin-top:4px;border-radius:50%;border:2px solid var(--barra-ink)}
.graf-tip .ev.crit i{border-color:var(--barra-crit)}
.graf-tip .ev.proj i{border-style:dashed}
.graf-tip .ev.oc i{width:7px;height:7px;margin:5px 1px 0;border:0;border-radius:1px;transform:rotate(45deg);
 background:var(--c,var(--barra-ink));box-shadow:0 0 0 1.5px var(--barra-ink)}
.graf-tip .ev em{display:block;font-style:normal;font-size:11.5px;color:var(--barra-muted)}
.graf-nota{font-size:12px;color:var(--faint);margin-top:8px;line-height:1.5}
.legend-inline{display:flex;gap:14px;font-size:12px;color:var(--muted);flex-wrap:wrap}
.legend-inline span{display:inline-flex;align-items:center;gap:6px}
.legend-inline i{width:14px;height:2px;display:inline-block}
.legend-inline i.area{height:8px;opacity:var(--graf-area-topo)}
/* linha com bolinha: "cada ponto é uma medição" já na legenda */
.legend-inline i.pt{position:relative}
.legend-inline i.pt::after{content:"";position:absolute;left:50%;top:50%;width:6px;height:6px;margin:-3px 0 0 -3px;
 border-radius:50%;background:inherit}
.legend-inline i.tracejado{height:0;border-top:2px dashed currentColor;background:none}
.legend-inline i.vertical{width:2px;height:12px}
/* "medido | projeção" (14/09, tarde): a linha clara da última medição entre
   as duas palavras e, depois dela, o tracejado com a bolinha apagada na ponta */
.legend-inline .divisa{gap:5px}
.legend-inline .divisa i.vertical{width:1px;background:var(--ink);opacity:.4}
.legend-inline i.tracejado.ponta{position:relative;width:16px;margin-right:7px}
.legend-inline i.tracejado.ponta::after{content:"";position:absolute;right:-7px;top:-5px;width:8px;height:8px;
 border-radius:50%;border:2px dashed currentColor;background:var(--panel);opacity:.6}
/* anel = momento-chave; losango = ocorrência (as mesmas formas da base do gráfico) */
.legend-inline i.mk{width:9px;height:9px;border-radius:50%;border:2px solid currentColor}
.legend-inline i.oc{width:9px;height:9px;clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)}
/* MOMENTOS-CHAVE E OCORRÊNCIAS NA BASE DO GRÁFICO DA FICHA (14/09, tarde —
   pedido do Samuel: "tira esse sinal de custo escrito do gráfico" e "tem
   outras barras que não sei qual utilidade"). Saíram de dentro do gráfico as
   linhas verticais, as faixas e todos os rótulos. Cada momento-chave é um
   ANEL pequeno (tracejado na previsão de estouro, que é projeção) e cada
   ocorrência um LOSANGO, na faixa de 12px entre o gráfico e o eixo do tempo
   (por isso a ficha tem 30px embaixo), na coluna do mês a que pertencem —
   dois no mesmo mês ficam lado a lado (--o é a posição na fila; o passo
   encolhe no celular). A caixa de 16px é a área de toque; o desenho é o <i>
   de dentro. Sem texto e sem title: o mouse, o toque e o teclado abrem o
   CARTÃO DO MÊS, que diz o que cada um é. Entram depois das bolinhas. */
.graf-ficha{padding-bottom:30px}
.graf-ficha .graf-y{bottom:30px}
.graf-ev{--ev-passo:10px;position:absolute;top:100%;width:16px;height:16px;
 margin:-2px 0 0 calc(-8px + var(--o,0) * var(--ev-passo));display:grid;place-items:center;cursor:default;
 animation:surgir var(--dur-media) var(--curva-saida) 700ms backwards}
.graf-ev i{display:block;width:8px;height:8px;border-radius:50%;border:2px solid var(--c);background:var(--panel);
 transition:transform var(--dur-rapida) var(--curva-saida)}
.graf-ev.proj i{width:10px;height:10px;border-style:dashed}
.graf-ev.oc i{width:9px;height:9px;border:0;border-radius:0;background:var(--c);
 clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)}
.graf-ev.on i{transform:scale(1.35)}
.graf-fora{font-size:11.5px;color:var(--faint);margin-top:4px;line-height:1.4}
/* o card do gráfico: cabeçalho com título, legenda e os números do momento */
.graf-card .card-h{align-items:flex-start}
.graf-nums{display:flex;gap:18px;flex-wrap:wrap;font-variant-numeric:tabular-nums}
.graf-nums .k{font-size:11px;color:var(--faint);display:block}
.graf-nums .v{font-size:15px;font-weight:600;color:var(--ink)}
/* A CHAVINHA DO GRÁFICO DA CARTEIRA E A VISÃO "ORÇADO × REALIZADO" (26/09/2026;
   o desenho do Samuel: uma pílula "✓ orçado | previsão" no canto direito do
   cabeçalho do gráfico). É a mesma .visao-troca da visão tabela/circular; o ✓
   é decoração por CSS (quem lê por leitor de tela tem o aria-current). A
   pílula e os números ficam num bloco só à direita (.graf-h-dir) — no celular
   o bloco desce inteiro para baixo do título e a pílula vem antes dos números.
   Na visão em R$: as linhas de REFERÊNCIA (.graf-ref — orçamento vigente,
   ritmo esperado pontilhado) aparecem junto com a área, sem a animação de
   "desenhar" (ela apagaria o pontilhado até terminar); a legenda ganha a
   amostra pontilhada; no cartão do mês a amostra do ritmo (anel) segue os
   tokens --barra-* do cartão noturno. (11/10/2026) O ORÇAMENTO VIGENTE é uma
   curva suave, grossa e no azul --graf-orcado (o pedido do Miguel: "num azul
   bonitão, bem chamativo") — a legenda e a amostra do cartão também. */
.graf-h-dir{display:flex;align-items:center;gap:16px;flex-wrap:wrap;justify-content:flex-end;margin-left:auto}
.graf-troca .atual::before{content:"✓ "}
.graf-nums .v small{font-size:12px;font-weight:500;color:var(--muted)}
.graf-ref{stroke-width:var(--graf-traco-sec);animation:surgir var(--dur-media) var(--curva-saida) 400ms backwards}
.graf-ref.orcado{stroke-width:var(--graf-traco-orcado)}
.legend-inline i.pontilhado{height:0;border-top:2px dotted currentColor;background:none}
.graf-tip .sw.orcado{--sw:var(--graf-orcado)}
.graf-tip .sw.ritmo{background:transparent;box-shadow:inset 0 0 0 1.5px var(--barra-muted)}

/* ============================== RADAR DE RISCO ============================
   manchete · gráfico da carteira · tabela das obras · painel deslizante
   (a manchete e a tabela enxuta da v0.50.0 estão no bloco RADAR ENXUTO, no
   fim do arquivo; aqui fica o que é comum às linhas do Radar)
   ========================================================================= */
.radar-grid{display:grid;grid-template-columns:1fr;gap:16px}
.tabela-obras .estado{font-size:12.5px}
.tabela-obras td{vertical-align:middle;white-space:nowrap}
.tabela-obras td.principal{min-width:220px;max-width:320px}
.cel-obra .td-sub{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* `.cel` embrulha valor e linha de apoio num bloco só, para o cartão do
   celular não os espalhar lado a lado (25/09). As regras da coluna "R$ em
   risco" e do gap em reais (.faixa-cel, .gap-rs) saíram com a tabela antiga
   na v0.50.0. */
.tabela-obras td>.cel{min-width:0}
.tabela-obras tr.oculta{display:none}
.tabela-obras tr.on>*{background:var(--brand-suave)!important}
.tabela-obras tr:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
/* botões de linha ("editar", "excluir"): discretos, sem competir com a ação principal da tela */
.table .btn-sm{--bs-btn-padding-y:.18rem;--bs-btn-padding-x:.5rem;--bs-btn-font-size:12px}
.aviso-fisica{display:inline-flex;align-items:center;gap:4px;color:var(--warn);font-size:11.5px}

/* o painel que desliza da direita com o resumo da obra (sem sair da lista).
   Entra com o véu escurecendo em fade e sai do mesmo jeito: a visibilidade
   só vira "hidden" DEPOIS do deslize (transition-delay), senão o painel
   sumiria antes de terminar de sair. */
.painel-veu{position:fixed;inset:0;background:var(--veu);z-index:900;opacity:0;visibility:hidden;
 transition:opacity var(--dur-media) var(--curva-entrada),visibility 0s linear var(--dur-media)}
.painel{position:fixed;top:0;right:0;bottom:0;width:460px;max-width:100vw;background:var(--elevado);color:var(--ink);
 border-left:1px solid var(--line);box-shadow:var(--sombra-alta);z-index:901;transform:translateX(102%);
 transition:transform var(--dur-media) var(--curva-entrada),visibility 0s linear var(--dur-media);
 display:flex;flex-direction:column;overflow:auto;visibility:hidden}
body.painel-aberto .painel{transform:none;visibility:visible;
 transition:transform var(--dur-media) var(--curva-saida),visibility 0s}
body.painel-aberto .painel-veu{opacity:1;visibility:visible;
 transition:opacity var(--dur-media) var(--curva-saida),visibility 0s}
/* o conteúdo do painel entra em cascata a cada obra aberta */
.painel-body>*{animation:entrar var(--dur-media) var(--curva-saida) backwards}
.painel-body>:nth-child(2){animation-delay:30ms}.painel-body>:nth-child(3){animation-delay:60ms}
.painel-body>:nth-child(4){animation-delay:90ms}.painel-body>:nth-child(5){animation-delay:120ms}
.painel-body>:nth-child(n+6){animation-delay:150ms}
.painel-head{display:flex;align-items:center;gap:6px;padding:10px 14px;border-bottom:1px solid var(--line);
 position:sticky;top:0;background:var(--elevado);z-index:1}
.painel-head .pos{font-size:12.5px;color:var(--faint);margin-left:4px}
.painel-head .fechar{margin-left:auto}
.painel-head .tb-btn{color:var(--muted)}
.painel-head .tb-btn:hover{background:var(--nav-on);color:var(--ink)}
.painel-body{padding:16px}
.painel-nome{font-size:17px;font-weight:600;line-height:1.25}
.painel-meta{font-size:12.5px;color:var(--faint);margin-top:2px}
.painel-acoes{display:flex;gap:6px;margin:12px 0 14px;flex-wrap:wrap}
.painel .kpis{margin-bottom:14px}
.painel .kpi-item{flex:1 1 30%;padding:9px 12px}
.painel .kpi-item .val{font-size:18px}
.painel .kpi-item .delta{white-space:normal}   /* "R$ 5,7 mi à frente do trabalho" cabe em duas linhas (25/09) */
.painel .sec{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);margin:14px 0 6px}
.painel .sec:first-child{margin-top:0}
.painel .proxima{background:var(--ground);border:1px solid var(--line);border-radius:6px;padding:10px 12px;font-size:13px;line-height:1.5}
.painel .faixa,.painel .faixa-vazia{margin-bottom:0}

/* ============================== FICHA DA OBRA ==============================
   Cabeçalho (nome, estado, dados de contrato, ações) + abas: Resumo ·
   Medições · Orçamento e revisões · Prazo · Desfecho.
   ========================================================================= */
/* (06/10, auditoria) saiu a faixa de 3 px na esquerda: a faixa lateral grossa
   colorida é o tique nº 1 de tela feita por IA. O tom do aviso já está no contorno
   de 1 px, no fundo suave e no ícone (o que ele diz está no texto em negrito). */
.aviso-gap{display:flex;align-items:center;gap:10px;padding:9px 14px;border-radius:6px;
 border:1px solid var(--crit);background:var(--crit-suave);font-size:13px;color:var(--ink)}
.aviso-gap.warn{border-color:var(--warn);background:var(--warn-suave)}
.aviso-gap.ok{border-color:var(--ok);background:var(--ok-suave)}
.aviso-gap.novo{border-color:var(--line);background:var(--panel)}
.aviso-gap svg{flex:none}
.aviso-gap b{font-weight:600}
.aviso-gap .det{color:var(--muted)}
.aviso-gap .ajuda{margin-left:auto}
.ficha-grid{display:grid;grid-template-columns:1fr 360px;gap:16px;align-items:start}
.ficha-grid.inv{grid-template-columns:360px 1fr}
.g2{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}
.pilha{display:flex;flex-direction:column;gap:16px}
.ficha-meta{display:flex;flex-wrap:wrap;gap:4px 18px;font-size:12.5px;color:var(--faint);margin-top:4px}
.ficha-meta b{color:var(--ink);font-weight:500}
.lanc{display:flex;flex-direction:column;gap:12px}
.lanc .campo{display:flex;flex-direction:column;gap:4px}
.lanc .form-label{display:flex;align-items:center;gap:2px;font-size:12px;color:var(--muted);margin:0;white-space:normal;min-height:0}
.lanc .form-control,.lanc .form-select{font-size:14px;min-height:38px}
.mem-row{display:grid;grid-template-columns:22px 1fr auto;gap:10px;align-items:baseline;padding:6px 0;
 border-top:1px solid var(--line);font-size:13px}
.mem-row .n{color:var(--faint);font-variant-numeric:tabular-nums}
.mem-row .conta{color:var(--faint);font-size:12px;font-variant-numeric:tabular-nums}
.mem-row .r{text-align:right;white-space:nowrap;font-weight:500}
.rev-list{display:grid;grid-template-columns:auto 1fr;gap:5px 14px;font-size:13px;font-variant-numeric:tabular-nums}
.rev-list .q,.rev-list .m{color:var(--faint)}
/* ao voltar de um POST (medição lançada, revisão registrada) a linha nova
   acende na tinta da marca e apaga em 1,5 s — a pessoa vê ONDE entrou o
   que acabou de fazer */
@keyframes destacar{from{background-color:var(--brand-suave)}}
tr.nova>*,.rev-list .nova{animation:destacar 1.5s var(--curva-entrada) 240ms backwards}
.rev-list .nova{border-radius:4px}
details.dobra>summary{list-style:none;cursor:pointer;user-select:none;display:inline-flex;align-items:center;gap:6px}
details.dobra>summary::-webkit-details-marker{display:none}
/* a seta do colapsável é um chevron que gira ao abrir */
details.dobra>summary::after{content:"";width:7px;height:7px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
 transform:rotate(-45deg) translateY(1px);margin-left:2px;transition:transform var(--dur-media) var(--curva-saida)}
details.dobra[open]>summary::after{transform:rotate(45deg) translateY(-2px)}
details.dobra[open]>summary{margin-bottom:10px}
details.dobra.js[open]>summary{margin-bottom:0}
details.dobra.js>.dobra-in>div{padding-top:10px}
/* CARTÃO DOBRADO (21/09) — cartão comprido (memória de cálculo, linha do
   tempo) nasce FECHADO e o cabeçalho inteiro é o alvo do clique. O resumo
   ao lado do título não é "ver mais": ele DIZ o que há dentro ("10 passos
   conferíveis na mão, do orçamento à faixa final"), para a conta continuar
   à vista mesmo fechada. Nada de interativo mora no <summary> — o "i" e o
   botão ficam no conteúdo, senão o Tab pararia neles e o Enter abriria a
   dobra sem querer. A seta vai para o canto direito por posição absoluta:
   com o resumo quebrando linha no celular, ela ficaria no meio do nada. */
details.dobra.dobra-card>summary{display:flex;width:100%;align-items:baseline;gap:4px 10px;flex-wrap:wrap;
 position:relative;padding:2px 22px 2px 2px;margin-left:-2px;border-radius:6px}
details.dobra.dobra-card>summary::after{position:absolute;right:5px;top:7px;margin-left:0;color:var(--faint)}
details.dobra.dobra-card[open]>summary::after{top:5px}
details.dobra.dobra-card>summary:hover .dobra-res,details.dobra.dobra-card>summary:hover::after{color:var(--muted)}
details.dobra.dobra-card>summary:focus-visible{outline:none;box-shadow:0 0 0 3px var(--anel)}
.dobra-res{flex:1 1 220px;font-size:12.5px;color:var(--faint);line-height:1.45;
 transition:color var(--dur-rapida) var(--curva-saida)}
/* a escolha gravada (localStorage) volta sem animação: a página não abre
   sozinha na cara de quem chega — o JS tira a classe no primeiro clique */
details.restaurada>.dobra-in{animation-name:none}
/* A NOTA DO GRÁFICO EM DUAS CAMADAS (25/09) — pedido do Samuel: o parágrafo
   "como ler" sob o gráfico poluía. Fica visível UMA linha (o que o gráfico
   mostra); a explicação inteira dorme num <details> fechado, na MESMA linha de
   links do "Ver mês a mês": o que abrir toma a linha inteira e o outro desce.
   Sem componente novo — é o `details.dobra` + `.dobra-res` de cima. (Fica
   DEPOIS do bloco do cartão dobrado de propósito: a checagem lê a primeira
   regra `.dobra-res{` do arquivo e espera a cor de lá.) */
.graf-dobras{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 24px;margin-top:8px}
.graf-dobras>details.dobra[open]{flex:1 1 100%}
.graf-dobras>details.dobra>summary{align-items:baseline}
.graf-dobras .dobra-res{flex:0 1 auto}
.graf-dobras .graf-nota{margin-top:0}
.prazo-val{font-size:22px;line-height:1.15;font-weight:600}
.excluir-obra{display:flex;justify-content:flex-end;align-items:center;gap:12px;font-size:12.5px;color:var(--faint)}
.etiqueta{font-size:11px;color:var(--faint);font-family:var(--mono);margin-left:4px}
/* a frase do motor sob o nome (os marcos que existem) e o motivo do silêncio */
.ficha-frase{font-size:13px;color:var(--muted);margin-top:6px;line-height:1.45;max-width:880px}
.ficha-motivo{color:var(--faint);font-size:12px;font-style:italic;white-space:nowrap}
.painel-frase{font-size:13px;color:var(--muted);margin-top:8px;line-height:1.45}
/* anel = momento-chave (14/09, tarde): a mesma forma da base do gráfico, no painel do Radar */
.pm-dot{display:inline-block;width:9px;height:9px;border-radius:50%;margin-right:6px;vertical-align:-1px;
 border:2px solid currentColor}
.oc-dot{display:inline-block;width:9px;height:9px;margin-right:6px;vertical-align:-1px;
 clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)}
.tabela-box td.oc-desc{white-space:normal;max-width:380px;line-height:1.4}
/* LINHA DO TEMPO (aba Resumo): momentos-chave e ocorrências em ordem de data
   — data à esquerda, a forma do gráfico sobre um fio vertical (anel na cor do
   momento, tracejado na projeção; losango na cor da causa da ocorrência),
   rótulo e detalhe. */
.tl{list-style:none;margin:8px 0 0;padding:0;position:relative}
.tl::before{content:"";position:absolute;left:96px;top:8px;bottom:8px;width:1px;background:var(--line)}
.tl-item{display:grid;grid-template-columns:84px 24px 1fr;align-items:start;padding:6px 0;font-size:13px}
.tl-data{color:var(--faint);font-size:12px;font-variant-numeric:tabular-nums;white-space:nowrap;padding-top:1px}
.tl-dot{width:9px;height:9px;border-radius:50%;margin:4px auto 0;position:relative;z-index:1;box-shadow:0 0 0 2px var(--panel)}
.tl-dot.mk{background:var(--panel);border:2px solid currentColor}
/* (2px: com 1,5px o Chrome arredonda a borda para 1px e o tracejado some) */
.tl-item.proj .tl-dot{background:var(--panel)!important;border:2px dashed var(--crit)}
.tl-item.oc .tl-dot{border-radius:0;box-shadow:none;width:10px;height:10px;clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)}
.tl-rot{font-weight:500;color:var(--ink)}
.tl-val{font-weight:600;font-variant-numeric:tabular-nums}
.tl-tag{display:inline-block;font-size:11px;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);
 border:1px solid var(--line);border-radius:3px;padding:0 5px;margin-left:6px;vertical-align:1px;line-height:15px}
.tl-tag.proj{color:var(--crit);border-color:var(--crit);border-style:dashed}
.tl-det{color:var(--muted);font-size:12.5px;line-height:1.45;margin-top:1px}
.tl-pe{font-size:12px;color:var(--faint);margin-top:8px}
.tl-vazio{font-size:13px;color:var(--muted);margin-top:8px;line-height:1.5}

/* ------------------------------- responsivo -------------------------------- */
@media(max-width:991.98px){
 .top{padding:0 10px 0 12px;gap:8px;position:sticky}
 .nav-burger{display:grid}
 .marca .by{display:none}
 /* a navegação vira um menu vertical que desce da barra — sem rolagem lateral */
 .nav-main{display:none;position:absolute;top:100%;left:0;right:0;background:var(--sidebar);flex-direction:column;
  padding:6px 8px 10px;border-top:1px solid var(--barra-linha);box-shadow:var(--sombra-alta);z-index:55}
 .top.aberto .nav-main{display:flex;animation:menu-abrir var(--dur-media) var(--curva-saida)}
 .nav-main .ind{display:none}   /* no menu vertical o ativo é o fundo, não o traço */
 .nav-item{min-height:42px;border:0;border-radius:6px;padding:0 12px;font-size:14px}
 .nav-item.on{background:var(--barra-on);box-shadow:inset var(--sel-traco) 0 0 var(--selecao)}  /* menu vertical: fundo + traço vermelho à esquerda */
 .abas-secao{display:none}
 .menu-conta .txt,.chip-empresa .txt{display:none}
 details.menu-conta>summary,.chip-empresa{padding:4px}
 .abas-in{padding:0 12px}
 .abas{gap:0 14px}
 .content-col{padding:14px 12px 28px;gap:14px}
 .pg-head{align-items:flex-start}
 .pg-head h1{font-size:18px}
 .ficha-grid,.ficha-grid.inv,.g2,.radar-grid{grid-template-columns:1fr}
 .dcols{grid-template-columns:1fr}
 .graf svg{height:200px}
 .kpi-item{flex:1 1 45%}
 .kpi-item:nth-child(2n){border-right:0}
 .kpi-item{border-bottom:1px solid var(--line)}
 .kpi-item:nth-last-child(-n+2){border-bottom:0}
 .form-control,.form-select{font-size:16px;min-height:44px}  /* iOS não dá zoom no foco */
 .filtro .form-select,.filtro .form-control{font-size:14px;min-height:34px}
}
/* tabelas viram cartões empilhados no celular — zero arrasto lateral */
@media(max-width:700px){
 .table thead{display:none}
 .table,.table tbody,.table tr,.table td{display:block;width:100%;border:0}
 .table tr{border-bottom:1px solid var(--line);padding:6px 14px}
 .table tr:last-child{border-bottom:0}
 .table td{display:flex;justify-content:space-between;align-items:baseline;gap:14px;text-align:right;
  border-bottom:1px dashed var(--line);padding:7px 0;background:transparent!important;box-shadow:none!important}
 .table td:last-child{border-bottom:none}
 .table td::before{content:attr(data-l);color:var(--faint);font-size:11px;letter-spacing:.05em;
  text-transform:uppercase;text-align:left;flex:none}
 .table td.principal{display:block;text-align:left}
 .table td.principal::before{display:none}
 .table td.chev{display:none}
 .table.mem td{display:block;text-align:left;padding:4px 0}
 .table.mem td:first-child{padding-top:9px}
 .table.mem td:last-child{padding-bottom:11px}
 .barra{justify-content:flex-end}
 .fin-tots{justify-content:flex-start}
 .faixa-mid .v{font-size:24px}
 .faixa-piso .v,.faixa-teto .v{font-size:15px}
 .painel{width:100%;border-left:0}
 .kpi-item{flex:1 1 45%}
 /* gráfico estreito (~290px): as marquinhas do mesmo mês ficam mais juntas
    (o cartão do mês continua abrindo no toque) */
 .graf-ev{--ev-passo:7px}
 /* o cartão do mês mais compacto: aqui o gráfico tem ~290px de largura */
 .graf-tip{min-width:0;max-width:210px;font-size:11.5px;padding:7px 9px 6px}
 .graf-tip .r{gap:10px}
 .tl::before{left:80px}
 .tl-item{grid-template-columns:70px 20px 1fr}
 .tl-data{font-size:11.5px}
 .ficha-motivo{white-space:normal}
 /* o cartão do celular: valor e linha de apoio empilhados à direita, e o resumo
    do "Como ler este gráfico" fica de fora (o título basta numa tela estreita) */
 .tabela-obras td>.cel{text-align:right}
 .graf-dobras .dobra-res{display:none}
 /* o eixo do tempo da carteira tem 6 rótulos (set/25 · dez/25 · mar/26 · jun/26 · set/26 · set/27); a ~250px
    de gráfico eles se atropelam ("set/25dez/25mar/26"), e o eixo em R$ (26/09) ainda tirou 26px de largura.
    Ficam o começo, o meio, a última medição e a borda; somem o 2º e o 4º. */
 .graf-carteira .graf-x span:nth-child(2),.graf-carteira .graf-x span:nth-child(4){display:none}
 /* o eixo do tempo da FICHA (28/09/2026 — a demo com curvas reais agravou o que estava na fila desde 21/09):
    até 5 rótulos do medido espremidos em ~40% do gráfico, porque a projeção ocupa os 12 meses à direita — a
    375 px eles se atropelavam em toda ficha ("02/04/26 06/07/26"). Ficam o primeiro mês, a última medição (em
    negrito) e a borda; o mês de cada ponto continua no cartão, ao tocar. */
 .graf-ficha .graf-x span:not(:first-child):not(:last-child):not(.hoje){display:none}
 /* com o medido espremido (3 medições ao lado de 12 meses de projeção: a classe curto), o primeiro mês ainda
    bate no da última medição — fica só a última medição e a borda */
 .graf-ficha.curto .graf-x span:first-child{display:none}
}

/* ============================ ENTRADA / LOGIN =============================
   "Acesse sua conta" (desenho 02): cartão centrado de 440px. Ao fundo, o
   ícone da Lumiset (o arco da figura, o sol e os raios) em tamanho grande e
   baixa opacidade, com DOIS movimentos lentos: os raios giram em volta do
   sol (um giro a cada 150 s) e o brilho atrás dele respira. Tudo CSS + SVG
   inline: sem GIF, sem canvas, sem WebGL, sem arquivo externo.

   Por que é leve: o que anima é um `rotate` num <svg> inteiro e uma
   `opacity` numa <div> — as duas propriedades que o navegador compõe na GPU
   sem repintar a página. E `prefers-reduced-motion` desliga os dois.

   A cor: `var(--cliente, var(--brand))` etc. Com a cor da empresa definida,
   o fundo inteiro assume a cor dela; sem ela, as cores do ícone (sol na
   marca, arco em verde, raios em vermelho — as mesmas --brand/--ok/--crit).
   ========================================================================= */
.entrada-wrap{min-height:100vh;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:20px;padding:96px 18px 64px;position:relative;isolation:isolate}
#fundo-sol{position:fixed;inset:0;z-index:-1;overflow:hidden;pointer-events:none}
/* a cena é um quadrado; o ícone (viewBox 150) enche o quadrado, e o sol fica
   em (101,25 ; 65,25)/150 = (67,5% ; 43,5%) dele — é daí que saem as posições
   do brilho e dos raios, que precisam ficar centrados no sol */
.fs-cena{position:absolute;top:50%;left:50%;width:min(92vh,820px);height:min(92vh,820px);
  transform:translate(calc(-50% + 9vw),-50%)}
/* o fundo é a versão AMBIENTE do ícone: um tom só (marca ou cliente), o sol
   mais presente que o arco e os raios — as três cores da identidade ficam
   para o ícone pequeno da marca, no topo */
.fs-icone{position:absolute;inset:0;width:100%;height:100%}
.fs-icone .fs-arco{opacity:.22}
.fs-icone .fs-sol{opacity:.4}
.fs-brilho{position:absolute;left:67.5%;top:43.5%;width:150%;height:150%;margin:-75% 0 0 -75%;
  border-radius:50%;--fs-min:.08;--fs-max:.2;
  background:radial-gradient(circle closest-side,var(--cliente,var(--brand)),transparent);
  animation:fs-respirar 9s ease-in-out infinite alternate}
/* os raios são um <svg> à parte (viewBox de 100 = 2/3 do ícone), centrado no
   sol: 67,5% − 33,3% e 43,5% − 33,3% */
.fs-raios{position:absolute;left:34.167%;top:10.167%;width:66.667%;height:66.667%;opacity:.24;
  animation:fs-girar 150s linear infinite}
@keyframes fs-girar{to{transform:rotate(360deg)}}
@keyframes fs-respirar{from{opacity:var(--fs-min)}to{opacity:var(--fs-max)}}
[data-tema="escuro"] .fs-icone .fs-arco{opacity:.3}
[data-tema="escuro"] .fs-icone .fs-sol{opacity:.55}
[data-tema="escuro"] .fs-raios{opacity:.32}
[data-tema="escuro"] .fs-brilho{--fs-min:.12;--fs-max:.28}
.entrada-topo{position:fixed;left:0;right:0;top:0;padding:24px 40px;display:flex;
  justify-content:space-between;align-items:center;gap:16px}
.entrada-marca{display:flex;align-items:center;gap:10px;text-decoration:none}
.entrada-marca .logo{width:30px;height:30px;display:grid;place-items:center}
.entrada-nome{font-size:17px;font-weight:600;letter-spacing:-.01em;line-height:1.1;color:var(--ink)}
.entrada-eyebrow{font-size:11px;color:var(--faint)}
.entrada-sigilo{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--faint)}

.entrada-card{width:100%;max-width:440px;border-radius:10px;padding:0;overflow:hidden;
  background:var(--elevado);border:1px solid var(--line);box-shadow:var(--sombra-alta);
  animation:entrar var(--dur-lenta) var(--curva-saida) backwards}
/* senha errada: o cartão treme uma vez (o :has() é o "tem um erro dentro") */
.entrada-card:has(.alert-danger){animation:tremer var(--dur-lenta) var(--curva-saida) 80ms}
[data-tema="escuro"] .entrada-card{box-shadow:0 24px 60px rgba(0,0,0,.35)}
.entrada-form{padding:32px 36px 28px;display:flex;flex-direction:column;gap:6px}
.entrada-card h1{font-size:22px;font-weight:600;letter-spacing:-.015em;line-height:1.15;margin:0 0 4px;color:var(--ink)}
.entrada-sub{font-size:13px;color:var(--faint);margin:0 0 18px;line-height:1.5}
.entrada-card .form-label{font-size:12.5px;color:var(--muted);font-weight:500;text-transform:none;
  letter-spacing:0;margin-bottom:5px;white-space:normal}
.entrada-card .form-control{background:var(--ground);border:1px solid var(--line);border-radius:6px;
  min-height:42px;font-size:14.5px;color:var(--ink)}
.entrada-card .form-control:focus{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-suave)}
.btn-entrar{width:100%;min-height:42px;border-radius:6px;cursor:pointer;margin-top:4px;
  background:var(--brand-solido);border:1px solid var(--brand-solido);color:var(--sobre-solido);font-size:14.5px;font-weight:500;
  display:flex;align-items:center;justify-content:center;gap:9px;
  transition:filter var(--dur-rapida),transform var(--dur-rapida),box-shadow var(--dur-rapida)}
.btn-entrar:hover{filter:brightness(1.1);box-shadow:var(--sombra-alta)}
.btn-entrar:active{transform:scale(.97);box-shadow:none}
.btn-entrar:focus-visible{outline:0;box-shadow:0 0 0 3px var(--anel)}
.btn-entrar .seta{font-size:15px;transition:transform var(--dur-rapida)}
.btn-entrar:hover .seta{transform:translateX(3px)}
.entrada-rodape-card{padding:12px 36px;border-top:1px solid var(--line);background:var(--ground);
  font-size:12.5px;color:var(--faint);text-align:center}
.entrada-rodape-card a{color:var(--brand-2);text-decoration:none}
.entrada-divisor{display:flex;align-items:center;gap:14px;margin:18px 0 12px}
.entrada-divisor::before,.entrada-divisor::after{content:"";height:1px;flex:1;background:var(--line)}
.entrada-divisor span{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
.entrada-nota{font-size:12.5px;color:var(--faint);line-height:1.55;margin:0}
.entrada-comando{font-family:var(--mono);font-size:12px;color:var(--ink);background:var(--ground);
  border:1px solid var(--line);border-radius:6px;padding:10px 12px;margin:14px 0 0;white-space:pre-wrap;word-break:break-all}
/* rodapé: o logo horizontal da Lumiset assina a tela. São dois arquivos —
   branco para o escuro, colorido para o claro — e o CSS mostra um por vez
   (dentro de <img> o SVG não enxerga o tema; por isso não dá para tingir). */
.entrada-rodape{position:fixed;left:40px;bottom:24px;display:flex;gap:20px;align-items:center;
  font-size:12px;color:var(--faint)}
.entrada-rodape a{color:var(--faint);text-decoration:none}
.entrada-rodape img{height:36px;width:auto}
/* (sem `display` na regra acima: ela tem mais especificidade que .so-escuro
   e engoliria o display:none — os dois logos apareciam juntos) */
.so-escuro{display:none}
[data-tema="escuro"] .so-escuro{display:inline-block}
[data-tema="escuro"] .so-claro{display:none}

/* senha com o olho (mostrar/esconder) e o link "Esqueceu a senha?" — desenho Entrar */
.campo-senha{position:relative}
.campo-senha .form-control{padding-right:44px}
.olho{position:absolute;right:4px;top:3px;width:36px;height:36px;border:0;background:transparent;
  color:var(--faint);display:grid;place-items:center;cursor:pointer;border-radius:6px;
  transition:color var(--dur-rapida),transform var(--dur-rapida)}
.olho:hover{color:var(--ink)}
.olho:active{transform:scale(.9)}
.entrada-link{font-size:12.5px;color:var(--brand-2);text-decoration:none;margin-bottom:5px}

@media (max-width:640px){
  .entrada-wrap{padding:80px 14px 40px}
  .entrada-topo{padding:16px 18px}
  .entrada-sigilo{display:none}
  /* no celular o sol espia por cima do cartão, à direita */
  .fs-cena{width:130vw;height:130vw;top:0;left:0;transform:translate(-22%,-32%)}
  .entrada-form{padding:26px 20px 22px}
  .entrada-rodape-card{padding:12px 20px}
  .entrada-card h1{font-size:20px}
  .entrada-rodape{position:static;justify-content:center}
}

/* ==================== PERMISSÕES POR ÁREA (tela de Usuários) ============== */
.linha-areas td{border-bottom:1px solid var(--line)}
.area-abrir{cursor:pointer;padding:9px 14px;font-size:12.5px;color:var(--brand-2);list-style:none;user-select:none}
.area-abrir::-webkit-details-marker{display:none}
.area-abrir:hover{background:var(--nav-on)}
.area-form{padding:6px 14px 18px}
.area-grade{display:grid;gap:8px;margin-top:8px;grid-template-columns:repeat(auto-fill,minmax(250px,1fr))}
.area-caixa{display:flex;gap:10px;align-items:flex-start;padding:9px 12px;background:var(--ground);
  border:1px solid var(--line);border-radius:6px;cursor:pointer;font-size:12.5px;line-height:1.35}
.area-caixa:hover{border-color:var(--brand)}
.area-caixa input{margin-top:2px;flex:none;accent-color:var(--brand);width:16px;height:16px}
.area-dica{font-size:12px;color:var(--faint);line-height:1.4}

/* atalho de desenvolvimento na tela de entrada */
.atalho-dev{background:var(--warn-suave);border:1px solid var(--warn);border-radius:6px;padding:12px 14px;margin-bottom:18px}
.rot-dev{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--warn);margin-bottom:8px}

/* ======================= AJUDA CONTEXTUAL (o "i" redondo) =================
   Desktop: bolha ao passar o mouse ou focar. Celular: folha inferior de
   largura cheia (desenho "Ajuda (i) · toque"). Sem JavaScript, é só CSS.
   (11/10/2026, pedido do Miguel: "o balão dos i fica em cima e cortado" — no
   Resultado do Radar e no "Por quê" —, "que seja um balão bonitinho" e "tira os
   pontos de interrogação quando a gente clica") COM o JavaScript da casca (OS
   BALÕES DOS "i", que põe `.ajuda-js` no <html>) o balão sobe à CAMADA DE CIMA
   da página — o popover do navegador: nenhum quadro, tabela que rola ou popup
   o corta — e o script o põe onde cabe: em cima do "i" ou, sem espaço, embaixo,
   nunca para fora da tela. O cursor é a mãozinha de clicar (era o "?" do
   cursor de ajuda). O balão: canto de 12 px, a seta da cor dele (antes, um
   triângulo da cor da borda), o título na fonte de título.
   ========================================================================= */
.ajuda{position:relative;display:inline-flex;align-items:center;vertical-align:middle;margin-left:5px;cursor:pointer;outline:none}
.ajuda-i{width:14px;height:14px;display:block;color:var(--faint);transition:color var(--dur-rapida)}
.ajuda:hover .ajuda-i,.ajuda:focus .ajuda-i{color:var(--brand-2)}
.ajuda-bolha{display:none;position:absolute;left:50%;bottom:calc(100% + 11px);transform:translateX(-50%);
  width:max-content;max-width:300px;z-index:60;background:var(--elevado);color:var(--muted);
  border:1px solid var(--line);border-radius:12px;box-shadow:var(--sombra-alta);
  padding:12px 14px 13px;font-family:var(--sans);font-size:12.5px;font-weight:400;line-height:1.55;text-align:left;
  text-transform:none;letter-spacing:0;font-style:normal;white-space:normal;cursor:default;
  opacity:0;visibility:hidden;transition:opacity var(--dur-rapida),visibility 0s linear var(--dur-rapida),transform var(--dur-media) var(--curva-saida);
  transform:translate(-50%,4px)}
.ajuda-bolha b{display:block;margin-bottom:5px;font-family:var(--titulo);font-size:13px;font-weight:600;line-height:1.35;
  letter-spacing:-.005em;color:var(--ink)}
@keyframes bolha-in{from{opacity:0;transform:translate(-50%,4px)}}
/* escondida = display:none (13/09): com visibility:hidden a bolha ainda contava na
   largura rolável da página e o Radar ganhava rolagem lateral a 1366 px */
.ajuda:hover .ajuda-bolha,.ajuda:focus .ajuda-bolha{display:block;opacity:1;visibility:visible;transform:translate(-50%,0);transition-delay:0s;animation:bolha-in var(--dur-rapida) var(--curva-saida)}
/* a seta: um quadradinho girado, da cor do balão, com a borda dele nos dois lados de fora */
.ajuda-bolha::after{content:"";position:absolute;top:100%;left:50%;width:10px;height:10px;margin:-5px 0 0 -5px;
  background:var(--elevado);border:solid var(--line);border-width:0 1px 1px 0;transform:rotate(45deg)}
.ajuda.ajuda-dir .ajuda-bolha{left:0;transform:translateY(4px)}
.ajuda.ajuda-dir:hover .ajuda-bolha,.ajuda.ajuda-dir:focus .ajuda-bolha{transform:none}
.ajuda.ajuda-dir .ajuda-bolha::after{left:14px}
/* "i" encostado na borda DIREITA (o do gap, no aviso da ficha): a bolha abre
   para a esquerda. Centrada, ela vazava 90px além da tela mesmo invisível
   (visibility:hidden ainda conta no scrollWidth) e a ficha ganhava rolagem
   lateral a 1280px. */
.ajuda.ajuda-esq .ajuda-bolha{left:auto;right:0;transform:translateY(4px)}
.ajuda.ajuda-esq:hover .ajuda-bolha,.ajuda.ajuda-esq:focus .ajuda-bolha{transform:none}
.ajuda.ajuda-esq .ajuda-bolha::after{left:auto;right:7px;margin-left:0}
@media (max-width:640px){
  .ajuda-bolha{position:fixed;left:0;right:0;bottom:0;top:auto;width:auto;max-width:none;transform:translateY(12px);
    border-radius:16px 16px 0 0;padding:20px 20px 32px;font-size:14px;box-shadow:var(--sombra-alta)}
  .ajuda:hover .ajuda-bolha,.ajuda:focus .ajuda-bolha{transform:none}
  .ajuda-bolha b{font-size:18px;margin-bottom:8px}
  .ajuda-bolha::after{display:none}
}
/* COM o JavaScript (OS BALÕES DOS "i", no `_JS_CASCA`): o balão aberto é um popover — na camada de cima, com a
   posição que o script calcula (`top`/`left` em px e `--seta-x`, onde a seta aponta o "i"); `data-lado="baixo"`
   quando não coube em cima. No celular (até 640 px), a folha de baixo de sempre (`.folha`). O balão só de CSS
   (acima) fica para o navegador sem popover. */
.ajuda-js .ajuda:hover .ajuda-bolha:not(:popover-open),.ajuda-js .ajuda:focus .ajuda-bolha:not(:popover-open){display:none}
.ajuda-js .ajuda .ajuda-bolha:popover-open{display:block;position:fixed;inset:auto;margin:0;transform:none;
  opacity:1;visibility:visible;overflow:visible;animation:bolha-abre var(--dur-rapida) var(--curva-saida)}
.ajuda-js .ajuda .ajuda-bolha:popover-open::after{left:var(--seta-x,50%);right:auto;margin:-5px 0 0 -5px}
.ajuda-js .ajuda .ajuda-bolha[data-lado="baixo"]:popover-open{--bolha-de:-4px}
.ajuda-js .ajuda .ajuda-bolha[data-lado="baixo"]:popover-open::after{top:auto;bottom:100%;margin:0 0 -5px -5px;
  border-width:1px 0 0 1px}
.ajuda-js .ajuda .ajuda-bolha.folha:popover-open{left:0;right:0;bottom:0;top:auto;width:auto;max-width:none;
  border-radius:16px 16px 0 0;padding:20px 20px 32px;font-size:14px;--bolha-de:12px}
.ajuda-js .ajuda .ajuda-bolha.folha b{font-size:18px;margin-bottom:8px}
.ajuda-js .ajuda .ajuda-bolha.folha:popover-open::after{display:none}
@keyframes bolha-abre{from{opacity:0;transform:translateY(var(--bolha-de,4px))}}
/* fim: AJUDA CONTEXTUAL */

/* ========================= TUTORIAL DE PRIMEIRO USO =======================
   Balões passo a passo (desenho de referência dos sócios): fundo escurecido,
   o alvo da vez ganha um anel na cor da marca e o balão fica ao lado — no
   celular, fixo embaixo. Sem biblioteca; os passos vêm da própria tela.
   ========================================================================= */
/* O fundo só bloqueia o clique; quem escurece a tela é a SOMBRA do foco
   (.tour-foco): uma caixa fixa sem fundo, com um box-shadow enorme em volta
   — o alvo aparece pela "janela" e o resto fica sob o véu. Ao passar de
   um passo ao outro a caixa DESLIZA até o alvo novo em vez de pular (único
   lugar do app que transiciona top/left/width/height: é um retângulo fixo,
   sem filhos — o custo de layout é o dele só). */
.tour-fundo{position:fixed;inset:0;z-index:1000}
.tour-foco{position:fixed;z-index:1001;border-radius:8px;outline:3px solid var(--brand);pointer-events:none;
 box-shadow:0 0 0 200vmax var(--veu);animation:surgir var(--dur-media) var(--curva-saida);
 transition:top var(--dur-lenta) var(--curva-saida),left var(--dur-lenta) var(--curva-saida),
  width var(--dur-lenta) var(--curva-saida),height var(--dur-lenta) var(--curva-saida)}
.tour-foco.sem-anima{transition:none}
.tour-card{position:fixed;z-index:1002;width:340px;max-width:calc(100vw - 24px);background:var(--elevado);
 color:var(--ink);border:1px solid var(--line);border-radius:10px;box-shadow:var(--sombra-alta);padding:14px 16px 12px;
 animation:entrar var(--dur-media) var(--curva-saida) 140ms backwards}
.tour-eyebrow{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--brand-2);margin-bottom:6px}
.tour-titulo{font-size:15px;font-weight:600;margin-bottom:5px;color:var(--ink)}
.tour-texto{font-size:13px;color:var(--muted);line-height:1.5;margin:0 0 12px}
.tour-pe{display:flex;align-items:center;gap:10px}
.tour-pular{border:0;background:transparent;color:var(--faint);font:inherit;font-size:12.5px;cursor:pointer;padding:0}
.tour-pular:hover{color:var(--ink);text-decoration:underline}
.tour-pontos{margin-left:auto;display:flex;gap:5px}
.tour-pontos i{width:6px;height:6px;border-radius:50%;background:var(--line);display:block}
.tour-pontos i.on{background:var(--brand)}
.tour-prox{font:inherit;font-size:13px;font-weight:500;padding:6px 13px;border-radius:6px;border:1px solid var(--brand-solido);
 background:var(--brand-solido);color:var(--sobre-solido);cursor:pointer;transition:filter var(--dur-rapida),transform var(--dur-rapida)}
.tour-prox:hover{filter:brightness(1.1)}
.tour-prox:active{transform:scale(.97)}
.tour-pontos i{transition:background-color var(--dur-media)}
@media (max-width:700px){
 .tour-card{left:12px!important;right:12px;bottom:12px;top:auto!important;width:auto;max-width:none}
}

/* aviso curto ("Link copiado"): sobe com fade e desce ao sair (.saindo) */
@keyframes toast-subir{from{opacity:0;transform:translate(-50%,10px)}}
.toast-radar{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:1100;
 background:var(--elevado);color:var(--ink);border:1px solid var(--line);border-radius:6px;
 padding:8px 14px;font-size:13px;box-shadow:var(--sombra-alta);max-width:calc(100vw - 24px);
 animation:toast-subir var(--dur-media) var(--curva-saida);
 transition:opacity var(--dur-media) var(--curva-entrada),transform var(--dur-media) var(--curva-entrada)}
.toast-radar.saindo{opacity:0;transform:translate(-50%,10px)}

/* ================================ MOVIMENTO ================================
   O que dá vida e orientação às telas (pedido de 12/09: "falta animação,
   está meio confuso"). Tudo lê os tokens --dur-* e --curva-* do topo.
   ========================================================================= */
/* ENTRADA DE PÁGINA: cada bloco do conteúdo entra com fade + 8px, em
   cascata de 40 ms até o 6º; do 7º em diante todos juntos. `backwards`
   (não `both`): terminada a animação não sobra transform nenhum — um
   transform residual prenderia o painel fixo e os menus suspensos dentro
   do bloco. O painel, o véu e o rodapé ficam de fora. */
@keyframes entrar{from{opacity:0;transform:translateY(8px)}}
.content-col>*{animation:entrar var(--dur-lenta) var(--curva-saida) backwards}
.content-col>:nth-child(2){animation-delay:40ms}.content-col>:nth-child(3){animation-delay:80ms}
.content-col>:nth-child(4){animation-delay:120ms}.content-col>:nth-child(5){animation-delay:160ms}
.content-col>:nth-child(n+6){animation-delay:200ms}
.content-col>.painel,.content-col>.painel-veu,.content-col>.rodape,.content-col>script,.content-col>template,
.content-col>.flash-wrap{animation:none}   /* o aviso tem a entrada dele (flash-entrar) */
/* BARRA DE PROGRESSO no topo (JS): liga ao clicar num link interno ou ao
   enviar um formulário — vai a 80% em --dur-lenta e depois RASTEJA até 94%
   enquanto a resposta não chega (é espera de rede, por isso 1,6 s); some
   sozinha porque a página é trocada. */
#barra-ir{position:fixed;top:0;left:0;right:0;height:3px;z-index:2000;background:var(--barra-acento);
 transform:scaleX(0);transform-origin:left;opacity:0;pointer-events:none;
 transition:transform var(--dur-lenta) var(--curva-saida),opacity var(--dur-rapida)}
#barra-ir.indo{opacity:1;transform:scaleX(.8)}
#barra-ir.indo.devagar{transform:scaleX(.94);transition:transform 1.6s linear,opacity var(--dur-rapida)}
/* <details> ABRINDO E FECHANDO: o JS envolve o conteúdo (tudo menos o
   summary) em .dobra-in > div e anima a altura por grid-template-rows
   0fr ↔ 1fr — o único jeito de animar "auto" sem medir nada. Ao fechar, o
   JS segura o <details> aberto até a animação acabar. O overflow:hidden só
   vale durante a animação (.animando): fora dela a bolha de ajuda precisa
   poder sair da caixa. Sem JS, o <details> abre e fecha do jeito nativo. */
.dobra-in{display:grid;grid-template-rows:1fr;animation:dobra-abrir var(--dur-media) var(--curva-saida)}
.dobra-in>div{min-height:0}
.dobra-in.animando>div{overflow:hidden}
@keyframes dobra-abrir{from{grid-template-rows:0fr;opacity:0}}
@keyframes dobra-fechar{to{grid-template-rows:0fr;opacity:0}}
details.fechando>.dobra-in{animation:dobra-fechar var(--dur-media) var(--curva-entrada) forwards}
/* MENOS MOVIMENTO: quem pediu ao sistema (prefers-reduced-motion) recebe o
   estado final direto — durações e atrasos a zero, loops a uma volta. O
   JS da casca também se cala (_movimento()). A primeira regra é a dos
   loops explícitos; a segunda cobre tudo o mais. */
@media (prefers-reduced-motion:reduce){
 :root:not([data-movimento="ligado"]) .fs-raios,:root:not([data-movimento="ligado"]) .fs-brilho,
 :root:not([data-movimento="ligado"]) .estado.b-crit::before{animation:none}
 :root:not([data-movimento="ligado"]) *,:root:not([data-movimento="ligado"]) *::before,
 :root:not([data-movimento="ligado"]) *::after{animation-duration:.01ms!important;animation-delay:0s!important;
  animation-iteration-count:1!important;transition-duration:.01ms!important;transition-delay:0s!important}
 /* a troca de visão (bloco A TROCA DE VISÃO SEM SOLAVANCO, no fim): a página nova
    aparece no lugar, sem cruzar. Regra À PARTE de propósito — o asterisco acima
    não alcança estas peças, e um navegador que não as conhece descartaria a regra
    inteira em que elas entrassem */
 :root:not([data-movimento="ligado"])::view-transition-group(*),
 :root:not([data-movimento="ligado"])::view-transition-old(*),
 :root:not([data-movimento="ligado"])::view-transition-new(*){animation-name:none}
}
/* A CHAVE DO APP (13/09): o Windows do Samuel está com "menos movimento"
   ligado (comum em máquina remota) e ele não via animação nenhuma. O botão
   da barra guarda em localStorage "movimento" = ligado | desligado; sem
   escolha, vale o sistema. "ligado" tira a página do bloco acima;
   "desligado" aplica as mesmas reduções mesmo com o sistema pedindo movimento. */
:root[data-movimento="desligado"] .fs-raios,:root[data-movimento="desligado"] .fs-brilho,
:root[data-movimento="desligado"] .estado.b-crit::before{animation:none}
:root[data-movimento="desligado"] *,:root[data-movimento="desligado"] *::before,
:root[data-movimento="desligado"] *::after{animation-duration:.01ms!important;animation-delay:0s!important;
 animation-iteration-count:1!important;transition-duration:.01ms!important;transition-delay:0s!important}
.tb-btn .mov-ponto{position:absolute;right:3px;bottom:3px;width:6px;height:6px;border-radius:50%;background:var(--faint)}
:root[data-movimento="ligado"] .tb-btn .mov-ponto{background:var(--ok)}
:root[data-movimento="desligado"] .tb-btn .mov-ponto{background:var(--crit)}

/* ============ DOCUMENTAÇÃO DA API (modo --docs, doc.bylumiset.com) ============
   Fase 2 do plano complementar (15/09/2026). Só tokens: vale no claro e no
   escuro. O `code` do Bootstrap é rosa e não segue o data-tema — aqui dentro
   ele assume a tinta do tema. */
.doc{display:flex;flex-direction:column;gap:16px;min-width:0}
.doc .card-body{padding:18px 20px}
.doc-h2{font-size:16px;margin:0 0 10px}
.doc-h3{font-size:11.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);font-weight:600;margin:18px 0 8px}
.doc p{font-size:13.5px;line-height:1.6;color:var(--ink);margin:0 0 10px}
.doc p.doc-lead{font-size:15px;color:var(--muted)}
.doc p.doc-nota{font-size:12.5px;color:var(--faint)}
.doc-lista{font-size:13.5px;line-height:1.6;padding-left:18px;margin:0 0 10px;color:var(--ink)}
.doc-lista li{margin-bottom:4px}
.doc code,.doc-inline{font-family:var(--mono);font-size:.86em;color:var(--ink);background:var(--panel-2);
 padding:.08em .38em;border-radius:4px;overflow-wrap:anywhere}
.doc-codigo{border:1px solid var(--line);border-radius:8px;background:var(--ground);margin:6px 0 12px;overflow:hidden}
.doc-codigo-topo{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:5px 8px 5px 12px;
 border-bottom:1px solid var(--line);font-size:11px;letter-spacing:.04em;text-transform:uppercase;color:var(--faint)}
.doc-copiar{border:1px solid var(--line);background:var(--panel);color:var(--muted);font-size:11.5px;border-radius:5px;
 padding:2px 9px;cursor:pointer;text-transform:none;letter-spacing:0}
.doc-copiar:hover{color:var(--ink);border-color:var(--brand)}
.doc-codigo pre{margin:0;padding:12px 14px;max-height:460px;overflow:auto;font-family:var(--mono);font-size:12.5px;
 line-height:1.55;color:var(--ink);white-space:pre}
.doc .doc-codigo pre code{background:none;padding:0;font-size:inherit;color:inherit;overflow-wrap:normal}
.doc-metodo{display:inline-block;font-family:var(--mono);font-size:11px;font-weight:700;letter-spacing:.04em;
 padding:2px 7px;border-radius:4px;background:var(--ok-suave);color:var(--ok-texto)}
.doc-rota{font-family:var(--mono);font-size:13px;color:var(--ink);overflow-wrap:anywhere}
a.doc-rota{text-decoration:none}
a.doc-rota:hover{color:var(--brand-2);text-decoration:underline}
.doc-endpoint{scroll-margin-top:72px}
.doc-endpoint-topo{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.doc-tabela{border:1px solid var(--line);border-radius:8px;margin-bottom:8px}
.doc-tabela .table td{font-size:12.5px;vertical-align:top}
.doc-tabela td.doc-campo{font-family:var(--mono);font-size:12px;white-space:nowrap;color:var(--ink)}
.doc-tabela td.doc-campo.n1{padding-left:24px}
.doc-tabela td.doc-campo.n2{padding-left:40px}
.doc-tabela td.doc-campo.n3{padding-left:56px}
.doc-tabela td.doc-tipo{white-space:nowrap;color:var(--muted)}
.doc-indice{list-style:none;padding:0;margin:0 0 8px;display:grid;gap:6px;font-size:13px}
.doc-indice a{text-decoration:none;display:inline-flex;align-items:center;gap:8px}
.doc-resumo{font-size:12.5px;color:var(--faint);margin-left:8px}
.doc-outras>summary{font-size:12.5px;color:var(--brand-2);margin:2px 0 8px}
/* dentro do <details> animado (.dobra-in é grid), o bloco de código não pode esticar a coluna até o tamanho da linha mais longa: no celular o botão Copiar sumia */
.doc .dobra-in>div{min-width:0}
.doc-mudancas{list-style:none;padding:0;margin:0;display:grid;gap:14px}
.doc-mudanca-topo{font-size:13.5px;margin-bottom:4px;color:var(--ink)}
.doc-data{color:var(--faint);font-size:12.5px;margin-left:8px}
.doc-mudanca ul{font-size:13.5px;line-height:1.6;padding-left:18px;margin:0;color:var(--ink)}
@media (max-width:700px){
 .doc .card-body{padding:14px}
 .doc-tabela td.doc-campo{white-space:normal;overflow-wrap:anywhere}
}

/* ========================= FEEDBACK DOS USUÁRIOS ==========================
   A pergunta que aparece depois de 6 usos de uma funcionalidade ou de 10
   entradas no sistema (regras em piloto/feedback.py; HTML em
   app.py::modal_feedback). É um <dialog> nativo aberto com showModal(): o
   navegador prende o foco dentro dele, deixa o resto da página inerte e
   devolve o foco ao fechar. Feito das peças que o sistema JÁ tem: o cartão
   do tutorial, a caixa de opção da tela de permissões, .btn e .form-control,
   o .invalido que treme. O véu é uma <div> com a mesma --veu do tutorial e
   do painel (o ::backdrop não enxerga as variáveis do tema em parte dos
   navegadores). Movimento só pelos tokens: o bloco de menos-movimento e a
   chave de animações do app valem aqui sem regra própria.
   No celular vira folha inferior, como a ajuda do "i".
   ========================================================================= */
@keyframes fb-entrar{from{opacity:0;transform:translateY(10px) scale(.985)}}
@keyframes fb-sair{to{opacity:0;transform:translateY(6px) scale(.99)}}
.fb-veu{position:fixed;inset:0;background:var(--veu);z-index:1040;animation:surgir var(--dur-media) var(--curva-saida)}
.fb-modal{width:min(520px,calc(100vw - 32px));max-width:none;max-height:calc(100vh - 32px);
 max-height:calc(100dvh - 32px);padding:0;overflow:auto;background:var(--elevado);color:var(--ink);
 border:1px solid var(--line);border-radius:10px;box-shadow:var(--sombra-alta);
 animation:fb-entrar var(--dur-media) var(--curva-saida)}
.fb-modal::backdrop{background:transparent}
.fb-modal.fechando{animation:fb-sair var(--dur-rapida) var(--curva-entrada) forwards}
.fb-form{position:relative;margin:0;padding:20px 22px 18px;display:flex;flex-direction:column;gap:16px}
.fb-cab{padding-right:30px}
.fb-eyebrow{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--brand-2);margin-bottom:6px}
.fb-titulo{font-family:var(--titulo);font-size:18px;font-weight:600;letter-spacing:-.01em;line-height:1.3;
 color:var(--ink);margin:0}
.fb-titulo:focus{outline:none}
.fb-desc{font-size:13px;color:var(--muted);line-height:1.5;margin:6px 0 0}
.fb-x{position:absolute;top:12px;right:12px;width:32px;height:32px;border:0;border-radius:6px;
 background:transparent;color:var(--faint);display:grid;place-items:center;cursor:pointer;padding:0}
.fb-x:hover{background:var(--nav-on);color:var(--ink)}
.fb-grupo{border:0;margin:0;padding:0;min-width:0}
.fb-pergunta{display:block;float:none;width:auto;font-size:13px;font-weight:600;color:var(--ink);
 margin:0 0 8px;padding:0;line-height:1.4}
.fb-opcional{font-weight:400;font-size:12px;color:var(--faint);margin-left:6px}
.fb-opcoes{display:flex;flex-direction:column;gap:6px}
.fb-opcao{display:flex;align-items:center;gap:10px;padding:9px 12px;background:var(--ground);
 border:1px solid var(--line);border-radius:6px;cursor:pointer;font-size:13px;color:var(--ink);
 line-height:1.35;margin:0;transition:border-color var(--dur-rapida),background-color var(--dur-rapida)}
.fb-opcao:hover{border-color:var(--brand)}
.fb-opcao input{flex:none;width:16px;height:16px;margin:0;accent-color:var(--brand)}
.fb-opcao:has(input:checked){border-color:var(--brand);background-color:var(--brand-suave)}
.fb-opcao:has(input:focus-visible){outline:2px solid var(--brand);outline-offset:2px}
/* nota de 1 a 5: cinco caixas iguais; o rádio fica invisível mas é ele que
   recebe o foco e as setas do teclado */
.fb-estrelas{display:flex;gap:6px}
.fb-estrela{position:relative;flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;
 padding:9px 0 7px;background:var(--ground);border:1px solid var(--line);border-radius:6px;cursor:pointer;
 color:var(--faint);font-size:12px;font-variant-numeric:tabular-nums;margin:0;
 transition:border-color var(--dur-rapida),background-color var(--dur-rapida),color var(--dur-rapida)}
.fb-estrela input{position:absolute;opacity:0;width:1px;height:1px;margin:0;pointer-events:none}
.fb-estrela svg{width:22px;height:22px;display:block}
.fb-estrela svg path{fill:none}
.fb-estrela:hover{border-color:var(--brand)}
.fb-estrela.acesa{color:var(--brand)}
.fb-estrela.acesa svg path{fill:currentColor}
.fb-estrela:has(input:checked){border-color:var(--brand);background-color:var(--brand-suave)}
.fb-estrela:has(input:focus-visible){outline:2px solid var(--brand);outline-offset:2px}
.fb-escala{display:flex;justify-content:space-between;font-size:11.5px;color:var(--faint);margin-top:6px}
.fb-form textarea.form-control{min-height:80px;resize:vertical;font-size:13.5px;line-height:1.45}
.fb-pe{display:flex;justify-content:flex-end;align-items:center;gap:8px;flex-wrap:wrap}
.fb-erro{font-size:12.5px;color:var(--crit-texto);margin-right:auto}
.fb-erro:empty{display:none}
@media (max-width:640px){
 /* a folha inferior não deixa a página rolar por trás (:root, não html: a regra da
    barra de rolagem sempre à vista, de 28/09, pesa mais que html.classe — ver o bloco LUMINA) */
 :root.fb-aberto{overflow:hidden}
 .fb-modal{width:100%;margin:auto 0 0;border-radius:14px 14px 0 0;border-bottom:0;
  max-height:calc(100vh - 24px);max-height:calc(100dvh - 24px)}
 .fb-form{padding:18px 16px 16px;gap:14px}
 .fb-titulo{font-size:17px}
 .fb-pe .btn{flex:1 1 auto}
}

/* A TELA "FEEDBACKS" DO DIRETOR (v0.40.0; app.py::tela_feedbacks) — a tabela
   densa de sempre. O comentário quebra linha em vez de esticar a coluna, e os
   selos das respostas ("Fácil de usar · 3") embrulham quando não cabem. No
   celular, onde a tabela vira cartões, o comentário ocupa a linha inteira
   abaixo do rótulo. */
.fb-selos{display:flex;flex-wrap:wrap;gap:4px 12px}
.tabela-box td.fb-comentario{white-space:normal;min-width:220px;max-width:420px;line-height:1.4;overflow-wrap:anywhere}
@media (max-width:700px){
 .fb-selos{justify-content:flex-end}
 .fb-selos .estado{white-space:normal;text-align:right}
 .table td.fb-comentario{display:block;min-width:0;max-width:none;text-align:left}
 .table td.fb-comentario::before{display:block;margin-bottom:3px}
}

/* ------------------------------ IMPRESSÃO -------------------------------
   Cartão dobrado FECHADO não sai no papel: o conteúdo está no DOM, mas o
   <details> não o desenha. Como a ficha é impressa por quem vai defender o
   número numa reunião, na impressão TUDO abre — a memória de cálculo é
   justamente o que sustenta a conversa.
   Duas frentes, porque nenhuma cobre todos os navegadores sozinha:
   1) o JS da casca abre os cartões no `beforeprint` e os fecha no
      `afterprint` (funciona em qualquer navegador e não mexe na preferência);
   2) aqui, `::details-content` (Chrome novo) para quem imprime com o JS
      desligado. A seta do summary some (não é informação no papel) e a altura
      do colapsável fica travada em 1fr sem animação: a animação de abrir
      começa em 0fr e a folha poderia sair em branco.
   O relatório HTML (piloto/relatorio.py) é outro caminho, com CSS próprio —
   nada aqui o alcança. */
@media print{
 details.dobra.dobra-card::details-content{content-visibility:visible!important}
 details.dobra.dobra-card>summary::after{display:none}
 details.dobra.dobra-card>.dobra-in{grid-template-rows:1fr!important;opacity:1!important;animation-name:none!important}
 details.dobra.dobra-card>.dobra-in>div{overflow:visible!important}
}

/* ---------------------------------------------------------------------------
   CHAVINHA DAS DUAS LEITURAS DA CARTEIRA (22/09/2026)
   Tabela × gráfico circular, no cabeçalho do Radar. Dois links; o atual é um
   `<span>`, não um link para a própria página — clicar no que já está aberto
   não faz nada e confunde. Cor só por token: o ativo usa o fundo da marca em
   tinta suave, que funciona no claro e no escuro.
   --------------------------------------------------------------------------- */
.visao-troca{display:inline-flex;align-items:center;gap:2px;padding:2px;
  border:1px solid var(--line);border-radius:8px;background:var(--panel)}
.visao-troca>*{padding:4px 10px;border-radius:6px;font-size:12.5px;line-height:1.6;
  text-decoration:none;color:var(--muted);white-space:nowrap}
.visao-troca>a:hover{background:var(--nav-on);color:var(--ink)}
.visao-troca .atual{background:var(--brand-suave);color:var(--brand-2);font-weight:500}
.visao-troca>a:focus-visible{outline:2px solid var(--anel);outline-offset:1px}
/* ============================================================================
   INDICADORES — A PÁGINA DE RELATÓRIO (23/09/2026)
   Pedido do Samuel: "uma tela de Power BI, gráficos, números [...] tente não
   colocar muitos cards, porque card passa a ideia de IA". UMA superfície (a
   página), com os visuais separados por espaço e por fios (--line): nada de
   cartão por visual, sombra, degradê ou quadrado de ícone no título.
   Cada faixa (caixa, carteira, o porquê, comercial e equipe) tem à esquerda
   uma MARGEM que diz em que relógio os números dela correm; abaixo de 1200px
   ela vira o cabeçalho da faixa. Cor só por token: --brand é a série
   principal (entradas, avanço físico), --cost o custo (saídas), --ink o
   resultado acumulado, --crit/--warn/--ok só situação, --oc-* as causas.
   ============================================================================ */
.rel{background:var(--panel);border:1px solid var(--line);border-radius:8px;min-width:0}
/* a barra de filtros fica presa sob a barra do topo enquanto a página rola
   (desktop): o filtro ligado continua à vista de quem está lá embaixo. Nada
   de overflow:hidden na .rel — ele desligaria o sticky. */
.rel-filtros{display:flex;flex-wrap:wrap;align-items:center;gap:8px 20px;padding:10px 20px;background:var(--panel);
 border-bottom:1px solid var(--line);border-radius:8px 8px 0 0}
@media (min-width:992px){.rel-filtros{position:sticky;top:52px;z-index:8}}
.rel-faixa{scroll-margin-top:120px}
.rel-faixa:target .rel-margem h2{color:var(--brand-2)}
.rel-fgrupo{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.rel-flab{font-size:12px;color:var(--muted)}
/* (08/10/2026) o período saiu da barra do topo e virou o botão do Caixa: ver INDICADORES EM CAIXAS */
.rel-form{padding:12px;min-width:260px}
.rel-form form{display:flex;flex-direction:column;gap:8px;margin:0}
.rel-form .filtro{justify-content:space-between}
.rel-form .filtro .form-control{width:160px}
.rel-form-nota{font-size:11.5px;color:var(--faint);line-height:1.4;white-space:normal}
.rel-obra-menu>summary{display:inline-flex;align-items:center;gap:6px;max-width:280px}
.rel-obra-menu>summary .rot{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rel-obra-menu .acao-lista a[aria-current]{background:var(--brand-suave);color:var(--brand-2)}
/* os filtros que vieram dos visuais, cada um com o seu ×, e o "Limpar filtros" */
.rel-chips{display:flex;align-items:center;gap:6px 10px;flex-wrap:wrap;margin-left:auto}
.rel-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 4px 3px 10px;border-radius:6px;
 background:var(--brand-suave);color:var(--brand-2);font-size:12.5px;text-decoration:none;white-space:nowrap;
 transition:background-color var(--dur-rapida),color var(--dur-rapida)}
.rel-chip b{font-weight:600}
.rel-chip .x{width:18px;height:18px;display:inline-grid;place-items:center;border-radius:4px;font-size:14px;line-height:1;
 transition:background-color var(--dur-rapida)}
.rel-chip:hover{color:var(--ink)}
.rel-chip:hover .x{background:var(--panel)}
.rel-limpar{font-size:12.5px;color:var(--brand-2);text-decoration:none}
.rel-limpar:hover{text-decoration:underline}

/* AS FAIXAS: a margem com o relógio dos números + o conteúdo, separadas por um fio */
.rel-faixa{display:grid;grid-template-columns:150px minmax(0,1fr);gap:0 28px;padding:24px 20px 28px;
 border-top:1px solid var(--line)}
.rel-filtros+.rel-faixa{border-top:0}
.rel-margem h2{font-family:var(--titulo);font-size:15px;font-weight:600;letter-spacing:-.01em;line-height:1.3;
 color:var(--ink);margin:0}
.rel-relogio{margin:6px 0 0;font-size:12.5px;font-weight:500;color:var(--ink);line-height:1.45;
 font-variant-numeric:tabular-nums}
.rel-comp{display:block;font-weight:400;color:var(--muted);margin-top:2px}
.rel-nota{margin:8px 0 0;font-size:12px;color:var(--faint);line-height:1.5}
.rel-corpo{display:flex;flex-direction:column;gap:26px;min-width:0}
/* visuais lado a lado, separados por um fio vertical — sem caixa */
.rel-lado{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr)}
.rel-lado.tres{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr) minmax(0,.8fr)}
.rel-lado>*+*{border-left:1px solid var(--line);padding-left:24px;margin-left:24px}
.rel-visual{min-width:0}
.rel-vh{display:flex;align-items:flex-start;justify-content:space-between;gap:8px 14px;flex-wrap:wrap;margin-bottom:12px}
.rel-vtxt{min-width:0;flex:1 1 220px}
.rel-vt{font-size:13.5px;font-weight:600;color:var(--ink);margin:0;line-height:1.35}
.rel-vd{font-size:12px;color:var(--faint);margin:3px 0 0;line-height:1.45;max-width:70ch}
.rel-vd a{color:var(--brand-2)}
.rel-troca>*{padding:3px 9px;font-size:12px}
/* a frase de leitura: regra fixa sobre os números da tela (nunca texto gerado) */
.rel-leitura{font-size:13px;color:var(--ink);margin:12px 0 0;line-height:1.5;max-width:74ch}
.rel-leitura .sub{color:var(--muted)}
.rel-aviso{font-size:12px;color:var(--muted);margin:10px 0 0;line-height:1.5}
.rel-mudo{color:var(--faint)}
/* vazio honesto (a mesma caixa tracejada da faixa sem número): diz o que lançar */
.rel-vazio{display:flex;flex-direction:column;gap:3px;padding:14px 16px;border:1px dashed var(--line);border-radius:6px;
 font-size:13px;color:var(--muted);line-height:1.5}
.rel-vazio b{color:var(--ink);font-weight:600}
/* "Ver como tabela": o desenho sai e a tabela entra no mesmo lugar */
.rel-tabela{margin-top:10px}
.rel-tabela>summary{font-size:12.5px}
.rel-tabela .f,.rel-tabela[open] .a{display:none}
.rel-tabela[open] .f{display:inline}
.rel-visual:has(>details.rel-tabela[open]) .rel-grafico{display:none}
.rel-tabela .table{font-size:12.5px}

/* OS NÚMEROS GRANDES do caixa: seis colunas divididas por fios, sem caixa. O
   primeiro fio de cada linha fica escondido (margem −1px + overflow:hidden). */
.rel-kpis{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));row-gap:16px;overflow:hidden;margin-left:-16px}
.rel-kpi{min-width:0;padding:0 16px;margin-left:-1px;border-left:1px solid var(--line);
 animation:entrar var(--dur-lenta) var(--curva-saida) backwards}
.rel-kpi:nth-child(2){animation-delay:40ms}.rel-kpi:nth-child(3){animation-delay:80ms}
.rel-kpi:nth-child(4){animation-delay:120ms}.rel-kpi:nth-child(5){animation-delay:160ms}
.rel-kpi:nth-child(n+6){animation-delay:200ms}
.rel-kpi .lab{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rel-kpi .val{font-family:var(--titulo);font-size:26px;font-weight:600;letter-spacing:-.02em;line-height:1.1;
 color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums;margin-top:3px}
.rel-kpi .delta{margin-top:4px;white-space:normal}
/* (sem minilinha ao lado do número: ela repetiria o gráfico "Entradas e
   saídas" logo abaixo — e na primeira versão passava por cima do número) */
/* a régua de atraso da inadimplência: 1–30, 31–60, 61–90, mais de 90 dias */
.rel-atraso{display:flex;height:4px;border-radius:2px;overflow:hidden;background:var(--panel-2);margin-top:7px}
.rel-atraso i{display:block;height:100%;flex:0 1 0;min-width:0;background:var(--crit)}
.rel-atraso i:nth-child(1){opacity:.4}.rel-atraso i:nth-child(2){opacity:.6}.rel-atraso i:nth-child(3){opacity:.8}

/* ENTRADAS E SAÍDAS: colunas acima e abaixo do zero, o em aberto claro por
   cima, e o resultado acumulado como linha com bolinhas (a gramática da ficha) */
.graf.graf-rs{padding-left:62px}
.graf-rs .graf-y{width:56px}
.graf-rs .graf-x{left:62px}
.graf-fluxo svg{height:280px}
.fx-ent{fill:var(--ok)}
.fx-sai{fill:var(--crit)}
.fx-col.aberto{fill-opacity:.18;stroke-width:1px}
.fx-ent.aberto{stroke:var(--ok)}
.fx-sai.aberto{stroke:var(--crit)}
.fx-zero{stroke:var(--ink);stroke-opacity:.4;stroke-width:1px}
.fx-col{animation:surgir var(--dur-media) var(--curva-saida) 120ms backwards}
.graf-linha.tinta{stroke-width:var(--graf-traco-sec)}
.graf-pt.tinta{--pt:var(--ink)}
.graf-pt.entrada,.graf-pt.aberto-ent{--pt:var(--ok)}
.graf-pt.saida,.graf-pt.aberto-sai{--pt:var(--crit)}
.graf-pt.aberto-ent,.graf-pt.aberto-sai{opacity:.78}
.graf-tip .sw.tinta{--sw:var(--barra-ink)}
.graf-tip .sw.fx-ent{--sw:var(--ok)}
.graf-tip .sw.fx-sai{--sw:var(--crit)}
.graf-tip .sw.entrada,.graf-tip .sw.aberto-ent{--sw:var(--ok)}
.graf-tip .sw.saida,.graf-tip .sw.aberto-sai{--sw:var(--crit)}
.graf-tip .sw.aberto-ent,.graf-tip .sw.aberto-sai{background:transparent;box-shadow:inset 0 0 0 1.5px var(--sw)}
.legend-inline i.bloco{width:10px;height:10px;border-radius:2px}
.legend-inline i.bloco.aberto{background:var(--nav-on);box-shadow:inset 0 0 0 1px var(--muted)}
.legend-inline i.aberto-ent,.legend-inline i.aberto-sai{display:inline-block;width:10px;height:10px;border-radius:50%;background:transparent}
.legend-inline i.aberto-ent{box-shadow:inset 0 0 0 1.5px var(--ok)}
.legend-inline i.aberto-sai{box-shadow:inset 0 0 0 1.5px var(--crit)}
/* BARRAS EM LISTA (para onde foi o dinheiro, as causas): nome · barra · valor · parte */
.rb-cab,.rb{display:grid;grid-template-columns:minmax(90px,38%) minmax(30px,1fr) auto 44px;align-items:center;gap:10px}
.rb-cab{font-size:11px;color:var(--faint);padding:0 6px 4px}
.rb-cab span:nth-child(n+3){text-align:right}
.rb-lista{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:1px}
.rb{padding:6px;border-radius:6px;color:var(--ink);text-decoration:none;font-size:12.5px;
 transition:background-color var(--dur-rapida),opacity var(--dur-rapida)}
a.rb:hover{background:var(--nav-on);color:var(--ink)}
a.rb:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
.rb-nome{display:flex;align-items:center;gap:7px;min-width:0}
.rb-nome .t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rb-nome .oc-dot{margin-right:0;flex:none}
.rb-trilho{position:relative;height:10px;min-width:0}
.rb-trilho>i{position:absolute;left:0;top:0;bottom:0;border-radius:2px;background:var(--c,var(--brand))}
.rb-v{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.rb-p{text-align:right;white-space:nowrap;color:var(--faint);font-variant-numeric:tabular-nums}
/* a escolha acesa, o resto apagado (é o filtro cruzado do Power BI) */
.rb-lista.tem-sel>li:not(.sel) .rb{opacity:.45}
.rb-lista.tem-sel>li:not(.sel) a.rb:hover{opacity:1}
.rb-lista>li.sel .rb{background:var(--brand-suave)}

/* A CARTEIRA OBRA A OBRA: a barra de bala (físico em cima, custo embaixo, na
   mesma escala; em vermelho o custo que passou da obra quando há sinal) */
.rel-carteira td{vertical-align:middle}
.rel .nw{white-space:nowrap}
/* no desktop as colunas têm largura fixa (o <colgroup> soma 100%) e um respiro
   menor: são oito colunas na largura que sobra ao lado da margem */
@media (min-width:701px){
 .rel-carteira{table-layout:fixed}
 .rel-carteira>:not(caption)>*>*{padding-left:8px;padding-right:8px}
}
.rel-obra{font-weight:500;color:var(--ink);text-decoration:none}
.table .principal a.rel-obra:hover,.rel-obra:hover{color:var(--brand-2);text-decoration:underline}
.table .principal a.rel-obra[aria-current]{color:var(--brand-2)}
.rel-carteira .td-sub a{color:var(--brand-2)}
.rel-carteira tbody tr{transition:opacity var(--dur-rapida)}
.rel-carteira.tem-sel tbody tr:not(.sel){opacity:.5}
.rel-carteira.tem-sel tbody tr:not(.sel):hover{opacity:1}
.rel-carteira tbody tr.sel>*{background:var(--brand-suave)}
.rel-carteira tfoot td{font-weight:600;border-top:1px solid var(--line);border-bottom:0;padding-top:10px}
.bala-w{display:inline-flex;flex-direction:column;gap:3px;width:100%;min-width:110px;max-width:220px;vertical-align:middle}
/* o trilho É a escala (0 a 100% da obra e do orçamento): sem ele, 20% não
   parece 20% de nada. Dois trilhos, um para cada barra, no fundo da caixa. */
.bala{position:relative;display:block;height:14px;
 background:linear-gradient(var(--panel-2),var(--panel-2)) 0 0/100% 8px no-repeat,
  linear-gradient(var(--panel-2),var(--panel-2)) 0 10px/100% 4px no-repeat}
.bala i{position:absolute;left:0;border-radius:2px}
.bala .fis{top:0;height:8px;background:var(--brand)}
.bala .custo{top:10px;height:4px;background:var(--cost)}
.bala .gap{top:10px;height:4px;background:var(--crit)}
.bala .cem{top:-2px;height:18px;width:1px;background:var(--ink);opacity:.35}
.bala-v{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.rel-gap{display:inline-flex;align-items:center;gap:8px}
.rel-spark-gap{width:52px;height:20px;flex:none;overflow:visible}
.rel-spark-gap path{fill:none;stroke:var(--muted);stroke-width:var(--graf-traco);stroke-linejoin:round}  /* o mesmo traço fino dos gráficos (26/09) */
.rel-spark-gap line{stroke:var(--crit);stroke-opacity:.5;stroke-width:1px;stroke-dasharray:2 2}

/* O QUE ACONTECEU: duas linhas por ocorrência (data · obra · impacto / causa — descrição) */
.rel-ocs{list-style:none;margin:0;padding:0}
.rel-ocs li{display:grid;grid-template-columns:62px minmax(0,1fr);gap:12px;padding:9px 0;border-top:1px solid var(--line)}
.rel-ocs li:first-child{border-top:0;padding-top:2px}
.rel-ocs .q{font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums;padding-top:1px}
.rel-ocs .l1{display:flex;justify-content:space-between;align-items:baseline;gap:4px 12px;flex-wrap:wrap}
.rel-ocs .imp{font-size:12px;color:var(--muted);white-space:nowrap;font-variant-numeric:tabular-nums}
.rel-ocs .l2{font-size:12.5px;color:var(--muted);line-height:1.45;margin-top:2px}
.rel-ocs .l2 b{font-weight:500;color:var(--ink)}

/* COMERCIAL E EQUIPE: as propostas numa barra só, pelo valor, e a tabela ao lado */
.rel-pilha{display:flex;height:12px;border-radius:3px;overflow:hidden;gap:2px;margin:2px 0 14px}
.rel-pilha i{display:block;height:100%;flex:0 1 0;min-width:2px;background:var(--c)}
.st-aprovado{--c:var(--brand)}
.st-enviado{--c:var(--brand);opacity:.55}
.st-pendente{--c:var(--brand-suave);box-shadow:inset 0 0 0 1px var(--brand)}   /* o que ainda não saiu: tinta clara com contorno (no escuro, só a opacidade sumia) */
.st-recusado{--c:var(--cost)}
.rel-mini .sw{display:inline-block;width:9px;height:9px;border-radius:2px;background:var(--c);margin-right:8px}
.rel-mini td,.rel-mini th{white-space:nowrap}
.rel-nums{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:12px 24px}
.rel-nums li{display:flex;flex-direction:column}
.rel-nums .n{font-family:var(--titulo);font-size:24px;font-weight:600;line-height:1.1;color:var(--ink);
 font-variant-numeric:tabular-nums}
.rel-nums .l{font-size:12px;color:var(--muted)}

@media (max-width:1199.98px){
 .rel-faixa{grid-template-columns:minmax(0,1fr);gap:14px}
 .rel-margem{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 14px}
 .rel-relogio{margin:0}
 .rel-comp{display:inline;margin:0 0 0 8px}
 .rel-nota{flex-basis:100%;margin:2px 0 0}
 .rel-kpis{grid-template-columns:repeat(3,minmax(0,1fr))}
 .rel-lado.tres{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
 .rel-lado.tres>:nth-child(3){grid-column:1/-1;border-left:0;margin-left:0;padding-left:0;
  border-top:1px solid var(--line);padding-top:20px;margin-top:20px}
}
@media (max-width:991.98px){
 .rel-lado,.rel-lado.tres{grid-template-columns:minmax(0,1fr)}
 .rel-lado>*+*,.rel-lado.tres>:nth-child(3){border-left:0;margin-left:0;padding-left:0;
  border-top:1px solid var(--line);padding-top:20px;margin-top:20px}
}
@media (max-width:700px){
 .rel-filtros{padding:10px 14px;gap:8px 14px}
 .rel-faixa{padding:18px 14px 22px}
 .rel-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
 .rel-kpi .val{font-size:22px}
 .rel-chips{margin-left:0}
 .graf-fluxo svg{height:200px}
 .rb-cab{display:none}
 .rb{grid-template-columns:minmax(0,1fr) auto auto;grid-template-areas:"nome v p" "trilho trilho trilho";row-gap:5px}
 .rb-nome{grid-area:nome}.rb-trilho{grid-area:trilho}.rb-v{grid-area:v}.rb-p{grid-area:p}
 .rel-carteira tfoot td.vazia{display:none}
 .bala-w{max-width:none;width:56%}
 .rel .table td>.cel{text-align:right;min-width:0}
 /* no celular o eixo do tempo do fluxo mostra um rótulo sim, um não (12 meses em ~300px se atropelavam) */
 .graf-fluxo .graf-x span:nth-child(even){display:none}
}
@media print{
 .rel-filtros{position:static}
}

/* MESMA TELA, OUTRO FILTRO (23/09/2026): quando o endereço novo é a mesma tela
   com outro filtro (o <script> do <head> compara com o document.referrer e
   marca data-entrada="mesma"), a página aparece no lugar — sem a entrada em
   cascata, sem os números contando de novo e sem os gráficos se desenhando
   outra vez. A entrada existe para quem CHEGA à tela; quem troca o filtro
   quer ver o número novo, não o balé de sempre. Vale para toda tela com
   filtro por link (Indicadores, a régua do Financeiro, a chavinha do Radar). */
/* (fora da regra, de propósito: o painel da aba que entra por clique — .troca —
   e o painel deslizante do Radar, que respondem a um gesto da pessoa) */
:root[data-entrada="mesma"] :is(.content-col>:not(.troca),.content-col>.kpis>.kpi-item,.rel-kpi,.graf-linha,.graf-area,
 .graf-proj,.graf-ref,.graf-tag,.graf-pt,.graf-ev,.fx-col,.barra .fill,.rb-trilho>i,.bala i,.rel-pilha i){animation:none}

/* ===========================================================================
   REFORMA VISUAL (23/09/2026) — MENOS CAIXA, MAIS HIERARQUIA
   Pedido do Samuel: "tudo virou card; parece dashboard de IA". A correção é de
   SISTEMA, não de tela: as telas usam as mesmas peças (.card, .tabela-box,
   .kpis, .tabela-head), então elas mudam aqui e valem em todas.
   A regra nova: conteúdo mora em SEÇÃO ABERTA; caixa só quando agrupa de
   verdade. Quem separa passa a ser espaço, tipografia e uma linha fina.
   Nenhuma cor muda — a paleta é a mesma.
   =========================================================================== */

/* 1. o card deixa de ser caixa e vira bloco de conteúdo -------------------- */
.card{--bs-card-bg:transparent;--bs-card-border-color:transparent;
 --bs-card-spacer-y:0;--bs-card-spacer-x:0;--bs-card-border-radius:0;
 border:0;box-shadow:none}
.card>.card-body{padding:0}
/* O GRÁFICO continua em painel: é o destaque da página, e o painel é o que o
   separa da tabela logo abaixo. */
.card.graf-card{--bs-card-bg:var(--panel);--bs-card-border-color:var(--line);
 --bs-card-border-radius:10px;border:1px solid var(--line)}
.card.graf-card>.card-body{padding:16px 18px}
/* Caixa continua existindo onde AGRUPA de verdade (alerta, área funcional):
   basta acrescentar `destaque` ao card. */
.card.destaque{--bs-card-bg:var(--panel);--bs-card-border-color:var(--line);
 --bs-card-border-radius:8px;border:1px solid var(--line);box-shadow:var(--sombra)}
.card.destaque>.card-body{padding:14px 16px}

/* 2. ritmo: as seções respiram ENTRE si, não por dentro -------------------- */
.content-col{gap:28px}
.pg-head h1{font-size:22px}

/* 3. hierarquia por tipografia -------------------------------------------- */
.card-title,.card-t,.tabela-head .t{font-size:15px;letter-spacing:-.01em}
.card-title.h5{font-size:15px;margin-bottom:10px}
/* A linha de apoio NUNCA encosta no título — sem a caixa, o subtítulo colado
   (a regra original puxa 4px para CIMA) deixa o topo das telas apertado. */
.card-sub,.tabela-head .sub{font-size:12.5px;color:var(--faint);line-height:1.55}
.tabela-head .sub{margin-top:8px}
.card-sub{margin-top:5px}
.pg-head .sub{margin-top:6px;font-size:13px}
.kpi-item .lab{margin-bottom:3px}
/* EXPLICAÇÃO de seção ("Como ler esta tela", nota do gráfico): texto corrido
   de verdade — corpo 13px, entrelinha larga e medida de ~96 caracteres. Curta
   demais vira coluna de jornal órfã; larga demais o olho perde a volta. */
.card .small,.card p.text-secondary,.graf-nota{font-size:13px;line-height:1.7;
 max-width:96ch;color:var(--muted)}
.card p.text-secondary+p,.card .small+.small{margin-top:10px}
/* A EXPLICAÇÃO de rodapé ("Como ler esta tela") fica no canto, como o resto da
   página, e o texto corre no enquadramento inteiro: centrar o bloco fazia ele
   parecer deslocado do conteúdo que explica (pedido do Samuel, 23/09). */
.card:has(>.card-body>p.text-secondary){max-width:none;margin-inline:0}
.card:has(>.card-body>p.text-secondary) .small,
.card:has(>.card-body>p.text-secondary) p.text-secondary{max-width:none}

/* 4. a TABELA é a superfície principal da página --------------------------- */
/* MENOS LINHA (23/09, 2ª rodada): trocar caixa por linha resolveu a poluição
   de contorno e criou outra, de divisória. Duas regras agora:
   (a) só existe UMA linha onde antes havia duas (o cabeçalho da tabela já
       separa o título do conteúdo — a do bloco saiu);
   (b) a divisória entre linhas de dado é um FIO, mais fraco que a borda de
       componente: ela guia o olho sem desenhar grade. */
:root{--fio:rgba(14,42,71,.10)}
:root[data-tema="escuro"]{--fio:rgba(255,255,255,.07)}
.tabela-box{background:transparent;border:0;border-radius:0;box-shadow:none}
.tabela-head{padding:0 2px 12px;border-bottom:0}
.table>:not(caption)>*>*{border-bottom-color:var(--fio)}
.tabela-box>.table,.tabela-box .tabela-rolavel>.table{border-radius:0}
.table>:not(caption)>*>*{padding:12px 10px}     /* linha mais alta: leitura de dado */
.table thead th{padding:0 10px 9px}
.tabela-box .vazio{padding:40px 20px}

/* 5. indicadores: UMA faixa dividida por fios, sem caixas e SEM linha embaixo
      (a linha de baixo fechava a faixa como se fosse caixa de novo) -------- */
.kpis{background:transparent;border:0;border-radius:0;box-shadow:none}
.kpi-item{padding:0 22px 2px;border-right:1px solid var(--fio)}
.kpi-item:first-child{padding-left:2px}
.kpi-item .val{font-size:25px}
.kpi-item .lab{color:var(--faint)}

/* 6. números de total (rodapé do Financeiro): espalhados pela largura, em vez
      de amontoados na direita ---------------------------------------------- */
.fin-tots{justify-content:space-between;gap:10px 18px}

/* 7. a barra de filtros do relatório (Indicadores) não é um cartão: ela usa a
      cor da PÁGINA e fica presa no topo só com um fio embaixo ------------- */
.rel-filtros{background:var(--ground);border-radius:0;border-bottom-color:var(--fio)}
.rel-faixa,.rel-lado>*+*{border-color:var(--fio)}

/* 8. TELAS NOVAS EM REACT (Importar planilha, Conciliação, Carteira, Kanban) --
      Elas vêm do front em `web/` (shadcn + Tailwind, compilado em
      static/exp/). Lá cada bloco é um <Card>, e o efeito na tela é o mesmo
      "mural" que esta reforma tirou do resto do sistema. Como o app carrega
      o tema.css ANTES do CSS compilado, aqui é o único lugar do arquivo que
      precisa de !important — e só nas propriedades da caixa. Recompilar o
      front resolveria sem isto, mas exige Node, que não está nesta máquina. */
/* Dois detalhes de cascata aqui, que custaram uma investigação:
   1. o CSS compilado mapeia os tokens do shadcn em `#raiz-react`. Mesmo
      seletor que o meu e carregado DEPOIS, então ele vencia: a cor do card
      sai por um seletor com mais peso (`html #raiz-react`), sem !important;
   2. as utilidades do Tailwind moram em `@layer utilities` e são todas
      !important. Entre declarações !important, a camada declarada ANTES
      vence — e este arquivo carrega antes. Por isso a caixa é desmontada
      dentro de uma camada própria, e não solta no arquivo. */
html #raiz-react,html #raiz{--card:transparent}
/* O compilado fixa o texto secundário em cor LITERAL (--muted-txt), porque dentro da
   ilha `--muted` é o FUNDO do shadcn. O valor do escuro ficou o do azul-noturno
   (#b4c7da): azulado sobre o grafite. Aqui ele segue o --muted do tema, calculado na
   raiz, onde --muted ainda é o do Prisma; o peso de `html:root` vence o `:root` do
   compilado. Quando `web/` for recompilado, levar isto para lá (24/09). */
html:root,html:root[data-tema="escuro"]{--muted-txt:var(--muted)}
/* O EXEMPLO dentro do campo do React (06/10, auditoria): o pacote não traz
   `placeholder:` próprio — vale o do preflight do Tailwind, a cor do texto a 50%,
   que dava 3,0:1 ("Filtrar cartões", "Nova lista…"). Aqui, o MESMO token dos
   `.form-control::placeholder` das telas do servidor, --desab:
     claro  #586c82 — 4,85:1 sobre o --ground #eef3f9, 5,41:1 sobre o campo #fff
     escuro #9ea3ac — 6,67:1 sobre o --ground #1b1d20, 5,83:1 sobre o --panel,
            4,92:1 sobre o --elevado #323439 (o pior caso: campo dentro do popup)
   O preflight está em `@layer base`; esta regra, sem camada, vence sem !important. */
#raiz-react input::placeholder,#raiz-react textarea::placeholder{color:var(--desab)}
/* os rótulos de % dos anéis da Circular saem do pacote com font-size="9.5" (atributo
   do SVG, que qualquer CSS vence): o piso de 11 px também aqui. Quando o `web/` for
   recompilado, levar para o Carteira.tsx (06/10). */
#raiz-react svg text[font-size="9.5"]{font-size:11px}
@layer reforma-prisma{
 /* o piso de 11 px (06/10): o `text-[0.68rem]` do React dá 10,88 px — os
    cabeçalhos da prévia da Importação, o selo de contagem, os rótulos da faixa do
    Radar. O utilitário é !important dentro de `@layer utilities`; entre
    !important vence a camada declarada ANTES — esta (o tema carrega primeiro). */
 #raiz-react .text-\[0\.68rem\]{font-size:11px!important}
 /* o par do bloco TOQUE (fim do arquivo): lá, `#raiz-react input{font-size:16px}` SEM
    camada e sem !important perdia para o `text-sm`/`text-[0.7rem]` do Tailwind, que
    são !important — conferido no dedo emulado: "Filtrar cartões" ficava em 14 px e os
    seletores das Tarefas em 11,2 px, e o iPhone daria zoom ao tocar. Aqui, numa
    camada declarada antes, o !important vence (06/10). */
 @media (pointer:coarse){
  #raiz-react select,#raiz-react input:not([type="checkbox"]):not([type="radio"]),
  #raiz-react textarea{font-size:16px!important}
 }
 /* padding-inline (24/09): sem caixa, o recuo lateral do cartão só desalinha — o
    resumo da importação ficava 16 px para dentro e a lista da conciliação 32 px */
 body [data-slot="card"]{box-shadow:none!important;outline:0!important;border-radius:0!important;
  padding-inline:0!important;
  --tw-ring-shadow:0 0 rgba(0,0,0,0)!important;--tw-ring-offset-shadow:0 0 rgba(0,0,0,0)!important}
 body [data-slot="card"]+[data-slot="card"]{border-top:1px solid var(--fio)!important}
 /* o cabeçalho do card vira título de seção, e o corpo perde o respiro de caixa */
 body [data-slot="card-header"],body [data-slot="card-content"],
 body [data-slot="card-footer"]{padding-inline:0!important}
 /* Na tela de importar, cada linha de coluna é uma caixa feita com utilidades
    (`rounded-lg border bg-card`), não um <Card>. Vira linha de lista: fio
    embaixo, sem contorno e sem recuo. Campos, seletores e o aviso amarelo não
    entram aqui — eles não usam `bg-card`, e a borda deles é informação. */
 html #raiz-react div.border.bg-card,html #raiz div.border.bg-card{
  border-color:transparent!important;border-radius:0!important;
  border-bottom:1px solid var(--fio)!important;padding-inline:0!important}
}

/* 9. o que continua sendo caixa, de propósito: painel lateral, modal, popup,
      balão de ajuda, cartão de entrada, tutorial, o aviso do motor
      (.aviso-gap), as faixas da tela de Indicadores (.faixa, da v0.44) e os
      selos de status — todos têm classe própria e não são .card. */

/* ===========================================================================
   RESULTADO E CAIXA NO RADAR (v0.48.0, 26/09/2026)
   Pedido do Samuel: "uma opção de ver o fluxo de caixa e uma opção de ver o
   resultado econômico da obra no radar de risco". As duas visões usam a
   gramática dos Indicadores (.rel: UMA superfície, faixas com a margem do
   relógio, tabela densa — nada de mural de cartões) e três formas que dizem
   o grau de certeza, legíveis sem cor: CHEIO = aconteceu; CLARO = lançado;
   TRACEJADO = projetado pelo motor; só CONTORNO / pontilhado = hipótese (a
   receita potencial). Cor só por token: --brand entra, --cost sai, --ink é o
   saldo, --crit o que já foi (e o resultado, o pior caso ou o caixa abaixo de
   zero), --ok o que ainda dá para economizar (desde 27/09, a régua do
   vermelho; até ali era --crit tracejado) e a virada do caixa.
   =========================================================================== */
/* a chavinha do Radar: as duas leituras do risco, um fio, as duas do dinheiro.
   O fio é um <span> vazio: sem o padding das opções, da altura da pílula. */
.visao-troca>.visao-sep{align-self:stretch;width:1px;padding:0;margin:3px 3px;border-radius:0;background:var(--line)}

/* RESULTADO — a primeira linha (em português, a da prévia), a conta de quem
   entra na soma e os quatro números */
.res-manchete{font-size:16px;line-height:1.55;color:var(--ink);margin:0;max-width:80ch}
.res-manchete b{font-weight:600}
.res-crit{color:var(--crit-texto)}
.res-conta{font-size:12.5px;color:var(--muted);line-height:1.55;margin:-14px 0 0;max-width:96ch}
.rel-kpis.res-kpis{grid-template-columns:repeat(4,minmax(0,1fr))}
.res-kpi-faixa .val{font-size:19px;white-space:normal;line-height:1.25}
/* A BARRA DA MARGEM: de zero à margem orçada — sobra (cheio), o que ainda dá
   para economizar (tracejado VERDE: é a parte que a obra ainda pode trazer de
   volta), o cenário base (tracejado apagado) e o que já foi (cheio, vermelho:
   perda de fato) colado na ponta; embaixo, a faixa do resultado com o provável.
   Em HTML: a largura acompanha a coluna. As partes enchem da esquerda. */
.res-barra{position:relative;min-width:0}
.res-barra.grande{max-width:760px;margin-top:4px}
.res-barra.mini{margin-top:6px}
.res-trilho{position:relative;height:16px;border-radius:3px;background:var(--panel-2)}
.res-barra.mini .res-trilho{height:6px;border-radius:2px}
.res-seg{position:absolute;top:0;bottom:0;box-sizing:border-box;transform-origin:left;
 animation:encher var(--dur-lenta) var(--curva-saida) 200ms backwards}
.res-seg.sobra{background:var(--brand)}
.res-seg.evit{background:var(--ok-suave);border:1px dashed var(--ok)}
.res-seg.base{border:1px dashed var(--faint)}
.res-seg.jafoi{background:var(--crit-solido)}
.res-zero{position:absolute;top:-4px;bottom:-4px;width:1px;margin-left:-.5px;background:var(--ink);opacity:.55}
.res-fx{position:relative;height:14px;margin-top:6px}
/* (2px e não 1,5px: borda fracionária o Chrome arredonda para 1px — armadilha de 14/09) */
.res-bigode{position:absolute;top:6px;height:2px;margin-top:-1px;background:var(--ink);opacity:.8}
.res-bigode::before,.res-bigode::after{content:"";position:absolute;top:-4px;width:2px;height:10px;background:var(--ink)}
.res-bigode::before{left:0}
.res-bigode::after{right:0}
.res-prov{position:absolute;top:6px;width:10px;height:10px;margin:-5px 0 0 -5px;border-radius:50%;
 background:var(--panel);border:2px solid var(--ink)}
.res-legenda{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px 18px;font-size:12px;color:var(--muted)}
.res-legenda li{display:inline-flex;align-items:center;gap:6px}
.res-legenda b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.res-legenda i{width:12px;height:10px;border-radius:2px;box-sizing:border-box;flex:none}
.res-legenda i.sobra{background:var(--brand)}
.res-legenda i.evit{background:var(--ok-suave);border:1px dashed var(--ok)}
.res-legenda i.base{border:1px dashed var(--faint)}
.res-legenda i.jafoi{background:var(--crit-solido)}
.res-legenda i.fx{height:2px;background:var(--ink);border-radius:0}
/* OBRA A OBRA: oito colunas de largura fixa no desktop (o <colgroup> soma 100%);
   no celular a tabela vira cartão e cada célula é um bloco só (.cel) */
.res-tabela td{vertical-align:middle}
/* cabeçalho em duas linhas quando precisa: com o nowrap padrão, "AINDA DÁ PARA
   SEGURAR" passava por cima de "RECEITA PREVISTA" (retrato de 26/09) */
.res-tabela thead th{white-space:normal;line-height:1.35}
@media (min-width:701px){
 .res-tabela{table-layout:fixed}
 .res-tabela>:not(caption)>*>*{padding-left:8px;padding-right:8px}
}
.res-tabela .td-sub a{color:var(--brand-2)}
.res-tabela tfoot td{font-weight:600;border-top:1px solid var(--line);border-bottom:0;padding-top:10px}
.res-tabela tfoot .td-sub{font-weight:400}
/* quem volta do "Guardar" cai na linha da obra (âncora), abaixo da barra fixa, e ela acende */
.res-tabela tr[id]{scroll-margin-top:84px}
.res-tabela tbody tr:target>*{animation:destacar 1.5s var(--curva-saida)}
/* (16/10/2026) DE ONDE VEIO A DIFERENÇA — a ponte da obra entregue, do que o orçamento previa
   deixar ao que ela deixou: o rótulo, o valor (vermelho o que passou, verde o que sobrou) e o detalhe */
.res-ponte{max-width:980px;margin:0}
.res-ponte th{font-weight:500;color:var(--ink);white-space:nowrap;width:1%;padding-right:28px}
.res-ponte td.n{white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums;width:1%;padding-right:28px}
.res-ponte td.det{color:var(--muted);font-size:12.5px;line-height:1.5}
.res-ponte tr.total th,.res-ponte tr.total td{font-weight:600;border-top:1px solid var(--line);border-bottom:0}
.res-ponte tr.total td.det{font-weight:400}
@media (max-width:640px){.res-ponte th{white-space:normal;width:auto;padding-right:12px}.res-ponte td.n{padding-right:12px}}
.res-tag{display:inline-block;padding:0 6px;border-radius:999px;border:1px dashed var(--faint);font-size:11px;
 line-height:1.6;color:var(--muted);white-space:nowrap}
/* O MÉTODO FÁCIL: sem receita, a linha da obra pergunta quanto ela vai render — UM campo */
.res-pergunta .res-form{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;margin:0;padding:10px 12px;
 border:1px dashed var(--line);border-radius:6px;text-align:left}
.res-q{font-weight:600;color:var(--ink);font-size:13px;margin:0}
.res-campo{display:inline-flex;gap:6px;align-items:center}
.res-campo .form-control{width:170px}
.res-dica{flex-basis:100%;font-size:12px;color:var(--faint);line-height:1.45}
/* A RECEITA INFORMADA: uma linha por obra (nome | versões + corrigir), separadas por fio */
.res-hist{list-style:none;margin:0;padding:0}
.res-hist>li{display:grid;grid-template-columns:minmax(150px,220px) minmax(0,1fr);gap:4px 24px;padding:12px 0;
 border-top:1px solid var(--fio);scroll-margin-top:84px}
.res-hist>li:first-child{border-top:0;padding-top:0}
.res-hist-h{display:flex;flex-direction:column;gap:2px;font-size:13px}
.res-hist-h .rel-mudo{font-size:12px}
.res-versoes{list-style:none;margin:0;padding:0;font-size:12.5px}
.res-versoes li{display:grid;grid-template-columns:62px minmax(84px,auto) minmax(0,1fr);gap:10px;padding:2px 0;align-items:baseline}
.res-versoes .q{color:var(--faint);font-variant-numeric:tabular-nums}
.res-versoes .v{font-weight:500;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.res-versoes .m{color:var(--muted)}
.res-versoes .m b{font-weight:500;color:var(--ok-texto)}
.res-aditivo{grid-column:2;margin-top:4px}
.res-aditivo>summary{font-size:12.5px}
.res-form-adit{display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px 14px;margin:10px 0 0}
.res-form-adit .filtro{flex-direction:column;align-items:flex-start;gap:3px}
.res-form-adit .dinheiro{width:160px}
.res-nota-form{font-size:12px;color:var(--faint);margin:8px 0 0;line-height:1.5;max-width:80ch}
.res-como .graf-nota p{margin:0 0 8px}

/* CAIXA — o gráfico mês a mês: colunas em camadas acima (entra) e abaixo (sai)
   do zero, o saldo acumulado em linha, o pior momento e a virada em anéis */
.graf-caixa svg{height:250px}
.cx-grade{stroke:var(--line);stroke-dasharray:2 4}
.cx-col{animation:surgir var(--dur-media) var(--curva-saida) 120ms backwards}
.cx-ent{fill:var(--brand)}
.cx-sai{fill:var(--cost)}
.cx-col.cx-lanc{fill-opacity:.38}
.cx-pot{fill:var(--brand);fill-opacity:.05;stroke:var(--brand);stroke-width:1px;stroke-dasharray:2 2}
.cx-proj{fill:var(--cost);fill-opacity:.16;stroke:var(--cost);stroke-width:1px;stroke-dasharray:4 3}
.cx-saldo{stroke:var(--ink)}
.cx-saldo-proj{stroke:var(--ink);stroke-width:var(--graf-traco-sec);stroke-dasharray:5 4;
 animation:surgir var(--dur-media) var(--curva-saida) 400ms backwards}
.cx-saldo-pot{stroke:var(--brand);stroke-width:var(--graf-traco);stroke-dasharray:1 4;stroke-linecap:round;
 animation:surgir var(--dur-media) var(--curva-saida) 480ms backwards}
/* as bolinhas de cada mês só aparecem ao LER a coluna (39 meses × 2 linhas
   seriam um colar de contas); o que fica sempre à vista são os dois anéis */
.graf-caixa .graf-pt:not(.on){opacity:0}
.graf-pt.pot{--pt:var(--brand)}
.cx-marca{position:absolute;width:11px;height:11px;margin:-5.5px 0 0 -5.5px;border-radius:50%;background:var(--panel);
 border:2px solid var(--c);pointer-events:none;z-index:2;animation:pt-entrar var(--dur-media) var(--curva-saida) 460ms backwards}
.cx-marca.pico{--c:var(--crit)}
.cx-marca.vira{--c:var(--ok)}
/* no cartão do mês (noturno nos dois temas) as amostras usam os tokens --barra-* */
.graf-tip .sw.ent{--sw:var(--barra-acento)}
.graf-tip .sw.sai{--sw:var(--barra-muted)}
.graf-tip .sw.lanc{opacity:.5}
.graf-tip .sw.pot,.graf-tip .sw.proj{background:transparent;box-shadow:inset 0 0 0 1.5px var(--sw)}
.graf-tip .sw.pot{--sw:var(--barra-acento)}
.graf-tip .sw.proj{--sw:var(--barra-muted)}
.legend-inline i.cx-l-ent{background:var(--brand)}
.legend-inline i.cx-l-sai{background:var(--cost)}
.legend-inline i.cx-l-lanc{opacity:.38}
.legend-inline i.cx-l-pot{background:transparent;border:1px dashed var(--brand);box-sizing:border-box}
.legend-inline i.cx-l-proj{background:transparent;border:1px dashed var(--cost);box-sizing:border-box}
.legend-inline i.cx-l-saldo{background:var(--ink);color:var(--ink)}
.legend-inline i.tracejado.cx-l-saldo,.legend-inline i.pontilhado{background:none}
.legend-inline i.cx-l-pot-linha{color:var(--brand)}
.legend-inline i.cx-l-marca{width:10px;height:10px;border-radius:50%;border:2px solid var(--c);box-sizing:border-box}
.legend-inline i.cx-l-marca.pico{--c:var(--crit)}
.legend-inline i.cx-l-marca.vira{--c:var(--ok)}
.rel-kpis.cx-kpis{grid-template-columns:repeat(5,minmax(0,1fr))}
.rel-kpis.cx-kpis.tres{grid-template-columns:repeat(3,minmax(0,1fr))}
.cx-tabela tr.hoje>*{font-weight:600}
/* o que o cálculo NÃO sustenta: à vista, logo depois do gráfico */
.cx-avisos-box{border-top:1px solid var(--fio);padding-top:14px}
.cx-avisos{list-style:none;margin:6px 0 0;padding:0;display:flex;flex-direction:column;gap:6px;max-width:96ch}
.cx-avisos li{position:relative;padding-left:16px;font-size:12.5px;line-height:1.5;color:var(--muted)}
.cx-avisos li::before{content:"";position:absolute;left:2px;top:.55em;width:6px;height:6px;border-radius:50%;background:var(--warn)}
/* obra a obra: a escolhida acesa, as outras apagadas (o filtro cruzado dos Indicadores) */
.cx-obras td{vertical-align:middle}
.cx-obras tbody tr{transition:opacity var(--dur-rapida)}
.cx-obras.tem-sel tbody tr:not(.sel){opacity:.5}
.cx-obras.tem-sel tbody tr:not(.sel):hover{opacity:1}
.cx-obras tbody tr.sel>*{background:var(--brand-suave)}
/* MESMA TELA, OUTRO FILTRO (a regra de 23/09): trocar a obra do caixa ou voltar
   do "Guardar" não refaz a entrada das peças novas */
:root[data-entrada="mesma"] :is(.cx-col,.cx-saldo-proj,.cx-saldo-pot,.cx-marca,.res-seg){animation:none}
@media (max-width:1199.98px){
 .rel-kpis.res-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
 .rel-kpis.cx-kpis{grid-template-columns:repeat(3,minmax(0,1fr))}
}
@media (max-width:700px){
 .rel-kpis.res-kpis,.rel-kpis.cx-kpis,.rel-kpis.cx-kpis.tres{grid-template-columns:repeat(2,minmax(0,1fr))}
 .res-manchete{font-size:15px}
 .res-conta{margin-top:-8px}
 .res-tabela td.res-pergunta{display:block;text-align:left}
 .res-tabela td.res-pergunta::before{display:block;margin-bottom:6px}
 /* rótulo comprido + valor comprido ("MARGEM ORÇADA → PREVISTA" | "R$ 17,5 mi → R$ 2,4 mi")
    não cabem lado a lado em 321 px: o valor desce, à direita, em vez de vazar */
 .res-tabela td{flex-wrap:wrap;row-gap:2px}
 .res-tabela td>.cel{margin-left:auto}
 .res-campo{display:flex;width:100%}
 .res-campo .form-control{width:auto;flex:1 1 auto;min-width:0}
 .res-barra.mini{width:140px;margin-left:auto}
 .res-hist>li{grid-template-columns:minmax(0,1fr)}
 .res-aditivo{grid-column:1}
 .res-form-adit .filtro,.res-form-adit .dinheiro{width:100%}
 .graf-caixa svg{height:200px}
 .graf-caixa .graf-x span.cx-2{display:none}
}
/* fim: RESULTADO E CAIXA NO RADAR (a checagem de cor literal lê daqui para cima) */

/* ===========================================================================
   (v0.50.0: esta linha de abertura tinha sumido no merge da v0.49.0 — o texto
   abaixo ficava FORA do comentário e o navegador descartava a regra `.cal`
   inteira, com --cal-h, --marca-tam, --regua, o fundo e a borda da agenda.
   Há checagem: todo fecho de comentário do arquivo tem a sua abertura.)
   AGENDA DE COMPROMISSOS (26/09/2026) — o calendário É a tela Compromissos.
   Desenho "MOSAICO" (4ª versão do dia). O que ficou de cada rodada:
   - da 1ª (aprovada nas funções): a estrutura de calendário de verdade;
   - o que o Miguel NÃO quis: grade de linhas finas estilo Teams (1ª e 2ª) e a
     tela aberta, sem estrutura, com tracinhos (3ª — "péssimo e estranho");
   - o que ele gostou: o sol da Lumiset marcando o hoje.
   Então: um painel com os dias em QUADROS levemente rebaixados (--ground sobre
   --panel, com respiro entre eles — nenhuma linha de grade); o dia de hoje em
   azul-claro com o sol; compromisso como ETIQUETA suave na cor da situação
   (âmbar pendente, verde concluído); e a hora atual do jeito que se lê: um
   selo com a hora exata na régua, um fio leve pela semana e o fio cheio, com o
   sol, no dia de hoje.
   Cor só de token; números e título em Poppins (--titulo).
   =========================================================================== */
.cal{--cal-h:44px;--marca-tam:7px;--regua:52px;background:var(--panel);border:1px solid var(--line);border-radius:14px;
 padding:18px 18px 14px;min-width:0}

/* ---- a barra: o período é o título da agenda ---- */
.cal-barra{display:flex;align-items:center;justify-content:space-between;gap:12px 24px;flex-wrap:wrap;margin-bottom:16px}
.cal-periodo{display:flex;align-items:center;gap:6px 14px;flex-wrap:wrap;min-width:0}
.cal-titulo{font-family:var(--titulo);font-size:24px;font-weight:600;letter-spacing:-.02em;line-height:1.15;margin:0;
 color:var(--ink);min-width:0}
.cal-titulo .ano{font-weight:400;color:var(--faint)}
.cal[data-vista="semana"] .cal-titulo,.cal[data-vista="dia"] .cal-titulo{font-size:19px}
.cal-nav{display:inline-flex;align-items:center;gap:2px;padding:2px;border-radius:18px;background:var(--ground)}
.cal-seta,.cal-hoje{border:0;background:transparent;color:var(--muted);height:30px;border-radius:15px;cursor:pointer;
 display:inline-flex;align-items:center;justify-content:center;
 transition:background-color var(--dur-rapida),color var(--dur-rapida)}
.cal-seta{width:30px}
.cal-hoje{gap:6px;padding:0 12px 0 9px;font-size:13px;font-weight:500;color:var(--ink)}
.cal-hoje svg{color:var(--brand)}
.cal-seta:hover,.cal-hoje:hover{background:var(--panel);color:var(--ink)}
.cal-dir{display:flex;align-items:center;gap:8px 20px;flex-wrap:wrap}
.cal-vistas{position:relative;display:flex;gap:18px}
.cal-vistas .aba{min-height:36px}
.cal-vistas.js .aba.on{border-bottom-color:transparent}      /* quem mostra a vista ativa é o traço que desliza */
/* como o .ind das abas: 1 px de largura esticado por scaleX — anima só transform */
.cal-traco{position:absolute;left:0;bottom:0;width:1px;height:var(--sel-traco);background:var(--selecao);opacity:0;
 transform-origin:left;pointer-events:none}
.cal-vistas.js .cal-traco{opacity:1}
.cal-vistas.pronto .cal-traco{transition:transform var(--dur-media) var(--curva-saida)}
.cal-novo{display:inline-flex;align-items:center;gap:6px}
.cal-corpo{min-width:0}

/* ---- mês: os dias em quadros, sem linhas de grade ---- */
.cal-sem,.cal-grade{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px}
.cal-sem>div{padding:0 10px 4px;font-size:12px;font-weight:500;color:var(--faint)}
.cal-sem>.fds{color:var(--desab)}
.cal-grade{grid-auto-rows:minmax(106px,auto)}
.cal-dia{position:relative;min-width:0;padding:6px 6px 8px;display:flex;flex-direction:column;gap:3px;border-radius:10px;
 background:var(--ground);user-select:none;-webkit-user-select:none;
 transition:background-color var(--dur-rapida),box-shadow var(--dur-rapida)}
.cal-dia:hover{box-shadow:inset 0 0 0 1px var(--line)}
.cal-dia.fora{background:transparent}                        /* os dias do mês vizinho ficam sem quadro */
.cal-dia-topo{display:flex;align-items:center;gap:2px;min-height:28px}
.cal-num{border:0;background:transparent;color:var(--ink);font-family:var(--titulo);font-size:14px;font-weight:600;
 min-width:28px;height:28px;padding:0 6px;border-radius:14px;font-variant-numeric:tabular-nums;line-height:28px;text-align:center}
button.cal-num{cursor:pointer;transition:background-color var(--dur-rapida)}
button.cal-num:hover{background:var(--nav-on)}
.cal-dia.fds .cal-num{color:var(--muted)}
.cal-dia.fora .cal-num{color:var(--desab);font-weight:500}
/* hoje: o quadro fica azul-claro e o sol da Lumiset nasce ao lado do número */
.cal-sol{display:inline-grid;place-items:center;width:24px;height:24px;flex:none}
.cal-dia.hoje,.cal-inteiro-dia.hoje{background:var(--brand-suave)}
.cal-dia.hoje .cal-num{color:var(--ink)}
/* o dia marcado com um clique: contorno azul (a cor da marca, não o vermelho de risco) */
.cal-dia.sel,.cal-dia.sel:hover,.cal-inteiro-dia.sel{box-shadow:inset 0 0 0 1.5px var(--brand-borda)}
.cal-add{margin-left:auto;border:0;background:transparent;color:var(--faint);width:26px;height:26px;border-radius:13px;
 display:grid;place-items:center;opacity:0;cursor:pointer;transition:opacity var(--dur-rapida),background-color var(--dur-rapida)}
.cal-dia:hover .cal-add,.cal-add:focus-visible{opacity:1}
.cal-add:hover{background:var(--nav-on);color:var(--ink)}
.cal-mais{border:0;background:transparent;color:var(--brand-2);font-size:12px;font-weight:500;text-align:left;
 padding:1px 7px;cursor:pointer;align-self:flex-start;border-radius:6px}
.cal-mais:hover{background:var(--nav-on)}

/* ---- o compromisso: etiqueta suave na cor da situação ---- */
.s-pendente{--cal-cor:var(--warn);--cal-suave:var(--warn-suave)}
.s-concluido{--cal-cor:var(--ok);--cal-suave:var(--ok-suave)}
.s-cancelado{--cal-cor:var(--faint);--cal-suave:var(--nav-on)}
/* a tinta da situação vai por cima da cor do PAINEL (camada), e não do quadro: no
   quadro azul de hoje a etiqueta âmbar continuaria âmbar, sem virar cinza */
.cal-ev{display:block;width:100%;min-width:0;text-align:left;border:0;border-radius:7px;
 background:linear-gradient(var(--cal-suave),var(--cal-suave)) var(--panel);
 color:var(--ink);padding:4px 8px 5px 20px;position:relative;font-size:12px;line-height:1.3;cursor:pointer;
 transition:box-shadow var(--dur-rapida)}
.cal-ev:hover{box-shadow:inset 0 0 0 1px var(--cal-cor)}
/* a marca: anel enquanto pendente, cheia quando concluído (a forma muda, não só a cor) */
.cal-ev::before,.cal-marca::before,.cal-fantasma::before{content:"";position:absolute;left:8px;top:8px;
 width:var(--marca-tam);height:var(--marca-tam);box-sizing:border-box;border-radius:50%;border:1.5px solid var(--cal-cor);background:transparent}
.cal-ev.s-concluido::before,.cal-marca.s-concluido::before{background:var(--cal-cor)}
.cal-ev-t,.cal-ev-c,.cal-ev-r{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal-ev-t{font-weight:600}
.cal-ev-c,.cal-ev-r{color:var(--muted)}
.cal-ev-h{font-family:var(--titulo);font-weight:600;font-variant-numeric:tabular-nums;margin-right:5px}
.cal-ev.s-concluido .cal-ev-t{font-weight:500;color:var(--muted)}
.cal-ev.s-cancelado .cal-ev-t{color:var(--faint);text-decoration:line-through}
.cal-ev.arrastando{opacity:.35}
/* o recém-criado pisca com o MESMO destaque da linha nova das tabelas */
.cal-ev.recente{animation:destacar 1.5s var(--curva-entrada) 240ms backwards}
.cal-dia.alvo,.cal-inteiro-dia.alvo,.cal-col.alvo{box-shadow:inset 0 0 0 1.5px var(--brand);background-color:var(--brand-suave)}

/* ---- semana e dia: colunas em quadros, a hora atual bem à vista ---- */
.cal-agenda{--colunas:var(--regua) repeat(var(--dias),minmax(0,1fr))}
.cal-cab,.cal-inteiro,.cal-horas{display:grid;grid-template-columns:var(--colunas);column-gap:6px}
/* a barra de rolagem das horas come largura: o cabeçalho e a linha "dia inteiro"
   reservam a MESMA calha, senão as colunas de cima e de baixo desalinham */
.cal-cab,.cal-inteiro{overflow:hidden;scrollbar-gutter:stable}
.cal-cab-dia{display:flex;align-items:center;gap:6px;padding:0 8px 8px;min-width:0}
.cal-cab-dia .sem{font-size:12px;font-weight:500;color:var(--faint)}
.cal-cab-dia .cal-num{font-size:17px}
.cal-cab-dia.fds .sem,.cal-cab-dia.fds .cal-num{color:var(--desab)}
.cal-cab-dia.hoje .sem{color:var(--brand-2)}
.cal-inteiro{margin-bottom:6px}
.cal-rot{font-size:11px;color:var(--faint);padding:8px 10px 0 0;text-align:right;line-height:1.2}
.cal-inteiro-dia{min-width:0;min-height:38px;padding:4px;display:flex;flex-direction:column;gap:3px;border-radius:10px;
 background:var(--ground);user-select:none;-webkit-user-select:none}
.cal-rolagem{max-height:min(66vh,620px);overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable}
.cal-horas{position:relative}
.cal-regua>div{height:var(--cal-h);font-family:var(--titulo);font-size:11px;color:var(--faint);text-align:right;
 padding-right:8px;transform:translateY(-.65em);font-variant-numeric:tabular-nums}
.cal-col{position:relative;min-width:0;height:calc(24 * var(--cal-h));border-radius:10px;background-color:var(--ground);
 background-image:linear-gradient(var(--fio) 1px,transparent 1px);background-size:100% var(--cal-h);
 user-select:none;-webkit-user-select:none}
.cal-col.hoje{background-color:var(--brand-suave)}
/* a etiqueta começa NA hora (topo 1 px abaixo da linha — o arrastar usa o mesmo
   número) e tem meia hora de altura: não sugere uma duração que ninguém informou */
.cal-etiqueta{position:absolute;top:calc(var(--ini) * var(--cal-h) / 60 + 1px);height:calc(var(--cal-h) / 2 - 2px);
 left:calc(100% / var(--n) * var(--k) + 3px);width:calc(100% / var(--n) - 6px);z-index:1;
 padding:0 8px 0 20px;line-height:calc(var(--cal-h) / 2 - 2px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal-etiqueta::before{top:calc(50% - var(--marca-tam) / 2)}
/* na régua de horas a etiqueta é UMA linha (hora, tipo, cliente); no dia, a linha
   dia inteiro também corre assim, com o responsável junto */
.cal-etiqueta .cal-ev-t,.cal-etiqueta .cal-ev-c,.cal-etiqueta .cal-ev-r,
.um-dia .cal-ev .cal-ev-t,.um-dia .cal-ev .cal-ev-c,.um-dia .cal-ev .cal-ev-r{display:inline;margin-right:10px}
/* A HORA AGORA: o selo com a hora exata fica na régua, o fio tracejado atravessa a
   semana (dá para ver "que horas são" em qualquer dia) e, no dia de hoje, o fio
   é cheio e sai do sol da Lumiset */
.cal-agora-fio{position:absolute;left:var(--regua);right:0;top:calc(var(--ini) * var(--cal-h) / 60);height:0;
 border-top:1px dashed var(--brand);z-index:2;pointer-events:none}
.cal-agora-hora{position:absolute;right:calc(100% + 4px);top:-10px;min-width:44px;height:20px;padding:0 6px;border-radius:10px;
 background:var(--brand-solido);color:var(--sobre-solido);font-family:var(--titulo);font-size:11px;font-weight:600;
 line-height:20px;text-align:center;font-variant-numeric:tabular-nums}
.cal-agora{position:absolute;left:0;right:0;top:calc(var(--ini) * var(--cal-h) / 60);height:2px;margin-top:-1px;
 background:var(--brand);z-index:3;pointer-events:none}
.cal-agora .cal-sol{position:absolute;left:-4px;top:-11px;width:22px;height:22px;border-radius:50%;background:var(--panel)}
.cal-fantasma{position:absolute;left:3px;right:3px;top:calc(var(--ini) * var(--cal-h) / 60 + 1px);
 height:calc(var(--cal-h) / 2 - 2px);border:1px dashed var(--brand);border-radius:7px;padding:0 8px 0 20px;
 font-family:var(--titulo);font-size:11.5px;line-height:calc(var(--cal-h) / 2 - 4px);color:var(--brand-2);
 font-variant-numeric:tabular-nums;pointer-events:none;z-index:4;--cal-cor:var(--brand)}
.cal-fantasma::before{top:calc(50% - var(--marca-tam) / 2)}

/* ---- rodapé: legenda e como usar ---- */
.cal-rodape{display:flex;justify-content:space-between;align-items:center;gap:6px 18px;flex-wrap:wrap;
 margin-top:14px;font-size:12px;color:var(--faint)}
.cal-legenda{display:flex;gap:18px}
.cal-marca{position:relative;padding-left:18px}
.cal-marca::before{left:3px;top:4px}
.so-toque{display:none}
@media (hover:none){.so-mouse{display:none}.so-toque{display:inline}}

/* ---- o painel do compromisso (o painel lateral do Radar) ---- */
.cal-situacao{margin-top:8px}
.cal-campos{display:grid;grid-template-columns:104px minmax(0,1fr);gap:10px 12px;margin:4px 0 0;font-size:13.5px}
.cal-campos dt{font-weight:400;font-size:12.5px;color:var(--faint);padding-top:1px}
.cal-campos dd{margin:0;white-space:pre-line;overflow-wrap:anywhere}
.cal-campos dd.nada{color:var(--desab)}
.cal-excluir{margin-top:22px;padding-top:14px;border-top:1px solid var(--fio)}
.cal-form .form-text{font-size:12px;color:var(--faint)}
.cal-form textarea{resize:vertical}
.cal-erro{color:var(--crit);font-size:13px;margin:12px 0 0}
.cal-erro:empty{display:none}

/* ---- celular: o mês vira marcas, e tocar no dia abre o dia ---- */
@media (max-width:640px){
 .cal{padding:12px 8px 10px;border-radius:12px}
 .cal-barra{margin-bottom:12px}
 .cal-titulo{font-size:20px}
 .cal[data-vista="semana"] .cal-titulo,.cal[data-vista="dia"] .cal-titulo{font-size:16px}
 .cal-dir{width:100%;justify-content:space-between;gap:8px}
 .cal-sem,.cal-grade{gap:3px}
 .cal-sem>div{padding:0 0 4px;text-align:center;font-size:11px}
 .cal-grade{grid-auto-rows:minmax(58px,auto)}
 .cal-dia{flex-direction:row;flex-wrap:wrap;justify-content:center;align-content:flex-start;gap:3px;padding:4px 2px;
  border-radius:8px;cursor:pointer}
 .cal-dia-topo{flex-basis:100%;justify-content:center;gap:0}
 .cal-dia .cal-sol{width:15px;height:15px;margin-right:-1px}
 .cal-dia .cal-sol svg{width:15px;height:15px}
 .cal-num{font-size:13px;min-width:24px;height:24px;line-height:24px;padding:0 3px}
 .cal-add{display:none}
 .cal-mes .cal-ev{width:var(--marca-tam);height:var(--marca-tam);padding:0;background:transparent;pointer-events:none}
 .cal-mes .cal-ev::before{left:0;top:0}
 .cal-mes .cal-ev .cal-ev-t,.cal-mes .cal-ev .cal-ev-c{display:none}
 .cal-mes .cal-mais{padding:0 2px;font-size:11px;line-height:var(--marca-tam);pointer-events:none}
 .cal[data-vista="semana"] .cal-corpo{overflow-x:auto}
 .cal[data-vista="semana"] .cal-agenda{min-width:640px}
 .cal-campos{grid-template-columns:88px minmax(0,1fr)}
}

/* ===========================================================================
   RADAR ENXUTO — A ECONOMIA PRIMEIRO (v0.50.0, 26/09/2026)
   O Samuel aprovou a prévia enxuta (".tmp/previa-radar-economia/", bloco
   ENXUTA): "gostei dessa tela mais enxuta, mas tem que passar o gráfico pra
   cima de obras em andamento". Ordem da tela: manchete → gráfico → tabela →
   "Ver os detalhes técnicos" → "O que o Prisma já mostrou". Três regras:
   (1) a MANCHETE é o maior número da tela, em --ok (o dinheiro que ainda dá
       para economizar); os três fatos ao lado ficam pequenos, em tinta;
   (2) o texto do estado é tinta, com o PONTO colorido. (Até 26/09 o vermelho
       morava só no ponto; desde 27/09 vale a RÉGUA DO VERMELHO, no bloco
       seguinte: vermelho é o que o cliente perdeu ou vai perder — o que já
       saiu, o custo final acima do orçado com alerta, a entrega depois do
       contrato, a projeção do custo com R$ em risco.)
   (3) cada número tem no máximo UMA linha de apoio; o resto fica a um clique
       (o painel da linha, o "i", as dobras).
   Cor só por token: a checagem de cor literal lê daqui até o "fim:".
   =========================================================================== */
/* (1) A MANCHETE: sem caixa, na gramática da página; os fatos à direita */
.eco-topo{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:32px;align-items:end;padding:4px 2px 6px}
.eco-man .lab{font-size:14px;font-weight:500;color:var(--ink)}
.eco-man .val{font-family:var(--titulo);font-size:48px;font-weight:600;letter-spacing:-.025em;line-height:1.05;
 color:var(--ok);margin-top:4px;font-variant-numeric:tabular-nums;white-space:nowrap}
.eco-man .val.eco-nada{font-size:28px;color:var(--faint);white-space:normal}
.eco-man .sub{font-size:14px;color:var(--muted);margin:6px 0 0}
.eco-man .sub a{color:var(--ink);font-weight:500}
.eco-man .sub .ajuda{margin-left:6px;vertical-align:-2px}
.eco-fatos{list-style:none;margin:0;padding:0 0 4px;display:flex;flex-direction:column;gap:8px;font-size:13.5px;
 color:var(--muted);text-align:right}
.eco-fatos b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
/* (2) "OBRAS EM ANDAMENTO": a obra com a palavra do estado embaixo e o dinheiro
   primeiro. O estado é texto em tinta com o ponto colorido; o que não tem número
   fica apagado com a razão; os avisos (medição velha) em --warn. */
.eco-tabela td{padding-top:14px;padding-bottom:14px}
.eco-tabela td.principal{min-width:200px}
.eco-tabela .nome{font-weight:600;color:var(--ink);text-decoration:none}
.eco-tabela .linha-clic:hover .nome{color:var(--brand-2)}
.eco-tabela .v,.eco-tec .v{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.eco-tabela .v.oport{color:var(--ok-texto)}
.eco-tabela .mudo,.eco-tec .mudo{color:var(--faint)}
.eco-aviso{color:var(--warn)}
.estado.eco-estado{color:var(--ink);font-size:12px}
.estado.eco-estado.b-crit::before{background:var(--crit)}
.estado.eco-estado.b-warn::before{background:var(--warn)}
.estado.eco-estado.b-ok::before{background:var(--ok)}
.estado.eco-estado.b-novo{color:var(--muted)}
.estado.eco-estado.b-novo::before{background:var(--faint)}
/* (3) "VER OS DETALHES TÉCNICOS": a tabela do motor, fechada na chegada */
.eco-tecnico{margin-top:14px}
.eco-tecnico .tabela-rolavel{margin-top:6px}
.eco-tec{font-size:12.5px}
/* (4) o "MAIS" do cabeçalho: a importação e, sob um rótulo, a lista do aditivo */
.acao-lista .acao-grupo{padding:9px 10px 3px;font-size:11px;letter-spacing:.05em;text-transform:uppercase;
 color:var(--faint)}
.acao-lista a+.acao-grupo{margin-top:4px;border-top:1px solid var(--fio)}
/* (5) "O QUE O PRISMA JÁ MOSTROU": uma linha com fio em cima. Dobrados, a linha
   do tempo início → primeiro alerta → entrega (anel = momento; o trecho verde é
   o tempo entre o alerta e a entrega), os dois fatos e a conta dita. */
.eco-mostrou{margin-top:6px;padding:14px 2px 0;border-top:1px solid var(--fio);font-size:14px;color:var(--ink)}
.eco-mostrou>details>summary{color:var(--ink);font-size:14px;align-items:baseline}
.eco-mostrou .eco-frase{flex:0 1 auto}
.eco-mostrou .eco-frase b{font-weight:600;color:var(--ok-texto)}
.eco-mostrou .dobra-res{flex:0 0 auto}
.eco-mostrou-corpo{padding:14px 0 4px;max-width:720px}
.eco-linha{position:relative;max-width:560px;margin:2px 6px 4px}
.eco-chave{font-size:12px;font-weight:600;color:var(--ok-texto);text-align:center;margin-bottom:6px;line-height:1.3}
.eco-trilho{position:relative;height:6px;border-radius:3px;background:var(--panel-2)}
.eco-folga{position:absolute;top:0;bottom:0;border-radius:3px;background:var(--ok)}
.eco-mk{position:absolute;top:50%;width:12px;height:12px;margin:-6px 0 0 -6px;border-radius:50%;
 background:var(--panel);box-shadow:inset 0 0 0 2px var(--ink)}
.eco-rots{position:relative;height:34px;margin-top:8px;font-size:11.5px;color:var(--muted);line-height:1.35;
 font-variant-numeric:tabular-nums}
.eco-rots span{position:absolute;top:0;transform:translateX(-50%);text-align:center;white-space:nowrap}
.eco-rots .ini{transform:none;text-align:left}
.eco-rots .fim{transform:translateX(-100%);text-align:right}
.eco-rots .apertado{display:none}
.eco-fatos-obra{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:6px;font-size:13px;
 color:var(--ink);line-height:1.5;max-width:66ch}
.eco-fatos-obra li{display:grid;grid-template-columns:62px minmax(0,1fr);gap:10px}
.eco-fatos-obra b{font-weight:600;font-variant-numeric:tabular-nums}
.eco-nota{font-size:12.5px;color:var(--muted);line-height:1.55;margin:10px 0 0;max-width:80ch}
@media (max-width:700px){
 .eco-topo{grid-template-columns:minmax(0,1fr);gap:14px;align-items:start}
 .eco-fatos{text-align:left}
 .eco-man .val{font-size:40px}
 /* no cartão do celular, rótulo comprido + valor com apoio não cabem lado a
    lado: o bloco do valor desce, à direita (a armadilha do .nw, 26/09) */
 .eco-tabela td,.eco-tec td{flex-wrap:wrap}
 .eco-tabela td>.cel,.eco-tec td>.cel{margin-left:auto;text-align:right}
 .eco-tabela td>.cel .td-sub,.eco-tec td>.cel .td-sub{white-space:normal}
 /* os resumos das dobras ficam de fora (o título basta numa tela estreita) */
 .eco-tecnico .dobra-res,.eco-mostrou .dobra-res{display:none}
 .eco-rots span.meio{display:none}
 .eco-fatos-obra li{grid-template-columns:minmax(0,1fr);gap:0}
}
/* fim: RADAR ENXUTO (a checagem de cor literal lê este bloco) */

/* ===========================================================================
   A RÉGUA DO VERMELHO (27/09/2026)
   Pedido do Samuel: "tudo o que o cara for perder coloque em vermelho". A
   regra, para o sistema todo:
     VERMELHO (--crit) = o que o cliente PERDEU (fato: o que já saiu do
       previsto, o estouro de uma obra entregue) ou VAI PERDER pela projeção do
       motor COM alerta (custo final acima do orçado, a projeção do custo com R$
       em risco), mais o que fica abaixo de zero (resultado, pior caso, margem,
       o pior momento do caixa) e o TEMPO perdido (entrega 1 mês ou mais depois
       do contrato);
     VERDE (--ok) = o que AINDA DÁ PARA ECONOMIZAR;
     o resto, NEUTRO — inclusive o cenário base de obra sem alerta (o motor não
       chama de perda) e a saída normal de caixa.
   Duas classes de texto servem a todas as telas: .perda e .oport (o -texto de
   cada cor, o tom de contraste para letra pequena). Nos números grandes dos
   relatórios valem .v-crit/.v-ok, que já existiam. As regras com mais classes
   vencem a tinta que a tabela do Radar dá a todo valor (.eco-tabela .v).
   Cor só por token: a checagem de cor literal lê este bloco até o "fim:".
   =========================================================================== */
.perda{color:var(--crit-texto)}
.oport{color:var(--ok-texto)}
.eco-tabela .v.perda,.eco-tec .v.perda,.eco-fatos b.perda,.td-sub .perda{color:var(--crit-texto)}
.eco-tabela .v.oport{color:var(--ok-texto)}
/* o "já foi" de obra SEM alerta, na barra da margem e na legenda: é fato, mas
   "abaixo do alerta" (o motor não o aponta como perda) — cheio e NEUTRO */
.res-seg.jafoi.abaixo,.res-legenda i.jafoi.abaixo{background:var(--faint)}
/* fim: A RÉGUA DO VERMELHO (a checagem de cor literal lê este bloco) */

/* ===========================================================================
   RESULTADO DE UMA OBRA (27/09/2026)
   Pedido do Samuel: "o resultado tem que conseguir ver por obra também". O
   molde do Caixa: o menu "Obra ▾" no alto (.rel-filtros, que já existia), a
   primeira faixa com a conta DESTA obra, a tabela com ela acesa (as outras a
   meia força, como no Caixa) e a receita só dela. Sem receita, a pergunta
   "Quanto esta obra vai render?" é o conteúdo principal — maior, sem caixa
   nova (o tracejado do método fácil). Cor só por token.
   =========================================================================== */
.res-links{margin:-6px 0 0;font-size:13px;color:var(--muted)}
.res-links a{color:var(--brand-2)}
.rel-kpis.res-kpis.tres{grid-template-columns:repeat(3,minmax(0,1fr))}
/* (as regras do método fácil valem dentro da célula da tabela, .res-pergunta; a
   visão da obra repete o desenho: flex que quebra, a dica na linha de baixo, o
   tracejado de "falta um número") */
.res-pergunta-obra .res-form{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin:0;padding:14px 16px;
 border:1px dashed var(--line);border-radius:6px;max-width:760px}
.res-pergunta-obra .res-q{font-size:16px}
.res-pergunta-obra .res-campo .form-control{width:220px}
.res-tabela tbody tr{transition:opacity var(--dur-rapida)}
.res-tabela.tem-sel tbody tr:not(.sel){opacity:.5}
.res-tabela.tem-sel tbody tr:not(.sel):hover{opacity:1}
.res-tabela tbody tr.sel>*{background:var(--brand-suave)}
@media (max-width:700px){
 .rel-kpis.res-kpis.tres{grid-template-columns:repeat(2,minmax(0,1fr))}
 .res-pergunta-obra .res-campo .form-control{width:auto}
}
/* fim: RESULTADO DE UMA OBRA (a checagem de cor literal lê este bloco) */

/* ===========================================================================
   O RELATÓRIO POC (27/09/2026) — Financeiro › Relatórios › "POC (evolução
   contábil)". A tabela do contador, no padrão das outras visões (filtros em
   linha + caixa de tabela), com o cabeçalho em dois andares (Evolução · Custo ·
   Receita · Resultado · Margem) e um fio fino no começo de cada grupo (.g0). O
   que o Prisma acrescenta: o físico medido ao lado do POC e, na evolução mês a
   mês, duas barrinhas — o POC na cor do CUSTO em cima, o físico na cor da OBRA
   embaixo (as cores dos gráficos). Vermelho só no que é perda (POC acima de
   100%, margem ou resultado negativos: .perda, da régua do vermelho); avisos em
   --warn. Cor só por token.
   =========================================================================== */
.poc-leitura{font-size:13.5px;line-height:1.55;color:var(--ink);margin:0;max-width:100ch}
.poc-resumo{font-size:13px;line-height:1.5;color:var(--muted);margin:-8px 0 0;max-width:100ch}
.poc-resumo b{color:var(--ink);font-weight:600}
.poc-tabela{font-size:12.5px}
.poc-tabela>:not(caption)>*>*{padding-left:8px;padding-right:8px}
/* doze colunas a 1280 px: o cabeçalho quebra linha ("ORÇAMENTO / VIGENTE", "MARGEM /
   ORÇADA") para a coluna da obra não ficar com uma palavra por linha (retrato de 27/09) */
.poc-tabela thead th{white-space:normal;line-height:1.3}
.poc-tabela td.principal{min-width:150px}
.poc-tabela .nw,.poc-evol-tab .nw{white-space:nowrap}
.poc-tabela thead tr.poc-grupos th{border-bottom:0;padding-bottom:0}
.poc-tabela thead th.poc-grupo{text-align:center;color:var(--muted);box-shadow:inset 0 -1px 0 var(--line)}
.poc-tabela .g0{border-left:1px solid var(--fio)}
.poc-tabela tfoot td{font-weight:600;border-top:1px solid var(--line);border-bottom:0;padding-top:10px}
.poc-tabela tfoot .td-sub{font-weight:400}
.poc-sem-rec{text-align:left;font-size:12px}
.poc-sem-rec a{color:var(--brand-2)}
.poc-velha,.poc-frente{color:var(--warn)}
.poc-frente{white-space:nowrap}      /* numa linha só: a coluna do POC alarga um pouco, a linha não triplica */
.poc-fora{margin:0}
.poc-avisos{border-top:0;padding-top:0}
.poc-evol{border-top:1px solid var(--fio);padding-top:12px}
.poc-evol>details>summary{font-size:14px;font-weight:600;color:var(--ink);align-items:baseline}
/* o título da dobra é longo ("Evolução mês a mês · <obra>"): o resumo não cresce
   e não o espreme (o padrão .dobra-res cresce — é para títulos curtos) */
.poc-evol .dobra-res{flex:0 1 auto;font-weight:400}
.poc-evol-corpo{padding:12px 0 0;display:flex;flex-direction:column;gap:10px;align-items:flex-start}
.poc-evol-corpo>.tabela-rolavel{align-self:stretch}
.poc-evol-tab{font-size:12.5px}
.poc-evol-tab tr.sel>*{background:var(--brand-suave)}
.poc-barras{position:relative;width:120px;height:12px;border-radius:2px;background:var(--panel-2)}
.poc-barras i{position:absolute;left:0;height:4px;border-radius:1px}
.poc-barras .b-poc{top:1px;background:var(--cost)}
.poc-barras .b-fis{bottom:1px;background:var(--brand)}
.poc-leg{display:inline-block;width:10px;height:4px;border-radius:1px;vertical-align:middle;margin:0 2px}
.poc-leg.b-poc{background:var(--cost)}
.poc-leg.b-fis{background:var(--brand)}
.poc-tag{display:inline-block;padding:0 6px;margin:1px 4px 1px 0;border:1px solid var(--line);border-radius:999px;
 font-size:11px;line-height:1.6;color:var(--muted);white-space:nowrap}
.poc-tag.aviso{border-color:var(--warn);color:var(--warn)}
.poc-tag.perda{border-color:var(--crit);color:var(--crit-texto)}
.poc-evol-pe{font-size:12px;color:var(--faint);margin:0}
.poc-evol-pe a{color:var(--brand-2)}
@media (max-width:700px){
 .poc-evol .dobra-res{display:none}
 .poc-tabela .g0{border-left:0}
 .poc-tabela td>.cel{margin-left:auto;text-align:right}
 .poc-tabela td.poc-sem-rec{display:block;text-align:left}
 .poc-tabela td.poc-sem-rec::before{display:block;margin-bottom:4px}
 .poc-barras{width:110px}
}
/* fim: O RELATÓRIO POC (a checagem de cor literal lê este bloco) */

/* ===========================================================================
   COMO CHEGAMOS NESSE VALOR (27/09/2026) — Radar › Resultado (carteira e obra)
   e a aba Insumos da ficha. Pedido do sócio: embaixo de cada um dos quatro
   números, a CONTA que leva até ele, onde o dinheiro foi, o porquê, onde ainda
   dá para economizar e onde a obra já economizou.
   A forma (desde 08/10/2026): o "Por quê" sob cada número abre um POPUP com
   abas — o desenho está no bloco "O RESULTADO EM POPUPS", logo abaixo deste.
   Aqui fica o que vai DENTRO: um RECIBO (sinal na margem, pontilhado até o
   valor, o "=" que fecha a conta com um fio cheio), tabelas densas e listas —
   nada de mural.
   Cor só por token (a checagem de cor literal lê este bloco até o "fim:"):
   .perda e .oport são as da régua do vermelho.
   =========================================================================== */
/* o link sob cada número */
.como-abre{display:inline-flex;align-items:center;gap:6px;margin-top:8px;padding:1px 0;font-size:12.5px;
 font-weight:500;line-height:1.35;color:var(--brand-2);text-decoration:none;
 transition:color var(--dur-rapida) var(--curva-saida),box-shadow var(--dur-rapida) var(--curva-saida)}
.como-abre:hover{color:var(--brand);text-decoration:underline}
.como-abre:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:3px}
.como-seta{width:6px;height:6px;flex:none;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
 transform:rotate(-45deg);transition:transform var(--dur-media) var(--curva-saida)}
/* o mesmo convite na manchete do Radar: leva ao painel do Resultado com a conta deste número */
.eco-como{display:inline-flex;align-items:center;gap:6px;margin-top:6px;font-size:12.5px;font-weight:500;
 color:var(--brand-2);text-decoration:none}
.eco-como:hover{color:var(--brand);text-decoration:underline}
.eco-como:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:3px}
.como-t{font-size:11.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);margin:0 0 3px}
.como-sub{font-size:12px;color:var(--faint);line-height:1.5;margin:0 0 8px;max-width:72ch}
.como-frase{font-size:13px;line-height:1.6;color:var(--ink);margin:0;max-width:72ch}
.como-frase b{font-weight:600}

/* A troca para as etapas segue a preferência de movimento do Prisma. */
@keyframes radar-etapas-entrada{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.radar-etapas-entrada{animation:radar-etapas-entrada var(--dur-media) var(--curva-saida) both}
:root[data-movimento="desligado"] .radar-etapas-entrada{animation:none}
.como-vazio{font-size:12.5px;color:var(--muted);margin:0;line-height:1.5}
.como-vazio a,.como-resto a{color:var(--brand-2)}
.como-resto{font-size:12px;color:var(--faint);margin:6px 0 0;line-height:1.5}

/* O RECIBO: sinal na margem · rótulo com o pontilhado até o valor · valor exato */
.como-recibo{list-style:none;margin:4px 0 0;padding:0;max-width:600px;font-size:13px}
.como-l{display:grid;grid-template-columns:14px minmax(0,1fr) auto;column-gap:8px;align-items:end;padding:5px 0}
.como-l .op{align-self:start;color:var(--faint);font-weight:600;text-align:center;line-height:1.45}
.como-l .r{display:flex;align-items:flex-end;color:var(--muted);line-height:1.45;min-width:0}
.como-l .r::after{content:"";flex:1 1 14px;min-width:14px;margin:0 0 .38em 8px;border-bottom:1px dotted var(--line)}
.como-l .r a{color:var(--brand-2)}
.como-l .v{white-space:nowrap;color:var(--ink);text-align:right;line-height:1.45;font-variant-numeric:tabular-nums}
.como-l.sub{border-top:1px dashed var(--line);margin-top:3px}
.como-l.tot{border-top:1px solid var(--ink);margin-top:5px;padding-top:8px}
.como-l.tot .r{color:var(--ink);font-weight:600}
.como-l.tot .v{font-family:var(--titulo);font-size:15px;font-weight:600}
.como-l.outra{margin-top:16px}

/* OS DOIS LIVROS: a medição (o "já foi") e o Financeiro (as etapas), que não somam um ao outro */
.como-livros{display:flex;flex-direction:column;gap:3px;padding:2px 0 2px 12px;border-left:2px solid var(--line)}
.como-livro{margin:0;font-size:12.5px;color:var(--muted);line-height:1.5}
.como-livro b{color:var(--ink);font-weight:600}
.como-livros-nota{margin:4px 0 0;font-size:12px;color:var(--faint);line-height:1.5;max-width:72ch}

/* as tabelas densas (onde o dinheiro foi, falta gastar, economizou, passou) */
.como-tab{font-size:12.5px;margin:0}
.como-tab thead th{white-space:normal;line-height:1.3}
.como-tab td{vertical-align:baseline}
/* (os valores numa linha só: "R$ 10,47 / mi" quebrado no meio foi o 1º retrato) */
.como-tab td.n,.como-tab .nw{white-space:nowrap}
.como-tab .rel-obra{font-weight:500}
.como-quando{color:var(--faint);white-space:nowrap}
@media (min-width:701px){
 .como-tab>:not(caption)>*>*{padding:7px 8px}
 .como-tab thead th{padding:0 8px 6px}
}
/* o porquê: a lista de ocorrências dos Indicadores; a que virou aditivo diz isso */
.como-causas li{padding:8px 0}
.como-adit{display:inline-block;margin:4px 0 0;padding:0 7px;border:1px solid var(--line);border-radius:999px;
 font-size:11.5px;line-height:1.6;color:var(--muted)}
.como-causas .l2 .como-adit{display:table;margin-top:5px}
/* como economizar: as frases do motor, numeradas */
.como-acoes{margin:0;padding-left:20px;display:flex;flex-direction:column;gap:7px;font-size:13px;line-height:1.5;
 color:var(--ink);max-width:80ch}
.como-acoes li::marker{color:var(--faint);font-weight:600}
.como-avisos{margin-top:4px}
.como-t-base{margin-top:18px}

/* A ABA INSUMOS DA FICHA: orçado × pago, a situação da etapa e o encerrar */
.etapas-tab .etapa-sit{min-width:160px;line-height:1.4}
.etapa-enc{margin-top:4px}
.etapa-enc>summary{font-size:12px}
.etapa-enc-form{display:flex;flex-wrap:wrap;align-items:flex-end;gap:6px 8px;margin:4px 0 0}
.etapa-enc-data{display:flex;flex-direction:column;gap:2px;margin:0;font-size:11.5px;color:var(--muted)}
.etapa-enc-data .form-control{width:150px}
.etapa-enc-nota{margin:6px 0 0;font-size:11.5px;color:var(--faint);line-height:1.45;max-width:38ch}
.etapa-reabrir{display:inline;margin:0}
.etapa-reabrir .btn-link{padding:0;font-size:12px;vertical-align:baseline;color:var(--brand-2)}
.etapas-sem{margin:10px 2px 0;font-size:12.5px;color:var(--muted);line-height:1.5;max-width:96ch}
.etapas-sem b{color:var(--ink);font-weight:600}

@media (max-width:700px){
 .como-l{grid-template-columns:12px minmax(0,1fr) auto;column-gap:6px}
 .como-l .r::after{display:none}
 /* a tabela do painel vira um cartão de DUAS linhas (o de quatro, padrão do celular, dava
    1.500 px para nove etapas): o nome e o valor que importa em cima; orçado e pago embaixo */
 .como-tab tr{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:12px;row-gap:3px;padding:9px 0}
 .como-tab td{display:block;padding:0;border:0;text-align:left;min-width:0}
 .como-tab td.principal{grid-row:1;grid-column:1}
 .como-tab td.como-ult{grid-row:1;grid-column:2;text-align:right}
 .como-tab td.como-ult::before{display:none}
 .como-tab td[data-l="Orçado"]{grid-row:2;grid-column:1;font-size:11.5px;color:var(--muted)}
 .como-tab td[data-l="Pago"]{grid-row:2;grid-column:2;font-size:11.5px;color:var(--muted);text-align:right}
 .como-tab td[data-l="Orçado"]::before,.como-tab td[data-l="Pago"]::before{display:inline;margin-right:5px;
  font-size:11px;letter-spacing:0;text-transform:lowercase}
 .etapas-tab .etapa-sit{display:block;text-align:left;min-width:0}
 .etapas-tab .etapa-sit::before{display:block;margin-bottom:4px}
 .etapa-enc-data .form-control{width:100%}
}
/* fim: COMO CHEGAMOS NESSE VALOR (a checagem de cor literal lê este bloco) */

/* ===========================================================================
   O RESULTADO EM POPUPS E O ECONOMIZOU (08/10/2026) — Radar › Resultado.
   Pedido do Samuel, com a prévia aprovada: "visual e sem poluição visual".
   1. Os números: sem parágrafo embaixo — uma linha e o "Por quê ›", que abre
      o POPUP do número (o desenho do popup da obra na Carteira: o número no
      alto, o que ele é numa frase e abas por rádio, com troca suave — os
      painéis na mesma célula da grade, sem pular de altura). Sem JavaScript, o
      endereço #como-… abre o popup no lugar (:target).
   2. Número e gráfico conversam: passar o mouse num número acende a parte
      dele na barra da margem (e as outras esmaecem); passar numa parte acende
      o número. Clicar na parte abre o popup dela.
   3. ECONOMIZOU: o número grande do período, o que passou e o saldo; mês a
      mês, a barra verde para cima, a vermelha para baixo e a linha do saldo.
      O período (12 meses · desde o início) é rádio + :has, sem recarregar.
   Cor só por token, duração só por --dur-* (a checagem lê este bloco até o
   "fim:").
   =========================================================================== */
/* quem entra na conta: o botãozinho que abre a lista */
.res-conta-chip{display:inline-flex;align-self:flex-start;align-items:center;gap:7px;width:fit-content;padding:3px 12px;
 border-radius:999px;background:var(--panel-2);color:var(--muted);font-size:12.5px;line-height:1.5;text-decoration:none;
 transition:color var(--dur-rapida) var(--curva-saida),background-color var(--dur-rapida) var(--curva-saida)}
.res-conta-chip:hover{color:var(--ink);text-decoration:none}
.res-conta-chip:focus-visible{outline:2px solid var(--anel);outline-offset:2px}

/* o número e a parte dele no gráfico, juntos */
.res .rel-kpi,.res-seg,.res-fx{transition:opacity var(--dur-rapida) var(--curva-saida)}
.res .rel-corpo:has(.rel-kpi[data-kpi="ja_foi"]:hover) .res-seg:not(.jafoi),
.res .rel-corpo:has(.rel-kpi[data-kpi="ainda"]:hover) .res-seg:not(.evit):not(.base),
.res .rel-corpo:has(.rel-kpi[data-kpi="sobra"]:hover) .res-seg:not(.sobra),
.res .rel-corpo:has(.rel-kpi[data-kpi="faixa"]:hover) .res-seg,
.res .rel-corpo:has(.rel-kpi[data-kpi="ja_foi"]:hover) .res-fx,
.res .rel-corpo:has(.rel-kpi[data-kpi="ainda"]:hover) .res-fx,
.res .rel-corpo:has(.rel-kpi[data-kpi="sobra"]:hover) .res-fx{opacity:.22}
.res .rel-corpo:has(.res-seg.jafoi:hover) .rel-kpi:not([data-kpi="ja_foi"]),
.res .rel-corpo:has(.res-seg.evit:hover) .rel-kpi:not([data-kpi="ainda"]),
.res .rel-corpo:has(.res-seg.base:hover) .rel-kpi:not([data-kpi="ainda"]),
.res .rel-corpo:has(.res-seg.sobra:hover) .rel-kpi:not([data-kpi="sobra"]),
.res .rel-corpo:has(.res-fx:hover) .rel-kpi:not([data-kpi="faixa"]){opacity:.45}
.res-seg[data-dialogo],.res-fx[data-dialogo]{cursor:pointer}

/* o popup */
.res-dialogo{width:min(820px,calc(100vw - 32px));max-width:none;max-height:min(900px,calc(100dvh - 40px));margin:auto;
 padding:0;overflow:auto;border:1px solid var(--line);border-radius:16px;background:var(--elevado);color:var(--ink);
 box-shadow:var(--sombra-alta);text-align:left}
.res-dialogo::backdrop{background:var(--veu)}
.res-dialogo:focus{outline:none}
.res-dialogo[open]{animation:surgir var(--dur-media) var(--curva-saida)}
/* sem JavaScript, o endereço abre o popup no lugar */
.res-dialogo:target:not([open]){display:block;position:fixed;inset:24px;z-index:1080}
.res-d-corpo{padding:20px 22px 18px}
.res-d-cab{display:flex;align-items:flex-start;gap:12px;margin-bottom:12px}
.res-d-tit{flex:1;min-width:0}
/* (11/10/2026) o "i" do popup ao lado do que ele explica: "Como chegamos nesse valor", em versalete, em cima do título */
.res-d-tit .res-d-olho{display:flex;align-items:center;max-width:none;margin:0 0 4px;font-size:11px;font-weight:600;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.res-d-tit h2{display:flex;align-items:center;gap:6px;margin:0;font-family:var(--sans);font-size:13px;font-weight:500;
 color:var(--muted)}
.res-d-val{margin:2px 0 0;font-family:var(--titulo);font-size:28px;font-weight:500;line-height:1.15;
 letter-spacing:-.01em;font-variant-numeric:tabular-nums}
.res-d-val.v-crit{color:var(--crit-texto)}
.res-d-val.v-ok{color:var(--ok-texto)}
.res-d-tit p{margin:6px 0 0;font-size:13px;line-height:1.5;color:var(--muted);max-width:64ch}
.res-dialogo .cart-fechar{display:grid;place-items:center;flex:none;width:34px;height:34px;padding:0;
 border:1px solid var(--line);border-radius:8px;background:var(--ground);color:var(--muted);cursor:pointer;
 transition:color var(--dur-rapida),border-color var(--dur-rapida)}
.res-dialogo .cart-fechar:hover{color:var(--ink);border-color:var(--brand-borda)}
.res-dialogo .cart-fechar:focus-visible{outline:2px solid var(--anel);outline-offset:2px}
.res-abas{display:flex;gap:2px;border-bottom:1px solid var(--line);overflow-x:auto}
.res-aba-r{position:absolute;opacity:0;pointer-events:none}
.res-aba{margin-bottom:-1px;padding:8px 12px;border-bottom:var(--sel-traco) solid transparent;font-size:13.5px;
 color:var(--muted);white-space:nowrap;cursor:pointer;transition:color var(--dur-rapida)}
.res-aba:hover{color:var(--ink)}
.res-aba-r:checked+.res-aba{color:var(--ink);font-weight:600;border-bottom-color:var(--selecao)}
.res-aba-r:focus-visible+.res-aba{outline:2px solid var(--anel);outline-offset:-2px;border-radius:4px}
.res-paineis{display:grid}
.res-painel{grid-area:1/1;min-width:0;padding-top:14px;visibility:hidden;opacity:0;transform:translateY(6px);
 pointer-events:none;
 transition:opacity var(--dur-media) var(--curva-saida),transform var(--dur-media) var(--curva-saida),visibility var(--dur-media)}
.res-d-corpo:has(.res-aba-r[id$="-a1"]:checked) .res-p-a1,
.res-d-corpo:has(.res-aba-r[id$="-a2"]:checked) .res-p-a2,
.res-d-corpo:has(.res-aba-r[id$="-a3"]:checked) .res-p-a3,
.res-d-corpo:has(.res-aba-r[id$="-a4"]:checked) .res-p-a4,
.res-d-corpo:has(.res-aba-r[id$="-a5"]:checked) .res-p-a5{visibility:visible;opacity:1;transform:none;pointer-events:auto}
.res-painel-unico{padding-top:2px}
.res-d-pe{display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px;margin-top:16px;padding-top:12px;
 border-top:1px solid var(--line)}
/* obra a obra, no popup da carteira: uma barra por obra em cima do recibo */
.como-barras{list-style:none;display:flex;flex-direction:column;gap:10px;margin:2px 0 16px;padding:0}
.como-barras li{display:grid;grid-template-columns:minmax(130px,1.1fr) minmax(0,2fr) auto;gap:12px;align-items:center;
 font-size:13px}
.como-barras .nm{display:flex;flex-direction:column;min-width:0}
.como-barras .nm .rel-obra{font-weight:600}
.como-barras .tr{position:relative;height:10px;border-radius:5px;background:var(--panel-2);overflow:hidden}
.como-barras .tr i{position:absolute;top:0;bottom:0;left:0;border-radius:5px}
.como-barras i.b-crit{background:var(--crit)}
.como-barras i.b-ok{background:var(--ok)}
.como-barras i.b-marca{background:var(--brand)}
.como-barras i.b-mudo{background:var(--cost)}
.como-barras .v{font-weight:600;white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums}
/* a faixa do resultado obra a obra */
.como-faixas{list-style:none;margin:2px 0 16px;padding:0}
.como-faixas li{display:grid;grid-template-columns:minmax(130px,1fr) minmax(0,2fr) auto;gap:12px;align-items:center;
 padding:9px 0;border-bottom:1px solid var(--line);font-size:13px}
.como-faixas li.tot{border-bottom:0;font-weight:600}
.como-faixas .tr{position:relative;height:16px}
.como-faixas .z{position:absolute;top:-4px;bottom:-4px;border-left:1px dashed var(--faint)}
.como-faixas .r{position:absolute;top:7px;height:2px;background:var(--ink)}
.como-faixas .p{position:absolute;top:2px;width:12px;height:12px;margin-left:-6px;border:2px solid var(--ink);
 border-radius:50%;background:var(--panel)}
.como-faixas .v{font-size:12.5px;color:var(--muted);white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums}

/* ECONOMIZOU */
.econ{position:relative}
.econ-per-r{position:absolute;opacity:0;pointer-events:none}
.econ-chips{position:absolute;top:0;right:0;display:flex;gap:4px}
.econ-chips label{padding:3px 12px;border:1px solid var(--line);border-radius:999px;background:var(--panel);
 color:var(--muted);font-size:12.5px;cursor:pointer;transition:color var(--dur-rapida),background-color var(--dur-rapida)}
.econ-chips label:hover{color:var(--ink)}
.econ:has(#econ-per-12:checked) label[for="econ-per-12"],
.econ:has(#econ-per-tudo:checked) label[for="econ-per-tudo"]{background:var(--ink);border-color:var(--ink);color:var(--panel)}
.econ:has(#econ-per-12:focus-visible) label[for="econ-per-12"],
.econ:has(#econ-per-tudo:focus-visible) label[for="econ-per-tudo"]{outline:2px solid var(--anel);outline-offset:2px}
.econ:has(#econ-per-tudo:checked) .econ-p12,.econ:has(#econ-per-12:checked) .econ-ptudo{display:none}
.econ-topo{display:flex;flex-wrap:wrap;align-items:flex-end;gap:14px 34px;padding-right:220px}
.econ-big .lab,.econ-par .lab{font-size:13px;color:var(--muted)}
.econ-big .val{font-family:var(--titulo);font-size:38px;font-weight:500;line-height:1.1;letter-spacing:-.01em;
 font-variant-numeric:tabular-nums}
.econ-big .lin,.econ-par .lin{font-size:12.5px;color:var(--faint)}
.econ-par{display:flex;gap:28px;padding-bottom:3px}
.econ-par .v{font-family:var(--titulo);font-size:20px;font-weight:500;font-variant-numeric:tabular-nums}
.econ .v-ok{color:var(--ok-texto)}
.econ .v-crit{color:var(--crit-texto)}
.econ-graf{display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 10px;margin:24px 0 34px}
.econ-y{position:relative;width:58px}
.econ-y span{position:absolute;right:0;transform:translateY(50%);font-size:11px;color:var(--faint);white-space:nowrap;
 font-variant-numeric:tabular-nums}
.econ-plot{position:relative;height:190px}
.econ-linha{position:absolute;left:0;right:0;height:0;border-top:1px solid var(--line)}
.econ-linha.zero{border-top-color:var(--faint)}
.econ-saldo{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.econ-saldo polyline{fill:none;stroke:var(--ink);stroke-width:var(--graf-traco);opacity:.7}
.econ-cols{position:absolute;inset:0;display:grid;grid-template-columns:repeat(var(--n),minmax(0,1fr));margin:0;padding:0;
 list-style:none}
.econ-cols>li{position:relative;min-width:0}
.econ-col{position:absolute;top:-8px;bottom:-8px;left:1px;right:1px;border-radius:6px;color:inherit;text-decoration:none}
a.econ-col{cursor:pointer;transition:background-color var(--dur-rapida)}
a.econ-col:hover{background:var(--nav-on)}
a.econ-col:focus-visible{outline:2px solid var(--anel);outline-offset:0}
.econ-b{position:absolute;left:50%;width:min(26px,56%);transform:translateX(-50%);border-radius:2px}
.econ-b.b-ok{background:var(--ok)}
.econ-b.b-crit{background:var(--crit)}
.econ-v{position:absolute;left:50%;transform:translateX(-50%);padding:0 3px;border-radius:3px;background:var(--panel);
 font-size:11px;font-weight:600;line-height:1.3;white-space:nowrap;font-variant-numeric:tabular-nums}
.econ-v.ok{color:var(--ok-texto)}
.econ-v.crit{color:var(--crit-texto)}
.econ-pt{position:absolute;left:50%;width:6px;height:6px;margin:0 0 -3px -3px;border:1.2px solid var(--ink);
 border-radius:50%;background:var(--panel)}
.econ-mes{position:absolute;top:calc(100% + 10px);left:50%;transform:translateX(-50%);font-size:11px;color:var(--faint);
 white-space:nowrap}
.econ-graf.muitos .econ-v{display:none}
.econ-graf.muitos .econ-cols>li:nth-child(even) .econ-mes{visibility:hidden}
.econ-leg{display:flex;flex-wrap:wrap;gap:6px 18px;margin:0;font-size:12.5px;color:var(--muted)}
.econ-leg i{display:inline-block;width:10px;height:10px;margin-right:6px;border-radius:2px;vertical-align:-1px}
.econ-leg i.b-ok{background:var(--ok)}
.econ-leg i.b-crit{background:var(--crit)}
.econ-leg i.l-saldo{width:14px;height:2px;border-radius:0;background:var(--ink);vertical-align:3px}
.econ-leg b{font-weight:600}
.econ-frase{margin:12px 0 0;font-size:14px;color:var(--ink)}
.econ-frase b{font-weight:600}
.econ-dica{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin:4px 0 0;font-size:12.5px;color:var(--faint)}
.econ-dica .como-abre{margin-top:0}
.econ-vazio{margin:0;font-size:13.5px;line-height:1.6;color:var(--muted);max-width:80ch}
.econ-vazio b{color:var(--ink);font-weight:600}
.econ-vazio a{color:var(--brand-2)}
.econ-tab .td-sub{line-height:1.35}
@media (max-width:900px){
 .econ-topo{padding-right:0}
 .econ-chips{position:static;margin:0 0 14px}
}
@media (max-width:640px){
 .res-dialogo{width:calc(100vw - 16px);max-height:calc(100dvh - 20px);border-radius:13px}
 .res-d-corpo{padding:16px 14px 14px}
 .res-d-val{font-size:24px}
 .como-barras li,.como-faixas li{grid-template-columns:minmax(0,1fr) auto}
 .como-barras .tr,.como-faixas .tr{grid-column:1/-1;grid-row:2}
 .econ-big .val{font-size:30px}
 .econ-y{width:46px}
 .econ-v{display:none}
 .econ-cols>li:nth-child(even) .econ-mes{visibility:hidden}
}
/* no papel, os popups saem abertos, um embaixo do outro (eles explicam os números) */
@media print{
 .res-dialogo{display:block!important;position:static;width:auto;max-height:none;margin:12px 0 0;border:0;box-shadow:none}
 .res-dialogo .cart-fechar,.res-abas,.como-abre{display:none}
 .res-painel{visibility:visible;opacity:1;transform:none;grid-area:auto}
}
/* fim: O RESULTADO EM POPUPS E O ECONOMIZOU (a checagem de cor literal lê este bloco) */

/* ============================================================================
   IMPORTAÇÃO DA PLANILHA DE CONTROLE E DO ORÇAMENTO POR ETAPA (01/10/2026)
   piloto/importar_extrato.py e piloto/importar_orcamento.py — a primeira
   construtora em teste controla a obra numa planilha (o extrato do banco com
   quem, o quê e a etapa) e tem o orçamento em linhas. Cada importação tem duas
   telas, o envio e a prévia, feitas das peças de sempre (tabela-box, kpis,
   listas dobradas). O que é próprio fica aqui: o formulário de envio, a linha
   que diz se a leitura fecha com o saldo da planilha, a coluna "vai para" com
   as sugestões de etapa e as decisões da prévia. Cor só por variável.
   ========================================================================= */
.imp-form{padding:14px}
.imp-regras{margin:0;padding:2px 14px 12px 32px;font-size:12.5px;color:var(--muted);line-height:1.55;max-width:110ch}
.imp-regras b{color:var(--ink);font-weight:600}
.imp-anteriores{margin-top:14px}
.imp-campos{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) auto;gap:12px 16px;
  align-items:start;padding:14px}
.imp-campos .btn{margin-top:26px;white-space:nowrap}   /* desce a altura do rótulo: alinha com os campos */
.imp-kpis{margin-top:14px}
.imp-sub{font-size:12px;color:var(--faint);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.imp-confere{margin:12px 2px 0;font-size:13px;color:var(--muted);line-height:1.5;max-width:110ch}
.imp-confere .estado{margin-right:6px}
.imp-confere b{color:var(--ink);font-weight:600}
.imp-nota-saldo{margin:4px 2px 0;font-size:12px;color:var(--faint);max-width:110ch}
.imp-etapas,.imp-resto{margin-top:14px}
.imp-aviso-orc{margin:0;padding:10px 14px;font-size:12.5px;color:var(--muted);line-height:1.5;
  border-bottom:1px solid var(--line);background:var(--warn-suave)}
.imp-aviso-orc b{color:var(--ink);font-weight:600}
.imp-dest{min-width:260px;max-width:420px}
.imp-sem{color:var(--muted);font-style:italic}
/* as sugestões de etapa: nomes do orçamento PARECIDOS com o da planilha, um clique escolhe */
.imp-sug{display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px;margin-top:5px;font-size:11.5px;color:var(--faint)}
.imp-usar{border:1px solid var(--line);background:var(--panel);color:var(--brand-2);border-radius:999px;
  padding:1px 9px;font-size:11.5px;line-height:1.6;cursor:pointer;max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.imp-usar:hover{background:var(--brand-suave)}
.imp-usar:focus-visible{outline:2px solid var(--anel);outline-offset:1px}
/* as listas dobradas da prévia (avisos, o que fica de fora, colunas, amostra) */
.imp-dobra{border-bottom:1px solid var(--line);padding:10px 14px;font-size:12.5px;color:var(--muted)}
.imp-dobra>summary{cursor:pointer;color:var(--ink);font-size:13px}
.imp-dobra>ul{margin:8px 0 0;padding-left:18px;line-height:1.55}
.imp-dobra .tabela-rolavel{margin-top:8px}
/* (02/10) a dobra animada embrulha o conteúdo numa grade (.dobra-in): sem isto a tabela das Colunas esticava a
   grade até a largura dela, e no celular a prévia inteira rolava de lado — é a tabela que rola, dentro da caixa */
.imp-dobra .dobra-in>div{min-width:0}
/* as decisões: o que parece repetido, o que saiu da planilha */
.imp-decisao{border-bottom:1px solid var(--line);padding:12px 14px;font-size:13px;color:var(--muted);line-height:1.5}
.imp-decisao .form-check{display:flex;gap:8px;align-items:flex-start;margin:0;padding:0}
.imp-decisao .form-check-input{margin:3px 0 0;flex:none;float:none}
.imp-decisao b{color:var(--ink);font-weight:600}
.imp-decisao .imp-dobra{border:0;padding:6px 0 0 24px}
.imp-linha-cab{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px}
.imp-linha-cab label{font-size:12.5px;color:var(--muted);margin:0}
.imp-linha-cab .form-control{width:80px}
.imp-acoes-txt{font-size:12.5px;color:var(--muted)}
.imp-botoes{display:flex;gap:8px;flex-wrap:wrap}
/* o orçamento por etapa: o campo de colar a tabela e a escolha do nível */
.imp-colar{font-family:var(--mono);font-size:12.5px;line-height:1.5;white-space:pre;overflow:auto}
.imp-form-pe{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.imp-ja{margin:0;padding:0 14px 12px;font-size:12.5px;color:var(--muted)}
.imp-niveis{display:flex;flex-wrap:wrap;align-items:center;gap:6px 18px;padding:12px 14px;
  border-bottom:1px solid var(--line);font-size:13px;color:var(--muted)}
.imp-niveis-t{color:var(--ink);font-weight:600}
.imp-nivel{display:inline-flex;align-items:baseline;gap:6px;margin:0;cursor:pointer}
.imp-topo .imp-confere{margin:12px 14px 0}
.imp-topo .imp-nota-saldo{margin:4px 14px 10px}
.imp-topo .imp-confere+.tabela-rolavel,.imp-topo .imp-nota-saldo+.tabela-rolavel{margin-top:10px;border-top:1px solid var(--line)}
/* MEDIÇÕES DE VÁRIOS MESES (piloto/medicoes_lote.py): um mês por linha, o custo já preenchido
   com o que o Financeiro pagou e o campo do avanço físico */
.lote-tab .lote-campo{width:190px}
.lote-tab .lote-campo .form-control{text-align:right;font-variant-numeric:tabular-nums}
.lote-falta{color:var(--warn);font-size:12.5px}
.lote-nota{margin:0;padding:10px 14px;font-size:12.5px;color:var(--muted);line-height:1.5;max-width:110ch;
  border-top:1px solid var(--line)}
.lote-nota b{color:var(--ink);font-weight:600}
.lanc-lote{display:inline-block;margin-top:10px}
@media (max-width:700px){
 .lote-tab .lote-campo{width:auto}
 .lote-tab td.lote-campo .form-control{max-width:170px}
}
@media (max-width:767.98px){
 .imp-campos{grid-template-columns:minmax(0,1fr)}
 .imp-campos .btn{margin-top:0}
 .imp-dest{min-width:0;max-width:none}
}
/* no celular a tabela vira cartão (regra geral, 700px): o "vai para" ocupa a largura toda — o
   rótulo em cima, o seletor e as sugestões embaixo (lado a lado o seletor ficava com 20px) —, e
   os números grandes ficam um por linha (R$ 1.234.567,89 não cabe em meia tela) */
@media (max-width:700px){
 .imp-etapas td.imp-dest{display:block;text-align:left}
 .imp-etapas td.imp-dest::before{display:block;margin-bottom:4px}
 .imp-kpis .kpi-item{flex:1 1 100%;border-right:0}
 .imp-kpis .kpi-item:nth-last-child(-n+2){border-bottom:1px solid var(--line)}
 .imp-kpis .kpi-item:last-child{border-bottom:0}
 .imp-acoes .imp-botoes{width:100%;justify-content:flex-end}
}
/* (01/10/2026) a prévia ganhou quatro perguntas: de qual planilha o arquivo é a continuação e
   qual aba dele entra (uma linha própria, embaixo da obra e da conta — o texto das opções é
   comprido), como ler o sinal do valor (junto da linha dos títulos) e o que fazer com o que
   saiu da planilha (duas opções, sem padrão) */
.imp-campos .imp-campo-largo{grid-column:1 / -1}
.imp-campos .imp-campo-aba{grid-column:1}
.imp-linha-cab .imp-sinal{width:auto;max-width:100%}
.imp-decisao p{margin:0 0 6px}
.imp-decisao .form-check + .form-check{margin-top:4px}
/* o seletor do papel de cada coluna cortava o texto da opção ("Texto do banco (histórico)") */
.imp-colunas td:last-child .form-select{min-width:230px}
/* o nome da etapa na ficha: linha de orçamento tem nome comprido ("ADMINISTRAÇÃO … (CASA 2)") e o
   campo, estreito, cortava no meio — a coluna do nome fica com um terço da tabela (no celular a
   tabela vira cartão e a regra não pega) */
@media (min-width:701px){
 .etapas-tab td.principal{width:34%}
}
/* fim: IMPORTAÇÃO DA PLANILHA DE CONTROLE */

/* ============================================================================
   A TROCA DE VISÃO SEM SOLAVANCO (28/09/2026)
   O Samuel, depois da v0.52.0: "quando clicamos em circular, resultado ou
   caixa, está mudando bruscamente — tem como deixar mais smooth?". Medido no
   Chrome sem janela, quadro a quadro (.tmp/v0521-transicao/): NÃO havia branco
   entre as páginas (o Chrome segura a página velha na tela até a nova pintar,
   nos dois temas). O solavanco era outro:
     a) a troca era SECA: a regra MESMA TELA, OUTRO FILTRO desliga a entrada em
        cascata (certo para filtro) e nada ficava no lugar dela — o conteúdo
        inteiro mudava de um quadro para o outro;
     b) a barra de rolagem de 15 px aparecia e sumia entre telas de alturas
        diferentes e empurrava a barra do topo e tudo o que é centrado;
     c) a Circular (ilha React) pintava VAZIA, com o rodapé colado na barra do
        topo, antes de buscar os dados (rodapé em y 98, depois 198, depois 931;
        layout-shift 0,52 a 1366 px).
   (A chavinha também muda de lugar ao ir para a Circular — ~300 px a 1366 —
   porque lá o cabeçalho é desenhado pelo React, sem os botões do lado. Isso
   não se conserta aqui: ver o HANDOFF-FRONT, 28/09.)

   (1) TRANSIÇÃO ENTRE DOCUMENTOS feita pelo próprio navegador (View
   Transitions): as duas páginas pedem, o navegador guarda um retrato da velha,
   mostra a nova e cruza as duas. Nenhuma linha de JavaScript. Navegador que não
   conhece a regra a ignora e troca como sempre. O PEDIDO (a regra
   @view-transition com navigation:auto) NÃO mora aqui: vem num <style> de uma
   linha no <head> do layout() (app.py). Medido com rede de verdade: este arquivo
   (196 KB) chegava depois de o Chrome conferir o pedido da página nova, e ele
   abortava a transição em 6 de cada 10 trocas. Aqui fica o resto: o que fica
   parado, a duração, o recorte da mesma tela e o menos movimento — quando a
   transição começa, esta folha já carregou.
   (2) SÓ A MESMA TELA ANIMA: a chavinha do Radar, o seletor de obra do
   Resultado e do Caixa, a pílula do gráfico, as visões de Financeiro ›
   Relatórios, os filtros dos Indicadores (e a própria tela depois de gravar) —
   o <head> já marca data-entrada="mesma" quando o endereço novo é a mesma tela.
   Ir para OUTRA tela segue como era: quem chega a uma tela nova tem a entrada
   em cascata, e as duas animações juntas embolariam. Ali a transição ainda
   acontece (as duas páginas pediram), mas sem animação e sem o retrato velho:
   o primeiro quadro já é a página nova.
   (3) O QUE FICA PARADO: a barra do topo, a barra de abas e a chavinha do Radar
   têm nome próprio — saem do retrato da página e viram peças à parte; como
   estão no mesmo lugar nas duas páginas, não se mexem (só a marca da opção
   atual cruza). O resto, o conteúdo, cruza em --dur-troca.
   (4) MENOS MOVIMENTO desliga — a regra está no bloco MENOS MOVIMENTO, lá em
   cima (o tema tem UM só bloco para o pedido de menos movimento do sistema, e
   blocos novos não repetem essa consulta) — e a chave "Animações" do app manda:
   "ligado" anima mesmo com o sistema pedindo menos; "desligado", nunca (abaixo).
   ========================================================================= */
.top{view-transition-name:barra-topo}
.abas-bar{view-transition-name:barra-abas}
/* só a chavinha EM PYTHON (#acoes-radar): a da Circular é desenhada pelo React
   depois do primeiro quadro, então não há o que segurar parado lá (ela entra
   com o conteúdo); quando o cabeçalho da Circular vier do servidor, ela entra
   nesta regra sozinha */
#acoes-radar>.visao-troca{view-transition-name:chave-visao}
::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){
 animation-duration:var(--dur-troca);animation-timing-function:var(--curva-saida)}
:root:not([data-entrada="mesma"])::view-transition-group(*),
:root:not([data-entrada="mesma"])::view-transition-old(*),
:root:not([data-entrada="mesma"])::view-transition-new(*){animation-name:none}
:root:not([data-entrada="mesma"])::view-transition-old(*){opacity:0}
:root[data-movimento="desligado"]::view-transition-group(*),
:root[data-movimento="desligado"]::view-transition-old(*),
:root[data-movimento="desligado"]::view-transition-new(*){animation-name:none}

/* (5) A BARRA DE ROLAGEM NÃO EMPURRA NADA: em toda tela com a barra do topo a
   barra de rolagem fica SEMPRE à vista — numa tela curta, só o trilho, sem o
   cursor. Medido a 1366×768: Obras, Cronograma, Conciliação, Orçamentos,
   Cadastros e Tarefas são curtas (sem barra) e as vizinhas de aba são longas; a
   1920×1080 até a Circular fica curta e as outras três visões do Radar não. Sem
   isto, cada troca dessas empurrava a barra do topo e o conteúdo 15 px.
   Por que não `scrollbar-gutter: stable` (a calha reservada e vazia): medido no
   Chrome, a calha vazia só recebe a COR de fundo da raiz — nenhuma imagem de
   fundo chega lá —, então numa tela curta sobrava uma faixa de 15 px no tom do
   fundo ao lado da barra do topo azul-noturno e ao lado de um véu escurecido. O
   trilho da barra é o que a pessoa já vê em toda tela longa. No celular e onde a
   barra é sobreposta (macOS) nada aparece a mais. Fora da tela de entrada (ela
   não tem a barra do topo) e do papel. */
@media screen{
 html:has(>body>header.top){overflow-y:scroll}
}

/* (6) A ILHA REACT SEGURA O LUGAR: o React só desenha depois de buscar os
   dados; até lá o miolo tinha altura zero e o rodapé subia para baixo da barra
   do topo (na Circular; em Importar planilha e na Conciliação, para baixo da
   barra de abas). Agora a coluna tem pelo menos a altura da tela — menos a barra
   do topo (52 px) e, quando há, a de abas (45 px) — e o miolo ocupa o que sobra:
   o rodapé fica embaixo desde o primeiro quadro. */
main.content-col:has(>#raiz-react){min-height:calc(100svh - 52px)}
body:has(>.abas-bar) main.content-col:has(>#raiz-react){min-height:calc(100svh - 97px)}
#raiz-react{flex:1 0 auto}

/* (7) NO CELULAR, A CHAVINHA NA MESMA ALTURA NAS QUATRO VISÕES: lá o cabeçalho
   empilha (título, linha de apoio, chavinha embaixo), e a linha de apoio da
   Tabela e da Circular ("… · 4 obras em andamento · última medição 09/2026")
   quebra em duas a 375 px, a do Resultado e a do Caixa não — a chavinha subia e
   descia 19 px a cada troca. Abaixo de 576 px a linha de apoio do cabeçalho do
   Radar reserva duas linhas nas quatro (a da Circular é desenhada pelo React). */
@media (max-width:575.98px){
 .pg-head:has(>#acoes-radar) .sub,#raiz-react[data-tela="carteira"] .pg-head .sub{min-height:2lh}
}
/* fim: A TROCA DE VISÃO SEM SOLAVANCO (a checagem de cor literal lê este bloco) */

/* ============================================================================
   SEGURANÇA — O SEGUNDO FATOR, OS CÓDIGOS DE RECUPERAÇÃO, A SENHA ESQUECIDA E A
   TRILHA DE AUDITORIA (28/09/2026)
   O Samuel: "segurança o máximo possível", com o PDF de MFA da Lumiset como
   contrato. As telas do meio da entrada (o código, ligar o segundo fator, os
   códigos de recuperação, confirmar que é você, esqueci a senha, a senha nova)
   usam o cartão da ENTRADA — aqui ficam só as peças novas. As de quem já entrou
   (Minha conta, Usuários, a trilha, a faixa de aviso) usam as peças do sistema:
   card, tabela densa, filtros em linha, alerta.

   O QUADRO DO QR É CLARO NOS DOIS TEMAS, de propósito: a câmera do celular
   procura módulos escuros sobre fundo claro, e QR invertido (claro sobre
   escuro) muito leitor não lê. Por isso o quadro não usa --panel nem --elevado
   (que escurecem no tema escuro): usa --papel e --papel-tinta, definidos UMA vez
   no bloco de tokens do topo, e que o tema escuro NÃO redefine. São os mesmos da
   folha impressa dos códigos de recuperação — impresso a partir do tema escuro,
   o texto sairia branco no papel branco. Nenhuma cor literal neste bloco.
   ========================================================================= */

/* o código: números espaçados e centrados — é o que a pessoa copia olhando para
   o celular (o espaço que o app mostra no meio, "123 456", é aceito). Grandes no
   cartão da entrada (lá é o único campo); na casca, do tamanho da senha ao lado
   (16 px: o celular não dá zoom no foco abaixo disso). Duas classes para vencer
   o `.entrada-card .form-control` */
.form-control.f2-digitos{font-family:var(--mono);font-size:16px;letter-spacing:.25em;padding-left:.25em;
  text-align:center;font-variant-numeric:tabular-nums}
.entrada-card .form-control.f2-digitos{font-size:22px;letter-spacing:.3em;padding-left:.3em}
.form-control.f2-cod-livre,.entrada-card .form-control.f2-cod-livre{font-family:var(--mono);font-size:16px;
  letter-spacing:.04em}

/* o 2º passo da entrada: o código de recuperação num <details>; aberto, ele
   toma o lugar do campo do app (o :has é o "tem o details aberto") — sem
   JavaScript, do mesmo jeito */
details.f2-recuperacao{margin-top:16px}
details.f2-recuperacao>summary{list-style:none;cursor:pointer;display:inline-block;font-size:12.5px;
  color:var(--brand-2);user-select:none}
details.f2-recuperacao>summary::-webkit-details-marker{display:none}
details.f2-recuperacao>summary:hover{text-decoration:underline}
details.f2-recuperacao .f2-ver-app,details.f2-recuperacao[open] .f2-ver-rec{display:none}
details.f2-recuperacao[open] .f2-ver-app{display:inline}
details.f2-recuperacao[open]>summary{margin-bottom:14px}
.entrada-form:has(>details.f2-recuperacao[open])>.f2-form-app{display:none}
/* as saídas discretas ("Voltar", "sair sem ligar", "Cancelar") e o link forte
   da nota da entrada ("Receber um link por e-mail") */
.f2-sair{color:var(--faint);font-size:12.5px;text-decoration:none}
.f2-sair:hover{color:var(--ink);text-decoration:underline}
.entrada-link-forte{font-weight:500;color:var(--brand-2)}
/* o botão da entrada também como LINK ("Guardei, continuar", "Pedir outro
   link"): sem o sublinhado do link e sem a cor de link no hover (azul sobre o
   azul do botão) */
a.btn-entrar,a.btn-entrar:hover{color:var(--sobre-solido);text-decoration:none}
.f2-enviado{font-size:14.5px;line-height:1.55;color:var(--ink);margin:0}

/* ligar o segundo fator: três passos numerados, o número no círculo da marca */
.f2-passos{list-style:none;counter-reset:passo;padding:0;margin:2px 0 0;display:flex;flex-direction:column;gap:20px}
.f2-passos>li{counter-increment:passo;position:relative;padding-left:36px;min-width:0}
.f2-passos>li::before{content:counter(passo);position:absolute;left:0;top:0;width:24px;height:24px;
  border-radius:50%;display:grid;place-items:center;font-size:12.5px;font-weight:600;
  background:var(--brand-suave);color:var(--brand-2)}
.f2-passo-t{font-family:var(--titulo);font-size:14px;font-weight:600;line-height:24px;color:var(--ink);margin-bottom:2px}
.f2-passos .entrada-nota{margin:0}
/* o quadro do QR: claro nos dois temas (ver o cabeçalho do bloco); a zona de
   silêncio do QR já vem no desenho, o quadro só dá a margem */
.f2-qr{background:var(--papel);color:var(--papel-tinta);border:1px solid var(--line);border-radius:8px;
  padding:8px;width:200px;max-width:100%;margin:12px 0 10px}
.f2-qr svg{display:block;width:100%;height:auto}
.f2-qr-falhou{margin:12px 0 10px;padding:10px 12px;border:1px dashed var(--warn);border-radius:8px;
  background:var(--warn-suave);color:var(--ink);font-size:12.5px;line-height:1.5}
/* "Abrir no app": só onde o ponteiro é o dedo (celular, tablet) — no computador
   não há app autenticador para abrir, e o link seria um botão morto */
.f2-abrir-app{display:none}
@media (pointer:coarse){
 .f2-abrir-app{display:inline-flex;align-items:center;min-height:40px;margin:0 0 8px;font-size:13.5px;
  font-weight:500;color:var(--brand-2)}
}
/* a chave para digitar: blocos de 4, um clique seleciona a chave inteira */
.f2-chave-bloco{display:flex;flex-direction:column;gap:6px;margin-top:4px}
.f2-chave{display:block;font-family:var(--mono);font-size:13px;letter-spacing:.02em;line-height:1.6;
  color:var(--ink);background:var(--ground);border:1px solid var(--line);border-radius:6px;padding:8px 10px;
  overflow-wrap:anywhere;user-select:all}
.f2-saida{margin-top:4px}
.f2-agora-nao{font-size:13px;font-weight:500;color:var(--brand-2)}

/* os códigos de recuperação: numerados, em fonte monoespaçada (0 e o, 1 e l não
   se confundem), dois por linha — um por linha no celular. O cartão alarga um
   pouco nesta tela: dois códigos lado a lado não cabem nos 440 px de sempre */
.entrada-card:has(.f2-papel){max-width:500px}
.f2-papel{margin:12px 0 14px;padding:14px 16px;border:1px solid var(--line);border-radius:8px;background:var(--ground)}
.f2-papel-cab{display:none}
.f2-lista{list-style:none;counter-reset:cod;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 20px}
.f2-lista li{counter-increment:cod;display:flex;align-items:baseline;gap:8px;min-width:0}
.f2-lista li::before{content:counter(cod);min-width:16px;text-align:right;font-size:11px;color:var(--faint);
  font-variant-numeric:tabular-nums}
.f2-lista code{font-family:var(--mono);font-size:14.5px;color:var(--ink);letter-spacing:.02em;white-space:nowrap}
.f2-papel-pe{margin:12px 0 0;font-size:12px;color:var(--muted)}
.f2-botoes:not([hidden]){display:flex;gap:8px;margin:0 0 12px}
@media (max-width:440px){
 .f2-lista{grid-template-columns:1fr}
}
/* NA IMPRESSÃO, SÓ OS CÓDIGOS: o Imprimir chama window.print(), e a folha sai
   com o cabeçalho (a conta e a data) e os dez códigos em tinta escura — nada da
   tela: fundo animado, barra, botões, avisos. A animação de entrada do cartão
   sai também (ela começa transparente, e a folha poderia sair em branco). */
@media print{
 /* o tema escuro diz color-scheme:dark, e o navegador pintava a MARGEM da folha
    de escuro (medido no PDF do Chrome): a folha dos códigos é papel claro. O
    seletor é :root e não html de propósito — o do tema escuro pesa (0,2,0), e
    um html:has(…) (0,1,1) perdia para ele sem erro nenhum */
 :root:has(.f2-papel){color-scheme:light;background:var(--papel)}
 body:has(.f2-papel){background:var(--papel)}
 body:has(.f2-papel) :is(#barra-ir,#fundo-sol,.entrada-topo,.entrada-rodape,.entrada-rodape-card){display:none!important}
 body:has(.f2-papel) .entrada-form>:not(.f2-papel){display:none!important}
 body:has(.f2-papel) .entrada-wrap{display:block;min-height:0;padding:0}
 body:has(.f2-papel) .entrada-card{max-width:none;border:0;border-radius:0;box-shadow:none;background:none;
  animation-name:none}
 body:has(.f2-papel) .entrada-form{padding:0}
 .f2-papel{border:1px solid var(--papel-tinta);background:var(--papel);color:var(--papel-tinta)}
 .f2-papel-cab{display:flex;justify-content:space-between;flex-wrap:wrap;gap:4px 16px;margin-bottom:12px;font-size:12px}
 .f2-papel code,.f2-papel .f2-papel-pe,.f2-papel .f2-lista li::before{color:var(--papel-tinta)}
}

/* MINHA CONTA: o estado do segundo fator, os códigos que sobram e as duas ações
   dobradas (cada uma pede a senha e o código) */
.f2-status{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 10px;margin:4px 0 8px}
.f2-status-sub{font-size:12.5px;color:var(--faint)}
.f2-restantes{font-size:13px;color:var(--muted);margin:0 0 12px}
.f2-restantes.baixo{color:var(--warn-texto)}
.f2-restantes.zero{color:var(--crit-texto)}
details.f2-acao{border-top:1px solid var(--line)}
details.f2-acao>summary{list-style:none;cursor:pointer;padding:10px 0;font-size:13px;font-weight:500;
  color:var(--brand-2);user-select:none}
details.f2-acao>summary::-webkit-details-marker{display:none}
details.f2-acao>summary::before{content:"›";display:inline-block;width:14px;
  transition:transform var(--dur-rapida) var(--curva-saida)}
details.f2-acao[open]>summary::before{transform:rotate(90deg)}
.f2-acao-form{padding:0 0 16px}
.f2-sem-email{font-size:12.5px;color:var(--warn-texto);margin:0 0 12px}

/* a faixa de aviso depois da entrada (o que mudou na conta desde a anterior) */
.aviso-seguranca ul{margin:4px 0;padding-left:18px}

/* A TRILHA DE AUDITORIA: a tabela densa de sempre. O detalhe quebra linha em vez
   de esticar a coluna; falhou e negado ganham cor e a marca na borda da linha
   (sem o ponto que pulsa: numa trilha com vinte tentativas, pulso cansa). A
   marca é um fundo de 3 px e não borda nem sombra: a sombra é o hover da linha
   no Bootstrap, e a borda empurraria o texto. */
.trilha-tabela td{vertical-align:top}
.trilha-tabela td.nw{white-space:nowrap}
.tabela-box .trilha-tabela td.trilha-detalhe{white-space:normal;min-width:180px;max-width:360px;line-height:1.4;
  overflow-wrap:anywhere}
.trilha-res{font-size:12.5px;font-weight:500;color:var(--muted)}
.trilha-res.falhou{color:var(--crit-texto)}
.trilha-res.negado{color:var(--warn-texto)}
.trilha-tabela tr.trilha-alerta>td:first-child{background-image:linear-gradient(var(--crit),var(--crit));
  background-size:3px 100%;background-repeat:no-repeat}
/* os filtros: a lista de ações tem rótulos compridos — a caixa não passa de
   260 px (o texto corta dentro dela) */
.trilha-filtros .filtro .form-select{max-width:260px}

/* USUÁRIOS: o e-mail editável na linha, a regra do segundo fator à vista e o
   "zerar" dobrado sob a linha da pessoa */
.usu-inativo{opacity:.55}
.usu-email{display:flex;gap:6px;align-items:center}
.usu-email .form-control{width:250px;min-width:0;max-width:100%}
.usu-f2-regra{font-size:12.5px;color:var(--muted);margin:0 0 12px}

@media (max-width:700px){
 .usu-tabela td>.cel{margin-left:auto;min-width:0;text-align:right}
 .usu-tabela td>.cel .td-sub{white-space:normal}
 .usu-email{flex:1 1 auto;min-width:0;justify-content:flex-end}
 .usu-email .form-control{width:auto;flex:1 1 auto}
 .table td.trilha-detalhe,.tabela-box .trilha-tabela td.trilha-detalhe{display:block;min-width:0;max-width:none;
  text-align:left}
 .table td.trilha-detalhe::before{display:block;margin-bottom:3px}
 .trilha-filtros .filtro{flex:1 1 100%;min-width:0}
 .trilha-filtros .filtro .form-select{flex:1 1 auto;max-width:none;min-width:0}
}
/* fim: SEGURANÇA (a checagem de cor literal lê este bloco) */

/* ============================================================================
   LUMINA — O BALÃO (28/09/2026, v0.55.0)
   A IA de economia do Prisma. O HTML e o JavaScript estão no app.py
   (_lumina_html, _LUMINA_JS) e só entram na página quando o servidor diz que a
   Lumina existe para aquela pessoa. O Samuel: "sem cara de IA" — nada de
   brilho, gradiente ou estrelinha; é uma ferramenta de trabalho, então tudo
   aqui é peça que o sistema já tem: a superfície que flutua (--elevado), a
   linha (--line), o véu do painel do Radar, o rótulo pequeno em caixa alta das
   tabelas, o aviso em --warn-suave.
   (1) O BOTÃO fica no canto de baixo, à direita, numa pílula clara com o sol da
   Lumiset em traço. Camada 40: acima do conteúdo, ABAIXO de tudo o que se abre
   por cima dele (menus 55–60, a folha do "i" no celular 60, o painel do Radar
   900, o tutorial 1000, o feedback 1040, o aviso curto 1100). Para não cobrir
   o fim da página (o botão de salvar de um formulário, o rodapé), a coluna do
   conteúdo ganha folga embaixo só quando o botão aparece.
   (2) O PAINEL é um <dialog> modal: no computador, a faixa da direita (420 px,
   a altura inteira); até 640 px, uma folha que sobe de baixo, na largura toda.
   A conversa rola por dentro; cabeçalho, campo e rodapé ficam parados.
   (3) A RESPOSTA guarda as quebras de linha (pre-line) e quebra palavra longa;
   "Por quê:" e "O que fazer:" ganham só o peso, sem virar cartão. O que o
   conferidor tirou vai numa nota com a borda de atenção.
   (4) MOVIMENTO: entrar e sair deslizando, pelos tokens — o bloco de menos
   movimento e a chave Animações valem aqui sem regra própria.
   (5) O RODAPÉ HONESTO e AS FONTES (30/09): o rodapé diz quem responde (a IA
   da Anthropic) e o que ela recebe, com o "Saiba o que é enviado" dobrado; no
   ensaio, outro texto ("nada sai do servidor"), que o módulo só mostra quando
   a central confirma. Embaixo de cada resposta, discreta, a linha "Fontes: …
   · N números conferidos" quando o servidor manda as fontes.
   ========================================================================= */
.lu-botao{position:fixed;right:20px;bottom:20px;z-index:40;display:inline-flex;align-items:center;gap:8px;
  height:40px;padding:0 16px 0 12px;border:1px solid var(--line);border-radius:999px;background:var(--elevado);
  color:var(--ink);font:inherit;font-size:13.5px;font-weight:600;line-height:1;box-shadow:var(--sombra-alta);
  cursor:pointer;transition:border-color var(--dur-rapida),transform var(--dur-rapida),box-shadow var(--dur-rapida),
  opacity var(--dur-rapida)}
.lu-botao svg{flex:none;color:var(--brand)}
.lu-botao:hover{border-color:var(--brand)}
.lu-botao:active{transform:scale(.97)}
.lu-botao:focus-visible{outline:0;box-shadow:0 0 0 3px var(--anel),var(--sombra-alta)}
/* SAI DA FRENTE: um botão de ação da página embaixo do canto (o JS marca
   .recuado) — o da Lumina some e o clique passa para o de baixo; com o foco do
   teclado nele, volta à vista (quem está no teclado não está clicando ali) */
.lu-botao.recuado{opacity:0;pointer-events:none}
.lu-botao.recuado:focus-visible{opacity:1;pointer-events:auto}
/* a marca de "pensando" e de "resposta nova" (chegou com o painel fechado): um ponto, parado */
.lu-marca{display:none;width:7px;height:7px;border-radius:50%;background:var(--brand);flex:none}
.lu-botao.pensando .lu-marca{display:block;background:var(--faint)}
.lu-botao.nova .lu-marca{display:block}
body:has(>.lu-botao:not([hidden])) main.content-col{padding-bottom:84px}

.lu-veu{position:fixed;inset:0;background:var(--veu);z-index:1040;animation:surgir var(--dur-media) var(--curva-saida)}
@keyframes lu-entrar{from{opacity:0;transform:translateX(28px)}}
@keyframes lu-sair{to{opacity:0;transform:translateX(28px)}}
@keyframes lu-subir{from{opacity:0;transform:translateY(40px)}}
@keyframes lu-descer{to{opacity:0;transform:translateY(40px)}}
dialog.lu-painel{position:fixed;inset:0 0 0 auto;margin:0;width:420px;max-width:100vw;height:100vh;height:100dvh;
  max-height:none;padding:0;border:0;border-left:1px solid var(--line);background:var(--elevado);color:var(--ink);
  box-shadow:var(--sombra-alta);overflow:hidden;animation:lu-entrar var(--dur-media) var(--curva-saida)}
dialog.lu-painel::backdrop{background:transparent}
dialog.lu-painel.fechando{animation:lu-sair var(--dur-rapida) var(--curva-entrada) forwards}
.lu-caixa{display:flex;flex-direction:column;height:100%;min-height:0}

/* o cabeçalho: o nome e as ações na primeira linha; a linha de apoio, a situação
   e — no ensaio — a etiqueta, na largura toda embaixo */
.lu-cab{flex:none;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:8px;
  padding:12px 12px 12px 18px;border-bottom:1px solid var(--line)}
.lu-cab>p{grid-column:1/-1}
.lu-titulo{display:flex;align-items:center;gap:8px;margin:0;font-family:var(--titulo);font-size:17px;font-weight:600;
  line-height:1.25;letter-spacing:-.01em;color:var(--ink)}
.lu-titulo svg{flex:none;color:var(--brand)}
.lu-apoio{margin:2px 0 0;font-size:12.5px;color:var(--muted);line-height:1.4}
/* (03/10/2026) a versão pré-alfa: a etiqueta de sempre (.lu-etq) e a frase, no tom da linha de apoio */
.lu-pre{margin:6px 0 0;font-size:12px;line-height:1.45;color:var(--muted)}
.lu-situ{margin:6px 0 0;font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
.lu-situ:empty{display:none}
.lu-ensaio{margin:6px 0 0;font-size:12px;line-height:1.45;color:var(--faint)}
.lu-etq{display:inline-block;margin-right:6px;padding:0 6px;border:1px solid var(--line);border-radius:4px;
  font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.lu-cab-acoes{flex:none;display:flex;align-items:center;gap:2px}
.lu-nova{height:32px;padding:0 8px;border:0;border-radius:6px;background:transparent;color:var(--brand-2);
  font:inherit;font-size:12.5px;cursor:pointer;transition:background-color var(--dur-rapida)}
.lu-nova:hover{background:var(--nav-on)}
.lu-nova:disabled{color:var(--faint);background:transparent;cursor:default}
.lu-x{width:32px;height:32px;padding:0;border:0;border-radius:6px;background:transparent;color:var(--faint);
  display:grid;place-items:center;cursor:pointer;transition:background-color var(--dur-rapida),color var(--dur-rapida)}
.lu-x:hover{background:var(--nav-on);color:var(--ink)}

/* a conversa: rola por dentro; cada troca é pergunta e resposta, separadas por um fio */
.lu-conversa{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:2px 18px 10px}
.lu-conversa:focus{outline:none}
.lu-vazia{padding:18px 0 6px}
.lu-vazia-t{margin:0 0 12px;font-size:13px;line-height:1.5;color:var(--muted)}
.lu-exemplos{display:flex;flex-direction:column;align-items:flex-start;gap:6px}
.lu-exemplo{max-width:100%;padding:7px 11px;border:1px solid var(--line);border-radius:6px;background:var(--ground);
  color:var(--ink);font:inherit;font-size:13px;line-height:1.35;text-align:left;cursor:pointer;
  transition:border-color var(--dur-rapida),background-color var(--dur-rapida)}
.lu-exemplo:hover{border-color:var(--brand)}
.lu-exemplo:disabled{color:var(--faint);border-color:var(--line);cursor:default}
.lu-par{padding:14px 0;border-bottom:1px solid var(--line)}
.lu-par:last-child{border-bottom:0}
.lu-quem{margin:0 0 3px;font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--faint)}
.lu-pergunta{margin:0 0 12px;font-size:13.5px;line-height:1.5;color:var(--muted);white-space:pre-line;
  overflow-wrap:anywhere}
.lu-resposta{font-size:13.5px;line-height:1.55;color:var(--ink);white-space:pre-line;overflow-wrap:anywhere}
.lu-resposta b{font-weight:600}
/* (06/10) contorno de 1 px em volta, como o .aviso-gap.warn — no lugar da faixa de
   3 px na esquerda (o tique de "cara de IA"); o fundo âmbar e a frase dizem o resto */
.lu-tirados,.lu-falha{margin:10px 0 0;padding:8px 10px;border:1px solid var(--warn);border-radius:6px;
  background:var(--warn-suave);font-size:12.5px;line-height:1.45;color:var(--ink);overflow-wrap:anywhere}
.lu-falha{margin-top:0}
.lu-tirados p{margin:0}
.lu-tirados summary{width:max-content;margin-top:4px;color:var(--brand-2);cursor:pointer}
.lu-tirados ul{margin:6px 0 0;padding-left:18px;color:var(--muted)}
/* de onde a resposta saiu (30/09): uma linha discreta logo abaixo dela — "Fontes: … · N números
   conferidos"; o rótulo um tom acima do resto, sem cor de destaque */
.lu-fontes{margin:8px 0 0;font-size:12px;line-height:1.45;color:var(--faint);overflow-wrap:anywhere;
  font-variant-numeric:tabular-nums}
.lu-fontes-r{color:var(--muted);font-weight:500}
.lu-pensando-t{margin:0;font-size:13px;color:var(--muted)}
.lu-tempo{color:var(--faint);font-variant-numeric:tabular-nums}
.lu-passos{margin:6px 0 0;padding-left:18px;font-size:12.5px;line-height:1.5;color:var(--faint)}
.lu-passos li{animation:surgir var(--dur-media) var(--curva-saida)}

/* o bloqueio (limite do dia, do mês, fora do ar), o campo e o rodapé fixo */
.lu-bloqueio{flex:none;margin:0 18px 10px;padding:8px 10px;border:1px solid var(--warn);border-radius:6px;
  background:var(--warn-suave);font-size:12.5px;line-height:1.45;color:var(--ink)}
.lu-form{flex:none;margin:0;padding:10px 18px 6px;border-top:1px solid var(--line)}
.lu-campo{display:block;min-height:64px;max-height:180px;field-sizing:content;resize:none;font-size:14px;
  line-height:1.45;background:var(--sup)}
.lu-form-pe{display:flex;align-items:center;justify-content:flex-end;gap:10px;margin-top:8px}
.lu-dica{margin-right:auto;font-size:11.5px;color:var(--faint)}
.lu-conta{font-size:11.5px;color:var(--faint);font-variant-numeric:tabular-nums}
.lu-conta:empty{display:none}
.lu-aviso{margin:6px 0 0;font-size:12.5px;color:var(--crit-texto)}
.lu-aviso:empty{display:none}
.lu-pe{flex:none;margin:0;padding:6px 18px 12px;font-size:11.5px;line-height:1.45;color:var(--faint)}
/* o rodapé honesto (30/09): a linha à vista e o "Saiba o que é enviado" — o marcador de sempre do
   <details> (o mesmo do "ver o que saiu"), na cor dos links; o detalhe um tom acima do rodapé */
.lu-pe p{margin:0}
.lu-enviado summary{width:max-content;max-width:100%;margin-top:3px;color:var(--brand-2);cursor:pointer}
.lu-enviado ul{margin:4px 0 0;padding-left:16px;color:var(--muted)}
.lu-enviado li+li{margin-top:3px}

@media (max-width:640px){
 /* a folha não deixa a página rolar por trás. :root e não html: a barra de rolagem
    sempre à vista (html:has(>body>header.top), bloco A TROCA DE VISÃO) pesa mais que
    um html.classe e mantinha a página rolando — medido na prévia a 375 */
 :root.lu-aberto{overflow:hidden}
 .lu-botao{right:12px;bottom:12px;padding:0 14px 0 10px}
 body:has(>.lu-botao:not([hidden])) main.content-col{padding-bottom:72px}
 dialog.lu-painel{inset:auto 0 0 0;width:100%;height:calc(100vh - 20px);height:calc(100dvh - 20px);border-left:0;
  border-top:1px solid var(--line);border-radius:14px 14px 0 0;animation-name:lu-subir}
 dialog.lu-painel.fechando{animation-name:lu-descer}
 .lu-cab{padding:12px 8px 10px 16px}
 .lu-conversa{padding:2px 16px 10px}
 .lu-bloqueio{margin:0 16px 10px}
 .lu-form{padding:10px 16px 6px}
 .lu-pe{padding:4px 16px 10px}
 .lu-dica{display:none}             /* no celular não há Shift+Enter: o botão basta */
}
/* no papel, nada da Lumina */
@media print{
 .lu-botao,.lu-veu,dialog.lu-painel{display:none!important}
}
/* fim: LUMINA (a checagem de cor literal lê este bloco) */

/* ============================================================================
   LUMINA — PLANO E USO (29/09/2026, v0.56.0)
   A tela do diretor (tela_lumina_plano, no app.py): a Lumina está ligada?
   Quanto do mês já foi? Quem perguntou? — com os números da central, SEM
   reais. É a página de relatório dos Indicadores (.rel, .rel-faixa,
   .rel-margem, .rel-nums, .rel-visual, .rel-lado, .rel-vazio): uma superfície
   com faixas separadas por um fio, sem cartão por bloco. Aqui ficam só as
   peças próprias dela:
   (1) a SITUAÇÃO: a palavra em tinta com o ponto no tom (como as palavras do
       Radar enxuto), a frase da central embaixo e, no ensaio, a mesma
       etiqueta do balão (.lu-etq);
   (2) o USO DO MÊS: o número grande e a barra num trilho que é a escala
       inteira (0 a 100%). A partir de 80% a barra fica em atenção — nunca em
       vermelho: aqui não há dinheiro perdido (a régua do vermelho), há um
       serviço que para;
   (3) POR DIA: uma coluna fina por dia do mês, em HTML (não SVG esticado); a
       de hoje com um fundo de coluna; o eixo só com os dias de referência,
       centrados na coluna mesmo quando o rótulo é mais largo que ela (flex);
   (4) o link "Plano e uso" do balão, só do diretor, na linha da situação.
   ========================================================================= */
.lp>.rel-faixa:first-child{border-top:0}          /* aqui não há barra de filtros em cima */
/* (1) a situação */
.lp-situ{max-width:78ch}
.lp-situ p{margin:0}
.estado.lp-e{color:var(--ink);font-size:14px;font-weight:600}
.estado.lp-e.b-ok::before{background:var(--ok)}
.estado.lp-e.b-warn::before{background:var(--warn)}
.estado.lp-e.b-novo{color:var(--muted)}
.estado.lp-e.b-novo::before{background:var(--faint)}
.lp-situ .lp-frase{margin-top:6px;font-size:13px;line-height:1.55;color:var(--muted)}
.lp-situ .lp-ensaio{margin-top:10px;font-size:12.5px;line-height:1.5;color:var(--faint)}
/* (03/10/2026) a versão pré-alfa: a mesma etiqueta e a mesma frase do balão, com o limite da empresa */
.lp-situ .lp-pre{margin-top:10px;font-size:12.5px;line-height:1.5;color:var(--muted)}
/* o total de hoje da empresa: "3 de 5" — o "de 5" menor, no tom do rótulo */
.lp-de{font-size:.55em;font-weight:500;letter-spacing:0;color:var(--muted)}
.lp-situ .lp-acao{margin-top:12px}
/* (2) o uso do mês */
.lp-uso{max-width:640px}
.lp-uso-l1{display:flex;align-items:baseline;flex-wrap:wrap;gap:2px 14px}
.lp-pct{font-family:var(--titulo);font-size:28px;font-weight:600;letter-spacing:-.02em;line-height:1.1;
  color:var(--ink);font-variant-numeric:tabular-nums}
.lp-renova{font-size:12.5px;color:var(--muted);font-variant-numeric:tabular-nums}
.lp-trilho{position:relative;height:8px;margin-top:10px;border-radius:4px;background:var(--panel-2);overflow:hidden}
.lp-trilho>i{position:absolute;inset:0 auto 0 0;border-radius:4px;background:var(--brand);transform-origin:left;
  animation:encher var(--dur-lenta) var(--curva-saida) 160ms backwards}
.lp-trilho.alto>i{background:var(--warn)}
.lp-aviso{margin:10px 0 0;font-size:12.5px;line-height:1.5;color:var(--warn-texto)}
.lp-plano{margin:12px 0 0;font-size:13px;line-height:1.55;color:var(--muted)}
.lp-plano b{color:var(--ink);font-weight:600}
.lp-extra{display:inline-block;margin-left:4px;padding:1px 7px;border-radius:4px;background:var(--brand-suave);
  color:var(--brand-2);font-size:12px;line-height:1.5;white-space:nowrap}
/* (3) as perguntas: os totais, a tabela por pessoa e as colunas por dia. Lado a
   lado só no computador — abaixo de 992 px o .rel-lado empilha (por isso a
   proporção fica dentro do @media: solta, ela venceria o empilhar) */
@media (min-width:992px){.lp-lado{grid-template-columns:minmax(0,1fr) minmax(0,1.2fr)}}
.lp-tab td.principal{font-weight:500;color:var(--ink)}
.lp-lim{color:var(--warn-texto);font-weight:600;white-space:nowrap}
.lp-dias{min-width:0;padding-top:4px}
.lp-barras{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(var(--n,30),minmax(0,1fr));
  gap:2px;height:72px;align-items:end;border-bottom:1px solid var(--line)}
.lp-barras>li{height:100%;display:flex;align-items:flex-end;min-width:0;border-radius:2px 2px 0 0}
.lp-barras>li.hoje{background:var(--nav-on)}
.lp-barras i{display:block;width:100%;border-radius:2px 2px 0 0;background:var(--brand);transform-origin:bottom;
  animation:lp-crescer var(--dur-lenta) var(--curva-saida) 160ms backwards}
@keyframes lp-crescer{from{transform:scaleY(0)}}
.lp-eixo{display:grid;grid-template-columns:repeat(var(--n,30),minmax(0,1fr));gap:2px;margin-top:5px;
  font-size:11px;line-height:1.2;color:var(--faint);font-variant-numeric:tabular-nums}
.lp-eixo span{display:flex;justify-content:center;min-width:0;white-space:nowrap}
.lp-eixo span.ini{justify-content:flex-start}
.lp-eixo span.fim{justify-content:flex-end}
.lp-eixo span.hoje{color:var(--ink);font-weight:600}
/* a mesma tela de novo ("Tentar de novo"): as barras não enchem outra vez */
:root[data-entrada="mesma"] :is(.lp-trilho>i,.lp-barras i){animation-name:none}
/* (4) o link "Plano e uso" no balão (só o diretor): na linha da situação, à direita */
.lu-cab>.lu-situ-l{grid-column:1/-1;display:flex;align-items:baseline;flex-wrap:wrap;gap:2px 12px;margin-top:6px}
.lu-situ-l>.lu-situ{margin:0}
.lu-plano{margin-left:auto;font-size:12px;color:var(--brand-2);text-decoration:none;white-space:nowrap}
.lu-plano:hover{text-decoration:underline}
.lu-plano[aria-current]{color:var(--faint);text-decoration:none;pointer-events:none}   /* já está na página */
@media (max-width:700px){
 .lp-pct{font-size:24px}
 .lp-barras{gap:1px;height:60px}
 .lp-eixo{gap:1px}
}
@media print{
 .lp-acao{display:none}
}
/* fim: PLANO E USO DA LUMINA (a checagem de cor literal lê este bloco) */

/* ============================================================================
   O PLANO DO PRISMA (29/09/2026, v0.56.0; os PREÇOS NOVOS e o WhatsApp em 03/10/2026)
   A tela do diretor (tela_plano, no app.py): as três faixas (3 · 5 · 10 obras),
   o preço grande no mensal e no anual, o botão que abre o WhatsApp da Lumiset e
   o que cada um inclui — a IDEIA da página de planos que o Samuel mandou,
   vestida com a identidade do Prisma:
   (1) UMA superfície (--panel, fio --line) com as colunas separadas por um
       fio. Nada de sombra, degradê ou selo — e nenhuma coluna "atual" (o Prisma
       não sabe qual faixa foi contratada);
   (2) as seis partes de cada coluna (nome, resumo, preço, nota, o botão, o que
       inclui) são LINHAS de uma grade comum (subgrid): o preço de uma coluna
       fica na altura do preço da outra mesmo quando um resumo quebra em mais
       linhas. Navegador sem subgrid: cada coluna empilha as suas partes;
   (3) A CHAVINHA Mensal | Anual (03/10): a mesma .visao-troca do Radar, feita
       de dois rádios de verdade (escondidos, focáveis) com o rótulo como
       botão; quem esconde o período que não está marcado nas três colunas é o
       :has — sem JavaScript. Num navegador sem :has, os dois períodos
       aparecem (nada some, nada mente);
   (4) a faixa de contexto, sobre o fundo da página: fatos separados por um fio
       (o período de teste, as obras em andamento) e o atalho para o plano e
       uso da Lumina; embaixo das colunas, o caminho para "mais de 10 obras" e
       a frase de que ainda não há pagamento pelo sistema;
   (5) abaixo de 992 px as colunas empilham, separadas por um fio horizontal;
       a 700 px os fatos também;
   (6) A BARRA DO TOPO COM O PLANO (8 itens em vez de 7): no fim do bloco.
   (11/10/2026, pedido do Miguel — a lógica da página de assinatura do Xbox
   Game Pass; 3ª rodada: "ficou muito IA, sem personalidade — uma brincadeira
   de cor, a progressão no tom, claro e ir escurecendo"). A MESMA marcação de
   antes (só a ordem das partes de cada faixa mudou), outro desenho:
   (7) a ABERTURA centrada (o rótulo, o título curto, uma linha) e o contexto
       embaixo dela; a chavinha também centrada;
   (8) a chavinha é uma PÍLULA grande, o período marcado no sólido da marca;
   (9) CINCO OPÇÕES COM COR: cada uma num degradê da SUA cor (as --pl-* do
       :root), do tom claro no canto de cima ao escuro embaixo — as três
       faixas são a família azul que aprofunda com o tamanho, a Lumina o
       verde, o personalizado o vermelho da Lumiset. Sem fio nem sombra: a cor é o bloco.
       Em cada faixa, o topo centrado (o nome, o preço, o botão num tom claro
       da cor, a nota em itálico) e, embaixo, o DESTAQUE ("Até 3 obras", em
       negrito) e a lista com o visto. As seis partes numa grade comum
       (subgrid): o preço, o botão e o destaque na mesma altura nos três;
   (10) embaixo, só a frase de que ainda não há pagamento pelo sistema (o
       "mais de 10 obras" saiu: é o bloco Personalizado, 11/10). */
.pl{display:flex;flex-direction:column;gap:26px;min-width:0}
/* (7) a abertura, centrada como numa página de assinatura, e o contexto embaixo dela */
.pl-topo{display:flex;flex-direction:column;align-items:center;gap:16px;min-width:0;text-align:center}
.pl-hero{min-width:0;max-width:760px}
.pl-hero-o{margin:0;font-size:11px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--brand-2)}
.pl-hero-t{margin:6px 0 0;font-family:var(--titulo);font-size:30px;font-weight:700;line-height:1.2;
  letter-spacing:-.02em;color:var(--ink)}
.pl-hero-s{margin:8px auto 0;max-width:64ch;font-size:14.5px;line-height:1.55;color:var(--muted)}
/* (4) o contexto */
.pl-contexto{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:12px 28px;min-width:0}
.pl-fatos{display:flex;flex-wrap:wrap;justify-content:center;gap:10px 0;margin:0;min-width:0}
.pl-fato{min-width:0;padding:0 22px;border-left:1px solid var(--line)}
.pl-fato:first-child{padding-left:0;border-left:0}
.pl-fato dt{font-size:11px;font-weight:500;letter-spacing:.05em;text-transform:uppercase;color:var(--faint)}
.pl-fato dd{margin:3px 0 0;font-size:14px;font-weight:600;line-height:1.35;color:var(--ink);
  font-variant-numeric:tabular-nums}
.pl-apoio{display:block;margin-top:1px;font-size:12px;font-weight:400;color:var(--muted)}
.pl-atalho{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--brand-2);
  text-decoration:none;white-space:nowrap}
.pl-atalho svg{color:var(--brand);flex:none}
.pl-atalho:hover{text-decoration:underline}
/* (3)(8) a chavinha Mensal | Anual, centrada: o rótulo, a pílula e a frase do período embaixo */
.pl-periodo{display:flex;flex-direction:column;align-items:center;gap:10px;min-width:0;margin:0;padding:0;border:0;
  text-align:center}
.pl-periodo-t{float:none;margin:0;padding:0;font-size:11px;font-weight:500;letter-spacing:.05em;
  text-transform:uppercase;color:var(--faint)}
.pl-troca{display:inline-flex;align-items:center;gap:4px;padding:4px;border:1px solid var(--line);border-radius:999px;
  background:var(--panel)}
.pl-troca label{min-width:112px;padding:8px 24px;border-radius:999px;font-size:14px;font-weight:500;line-height:1.4;
  text-align:center;color:var(--muted);cursor:pointer;white-space:nowrap;
  transition:background-color var(--dur-rapida),color var(--dur-rapida)}
.pl-troca label:hover{background:var(--nav-on);color:var(--ink)}
/* o rádio sai da vista e continua no teclado (as setas trocam o período); o rótulo é o desenho */
.pl-radio{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}
/* (8) o período marcado no sólido da marca (o mesmo do botão principal: 6,7:1 no texto) */
.pl-radio:checked+label{background:var(--brand-solido);color:var(--sobre-solido);font-weight:600}
.pl-radio:focus-visible+label{outline:2px solid var(--anel);outline-offset:1px}
.pl-periodo-nota{margin:0;font-size:13px;line-height:1.5;color:var(--muted)}
/* quem esconde o período que não está marcado, nas colunas, nos blocos e na frase (sem :has, os dois ficam) */
.pl:has(#pl-p-anual:checked) .pl-so-mensal{display:none}
.pl:has(#pl-p-mensal:checked) .pl-so-anual{display:none}
/* (9) AS CINCO OPÇÕES COM COR: o degradê da cor de cada uma — um brilho no canto de cima sobre a
   descida do tom claro ao escuro. Cada bloco lê as SUAS quatro cores (--pl-a, -b, -botao, -tinta) */
.pl-col,.pl-extra{--pl-a:var(--pl-3-a);--pl-b:var(--pl-3-b);--pl-botao:var(--pl-3-botao);--pl-tinta:var(--pl-3-tinta);
  color:var(--pl-texto);border-radius:14px;
  background:radial-gradient(120% 70% at 0% 0%,var(--pl-a) 0%,transparent 72%),
    linear-gradient(165deg,var(--pl-a) 0%,var(--pl-b) 84%)}
.pl-col[data-plano="5_obras"]{--pl-a:var(--pl-5-a);--pl-b:var(--pl-5-b);--pl-botao:var(--pl-5-botao);
  --pl-tinta:var(--pl-5-tinta)}
.pl-col[data-plano="10_obras"]{--pl-a:var(--pl-10-a);--pl-b:var(--pl-10-b);--pl-botao:var(--pl-10-botao);
  --pl-tinta:var(--pl-10-tinta)}
.pl-extra[data-extra="lumina"]{--pl-a:var(--pl-lu-a);--pl-b:var(--pl-lu-b);--pl-botao:var(--pl-lu-botao);
  --pl-tinta:var(--pl-lu-tinta)}
.pl-extra[data-extra="personalizado"]{--pl-a:var(--pl-pe-a);--pl-b:var(--pl-pe-b);--pl-botao:var(--pl-pe-botao);
  --pl-tinta:var(--pl-pe-tinta)}
/* as três faixas lado a lado (a linha da grade sem vão — o subgrid herda o vão) */
.pl-planos{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 18px}
.pl-col{grid-row:span 6;display:grid;grid-template-rows:subgrid;align-content:start;min-width:0;
  padding:32px 28px 30px;position:relative;overflow:hidden}
/* o topo centrado: o nome, o preço, o botão e a nota */
.pl-nome{margin:0;text-align:center;font-family:var(--titulo);font-size:26px;font-weight:700;letter-spacing:-.015em;
  line-height:1.15;color:var(--pl-texto)}
.pl-preco{margin:10px 0 0;text-align:center}
.pl-p{margin:0;display:flex;flex-direction:column;align-items:center;gap:2px}
.pl-valor{font-family:var(--titulo);font-size:40px;font-weight:600;letter-spacing:-.025em;line-height:1.05;
  color:var(--pl-texto);white-space:nowrap;font-variant-numeric:tabular-nums}
.pl-moeda{margin-right:6px;font-size:.45em;letter-spacing:0;vertical-align:.8em}
.pl-unid{font-size:13px;color:var(--pl-texto-2)}
/* o botão de contratar (link de verdade para o WhatsApp; a seta diz que abre noutra aba): num tom
   CLARO da cor do bloco, com o texto no escuro dela — salta do fundo sem sair da família */
.pl-acao{margin:18px 0 0;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;align-self:start;
  gap:8px 10px}
.pl-whats{flex:1 1 auto;min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:44px;padding:11px 22px;border:0;border-radius:8px;background:var(--pl-botao);color:var(--pl-tinta);
  font-size:13px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  transition:filter var(--dur-rapida),transform var(--dur-rapida)}
.pl-whats:hover,.pl-whats:focus-visible,.pl-whats:active{background:var(--pl-botao);color:var(--pl-tinta);
  filter:brightness(1.05)}
.pl-whats:focus-visible{outline:2px solid var(--pl-texto);outline-offset:2px}
.pl-col .pl-whats{flex:0 1 auto;min-width:min(100%,250px)}
.pl-whats svg{flex:none}
/* a nota, em itálico como a linha miúda da referência; no anual, o total pago de uma vez em destaque */
.pl-nota{margin:10px 0 0;text-align:center;font-size:12.5px;font-style:italic;line-height:1.5;color:var(--pl-texto-2)}
.pl-nota p{margin:0}
.pl-nota b{font-style:normal;font-weight:600;color:var(--pl-texto)}
/* (11/10/2026, 8ª rodada do Miguel) quanto o anual economiza, em DESTAQUE: uma pílula no tom claro da cor da
   opção, com o texto escuro dela (o par do botão, contraste medido), o valor em negrito */
.pl-eco-destaque{display:inline-flex;align-items:baseline;gap:4px;padding:5px 12px;border-radius:999px;
  background:var(--pl-botao);color:var(--pl-tinta);font-size:13px;font-style:normal;font-weight:600;line-height:1.35}
.pl-eco-destaque b,.pl-conta .pl-eco-destaque b{color:var(--pl-tinta);font-weight:800;white-space:nowrap}   /* (o .pl-conta b pinta o negrito de branco) */
.pl-nota .pl-eco-destaque{margin-top:8px}
/* o DESTAQUE: quantas obras, grande e em negrito — e o resto do resumo embaixo */
.pl-resumo{margin:30px 0 0;font-size:14px;line-height:1.5;color:var(--pl-texto-2)}
.pl-resumo b{display:block;margin-bottom:2px;font-family:var(--titulo);font-size:22px;font-weight:700;
  letter-spacing:-.01em;line-height:1.2;color:var(--pl-texto)}
/* o que inclui: a lista com o visto, sem fio (o título fica para o leitor de tela: o destaque já diz) */
.pl-inclui{margin-top:14px}
.pl-inclui-t{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}
.pl-itens{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.pl-itens li{display:grid;grid-template-columns:18px minmax(0,1fr);gap:10px;align-items:start;padding:6px 0;
  font-size:14px;line-height:1.45;color:var(--pl-texto)}
.pl-itens svg{margin-top:1px;color:var(--pl-texto)}
/* (10) embaixo de tudo: a frase de que ainda não há pagamento pelo sistema */
.pl-pe{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:0;text-align:center}
.pl-como{margin:0;max-width:90ch;font-size:12.5px;line-height:1.55;color:var(--muted)}
/* (11) O SALTO: com o mouse em cima o bloco sobe 6 px, cresce um tico (na curva de mola) e a cor
   acende um pouco. Só em quem tem mouse (no dedo, o "hover" grudaria); no teclado, com o foco À
   VISTA dentro dele (o clique de mouse numa pílula não o deixa preso no alto) */
.pl-col,.pl-extra{transition:transform var(--dur-media) var(--curva-mola),filter var(--dur-media)}
@media (hover:hover){
 .pl-col:hover,.pl-extra:hover{transform:translateY(-6px) scale(1.012);filter:brightness(1.08) saturate(1.06)}
}
.pl-col:has(:focus-visible),.pl-extra:has(:focus-visible){transform:translateY(-6px) scale(1.012);
  filter:brightness(1.08) saturate(1.06)}
/* (12) OS DOIS BLOCOS DE BAIXO: a Lumina como adicional e o personalizado acima de 10 obras, lado
   a lado, na mesma linguagem (a cor, o topo centrado); as escolhas em pílulas de vidro (rádios de
   verdade) — a marcada no tom claro da cor, como o botão — e o resultado num quadro mais escuro */
.pl-extras{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px;align-items:stretch;min-width:0}
.pl-extra{display:flex;flex-direction:column;min-width:0;overflow:hidden}
/* (13/10/2026) com a Lumina fora da venda só o Personalizado fica: um bloco sozinho não deixa um buraco na
   metade da direita — ocupa a linha, centrado, na largura de uma coluna e meia */
.pl-extras>.pl-extra:only-child{grid-column:1/-1;justify-self:center;width:min(100%,640px)}
.pl-escolhas>.pl-esc:only-child{grid-column:1/-1}   /* sem a escolha da Lumina, as obras ocupam a linha */
.pl-extra-cab{padding:30px 28px 4px;text-align:center}
.pl-extra-o{display:flex;align-items:center;justify-content:center;gap:7px;margin:0;font-size:11px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--pl-texto-2)}
.pl-extra-o svg{flex:none}
.pl-extra-t{margin:8px 0 0;font-family:var(--titulo);font-size:26px;font-weight:700;letter-spacing:-.015em;
  line-height:1.2;color:var(--pl-texto)}
.pl-extra-r{margin:8px auto 0;max-width:56ch;font-size:14px;line-height:1.5;color:var(--pl-texto-2)}
.pl-extra-corpo{flex:1 1 auto;display:flex;flex-direction:column;gap:22px;padding:22px 28px 28px}
.pl-escolhas{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 24px;align-items:start}
.pl-esc{min-width:0;margin:0;padding:0;border:0}
/* no personalizado, o seletor de obras precisa de menos largura que as três pílulas da Lumina */
[data-extra="personalizado"] .pl-escolhas{grid-template-columns:minmax(0,.64fr) minmax(0,1.36fr)}
.pl-esc-t{display:block;float:none;width:auto;margin:0 0 9px;padding:0;font-size:11px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--pl-texto-2)}
.pl-pilulas{display:flex;flex-wrap:wrap;gap:8px}
/* o rádio sai da vista e continua no teclado; o rótulo é a pílula */
.pl-op{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}
.pl-pilulas label{display:inline-flex;flex-direction:column;align-items:flex-start;gap:1px;padding:8px 12px;
  border:1px solid var(--pl-borda);border-radius:10px;background:var(--pl-vidro);font-size:13.5px;font-weight:600;
  line-height:1.3;color:var(--pl-texto);cursor:pointer;
  transition:background-color var(--dur-rapida),border-color var(--dur-rapida),color var(--dur-rapida)}
.pl-pilulas label small{font-size:11.5px;font-weight:400;color:var(--pl-texto-2)}
.pl-pilulas label:hover{border-color:var(--pl-texto);background:var(--pl-vidro-on)}
.pl-op:checked+label{background:var(--pl-botao);border-color:var(--pl-botao);color:var(--pl-tinta)}
.pl-op:checked+label small{color:var(--pl-tinta)}
.pl-op:focus-visible+label{outline:2px solid var(--pl-texto);outline-offset:2px}
/* a quantidade de obras: − [número] + e a régua de arrastar embaixo, no mesmo vidro */
.pl-passo{display:inline-flex;align-items:stretch;border:1px solid var(--pl-borda);border-radius:10px;overflow:hidden;
  background:var(--pl-vidro)}
.pl-passo button{width:42px;padding:0;border:0;background:transparent;font-size:18px;line-height:1;
  color:var(--pl-texto);cursor:pointer;transition:background-color var(--dur-rapida),color var(--dur-rapida)}
.pl-passo button:hover{background:var(--pl-vidro-on)}
.pl-passo button:focus-visible{outline:2px solid var(--pl-texto);outline-offset:-2px}
.pl-num{width:76px;padding:8px 4px;border:0;border-left:1px solid var(--pl-borda);border-right:1px solid var(--pl-borda);
  background:transparent;font-family:var(--titulo);font-size:20px;font-weight:600;text-align:center;
  color:var(--pl-texto);font-variant-numeric:tabular-nums;appearance:textfield;-moz-appearance:textfield}
.pl-num::-webkit-inner-spin-button,.pl-num::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.pl-num:focus-visible{outline:2px solid var(--pl-texto);outline-offset:-2px}
.pl-arrasto{display:block;width:100%;margin:14px 0 0;accent-color:var(--pl-botao)}
.pl-esc-dica{margin:6px 0 0;font-size:12px;color:var(--pl-texto-2)}
/* o resultado: um quadro mais escuro, o total grande à esquerda e o botão à direita */
.pl-resultado{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:14px 22px;margin-top:auto;
  padding:18px 20px;border-radius:12px;background:var(--pl-quadro)}
.pl-res-valores{min-width:0}
.pl-res-t{margin:0 0 4px;font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--pl-texto-2)}
.pl-resultado .pl-p{align-items:flex-start}
.pl-resultado .pl-valor{font-size:36px}
.pl-conta{margin:6px 0 0;font-size:12.5px;line-height:1.5;color:var(--pl-texto-2)}
.pl-conta b{color:var(--pl-texto);font-weight:600}
.pl-conta b,.pl-conta [data-c]{white-space:nowrap}   /* "R$" e o número nunca em linhas diferentes */
.sem-lumina .pl-com-lu{visibility:hidden}
.pl-resultado .pl-acao{margin:0;min-width:210px}
@media (max-width:1199.98px){
 .pl-escolhas,[data-extra="personalizado"] .pl-escolhas{grid-template-columns:minmax(0,1fr)}
 .pl-resultado{grid-template-columns:minmax(0,1fr)}
 .pl-resultado .pl-acao{min-width:0}
}
/* (5) tablet e celular: as faixas e os blocos empilham, com ar entre eles; a 700 px, os fatos também */
@media (max-width:991.98px){
 .pl-planos{grid-template-columns:minmax(0,1fr)}
 .pl-col{padding:26px 20px 24px}
 .pl-col+.pl-col{margin-top:16px}            /* empilhados: um bloco embaixo do outro, com ar */
 .pl-extras{grid-template-columns:minmax(0,1fr)}
 .pl-extra-cab{padding:26px 20px 4px}
 .pl-extra-corpo{padding:18px 20px 22px}
}
@media (max-width:700px){
 .pl-fatos{flex-direction:column;gap:12px}
 .pl-fato{padding:0;border-left:0}
 .pl-hero-t{font-size:24px}
 .pl-valor{font-size:34px}
 .pl-troca{display:flex;width:100%}
 .pl-troca label{flex:1 1 0;min-width:0;padding:8px 12px}
 .pl-extra-t{font-size:22px}
 .pl-resultado{padding:16px}
 .pl-resultado .pl-valor{font-size:32px}
}
/* (6) A BARRA DO TOPO COM O PLANO. O item "Plano" (só o diretor) soma 58 px à
   barra. Medido no Chrome sem janela (.tmp/v056-plano/plano_barra.py: tela COM
   tutorial, obra em foco, nome de empresa comprido), o seletor de obra passava
   POR BAIXO dos botões da direita a 992–1000 px (−11), 1140–1180 (−40), 1280–1320
   (−33), 1366–1399 (−27) e 1400–1440 (−55). Com o Plano na barra (:has), os
   itens ficam mais juntos entre 992 e 1599 px: 7 px de cada lado em vez de 11
   (64 px de volta; o rótulo continua com 16 px de ar para o vizinho). A partir
   de 1600 px sobra espaço (145 px) e o desenho é o de sempre. */
@media (min-width:992px) and (max-width:1599.98px){
 .top:has(.nav-plano) .nav-item{padding:0 7px}
}
/* (11/10/2026, 5ª rodada do Miguel) o NOME DO PACOTE em cima de cada faixa — Básico, Premium, Platinum —, no
   mesmo versalete do "Adicional" e do "Personalizado" dos blocos de baixo */
.pl-col-o{display:block;margin:0 0 8px;font-family:var(--sans);font-size:11px;font-weight:700;letter-spacing:.12em;
  line-height:1.4;text-transform:uppercase;color:var(--pl-texto-2)}
/* (11/10/2026, o bug do Miguel: escolher a Lumina no Personalizado fazia os DOIS blocos de baixo crescerem — e a
   chavinha Mensal | Anual também mexia na altura) a conta dos dois períodos e a parte da Lumina ocupam SEMPRE o
   seu lugar: empilhadas na mesma célula da grade, a que não vale fica invisível (e fora do leitor de tela) — a
   altura é a da maior, e nada pula quando a escolha muda */
.pl-res-valores{display:grid;grid-template-columns:minmax(0,1fr)}
.pl-res-valores>.pl-p{grid-area:2/1}
.pl-res-valores>.pl-conta{grid-area:3/1;min-height:3.4em}   /* a conta do mensal (até duas linhas) ou a pílula do anual */
.pl:has(#pl-p-anual:checked) .pl-res-valores>.pl-p.pl-so-mensal,
.pl:has(#pl-p-mensal:checked) .pl-res-valores>.pl-p.pl-so-anual{display:flex;visibility:hidden}
.pl:has(#pl-p-anual:checked) .pl-res-valores>.pl-conta.pl-so-mensal,
.pl:has(#pl-p-mensal:checked) .pl-res-valores>.pl-conta.pl-so-anual{display:block;visibility:hidden}
/* fim: O PLANO DO PRISMA (a checagem de cor literal lê este bloco) */

/* ============================================================================
   A AMOSTRA DA LUMINA — O CHAT TRANCADO (30/09/2026; no lugar do cartão "em
   desenvolvimento" de 29/09)
   O pedido do Samuel: na demo, a Lumina abre "o chat mesmo", com a parte de
   digitar TRANCADA e a mensagem do plano que a libera, e em cima balões com
   perguntas prontas que ela responde com respostas prontas. O painel é o do
   balão que conversa (o bloco LUMINA — O BALÃO, lá em cima): a faixa de 420 px
   à direita, na altura toda; até 640 px, a folha de baixo para cima. Aqui
   ficam as peças novas e QUEM aparece em cada estado — decide a classe
   `lu-trancada` no <dialog>:
     · no "em desenvolvimento" (a demo e a produção sem a central) ela vem do
       servidor, e o painel só tem as peças da amostra;
     · no que conversa, o módulo a põe quando a central diz que a Lumina não
       está no plano ("nao_contratada"): somem o campo, os exemplos que o
       preenchem, o bloqueio, a situação, o ensaio, "Nova conversa", o rodapé
       da IA e a conversa guardada (ela continua na memória da aba); aparecem
       as perguntas prontas, a caixa trancada e o rodapé da amostra.
   (1) AS PERGUNTAS PRONTAS: uma faixa PARADA entre o cabeçalho e a conversa (a
   conversa rola, os balões ficam à mão) — pílulas com o fio da linha no fundo
   da página; a já respondida desce um tom e ganha o visto (um traço em L
   girado, na cor do texto: nada de ícone novo) — clicada de novo, leva de
   volta à resposta.
   (2) A CAIXA TRANCADA: o campo de verdade, desabilitado, no fundo da página
   (e não no branco de um campo que aceita texto), com a frase do plano DENTRO
   dele: o <p> e o <textarea> dividem a mesma célula de grade — a célula cresce
   com a frase (no celular ela quebra em duas linhas) e o campo estica junto.
   O cadeado é o do rodapé do sistema, em traço.
   (3) A RESPOSTA DE EXEMPLO: a etiqueta "exemplo" é a pecinha do "ensaio"
   (.lu-etq), ao lado do "Lumina".
   ========================================================================= */
/* quem aparece em cada estado — (0,4,0) e (0,3,0): vencem as regras do balão sem !important */
.lu-painel:not(.lu-trancada) :is(.lu-prontas,.lu-amostra-vazia,.lu-trancado,.lu-pe-amostra,.lu-par.lu-ex){display:none}
.lu-trancada :is(.lu-form,.lu-bloqueio,.lu-vazia,.lu-nova,.lu-situ,.lu-situ-l,.lu-ensaio,.lu-pe-ia,.lu-pe-ensaio,
  .lu-par:not(.lu-ex)){display:none}
/* (1) as perguntas prontas */
.lu-prontas{flex:none;display:flex;flex-wrap:wrap;gap:6px;padding:12px 18px;border-bottom:1px solid var(--line)}
.lu-pronta{display:inline-flex;align-items:center;gap:7px;max-width:100%;padding:6px 12px;border:1px solid var(--line);
  border-radius:16px;background:var(--ground);color:var(--ink);font:inherit;font-size:13px;line-height:1.35;
  text-align:left;cursor:pointer;transition:border-color var(--dur-rapida),color var(--dur-rapida)}
.lu-pronta:hover{border-color:var(--brand)}
.lu-pronta:focus-visible{outline:0;border-color:var(--brand);box-shadow:0 0 0 3px var(--anel)}
.lu-pronta.feita{color:var(--muted)}
.lu-pronta.feita::before{content:"";flex:none;width:9px;height:5px;margin-top:-3px;border:solid currentColor;
  border-width:0 0 2px 2px;transform:rotate(-45deg)}
/* a conversa da amostra: a frase de antes da primeira pergunta; a etiqueta junto do nome */
.lu-amostra-vazia{margin:0;padding:16px 0 6px;font-size:13px;line-height:1.5;color:var(--muted)}
.lu-quem .lu-etq{margin:0;vertical-align:1px}
.lu-par.lu-ex:focus{outline:none}
.lu-par.lu-ex:focus-visible{outline:2px solid var(--brand);outline-offset:3px;border-radius:4px}
/* (2) a caixa trancada */
.lu-trancado{flex:none;margin:0;padding:10px 18px 6px;border-top:1px solid var(--line)}
.lu-trava-caixa{display:grid}
.lu-trava-caixa>*{grid-area:1/1}
.lu-trancado .lu-campo{align-self:stretch;height:auto;min-height:56px;max-height:none;field-sizing:fixed;resize:none;
  cursor:not-allowed}
.lu-trancado .lu-campo:disabled{background-color:var(--ground);border-color:var(--line);opacity:1}
.lu-trava{z-index:1;display:flex;align-items:center;gap:9px;margin:0;padding:10px 14px;pointer-events:none;
  font-size:13px;line-height:1.45;color:var(--muted)}
.lu-trava svg{flex:none;width:15px;height:15px;color:var(--faint)}
.lu-trava b{font-weight:600;color:var(--ink)}
.lu-ver-planos{margin-right:auto;font-size:12.5px;color:var(--brand-2);text-decoration:none}
.lu-ver-planos:hover{text-decoration:underline}
@media (max-width:640px){
 .lu-prontas{padding:10px 16px}
 .lu-trancado{padding:10px 16px 6px}
 .lu-trava{padding:9px 12px}
}
/* fim: A AMOSTRA DA LUMINA (a checagem de cor literal lê este bloco) */

/* ============================================================================
   O SINO DE NOVIDADES (01/10/2026, v0.58.0)
   O pedido do Samuel: "em cima na direita, um símbolo de sino para colocar as
   atualizações do sistema para os clientes ficarem sabendo o que estamos
   fazendo". O HTML e o JavaScript estão no app.py (_sino_html, _SINO_JS); a
   lista, em piloto/novidades.py.
   (1) O BOTÃO é um .tb-btn como os vizinhos, logo antes do menu da empresa. A
       BOLINHA (há novidade que a pessoa ainda não abriu) é o acento da barra,
       não o vermelho: no Prisma vermelho é perda e é a marca da seleção. Um
       anel no tom da barra a separa do desenho do sino. Aberto, o botão fica
       com o fundo de "em uso" (o mesmo do hover).
   (2) O PAINEL desce do sino como os menus da barra — a mesma superfície que
       flutua, a mesma camada 60 dentro da barra, a mesma entrada —: no
       computador, 380 px alinhado à direita do sino; até 575 px, a largura
       inteira logo abaixo da barra (a caixa do sino deixa de ser a referência
       e quem manda é a barra, como no menu das seções), com uma sobra embaixo
       para tocar fora. Altura máxima e a rolagem POR DENTRO: o título fica
       parado em cima e a página atrás não rola junto.
   (3) UMA SUPERFÍCIE com faixas: um fio entre as entradas, nada de cartão por
       entrada (a régua "sem cara de IA"). A data discreta, o título na tinta
       cheia, as frases um tom abaixo; com mais de uma frase, os marcadores.
   (4) Só tokens: vale no claro e no escuro (a barra é noturna nos dois). O
       movimento é o dos menus — o bloco de menos movimento e a chave
       Animações valem aqui sem regra própria.
   ============================================================================ */
.sino{position:relative;display:flex;align-items:center}
.sino-btn{position:relative}
.sino-btn[aria-expanded="true"]{background:var(--barra-on);color:var(--barra-ink)}
.sino-btn.sino-nova::after{content:"";position:absolute;top:6px;right:6px;width:8px;height:8px;border-radius:50%;
  background:var(--barra-acento);box-shadow:0 0 0 2px var(--sidebar);pointer-events:none}
.sino-painel{position:absolute;top:calc(100% + 6px);right:0;z-index:60;width:380px;max-width:calc(100vw - 24px);
  max-height:min(560px,calc(100vh - 72px));max-height:min(560px,calc(100dvh - 72px));overflow-y:auto;
  overscroll-behavior:contain;background:var(--elevado);color:var(--ink);border:1px solid var(--line);
  border-radius:8px;box-shadow:var(--sombra-alta)}
.sino-painel:not([hidden]){animation:menu-abrir var(--dur-media) var(--curva-saida)}
.sino-painel:focus{outline:none}
.sino-painel:focus-visible{box-shadow:0 0 0 3px var(--anel),var(--sombra-alta)}
.sino-titulo{position:sticky;top:0;z-index:1;margin:0;padding:12px 16px 10px;background:var(--elevado);
  border-bottom:1px solid var(--line);font-family:var(--titulo);font-size:15px;font-weight:600;line-height:1.3;
  letter-spacing:-.01em;color:var(--ink)}
.sino-lista{list-style:none;margin:0;padding:0}
.sino-item{padding:12px 16px 14px}
.sino-item+.sino-item{border-top:1px solid var(--line)}
.sino-data{margin:0 0 2px;font-size:11.5px;line-height:1.4;color:var(--faint);font-variant-numeric:tabular-nums}
.sino-tit{margin:0;font-family:var(--sans);font-size:13.5px;font-weight:600;line-height:1.35;color:var(--ink)}
.sino-itens{margin:4px 0 0;padding:0;list-style:none;font-size:13px;line-height:1.5;color:var(--muted)}
.sino-itens li+li{margin-top:4px}
.sino-itens:has(>li+li){padding-left:17px;list-style:disc}
.sino-itens li::marker{color:var(--faint)}
@media (max-width:575.98px){
 .sino{position:static}
 .sino-painel{top:100%;left:0;right:0;width:auto;max-width:none;border-width:0 0 1px;border-radius:0 0 10px 10px;
  max-height:calc(100vh - 108px);max-height:calc(100dvh - 108px)}
}
/* (5) A BARRA DO CELULAR com o sino: são 34 px a mais na linha da marca, dos
   botões e do ☰. Medido (.tmp/v058-sino/banca.py barra), numa tela COM tutorial:
   a 375 px o ☰ era espremido de 36 para 28 px, e abaixo de 360 a página rolava
   de lado (já a 320 sem o sino, por 3 px). Até 420 px, os botões da barra têm 30
   px de largura (a altura continua 32), sem vão entre eles, e as três partes da
   barra ficam mais juntas; abaixo de 360, as bordas da barra mais justas e o
   botão "Animações" sai — no celular o movimento segue o do sistema, que é o
   modo automático. (No computador, o que o sino mudou está no bloco OBRA EM
   FOCO, lá em cima: o seletor pendurado e o teto do nome da empresa.) */
@media (max-width:420px){
 .top{gap:4px}
 .top-dir{gap:0}
 .top-dir .tb-btn{width:30px}
 details.menu-conta,.chip-empresa{margin-left:2px}
}
@media (max-width:359.98px){
 .top{padding:0 6px 0 8px}
 #btn-mov{display:none}
}
@media print{
 .sino-painel{display:none}
}
/* fim: O SINO DE NOVIDADES (a checagem de cor literal lê este bloco) */

/* ============================================================================
   AS OBRAS SEM MEDIÇÃO (02/10/2026, v0.60.0 — o piloto da Domus: "as obras
   dela têm de aparecer"). Obra com orçamento e pagamentos, mas sem o avanço
   físico: o Radar a lista numa tabela própria (a mesma superfície das outras),
   as outras leituras dizem quantas são numa linha, a ficha mostra o que já dá
   para ver e o Financeiro abre onde há lançamento. A régua na tela: o pago é
   "do orçamento já pago" e NÃO tem barra (pareceria avanço da obra); nenhuma
   cor de estado; o único vermelho é a etapa que já passou do orçado (a classe
   perda, da régua do vermelho). Cor só por token: a checagem de cor literal
   lê este bloco até o "fim:".
   ============================================================================ */
/* (1) o Radar: a tabela das obras sem análise, irmã de "Obras em andamento" */
.sm-tabela td{padding-top:14px;padding-bottom:14px}
.sm-tabela td.principal{min-width:200px}
.sm-tabela .nome{font-weight:600;color:var(--ink);text-decoration:none}
.sm-tabela .nome:hover{color:var(--brand-2);text-decoration:underline}
.sm-tabela .v{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.sm-tabela .v.perda{color:var(--crit-texto)}
.sm-tabela .mudo{color:var(--faint)}
.sm-tabela td.sm-acao{white-space:nowrap}
/* (2) a linha das leituras que não listam essas obras (Circular, Resultado, Caixa) */
.sm-linha{margin:0;font-size:13px;color:var(--muted);line-height:1.55;max-width:110ch}
.sm-linha b{color:var(--ink);font-weight:600}
.sm-linha a{color:var(--brand-2);font-weight:500}
/* (3) a ficha: o que falta (na faixa do aviso do motor, com o botão) e o que já dá para ver */
.aviso-gap.sm-falta,.aviso-gap.sm-combinado{flex-wrap:wrap}
.sm-falta-txt{flex:1 1 320px;min-width:0}
.sm-acoes{margin-left:auto;flex:none;display:flex;gap:8px;flex-wrap:wrap}
.sm-fatos{display:flex;flex-wrap:wrap;gap:14px 0;margin:2px 0 16px}
.sm-fato{padding:0 22px 2px;border-right:1px solid var(--fio);min-width:0}
.sm-fato:first-child{padding-left:2px}
.sm-fato:last-child{border-right:0}
.sm-fato dt{font-size:12px;font-weight:500;color:var(--faint);margin-bottom:3px}
.sm-fato dd{margin:0;display:flex;flex-direction:column;gap:2px}
.sm-fato .v{font-size:18px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.sm-fato .v.perda{color:var(--crit-texto)}
.sm-fato .v .mudo{color:var(--faint);font-weight:400}
.sm-fato .ap{font-size:12px;color:var(--muted)}
.sm-etapas td.principal{white-space:normal}
.sm-etapas .mudo{color:var(--faint)}
.sm-nota{font-size:12.5px;color:var(--muted);line-height:1.55;margin:10px 2px 0;max-width:96ch}
.sm-nota b{color:var(--ink);font-weight:600}
.sm-nota a{color:var(--brand-2)}
.sm-pe{margin-top:12px;padding:12px 2px 0}
/* o "Lançamento mensal" da primeira medição: a referência do Financeiro */
.lanc-ref b{color:var(--ink);font-weight:600}
/* (4) a Carteira dos Indicadores: a sub-lista das obras sem análise, como a de cima */
.rel-sem-med td{vertical-align:middle}
.rel-sem-med .td-sub a{color:var(--brand-2)}
.rel-sem-med tbody tr{transition:opacity var(--dur-rapida)}
.rel-sem-med.tem-sel tbody tr:not(.sel){opacity:.5}
.rel-sem-med.tem-sel tbody tr:not(.sel):hover{opacity:1}
.rel-sem-med tbody tr.sel>*{background:var(--brand-suave)}
/* (5) o Resultado e o Caixa das obras sem medição: desde 03/10/2026 (a estrutura da demo) elas
   são linhas das tabelas de sempre (.res-tabela, .cx-obras), com "—" — nada próprio aqui */
/* (6) o Financeiro: o mês que a tela abriu e o vazio que diz onde está o dado */
.fin-onde{font-size:13px;color:var(--muted);margin:0;line-height:1.55}
.fin-onde b{color:var(--ink);font-weight:600}
.fin-onde a{color:var(--brand-2);font-weight:500}
.vazio .fin-onde{margin:0 auto 10px;max-width:72ch}
@media (max-width:700px){
 .sm-tabela td{flex-wrap:wrap}
 .sm-tabela td>.cel{margin-left:auto;text-align:right}
 .sm-tabela td>.cel .td-sub,.sm-tabela td.principal .td-sub{white-space:normal}
 .sm-tabela td.sm-acao{white-space:normal;justify-content:flex-end}
 .sm-acoes{margin-left:0;width:100%}
 .sm-acoes .btn{flex:1 1 auto}
 .sm-fato{flex:1 1 45%;padding:0 12px 0 2px;border-right:0}
 .sm-fato .v{font-size:16px}
 .sm-pe{flex-direction:column;align-items:stretch}
 /* as etapas da ficha viram um cartão de DUAS linhas (o molde do "como chegamos"; o de quatro,
    o padrão do celular, dava 1.300 px para oito etapas): o nome e a situação em cima; orçado e
    pago embaixo */
 .sm-etapas tr{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:12px;row-gap:3px;padding:9px 2px}
 .sm-etapas td{display:block;padding:0;border:0;text-align:left;min-width:0}
 .sm-etapas td.principal{grid-row:1;grid-column:1}
 .sm-etapas td.sm-situ{grid-row:1;grid-column:2;text-align:right}
 .sm-etapas td.sm-situ::before{display:none}
 .sm-etapas td[data-l="Orçado"]{grid-row:2;grid-column:1;font-size:11.5px;color:var(--muted)}
 .sm-etapas td[data-l="Pago"]{grid-row:2;grid-column:2;font-size:11.5px;color:var(--muted);text-align:right}
 .sm-etapas td[data-l="Orçado"]::before,.sm-etapas td[data-l="Pago"]::before{display:inline;margin-right:5px;
  font-size:11px;letter-spacing:0;text-transform:lowercase}
}
/* fim: AS OBRAS SEM MEDIÇÃO (a checagem de cor literal lê este bloco) */

/* ============================================================================
   FALTA INFORMAÇÃO (02/10/2026, v0.61.0 — o pedido do Samuel: "com a falta de
   informação fica muito vazio [...] pegar a tela da demo e colocar um blur nas
   coisas, tipo no gráfico, e colocar que falta a informação que precisa para
   aparecer a opção"). Onde um bloco NÃO PODE existir porque falta um dado da
   construtora, a tela mostra o MESMO bloco desenhado com a DEMO (dado fictício,
   `piloto/exemplo.py`), desfocado por baixo, e por cima o aviso: o que falta
   (ou quando aparece), por quê, e o botão de onde informar. Só na parte que
   falta — o que a construtora já tem continua como sempre (`_falta_info`).
   A gramática, sem cara de IA:
     * o FUNDO é o desenho de verdade (as mesmas classes da tela), sem vida:
       `aria-hidden` + `inert` no HTML e, aqui, sem clique nem seleção; o
       desfoque e o esmaecido vêm de tokens (--falta-desfoque, --falta-opacidade
       nos dois temas) e a altura é limitada (--falta-alt, que a tela pode
       ajustar) — nenhum número da demo dá para ler;
     * o AVISO é uma superfície só (a do que flutua, --elevado, com o fio do
       tema), sem gradiente, sem vidro, sem sombra pesada: a etiqueta "Exemplo
       com dados fictícios" (o cliente não pode achar que o número é dele), o
       "Falta: …"/"Aparece quando: …", a frase e o botão;
     * SEM FUNDO (o exemplo falhou ao montar): o aviso sozinho numa caixa
       tracejada — a mesma do "sem faixa" da ficha —, com altura mínima, sem a
       etiqueta (não há exemplo). A tela nunca quebra;
     * na IMPRESSÃO o fundo sai (papel não desfoca, e um número fictício
       impresso viraria "número da obra"); no celular, nada rola de lado.
   ============================================================================ */
/* a LARGURA do bloco decide o arranjo (container query na caixa de fora): largo, o aviso
   centrado POR CIMA do exemplo (grid de uma célula); estreito (o cartão Custo da ficha, o
   celular), o exemplo em cima e o aviso sobre a parte de baixo dele — por cima de tudo, num
   bloco estreito, o aviso cobriria o exemplo inteiro e a ideia sumiria */
.falta-info{container-type:inline-size;border-radius:8px;margin:2px 0}
.falta-caixa{position:relative;display:grid;grid-template-columns:minmax(0,1fr);overflow:hidden;
 border-radius:8px;isolation:isolate}
.falta-caixa>.falta-fundo,.falta-caixa>.falta-aviso{grid-area:1/1;min-width:0}
.falta-fundo{max-height:var(--falta-alt,300px);overflow:hidden;filter:blur(var(--falta-desfoque));
 opacity:var(--falta-opacidade);pointer-events:none;user-select:none;-webkit-user-select:none}
/* o TEXTO do exemplo vira mancha: a letra fica transparente e sobra só a sombra difusa,
   no tom apagado do tema, proporcional ao tamanho da letra (o número grande borra mais).
   Só o desfoque geral não basta: o que apaga um "R$ 7,7 mi" de 26 px apaga junto a linha
   de 1 px do gráfico (medido no retrato) — assim o desenho continua à vista e nenhum número
   se lê. O `!important` vence a cor que o próprio pedaço traz no style (a do "mais provável") */
.falta-fundo *{color:transparent!important;text-shadow:0 0 .7em var(--faint)}
.falta-aviso{position:relative;z-index:1;align-self:center;justify-self:center;
 width:min(440px,calc(100% - 24px));margin:18px 12px;padding:14px 16px 15px;
 background:var(--elevado);border:1px solid var(--line);border-radius:8px;box-shadow:var(--sombra)}
.falta-etq{margin:0 0 6px;font-size:11px;font-weight:500;letter-spacing:.06em;text-transform:uppercase;
 color:var(--faint)}
.falta-tit{margin:0;font-family:var(--titulo);font-size:15px;font-weight:600;line-height:1.35;color:var(--ink)}
.falta-k{color:var(--muted);font-weight:500}
.falta-txt{margin:6px 0 0;font-size:13px;line-height:1.5;color:var(--muted)}
.falta-txt b{color:var(--ink);font-weight:600}
.falta-acao{margin:12px 0 0;display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px}
.falta-acao .link-suave{font-size:13px}
/* sem o exemplo: a caixa tracejada do "sem faixa", o aviso sem superfície própria */
.falta-info.sem-fundo{border:1px dashed var(--line);background:transparent}
.falta-info.sem-fundo .falta-caixa{min-height:120px}
.falta-info.sem-fundo .falta-aviso{background:transparent;border:0;box-shadow:none;margin:10px 8px}
@container (max-width:520px){
 .falta-caixa{display:block}
 .falta-fundo{max-height:min(var(--falta-alt,300px),170px)}
 .falta-aviso{width:auto;margin:-56px 8px 8px}
 .sem-fundo .falta-aviso{margin:10px 8px}
}
/* dentro de um cartão (o gráfico e o custo da ficha), o aviso respira menos */
.card .falta-info{margin:8px 0 0}
/* a manchete do Radar quando o motor ainda não tem a faixa de nenhuma obra: a faixa
   inteira é o exemplo (o .eco-topo de dentro, o da demo, guarda a grade de sempre) */
.eco-topo.eco-falta{display:block;padding:0}
/* a Circular sem obra analisada: o aviso fica no lugar da ilha React (que só diria
   "nenhuma obra marcada" — sem a análise do motor não há o que marcar) */
.falta-info.falta-circular~#raiz-react{display:none}
@media (max-width:575.98px){
 .falta-aviso{padding:12px 13px 13px}
 .falta-tit{font-size:14px}
 .falta-acao .btn{flex:1 1 auto}
}
@media print{
 .falta-fundo{display:none}
 .falta-info{border:1px dashed var(--line)}
 .falta-aviso{box-shadow:none;border:0}
}
/* fim: FALTA INFORMAÇÃO (a checagem de cor literal lê este bloco) */

/* ===== TOQUE (06/10, auditoria de responsivo) =====
   Onde o ponteiro é o DEDO (celular e tablet no canteiro, com pressa e uma mão
   só), todo controle ganha a área de toque de 44 px (WCAG 2.5.5 / guia da Apple)
   — por `pointer:coarse`, não pela largura: o computador com mouse mantém a
   densidade de sempre, e o tablet deitado (largo, mas no dedo) também ganha.
   Três jeitos, conforme o controle:
   1) botão e chavinha: altura mínima de verdade (a linha cresce um pouco);
   2) link solto no texto e o "?" da ajuda: a ÁREA cresce, o desenho não —
      padding + margem negativa (ou um ::after invisível) não mexem no layout;
   3) campo de digitar: letra de 16 px — abaixo disso o Safari do iPhone dá zoom
      na página ao tocar no campo, e a pessoa perde onde estava.
   As telas em React (Tarefas, Conciliação, Importação) entram pelo #raiz-react,
   sem recompilar o pacote: a ALTURA vem daqui (o Tailwind dá `height`, não
   `min-height`, então não há disputa); a LETRA de 16 px não — o `text-sm` do
   Tailwind é !important e venceria; ela mora na `@layer reforma-prisma`, lá em
   cima (bloco "o par do bloco TOQUE"). */
@media (pointer:coarse){
 /* a barra do topo: 44 de altura; o menu da conta e o ☰ também */
 .tb-btn{width:40px;height:44px}
 details.menu-conta>summary{min-height:44px}
 .nav-burger{width:40px;height:44px}
 .olho{width:44px;height:44px;top:0;right:0}
 /* botões (os do Bootstrap e os <summary> que abrem menu) */
 .btn,summary.btn{min-height:44px;display:inline-flex;align-items:center;justify-content:center;gap:4px}
 .table .btn-sm{min-height:40px;min-width:44px}
 .table td .btn-sm+.btn-sm,.table td form+.btn-sm,.table td .btn-sm+form,.table td form+form{margin-left:6px}
 /* a chavinha Tabela | Circular | Resultado | Caixa (e as outras .visao-troca) */
 .visao-troca>*:not(.visao-sep){min-height:40px;display:inline-flex;align-items:center;gap:4px}
 /* (o gap devolve o espaço do "✓ previsão": num flex, o espaço entre o ✓ e a
    palavra some) */
 /* links soltos: a área de toque cresce para cima e para baixo, o texto fica onde está */
 .link-suave,.entrada-link,summary.link-suave,a.nome,td>a.fw-semibold{padding-block:10px;margin-block:-10px}
 /* o "?" da ajuda: o desenho segue com 14 px, o dedo acerta 44 */
 .ajuda::after{content:"";position:absolute;inset:-15px}
 /* o "mudar ›" dos orçamentos */
 .kb-mover{min-height:44px}
 /* campos: 16 px evita o zoom do iPhone; 44 de altura para acertar o campo */
 .form-control,.form-select,input[type="search"]{font-size:16px;min-height:44px}
 /* os filtros (datas do Financeiro, selects das listas) desciam a 14 px no
    celular — o bastante para o iPhone dar zoom; no dedo, 16 */
 .filtro .form-select,.filtro .form-control{font-size:16px;min-height:44px}
 /* React: os botões do shadcn (xs = 24 px, sm = 28 px) e os seletores e campos crus */
 #raiz-react button,#raiz-react [data-slot="button"]{min-height:44px}
 #raiz-react [data-slot="button"][data-size="xs"],#raiz-react [data-slot="button"][data-size^="icon"]{min-width:44px}
 #raiz-react select,#raiz-react input:not([type="checkbox"]):not([type="radio"]){min-height:44px}
 /* o seletor "obra em foco" (na barra do tablet) */
 .foco-obra>summary{min-height:44px}
 /* o pé do cartão das Tarefas: com o "mover ›" em 16 px e ‹ › ✕ em 44, a fila não
    cabe ao lado do "desde" num cartão de 270 — o ✕ saía do cartão. Os botões
    descem para a linha de baixo, à direita (o `flex` do Tailwind não define
    `flex-wrap`, então aqui não há disputa) */
 #raiz-react div.flex:has(>span.flex>select){flex-wrap:wrap;row-gap:6px}
 #raiz-react span.flex:has(>select){margin-left:auto}
}
/* no celular estreito (até 420 px) a barra só tem 150 px para os ícones — por
   isso eles tinham 30 de largura. No dedo, o "Animações" sai (o movimento segue
   o do sistema, como já acontece abaixo de 360) e os que ficam ganham 36 x 44:
   4 x 36 = 144 cabe onde cabiam 5 x 30. */
@media (pointer:coarse) and (max-width:420px){
 #btn-mov{display:none}
 .top-dir .tb-btn{width:36px}
 .nav-burger{width:36px;flex:none}
}
/* abaixo de 360 (celular pequeno) não sobra nem isso: no Radar, com o botão do
   tutorial, o ☰ era espremido para 21 px. Ali os ícones voltam aos 30 de
   largura de antes (a altura de 44 fica) e o ☰ não encolhe. */
@media (pointer:coarse) and (max-width:359.98px){
 .top-dir .tb-btn{width:30px}
}
/* a régua do Financeiro (Confirmação | Vencimento | Competência) passava 3 px da
   tela a 320 — com mouse ou no dedo; os três botões ficam um pouco mais justos */
@media (max-width:359.98px){
 .filtro .btn-group .btn{--bs-btn-padding-x:.42rem}
}
/* fim: TOQUE */

/* INDICADORES EM CAIXAS (v0.61.2; refeito em 08/10/2026). Pedido do Samuel,
   vindo do sócio: cada seção da página é uma CAIXA — Caixa, O porquê,
   Carteira, Comercial e equipe. A primeira, "Caixa", tem no cabeçalho os
   botões Período e Métricas e, dentro, os cartões das métricas: o valor
   grande, verde quando o dinheiro entra (ou o resultado é positivo) e
   vermelho quando sai (ou é negativo), e no rodapé de cada cartão, separado
   por um fio e num tom abaixo, a comparação ou o que está em aberto — o
   desenho dos dois retratos de referência que ele mandou. Tudo pelos tokens:
   o claro e o escuro saem do mesmo CSS. */
:is(#relatorio,#resultado).rel-dashboard{display:flex;flex-direction:column;gap:14px;background:transparent;border:0;border-radius:0}
:is(#relatorio,#resultado).rel-dashboard>.rel-filtros{position:sticky;top:52px;z-index:8;padding:8px 16px;
 border:1px solid var(--line);border-radius:10px;background:var(--panel)}
:is(#relatorio,#resultado).rel-dashboard>.rel-faixa{display:flex;flex-direction:column;gap:18px;min-width:0;margin:0;padding:20px 22px 22px;
 border:1px solid var(--line);border-radius:12px;background:var(--panel);scroll-margin-top:120px}
/* o cabeçalho de cada caixa: o título e, embaixo, as datas dos números; à direita, os botões (no Caixa) */
:is(#relatorio,#resultado).rel-dashboard .rel-margem{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:3px 14px}
:is(#relatorio,#resultado).rel-dashboard .rel-margem h2{grid-column:1;grid-row:1;font-size:17px}
:is(#relatorio,#resultado).rel-dashboard .rel-relogio{grid-column:1;grid-row:2;margin:0;font-size:12.5px;font-weight:400;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .rel-comp{display:inline;margin:0;color:var(--faint)}
:is(#relatorio,#resultado).rel-dashboard .rel-comp::before{content:" · "}
:is(#relatorio,#resultado).rel-dashboard .rel-acoes{grid-column:2;grid-row:1/span 2;display:flex;align-items:center;justify-content:flex-end;
 flex-wrap:wrap;gap:8px}
:is(#relatorio,#resultado).rel-dashboard .rel-nota{grid-column:1/-1;margin:2px 0 0;max-width:90ch}
:is(#relatorio,#resultado).rel-dashboard .rel-corpo{gap:20px}

/* os botões Período e Métricas: o mesmo menu suspenso do sistema (details.acao-menu,
   que fecha ao clicar fora), abrindo para dentro da caixa */
:is(#relatorio,#resultado).rel-dashboard .rel-acoes>details>summary{display:inline-flex;align-items:center;gap:7px;min-height:34px;
 padding:5px 11px;border-radius:8px;font-size:13px;font-weight:500;white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .rel-acoes>details>summary>svg{flex:none}
:is(#relatorio,#resultado).rel-dashboard .rel-acoes>details>summary>svg:last-child{color:var(--muted);
 transition:transform var(--dur-rapida) var(--curva-saida)}
:is(#relatorio,#resultado).rel-dashboard .rel-acoes>details[open]>summary>svg:last-child{transform:rotate(180deg)}
:is(#relatorio,#resultado).rel-dashboard .rel-acoes .acao-lista{left:auto;right:0;min-width:240px;max-height:none}
:is(#relatorio,#resultado).rel-dashboard .rel-periodo-lista>.atual{display:flex;justify-content:space-between;align-items:center;gap:12px;
 padding:7px 10px;border-radius:6px;background:var(--brand-suave);color:var(--brand-2);font-size:13px;font-weight:500}
:is(#relatorio,#resultado).rel-dashboard .rel-periodo-lista .rel-form{min-width:0;margin-top:4px;padding:10px 6px 4px;border-top:1px solid var(--line)}
:is(#relatorio,#resultado).rel-dashboard .rel-form-tit{font-size:12px;font-weight:600;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .rel-form.atual .rel-form-tit{color:var(--brand-2)}
:is(#relatorio,#resultado).rel-dashboard .rel-metricas-painel{min-width:220px;padding:8px}
:is(#relatorio,#resultado).rel-dashboard .rel-met-dica{margin:2px 6px 6px;font-size:12px;color:var(--faint)}
:is(#relatorio,#resultado).rel-dashboard .rel-met-op{display:flex;align-items:center;gap:9px;min-height:36px;margin:0;padding:5px 8px;
 border-radius:6px;font-size:13px;color:var(--ink);cursor:pointer}
:is(#relatorio,#resultado).rel-dashboard .rel-met-op:hover{background:var(--nav-on)}
:is(#relatorio,#resultado).rel-dashboard .rel-met-op input{width:16px;height:16px;margin:0;flex:none;accent-color:var(--brand)}
:is(#relatorio,#resultado).rel-dashboard .rel-met-op:has(input:disabled){color:var(--faint);cursor:not-allowed}
:is(#relatorio,#resultado).rel-dashboard .rel-met-op:has(input:disabled):hover{background:transparent}
:is(#relatorio,#resultado).rel-dashboard .rel-met-op:has(input:focus-visible){outline:2px solid var(--anel);outline-offset:1px}

/* AS MÉTRICAS: as seis estão no HTML e só as marcadas no botão aparecem (funciona sem JS) */
:is(#relatorio,#resultado).rel-dashboard #f-caixa:has(#met-resultado:not(:checked)) [data-kpi="resultado"],
:is(#relatorio,#resultado).rel-dashboard #f-caixa:has(#met-a-receber:not(:checked)) [data-kpi="a_receber"],
:is(#relatorio,#resultado).rel-dashboard #f-caixa:has(#met-a-pagar:not(:checked)) [data-kpi="a_pagar"],
:is(#relatorio,#resultado).rel-dashboard #f-caixa:has(#met-recebido:not(:checked)) [data-kpi="recebido"],
:is(#relatorio,#resultado).rel-dashboard #f-caixa:has(#met-pago:not(:checked)) [data-kpi="pago"],
:is(#relatorio,#resultado).rel-dashboard #f-caixa:has(#met-inadimplencia:not(:checked)) [data-kpi="inadimplencia"]{display:none}
/* no exemplo desfocado do "Falta …" não há botão: ficam as 3 de sempre (as primeiras da ordem) */
:is(#relatorio,#resultado).rel-dashboard .falta-fundo .rel-kpi:nth-child(n+4){display:none}

/* OS CARTÕES DAS MÉTRICAS: o número grande na cor do sentido do dinheiro (.v-ok/.v-crit), o rodapé com o fio */
:is(#relatorio,#resultado).rel-dashboard .rel-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;
 margin:0;overflow:visible}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi{display:flex;flex-direction:column;min-width:0;margin:0;padding:0;
 border:1px solid var(--line);border-radius:12px;background:var(--panel);overflow:hidden;animation:none}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi .lab{padding:16px 18px 0;font-size:13.5px;line-height:1.35;color:var(--muted);white-space:normal}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi .val{margin:0;padding:8px 18px 18px;font-size:32px;line-height:1.1;letter-spacing:-.02em;
 white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe{margin-top:auto;padding:10px 18px 12px;border-top:1px solid var(--line);background:var(--ground)}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe .delta{margin:0;font-size:12.5px;line-height:1.45;color:var(--muted);white-space:normal}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe .delta+.delta{margin-top:2px}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe .delta>svg{display:inline-block;margin-right:4px;vertical-align:-1px}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe .delta>b{font-weight:600;color:var(--ink)}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe .delta.bom>:is(b,svg){color:var(--ok)}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe .delta.ruim>:is(b,svg){color:var(--crit)}
:is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe .rel-atraso{margin:2px 0 8px}

/* o gráfico e "para onde foi o dinheiro", lado a lado dentro da caixa, divididos por um fio */
:is(#relatorio,#resultado).rel-dashboard .rel-lado{grid-template-columns:minmax(0,1.65fr) minmax(280px,.9fr);gap:0}
:is(#relatorio,#resultado).rel-dashboard .rel-lado>*+*{border-left:1px solid var(--line);padding-left:22px;margin-left:22px}
:is(#relatorio,#resultado).rel-dashboard .rel-lado.tres{grid-template-columns:1fr;gap:0}
:is(#relatorio,#resultado).rel-dashboard .rel-lado.tres>*+*{border-left:0;border-top:1px solid var(--line);padding:16px 0 0;margin:14px 0 0}
:is(#relatorio,#resultado).rel-dashboard .rel-visual,:is(#relatorio,#resultado).rel-dashboard .rel-grafico{min-width:0}
:is(#relatorio,#resultado).rel-dashboard .rel-vh{align-items:center;margin-bottom:10px}
:is(#relatorio,#resultado).rel-dashboard .rel-vt{font-size:14px}
:is(#relatorio,#resultado).rel-dashboard .rel-vd{max-width:76ch}
@media (max-width:991px){
 :is(#relatorio,#resultado).rel-dashboard{gap:10px}
 :is(#relatorio,#resultado).rel-dashboard>.rel-filtros{position:static}
 :is(#relatorio,#resultado).rel-dashboard .rel-lado{grid-template-columns:minmax(0,1fr)}
 :is(#relatorio,#resultado).rel-dashboard .rel-lado>*+*{border-left:0;border-top:1px solid var(--line);padding:18px 0 0;margin:16px 0 0}
}
/* no celular: os botões descem para baixo do título, os cartões empilham e o número encolhe um pouco */
@media (max-width:640px){
 :is(#relatorio,#resultado).rel-dashboard>.rel-faixa{padding:16px 14px 18px;gap:14px;border-radius:10px}
 :is(#relatorio,#resultado).rel-dashboard .rel-margem{grid-template-columns:minmax(0,1fr)}
 :is(#relatorio,#resultado).rel-dashboard .rel-acoes{grid-column:1;grid-row:3;justify-content:flex-start;margin-top:8px}
 :is(#relatorio,#resultado).rel-dashboard .rel-acoes .rel-periodo-menu .acao-lista{left:0;right:auto}
 :is(#relatorio,#resultado).rel-dashboard .rel-kpis{grid-template-columns:minmax(0,1fr);gap:12px}
 :is(#relatorio,#resultado).rel-dashboard .rel-kpi .lab{padding:14px 16px 0}
 :is(#relatorio,#resultado).rel-dashboard .rel-kpi .val{padding:6px 16px 14px;font-size:28px}
 :is(#relatorio,#resultado).rel-dashboard .rel-kpi-pe{padding:9px 16px 11px}
}

/* O GRÁFICO AMPLIADO: o mesmo gráfico (com a dica do mês), num <dialog> com o foco preso nele */
:is(#relatorio,#resultado).rel-dashboard .ind-graf-ampliar,
:is(#relatorio,#resultado).rel-dashboard .ind-graf-fechar{display:grid;place-items:center;flex:none;width:36px;height:36px;padding:0;
 border:1px solid var(--line);border-radius:8px;background:var(--ground);color:var(--muted);cursor:pointer;
 transition:color var(--dur-rapida),background-color var(--dur-rapida),border-color var(--dur-rapida),transform var(--dur-rapida)}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-ampliar[hidden]{display:none}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-ampliar:hover,
:is(#relatorio,#resultado).rel-dashboard .ind-graf-fechar:hover{color:var(--ink);background-color:var(--panel);border-color:var(--brand-borda)}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-ampliar:active{transform:scale(.96)}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-ampliar:focus-visible,
:is(#relatorio,#resultado).rel-dashboard .ind-graf-fechar:focus-visible{outline:2px solid var(--anel);outline-offset:2px}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-dialog{width:min(1120px,calc(100vw - 40px));max-width:none;
 max-height:min(900px,calc(100dvh - 48px));margin:auto;padding:24px 28px 22px;overflow:auto;
 border:1px solid var(--line);border-radius:16px;background:var(--elevado);color:var(--ink);box-shadow:var(--sombra-alta)}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-dialog::backdrop{background:var(--veu)}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-cab{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:14px}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-cab h2{margin:0;color:var(--ink);font-size:18px;font-weight:600;letter-spacing:-.02em}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-conteudo .graf-fluxo svg{height:clamp(360px,58vh,650px)}
:is(#relatorio,#resultado).rel-dashboard .ind-graf-conteudo .graf-x{font-size:12px}
@media(max-width:640px){
 :is(#relatorio,#resultado).rel-dashboard .ind-graf-dialog{width:calc(100vw - 20px);max-height:calc(100dvh - 24px);padding:16px 12px 14px;border-radius:13px}
 :is(#relatorio,#resultado).rel-dashboard .ind-graf-conteudo .graf-fluxo svg{height:clamp(300px,48vh,480px)}
 :is(#relatorio,#resultado).rel-dashboard .ind-graf-cab h2{font-size:16px}
}

/* PARA ONDE FOI O DINHEIRO EM ROSCA (08/10/2026): o total pago no meio e as
   fatias em tons do vermelho do "Pago" — a maior, a mais escura; a mistura é
   com o painel, então no escuro os tons descem para o grafite do mesmo jeito.
   "Outros" fica neutro. A lista ao lado é a de barras sem o trilho (nome ·
   valor · parte); passar o mouse numa linha acende a fatia dela. */
:is(#relatorio,#resultado).rel-dashboard .po-c1{--po:var(--crit)}
:is(#relatorio,#resultado).rel-dashboard .po-c2{--po:color-mix(in srgb,var(--crit) 74%,var(--panel))}
:is(#relatorio,#resultado).rel-dashboard .po-c3{--po:color-mix(in srgb,var(--crit) 52%,var(--panel))}
:is(#relatorio,#resultado).rel-dashboard .po-c4{--po:color-mix(in srgb,var(--crit) 34%,var(--panel))}
:is(#relatorio,#resultado).rel-dashboard .po-c5{--po:color-mix(in srgb,var(--crit) 20%,var(--panel))}
:is(#relatorio,#resultado).rel-dashboard .po-c0{--po:color-mix(in srgb,var(--muted) 30%,var(--panel))}
:is(#relatorio,#resultado).rel-dashboard .po-rosca{display:grid;grid-template-columns:148px minmax(0,1fr);align-items:center;gap:20px}
:is(#relatorio,#resultado).rel-dashboard .po-rosca-g{position:relative;width:148px;height:148px}
:is(#relatorio,#resultado).rel-dashboard .po-rosca-svg{display:block;width:100%;height:100%}
:is(#relatorio,#resultado).rel-dashboard .po-seg{fill:none;stroke:var(--po);stroke-width:13;transition:opacity var(--dur-rapida) var(--curva-saida)}
:is(#relatorio,#resultado).rel-dashboard .po-seg.apagado{opacity:.28}
:is(#relatorio,#resultado).rel-dashboard .po-centro{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
 justify-content:center;gap:1px;text-align:center;pointer-events:none}
:is(#relatorio,#resultado).rel-dashboard .po-centro b{font-family:var(--titulo);font-size:17px;font-weight:600;line-height:1.15;
 color:var(--crit);font-variant-numeric:tabular-nums}
:is(#relatorio,#resultado).rel-dashboard .po-centro span{font-size:12px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .po-dot{display:inline-block;flex:none;width:10px;height:10px;border-radius:50%;background:var(--po)}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-trilho,
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-cab>span:nth-child(2){display:none}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb,
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-cab{grid-template-columns:minmax(0,1fr) auto 40px}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-v{font-weight:600}
/* nome comprido ("Licença / aprovação / órgão") quebra a linha em vez de virar reticências:
   ao lado da rosca a coluna é estreita, e o nome é a informação */
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-nome{align-items:flex-start}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-nome .po-dot{margin-top:4px}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-nome .t{white-space:normal;overflow:visible;text-overflow:clip;line-height:1.3}
/* no celular a lista de barras ganha a linha do trilho embaixo; aqui não há trilho */
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb{grid-template-areas:none;row-gap:0}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb>*{grid-area:auto}
:is(#relatorio,#resultado).rel-dashboard .po-rosca:has(.rb-lista>li:nth-child(1):hover) .po-seg:not(.po-i1),
:is(#relatorio,#resultado).rel-dashboard .po-rosca:has(.rb-lista>li:nth-child(2):hover) .po-seg:not(.po-i2),
:is(#relatorio,#resultado).rel-dashboard .po-rosca:has(.rb-lista>li:nth-child(3):hover) .po-seg:not(.po-i3),
:is(#relatorio,#resultado).rel-dashboard .po-rosca:has(.rb-lista>li:nth-child(4):hover) .po-seg:not(.po-i4),
:is(#relatorio,#resultado).rel-dashboard .po-rosca:has(.rb-lista>li:nth-child(5):hover) .po-seg:not(.po-i5),
:is(#relatorio,#resultado).rel-dashboard .po-rosca:has(.rb-lista>li:nth-child(6):hover) .po-seg:not(.po-i6),
:is(#relatorio,#resultado).rel-dashboard .po-rosca:has(.rb-lista>li:nth-child(7):hover) .po-seg:not(.po-i7){opacity:.28}
/* estreito (o celular e a coluna apertada): a rosca em cima, a lista inteira embaixo */
@media (max-width:480px){
 :is(#relatorio,#resultado).rel-dashboard .po-rosca{grid-template-columns:minmax(0,1fr);justify-items:center;gap:14px}
 :is(#relatorio,#resultado).rel-dashboard .po-lista{width:100%}
}

/* A LINHA DO TEMPO DO PORQUÊ (08/10/2026): uma linha por obra, uma bolinha
   por ocorrência no dia dela — a cor é a da causa (--c, a mesma variável do
   gráfico da ficha), a área é o impacto estimado (--d). O cartão abre no
   :hover e no :focus-within (o toque foca o botão): só CSS. A grade tracejada
   e a régua embaixo marcam os mesmos baldes do gráfico do Caixa. */
:is(#relatorio,#resultado).rel-dashboard .oc-tempo{--oc-rot:150px;--oc-alt:66px;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .oc-corpo{position:relative}
:is(#relatorio,#resultado).rel-dashboard .oc-grade{position:absolute;top:0;bottom:0;left:calc(var(--oc-rot) + 16px);right:16px;pointer-events:none}
:is(#relatorio,#resultado).rel-dashboard .oc-grade i{position:absolute;top:0;bottom:0;border-left:1px dashed var(--line)}
:is(#relatorio,#resultado).rel-dashboard .oc-linha{display:grid;grid-template-columns:var(--oc-rot) minmax(0,1fr);align-items:center;
 min-height:var(--oc-alt);border-bottom:1px solid var(--line)}
:is(#relatorio,#resultado).rel-dashboard .oc-linha:first-child{border-top:1px solid var(--line)}
:is(#relatorio,#resultado).rel-dashboard .oc-obra{min-width:0;padding-right:10px;overflow:hidden;font-size:13px;font-weight:500;
 text-overflow:ellipsis;white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .oc-linha.sel .oc-obra{color:var(--brand-2)}
:is(#relatorio,#resultado).rel-dashboard .oc-trilho{position:relative;height:var(--oc-alt);margin:0 16px;padding:0;list-style:none}
:is(#relatorio,#resultado).rel-dashboard .oc-trilho::before{content:"";position:absolute;left:0;right:0;top:50%;border-top:1px solid var(--line)}
:is(#relatorio,#resultado).rel-dashboard .oc-p{position:absolute;top:50%;z-index:1;transform:translate(-50%,-50%)}
:is(#relatorio,#resultado).rel-dashboard .oc-p:hover,:is(#relatorio,#resultado).rel-dashboard .oc-p:focus-within{z-index:30}
:is(#relatorio,#resultado).rel-dashboard .oc-bola{display:block;width:var(--d);height:var(--d);padding:0;border:2px solid var(--panel);
 border-radius:50%;background:var(--c);opacity:.9;cursor:pointer;
 transition:transform var(--dur-rapida) var(--curva-saida),opacity var(--dur-rapida)}
:is(#relatorio,#resultado).rel-dashboard .oc-bola.sem{background:var(--panel);border-color:var(--c)}
:is(#relatorio,#resultado).rel-dashboard .oc-bola:hover,:is(#relatorio,#resultado).rel-dashboard .oc-bola:focus-visible{opacity:1;transform:scale(1.1)}
:is(#relatorio,#resultado).rel-dashboard .oc-bola:focus-visible{outline:2px solid var(--anel);outline-offset:2px}
:is(#relatorio,#resultado).rel-dashboard .oc-cartao{display:none;position:absolute;top:calc(100% + 8px);left:50%;width:270px;padding:10px 12px;
 transform:translateX(-50%);background:var(--elevado);border:1px solid var(--line);border-radius:8px;box-shadow:var(--sombra-alta);
 font-size:12.5px;line-height:1.45;color:var(--ink);text-align:left}
:is(#relatorio,#resultado).rel-dashboard .oc-p.esq .oc-cartao{left:0;transform:none}
:is(#relatorio,#resultado).rel-dashboard .oc-p.dir .oc-cartao{left:auto;right:0;transform:none}
:is(#relatorio,#resultado).rel-dashboard .oc-p:hover .oc-cartao,:is(#relatorio,#resultado).rel-dashboard .oc-p:focus-within .oc-cartao{display:block}
:is(#relatorio,#resultado).rel-dashboard .oc-c1{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
:is(#relatorio,#resultado).rel-dashboard .oc-c1 span{color:var(--crit);font-weight:600;white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .oc-c2{display:flex;align-items:center;gap:6px;margin-top:3px;font-weight:500}
:is(#relatorio,#resultado).rel-dashboard .oc-cartao p{margin:6px 0 0;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .oc-eixo{position:relative;height:24px;margin:0 16px 0 calc(var(--oc-rot) + 16px)}
:is(#relatorio,#resultado).rel-dashboard .oc-eixo span{position:absolute;top:6px;transform:translateX(-50%);font-size:11px;color:var(--faint);
 white-space:nowrap;font-variant-numeric:tabular-nums}
:is(#relatorio,#resultado).rel-dashboard .oc-legenda{display:flex;flex-wrap:wrap;align-items:center;gap:6px 14px;margin-top:10px;font-size:12px;
 color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .oc-legenda>span{display:inline-flex;align-items:center;gap:6px}
:is(#relatorio,#resultado).rel-dashboard .oc-medida{color:var(--faint)}
@media (max-width:640px){
 :is(#relatorio,#resultado).rel-dashboard .oc-tempo{--oc-rot:92px;--oc-alt:58px}
 :is(#relatorio,#resultado).rel-dashboard .oc-obra{font-size:12px;white-space:normal;line-height:1.3}
 :is(#relatorio,#resultado).rel-dashboard .oc-eixo span:nth-child(even){display:none}
 :is(#relatorio,#resultado).rel-dashboard .oc-cartao{width:220px;max-width:calc(100vw - 40px)}
 :is(#relatorio,#resultado).rel-dashboard .oc-p.m-esq .oc-cartao{left:0;right:auto;transform:none}
 :is(#relatorio,#resultado).rel-dashboard .oc-p.m-dir .oc-cartao{left:auto;right:0;transform:none}
}

/* A CARTEIRA EM LISTA E O POPUP DA OBRA (08/10/2026; antes, a "carteira
   minimal" da v0.61.2). A lista da referência do Samuel: o quadradinho com as
   iniciais na cor da situação, o nome com a cidade embaixo, a situação, o
   prazo e o estouro provável — sem caixa em volta de cada linha, separadas por
   um fio. A linha inteira abre o popup da obra (um <dialog>): os números do
   motor, a barra de bala e as três abas, que são botões de rádio + CSS. */
:is(#relatorio,#resultado).rel-dashboard .rel-carteira{table-layout:fixed;min-width:640px;border-collapse:collapse}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira thead th{padding:9px 12px 10px;border-bottom:1px solid var(--line);color:var(--muted);
 font-size:12.5px;font-weight:500;letter-spacing:0;text-transform:none;white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira tbody td{padding:13px 12px;border-bottom:1px solid var(--line);vertical-align:middle}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira tbody tr{cursor:pointer;transition:background-color var(--dur-rapida),opacity var(--dur-rapida)}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira tbody tr:hover>*{background:var(--nav-on)}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira tbody tr.sel>*{background:var(--brand-suave)}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira tbody td>.td-sub,:is(#relatorio,#resultado).rel-dashboard .rel-carteira .cart-v{display:block}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira tfoot td{padding:12px;border-top:1px solid var(--line);font-size:12.5px}
:is(#relatorio,#resultado).rel-dashboard .rel-carteira tfoot td.principal{color:var(--ink)}
:is(#relatorio,#resultado).rel-dashboard .cart-obra{display:flex;align-items:center;gap:12px;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .cart-tile{display:grid;place-items:center;flex:none;width:38px;height:38px;border-radius:9px;
 font:600 12px/1 var(--titulo);letter-spacing:.02em}
:is(#relatorio,#resultado).rel-dashboard .cart-tile.st-crit{background:var(--crit-suave);color:var(--crit-texto)}
:is(#relatorio,#resultado).rel-dashboard .cart-tile.st-warn{background:var(--warn-suave);color:var(--warn-texto)}
:is(#relatorio,#resultado).rel-dashboard .cart-tile.st-ok{background:var(--ok-suave);color:var(--ok-texto)}
:is(#relatorio,#resultado).rel-dashboard .cart-tile.st-novo{background:var(--nav-on);color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .cart-id{display:flex;flex-direction:column;gap:2px;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .cart-nome{overflow:hidden;color:var(--ink);font-weight:600;text-decoration:none;text-overflow:ellipsis;white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .cart-nome:hover{color:var(--brand-2);text-decoration:underline}
:is(#relatorio,#resultado).rel-dashboard .cart-id .td-sub{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .cart-v{font-weight:600;font-variant-numeric:tabular-nums}
:is(#relatorio,#resultado).rel-dashboard .cart-st.st-crit{color:var(--crit-texto)}
:is(#relatorio,#resultado).rel-dashboard .cart-st.st-warn{color:var(--warn-texto)}
:is(#relatorio,#resultado).rel-dashboard .cart-st.st-ok{color:var(--ok-texto)}
:is(#relatorio,#resultado).rel-dashboard .cart-st.st-novo{color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .cart-busca{width:200px;max-width:100%}
@media(max-width:700px){
 :is(#relatorio,#resultado).rel-dashboard .rel-carteira tbody td{padding:12px 8px}
 :is(#relatorio,#resultado).rel-dashboard .cart-busca{width:100%}
}
/* o popup da obra */
:is(#relatorio,#resultado).rel-dashboard .cart-dialogo{width:min(900px,calc(100vw - 32px));max-width:none;max-height:min(920px,calc(100dvh - 40px));
 margin:auto;padding:0;overflow:auto;border:1px solid var(--line);border-radius:16px;background:var(--elevado);color:var(--ink);
 box-shadow:var(--sombra-alta);text-align:left;cursor:auto}
:is(#relatorio,#resultado).rel-dashboard .cart-dialogo::backdrop{background:var(--veu)}
/* ao abrir, o foco vai para o próprio popup (para o Esc e o Tab começarem nele): sem o anel em volta dele todo */
:is(#relatorio,#resultado).rel-dashboard .cart-dialogo:focus{outline:none}
:is(#relatorio,#resultado).rel-dashboard .cart-d-corpo{padding:20px 22px 18px}
:is(#relatorio,#resultado).rel-dashboard .cart-d-cab{display:flex;align-items:flex-start;gap:12px}
:is(#relatorio,#resultado).rel-dashboard .cart-d-cab .cart-tile{width:44px;height:44px;font-size:13px}
:is(#relatorio,#resultado).rel-dashboard .cart-d-tit{flex:1;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .cart-d-tit h2{margin:0;font-family:var(--titulo);font-size:18px;font-weight:600;letter-spacing:-.01em}
:is(#relatorio,#resultado).rel-dashboard .cart-d-tit p{margin:3px 0 0;font-size:12.5px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .cart-fechar{display:grid;place-items:center;flex:none;width:34px;height:34px;padding:0;border:1px solid var(--line);
 border-radius:8px;background:var(--ground);color:var(--muted);cursor:pointer;
 transition:color var(--dur-rapida),background-color var(--dur-rapida),border-color var(--dur-rapida)}
:is(#relatorio,#resultado).rel-dashboard .cart-fechar:hover{color:var(--ink);border-color:var(--brand-borda)}
:is(#relatorio,#resultado).rel-dashboard .cart-fechar:focus-visible{outline:2px solid var(--anel);outline-offset:2px}
:is(#relatorio,#resultado).rel-dashboard .cart-kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin:16px 0 10px}
:is(#relatorio,#resultado).rel-dashboard .cart-kpis>div,:is(#relatorio,#resultado).rel-dashboard .cart-din>div{display:flex;flex-direction:column;gap:2px;min-width:0;
 padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:var(--panel)}
:is(#relatorio,#resultado).rel-dashboard .cart-kpis span,:is(#relatorio,#resultado).rel-dashboard .cart-din span{font-size:12px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .cart-kpis b,:is(#relatorio,#resultado).rel-dashboard .cart-din b{font-family:var(--titulo);font-size:19px;font-weight:600;
 line-height:1.2;font-variant-numeric:tabular-nums}
:is(#relatorio,#resultado).rel-dashboard .cart-kpis small,:is(#relatorio,#resultado).rel-dashboard .cart-din small{font-size:12px;color:var(--faint);line-height:1.35}
:is(#relatorio,#resultado).rel-dashboard .cart-kpis .rel-spark-gap{width:64px;height:20px;margin:2px 0}
/* o físico e o custo: o número maior, no meio do que sobra da caixa (pedido do Samuel) */
:is(#relatorio,#resultado).rel-dashboard .cart-kpis>.cart-k-grande>b{margin:auto;font-size:30px;line-height:1.1}
:is(#relatorio,#resultado).rel-dashboard .cart-indic{display:inline-block;margin-left:4px;color:var(--warn-texto)}
:is(#relatorio,#resultado).rel-dashboard .cart-abas{display:flex;gap:4px;padding-bottom:10px;border-bottom:1px solid var(--line)}
:is(#relatorio,#resultado).rel-dashboard .cart-aba-r{position:absolute;opacity:0;pointer-events:none}
:is(#relatorio,#resultado).rel-dashboard .cart-aba{padding:6px 12px;border-radius:7px;font-size:13px;color:var(--muted);cursor:pointer;
 transition:background-color var(--dur-rapida),color var(--dur-rapida)}
:is(#relatorio,#resultado).rel-dashboard .cart-aba:hover{background:var(--nav-on);color:var(--ink)}
:is(#relatorio,#resultado).rel-dashboard .cart-aba-r:checked+.cart-aba{background:var(--brand-suave);color:var(--brand-2);font-weight:500}
:is(#relatorio,#resultado).rel-dashboard .cart-aba-r:focus-visible+.cart-aba{outline:2px solid var(--anel);outline-offset:1px}
/* A TROCA DE ABA SUAVE (pedido do Samuel: "muito brusca"): os três painéis moram na MESMA célula
   da grade — a caixa fica com a altura do maior e não pula — e o escolhido aparece com fade e um
   deslize curto, pelos tokens de movimento (quem pediu menos movimento vê a troca direta) */
:is(#relatorio,#resultado).rel-dashboard .cart-paineis{display:grid}
:is(#relatorio,#resultado).rel-dashboard .cart-painel{grid-area:1/1;min-width:0;padding-top:14px;visibility:hidden;opacity:0;
 transform:translateY(6px);pointer-events:none;
 transition:opacity var(--dur-media) var(--curva-saida),transform var(--dur-media) var(--curva-saida),visibility var(--dur-media)}
:is(#relatorio,#resultado).rel-dashboard .cart-d-corpo:has(.cart-aba-r[id$="-ev"]:checked) .cart-p-ev,
:is(#relatorio,#resultado).rel-dashboard .cart-d-corpo:has(.cart-aba-r[id$="-oc"]:checked) .cart-p-oc,
:is(#relatorio,#resultado).rel-dashboard .cart-d-corpo:has(.cart-aba-r[id$="-din"]:checked) .cart-p-din{visibility:visible;opacity:1;
 transform:none;pointer-events:auto}
:is(#relatorio,#resultado).rel-dashboard .cart-leg .cart-l-fis{background:var(--brand)}
:is(#relatorio,#resultado).rel-dashboard .cart-leg .cart-l-cus{background:var(--cost)}
:is(#relatorio,#resultado).rel-dashboard .cart-ocs{list-style:none;margin:0;padding:0}
:is(#relatorio,#resultado).rel-dashboard .cart-ocs li{padding:10px 0;border-bottom:1px solid var(--line)}
:is(#relatorio,#resultado).rel-dashboard .cart-ocs li:last-child{border-bottom:0}
:is(#relatorio,#resultado).rel-dashboard .cart-oc1{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
:is(#relatorio,#resultado).rel-dashboard .cart-oc1 b{font-weight:600}
:is(#relatorio,#resultado).rel-dashboard .cart-oc-imp{color:var(--crit);font-weight:600;white-space:nowrap;font-variant-numeric:tabular-nums}
:is(#relatorio,#resultado).rel-dashboard .cart-nada{margin:6px 0 0;font-size:13px}
:is(#relatorio,#resultado).rel-dashboard .cart-din{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
:is(#relatorio,#resultado).rel-dashboard .cart-sinal{margin:10px 0 0;font-size:12.5px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .cart-d-pe{display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px;margin-top:18px}
@media(max-width:640px){
 :is(#relatorio,#resultado).rel-dashboard .cart-dialogo{width:calc(100vw - 16px);max-height:calc(100dvh - 20px);border-radius:13px}
 :is(#relatorio,#resultado).rel-dashboard .cart-d-corpo{padding:16px 14px 14px}
 :is(#relatorio,#resultado).rel-dashboard .cart-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
 :is(#relatorio,#resultado).rel-dashboard .cart-din{grid-template-columns:minmax(0,1fr)}
 :is(#relatorio,#resultado).rel-dashboard .cart-abas{overflow-x:auto}
 :is(#relatorio,#resultado).rel-dashboard .cart-aba{white-space:nowrap}
}

/* COMERCIAL E EQUIPE EM TRÊS CAIXINHAS (08/10/2026, a "versão enxuta" que o Samuel escolheu): as
   propostas numa rosca por situação com os números ao lado, a agenda em blocos de data e a equipe
   pelo quadro de tarefas. Cada caixinha com fio e canto, dentro da caixa da seção. */
:is(#relatorio,#resultado).rel-dashboard #f-comercial .rel-lado.tres{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr) minmax(0,1fr);gap:14px}
:is(#relatorio,#resultado).rel-dashboard #f-comercial .rel-lado.tres>*,
:is(#relatorio,#resultado).rel-dashboard #f-comercial .rel-lado.tres>*+*{margin:0;padding:14px 16px;border:1px solid var(--line);border-radius:12px;
 background:var(--panel)}
:is(#relatorio,#resultado).rel-dashboard .com-prop{display:flex;align-items:center;gap:18px}
:is(#relatorio,#resultado).rel-dashboard #f-comercial .po-rosca-g{width:124px;height:124px;flex:none}
:is(#relatorio,#resultado).rel-dashboard #f-comercial .po-centro b{color:var(--ink);font-size:15px}
:is(#relatorio,#resultado).rel-dashboard .po-seg.po-clica{cursor:pointer}
:is(#relatorio,#resultado).rel-dashboard .com-nums{display:grid;gap:8px;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .com-nums span{display:block;font-size:12px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .com-nums b{display:block;font-family:var(--titulo);font-size:20px;font-weight:600;line-height:1.15;
 font-variant-numeric:tabular-nums}
:is(#relatorio,#resultado).rel-dashboard .com-nums .com-neg{color:var(--warn-texto)}
:is(#relatorio,#resultado).rel-dashboard .com-nums p{margin:0;font-size:12px;color:var(--muted);line-height:1.4}
:is(#relatorio,#resultado).rel-dashboard .com-legenda{display:flex;flex-direction:column;gap:1px;margin-top:12px}
:is(#relatorio,#resultado).rel-dashboard .com-st{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;color:var(--ink);
 font-size:12.5px;text-decoration:none;transition:background-color var(--dur-rapida)}
:is(#relatorio,#resultado).rel-dashboard .com-st:hover{background:var(--nav-on);color:var(--ink)}
:is(#relatorio,#resultado).rel-dashboard .com-st:focus-visible{outline:2px solid var(--anel);outline-offset:1px}
:is(#relatorio,#resultado).rel-dashboard .com-st span{flex:1;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .com-st b{font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
:is(#relatorio,#resultado).rel-dashboard .com-agenda{display:grid;gap:10px;margin:0;padding:0;list-style:none}
:is(#relatorio,#resultado).rel-dashboard .com-agenda li{display:flex;align-items:center;gap:10px;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .com-data{display:flex;flex-direction:column;align-items:center;justify-content:center;flex:none;
 width:44px;height:46px;border:1px solid var(--line);border-radius:9px;background:var(--ground)}
:is(#relatorio,#resultado).rel-dashboard .com-data b{font-family:var(--titulo);font-size:17px;font-weight:600;line-height:1}
:is(#relatorio,#resultado).rel-dashboard .com-data span{font-size:11px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .com-ag{display:flex;flex-direction:column;min-width:0}
:is(#relatorio,#resultado).rel-dashboard .com-ag b{font-size:13px;font-weight:600}
:is(#relatorio,#resultado).rel-dashboard .com-equipe>b{display:block;font-family:var(--titulo);font-size:26px;font-weight:600;line-height:1.1}
:is(#relatorio,#resultado).rel-dashboard .com-equipe>span{font-size:12px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .com-barra{height:8px;margin:10px 0 8px;overflow:hidden;border-radius:4px;background:var(--nav-on)}
:is(#relatorio,#resultado).rel-dashboard .com-barra i{display:block;height:100%;border-radius:4px;background:var(--ok)}
:is(#relatorio,#resultado).rel-dashboard .com-equipe p{margin:0;font-size:12px;color:var(--muted)}
:is(#relatorio,#resultado).rel-dashboard .com-tile{flex:none;width:44px;height:44px;border-radius:9px;
 background:color-mix(in srgb,var(--po) 22%,var(--panel));box-shadow:inset 0 0 0 1px var(--po)}
:is(#relatorio,#resultado).rel-dashboard .com-v{font-weight:600;white-space:nowrap;font-variant-numeric:tabular-nums}
@media(max-width:991px){
 :is(#relatorio,#resultado).rel-dashboard #f-comercial .rel-lado.tres{grid-template-columns:minmax(0,1fr)}
}
@media(max-width:480px){
 :is(#relatorio,#resultado).rel-dashboard .com-prop{flex-direction:column;align-items:flex-start}
}

/* ===========================================================================
   O FUNDO EM VÍDEO (08/10/2026) — pedido do Samuel: "um fundo animado, simples, no
   fundo do modo claro e do escuro de todo o sistema". Um laço curto gerado no
   Higgsfield (o Genjutsu reestilizou um vídeo de movimento feito aqui: faixas de
   luz passando por um prisma, a ideia da marca), num arquivo de cada tema, e a
   imagem parada de cada tema — a que fica com as animações desligadas, sem
   JavaScript ou na impressão (que nem leva o fundo).
   Só nas telas do sistema (a de entrada tem o fundo dela, o ícone da Lumiset).
   A camada é FIXA, atrás de toda a página, sem toque; os cartões e painéis são
   opacos, então o fundo só aparece nas margens — nunca atrás de um número. A
   FORÇA é um token por tema (--fundo-forca): é ele que se ajusta, não o vídeo.
   Cor só por token (a checagem de cor literal lê este bloco até o "fim:").
   =========================================================================== */
:root{--fundo-forca:1;--fundo-imagem:url("/static/fundo/claro.jpg")}
:root[data-tema="escuro"]{--fundo-forca:.75;--fundo-imagem:url("/static/fundo/escuro.jpg")}
.fundo-video{position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:var(--fundo-forca);
 background:var(--fundo-imagem) center/cover no-repeat var(--ground)}
.fundo-video video{display:block;width:100%;height:100%;object-fit:cover;opacity:0;
 transition:opacity var(--dur-lenta) var(--curva-saida)}
.fundo-video video.tocando{opacity:1}
@media print{.fundo-video{display:none}}
/* fim: O FUNDO EM VÍDEO (a checagem de cor literal lê este bloco) */

/* ===========================================================================
   O FEEDBACK DOS INDICADORES (09/10/2026): os cartões do Caixa com o fundo na
   cor do dinheiro, as faixas cinzas na lista de "para onde foi", os vermelhos
   da rosca mais distintos entre si, o índice (descrição + recolher) e o ícone
   do terceiro tema no botão. Cor só por token (a checagem lê até o "fim:").
   =========================================================================== */
/* o botão de tema mostra o PRÓXIMO: claro → lua; escuro → o azul; azul → sol */
#btn-tema .azul{display:none}
[data-tema="escuro"]:not([data-tom="azul"]) #btn-tema .sol{display:none}
[data-tema="escuro"]:not([data-tom="azul"]) #btn-tema .azul{display:flex}
/* os cartões do Caixa: o fundo e o rodapé na cor do sentido (entra verde, sai vermelho; o zero fica neutro) */
:root{--kpi-tinta:12%;--kpi-tinta-pe:18%}
:root[data-tema="escuro"]{--kpi-tinta:30%;--kpi-tinta-pe:38%}
:is(#relatorio,#resultado).rel-dashboard #f-caixa .rel-kpi:has(>.val.v-crit){background:color-mix(in srgb,var(--crit) var(--kpi-tinta),var(--panel));
 border-color:color-mix(in srgb,var(--crit) 45%,var(--line))}
:is(#relatorio,#resultado).rel-dashboard #f-caixa .rel-kpi:has(>.val.v-ok){background:color-mix(in srgb,var(--ok) var(--kpi-tinta),var(--panel));
 border-color:color-mix(in srgb,var(--ok) 45%,var(--line))}
:is(#relatorio,#resultado).rel-dashboard #f-caixa .rel-kpi:has(>.val.v-crit)>.rel-kpi-pe{
 background:color-mix(in srgb,var(--crit) var(--kpi-tinta-pe),var(--panel));border-top-color:color-mix(in srgb,var(--crit) 35%,var(--line))}
:is(#relatorio,#resultado).rel-dashboard #f-caixa .rel-kpi:has(>.val.v-ok)>.rel-kpi-pe{
 background:color-mix(in srgb,var(--ok) var(--kpi-tinta-pe),var(--panel));border-top-color:color-mix(in srgb,var(--ok) 35%,var(--line))}
/* para onde foi o dinheiro: faixas cinzas alternadas, ideia de tabela */
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-lista>li>.rb{padding:6px 8px;border-radius:6px}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-lista>li:nth-child(odd)>.rb{background:var(--panel-2)}
:is(#relatorio,#resultado).rel-dashboard .po-lista .rb-cab{padding:0 8px}
/* os vermelhos da rosca mais distintos: a cor muda de TOM (vermelho, laranja, rosado,
   vinho, âmbar), não só de força — continuam na família quente de "saiu dinheiro";
   os tons moram nos tokens de cada tema (--rosca-N), porque um mesmo "misturado com
   o painel" clareia no claro e escurece no escuro */
:is(#relatorio,#resultado).rel-dashboard .po-c2{--po:var(--rosca-2)}
:is(#relatorio,#resultado).rel-dashboard .po-c3{--po:var(--rosca-3)}
:is(#relatorio,#resultado).rel-dashboard .po-c4{--po:var(--rosca-4)}
:is(#relatorio,#resultado).rel-dashboard .po-c5{--po:var(--rosca-5)}
/* o ÍNDICE: a descrição sob o título e a setinha no canto; recolhida, a seção fica só com o cabeçalho */
:is(#relatorio,#resultado).rel-dashboard>.rel-faixa{position:relative}
:is(#relatorio,#resultado).rel-dashboard>.rel-faixa[data-dobra]>.rel-margem{padding-right:44px}
:is(#relatorio,#resultado).rel-dashboard .rel-desc{grid-column:1/-1;grid-row:3;margin:2px 0 0;font-size:13px;line-height:1.45;color:var(--muted);max-width:80ch}
:is(#relatorio,#resultado).rel-dashboard .rel-dobrar{position:absolute;top:16px;right:16px;display:grid;place-items:center;width:32px;height:32px;
 padding:0;border:1px solid var(--line);border-radius:8px;background:var(--panel);color:var(--muted);cursor:pointer;
 transition:color var(--dur-rapida),border-color var(--dur-rapida)}
:is(#relatorio,#resultado).rel-dashboard .rel-dobrar:hover{color:var(--ink);border-color:var(--brand-borda)}
:is(#relatorio,#resultado).rel-dashboard .rel-dobrar:focus-visible{outline:2px solid var(--anel);outline-offset:2px}
:is(#relatorio,#resultado).rel-dashboard .rel-dobrar svg{transform:rotate(180deg);transition:transform var(--dur-media) var(--curva-saida)}
:is(#relatorio,#resultado).rel-dashboard .rel-faixa[data-dobra="fechada"] .rel-dobrar svg{transform:none}
:is(#relatorio,#resultado).rel-dashboard .rel-faixa[data-dobra="fechada"]>.rel-corpo{display:none}
:is(#relatorio,#resultado).rel-dashboard .rel-faixa[data-dobra="aberta"]>.rel-corpo{animation:surgir var(--dur-media) var(--curva-saida)}
@media(max-width:640px){
 :is(#relatorio,#resultado).rel-dashboard .rel-dobrar{top:12px;right:12px}
 :is(#relatorio,#resultado).rel-dashboard .rel-faixa[data-dobra] .rel-acoes{grid-row:4}
}
/* fim: O FEEDBACK DOS INDICADORES (a checagem de cor literal lê este bloco) */

/* ===========================================================================
   O RESULTADO COM A CARA DOS INDICADORES e AS AÇÕES PARA ECONOMIZAR (09/10/2026)
   O Samuel: "a tela de Resultado tem que ser parecida com a de Indicadores" — o
   desenho de painel vale para os dois (o `:is(#relatorio,#resultado)` acima) e
   aqui fica só o que é do Resultado: os cartões pintados, o Economizou em
   cartões e a lista "Para economizar mais". Cor só por token.
   =========================================================================== */
/* os cartões pintados pelo sentido, como os do Caixa (o zero e o neutro sem tinta) */
#resultado.rel-dashboard .rel-kpi:has(>.val.v-crit){background:color-mix(in srgb,var(--crit) var(--kpi-tinta),var(--panel));
 border-color:color-mix(in srgb,var(--crit) 45%,var(--line))}
#resultado.rel-dashboard .rel-kpi:has(>.val.v-ok){background:color-mix(in srgb,var(--ok) var(--kpi-tinta),var(--panel));
 border-color:color-mix(in srgb,var(--ok) 45%,var(--line))}
#resultado.rel-dashboard .rel-kpi:has(>.val.v-crit)>.rel-kpi-pe{
 background:color-mix(in srgb,var(--crit) var(--kpi-tinta-pe),var(--panel));border-top-color:color-mix(in srgb,var(--crit) 35%,var(--line))}
#resultado.rel-dashboard .rel-kpi:has(>.val.v-ok)>.rel-kpi-pe{
 background:color-mix(in srgb,var(--ok) var(--kpi-tinta-pe),var(--panel));border-top-color:color-mix(in srgb,var(--ok) 35%,var(--line))}
/* o "Por quê" mora no rodapé do cartão, ao lado da linha de apoio */
#resultado.rel-dashboard .rel-kpi-pe{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:2px 12px}
#resultado.rel-dashboard .rel-kpi-pe .como-abre{margin-top:0;flex:none}
/* a faixa do resultado (as duas pontas) cabe no cartão */
#resultado.rel-dashboard .res-kpi-faixa .val{font-size:22px;line-height:1.25;white-space:normal}
#resultado.rel-dashboard .res-manchete{font-size:16px}
#resultado.rel-dashboard .res-conta-chip{margin-top:-6px}
/* o Economizou: três cartões em cima do gráfico */
#resultado.rel-dashboard .econ-kpis{margin-bottom:18px}

/* ---- PARA ECONOMIZAR MAIS: a lista que a equipe risca */
.econ-acoes{display:flex;flex-direction:column;gap:12px;margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}
.econ-a-cab{display:flex;justify-content:space-between;align-items:flex-start;gap:16px}
.econ-a-h{margin:0;font-size:15px;font-weight:600;color:var(--ink)}
.econ-a-sub{margin:2px 0 0;font-size:13px;line-height:1.45;color:var(--muted)}
.econ-a-nova{display:inline-flex;align-items:center;gap:6px;flex:none}
.econ-a-resumo{display:flex;flex-direction:column;gap:7px}
.econ-a-resumo p{margin:0;font-size:13.5px;line-height:1.5;color:var(--muted)}
.econ-a-resumo b{font-weight:600;color:var(--ink)}
.econ-a-resumo b.oport{color:var(--ok-texto)}
.econ-a-aviso{font-size:12.5px;color:var(--faint)}
.econ-a-prog{height:6px;max-width:420px;overflow:hidden;border-radius:99px;background:var(--panel-2)}
.econ-a-prog i{display:block;height:100%;border-radius:inherit;background:var(--ok)}
.econ-a-vazio{margin:0;padding:12px 14px;border:1px dashed var(--line);border-radius:10px;font-size:13px;
 line-height:1.5;color:var(--muted)}
.econ-a-lista{margin:0;padding:0;list-style:none;overflow:hidden;border:1px solid var(--line);border-radius:10px}
.econ-a{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:start;gap:4px 14px;
 padding:12px 14px;border-top:1px solid var(--line);background:var(--panel)}
.econ-a:first-child{border-top:0}
.econ-a:nth-child(even){background:color-mix(in srgb,var(--panel-2) 60%,var(--panel))}
.econ-a-marcar{margin:0}
.econ-caixa{display:grid;place-items:center;width:22px;height:22px;margin-top:1px;padding:0;cursor:pointer;
 border:1.5px solid var(--muted);border-radius:6px;background:var(--panel);color:transparent;
 transition:border-color var(--dur-rapida) var(--curva-saida),color var(--dur-rapida) var(--curva-saida)}
.econ-caixa:hover{border-color:var(--ok);color:color-mix(in srgb,var(--ok) 45%,transparent)}
.econ-caixa:focus-visible{outline:2px solid var(--anel);outline-offset:2px}
.econ-caixa[aria-pressed="true"]{border-color:var(--ok-solido);background:var(--ok-solido);color:var(--sobre-solido)}
.econ-caixa:disabled{cursor:progress;opacity:.6}
.econ-a-txt{min-width:0}
.econ-a-tit{margin:0;font-size:14px;font-weight:600;line-height:1.4;color:var(--ink)}
.econ-a.feita .econ-a-tit{color:var(--muted);text-decoration:line-through;text-decoration-thickness:1.5px}
.econ-a.feita .econ-a-fato,.econ-a.feita .econ-a-val{opacity:.6}
.econ-a-fato{display:-webkit-box;margin:2px 0 0;overflow:hidden;font-size:12.5px;line-height:1.45;color:var(--muted);
 -webkit-line-clamp:2;-webkit-box-orient:vertical}
.econ-a-meta{margin:5px 0 0;font-size:12px;line-height:1.5;color:var(--faint)}
.econ-a-nat{display:inline-block;padding:0 8px;border-radius:99px;font-size:11.5px;font-weight:600;line-height:18px;
 background:var(--panel-2);color:var(--muted)}
.econ-a-nat.n-preco{background:color-mix(in srgb,var(--ok) 14%,var(--panel));color:var(--ok-texto)}
.econ-a-nat.n-gasto{background:color-mix(in srgb,var(--crit) 12%,var(--panel));color:var(--crit-texto)}
.econ-a-nat.n-prazo{background:color-mix(in srgb,var(--warn) 16%,var(--panel));color:var(--warn-texto)}
.econ-a-nat.n-processo,.econ-a-nat.n-sua{background:var(--brand-suave);color:var(--brand-2)}
.econ-a-sumiu{color:var(--warn-texto)}
.econ-a-val{min-width:110px;font-size:12px;line-height:1.3;text-align:right;white-space:nowrap;color:var(--muted)}
.econ-a-rot{display:block}
.econ-a-num{display:block;font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ink)}
.econ-a-num.oport{color:var(--ok-texto)}
.econ-a-semv{color:var(--faint)}
.econ-a-editar{display:grid;place-items:center;width:30px;height:30px;border:1px solid transparent;border-radius:8px;
 color:var(--muted);transition:border-color var(--dur-rapida) var(--curva-saida),color var(--dur-rapida) var(--curva-saida)}
.econ-a-editar:hover{border-color:var(--line);color:var(--ink)}
.econ-a-editar:focus-visible{outline:2px solid var(--anel);outline-offset:2px}
.econ-a-grupo{margin:6px 0 0;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.econ-a-mais>summary,.econ-a-desc>summary{width:fit-content;margin:4px 0;font-size:13px;cursor:pointer}
.econ-a-mais>.econ-a-lista{margin-top:6px}
.econ-a-desc>.econ-a-lista{margin-top:6px}
.econ-a-avisos{margin:0}
/* o popup de editar e o de criar (o título é o do formulário, não o rótulo pequeno dos popups de número) */
.econ-d .res-d-tit h2{font-size:17px;font-weight:600;color:var(--ink)}
.econ-d-fato{margin:0 0 14px;padding:10px 12px;border-radius:8px;background:var(--panel-2);font-size:13px;line-height:1.5;
 color:var(--muted)}
.econ-d-fato p{margin:0}
.econ-d-k{margin:0 0 2px!important;font-size:11.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
 color:var(--faint)}
.econ-d-fato .econ-d-hoje{margin-top:6px;color:var(--ink)}
.econ-form{display:flex;flex-direction:column;gap:10px}
.econ-campo{display:flex;flex-direction:column;gap:4px;margin:0;font-size:12.5px;font-weight:600;color:var(--muted)}
.econ-campos-l{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
.econ-form-pe{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}
@media(max-width:640px){
 .econ-a-cab{flex-direction:column}
 .econ-a{grid-template-columns:auto minmax(0,1fr) auto}
 .econ-a-val{grid-column:2;grid-row:2;min-width:0;text-align:left}
 .econ-a-rot,.econ-a-num{display:inline}
 .econ-a-rot::after{content:" "}
 .econ-a-editar{grid-column:3;grid-row:1}
 .econ-campos-l{grid-template-columns:minmax(0,1fr)}
}
@media print{.econ-a-marcar,.econ-a-editar,.econ-a-nova{display:none}}
/* fim: O RESULTADO COM A CARA DOS INDICADORES */

/* ============================================================================
   OBRAS EM BLOCOS (11/10/2026, pedido do Miguel: "a página Obras com a
   organização do Radar de Risco"; na 5ª rodada, "o mais próximo possível da
   print" — o painel de obras do Radar —, "mais bonito e original", e "não caga
   no tema escuro com esse header azul feio")
   (1) o cabeçalho: o de sempre, com mais ar embaixo e o "Nova obra" no tamanho
       normal (o mais importante da página);
   (2) a abertura: o olho "Carteira de obras" na cor da marca, o nome da empresa
       e a linha das obras; embaixo, a FAIXA DE NÚMEROS — a superfície neutra de
       sempre (--panel), SEM linhas (6ª rodada: "tira essas linhas e deixa sem"),
       quatro números com o rótulo em versalete em cima e a linha de apoio
       embaixo. Nada de fundo azul: no escuro ela é o cinza dos painéis, como os
       blocos. "A economizar" em verde, "Em risco" em vermelho;
   (3) os blocos: a superfície de sempre (--panel, fio --line, canto de 14 px);
       o nome em destaque com a situação à direita (a palavra do Radar numa
       pílula com o tom da situação), as DUAS barras do painel de referência —
       avanço físico na tinta, custo consumido na marca (o número também) —, a
       leitura do motor em linhas curtas, um fio, e os três fatos lado a lado. O
       bloco INTEIRO abre a ficha (o link do nome se estica por cima dele); o
       "abrir a ficha" fica à vista. Com o mouse em cima, o bloco SALTA como os da
       tela Plano (6ª rodada: "faz elas popar quando passa o mouse igual os cards
       do planos") — sobe, cresce um tico na curva de mola e ganha a sombra de
       flutuar; no teclado, com o foco à vista dentro dele;
   (4) duas colunas a partir de 900 px; uma abaixo disso. A faixa vira 2 × 2
       abaixo de 900 px.
   Só tokens: vale no claro, no escuro e no azul noturno.
   ========================================================================= */
.ob-head .pg-acoes .btn{display:inline-flex;align-items:center;gap:6px;font-weight:500}
/* (2) a abertura e a faixa de números */
.ob-abertura{display:flex;flex-direction:column;gap:16px;min-width:0}
.ob-painel{margin:0}
.ob-olho{margin:0;font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--brand-2)}
.ob-painel-t{margin:6px 0 0;font-family:var(--titulo);font-size:22px;font-weight:600;letter-spacing:-.01em;
  line-height:1.2;color:var(--ink)}
.ob-painel-s{margin:4px 0 0;font-size:13px;color:var(--muted)}
.ob-resumo{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));margin:0;padding:18px 0;
  background:var(--panel);border-radius:14px}
.ob-kpi{min-width:0;padding:0 22px;text-align:center}
.ob-kpi dt{font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.ob-kpi dd{margin:6px 0 0;display:flex;flex-direction:column;align-items:center;gap:3px}
.ob-kpi-v{font-family:var(--titulo);font-size:22px;font-weight:600;line-height:1.15;letter-spacing:-.01em;
  color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.ob-kpi-risco .ob-kpi-v{color:var(--crit)}
.ob-kpi-eco .ob-kpi-v{color:var(--ok-texto)}
.ob-kpi-a{font-size:12px;line-height:1.4;color:var(--muted)}
.ob-sec{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 10px;margin:0 0 12px;font-size:12.5px;font-weight:400;line-height:1.4}
.ob-sec .t{font-family:var(--titulo);font-size:15px;font-weight:600;color:var(--ink)}
.ob-sec .n{color:var(--muted)}
/* (3) os blocos */
.ob-grade{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
.ob-item{position:relative;display:flex;flex-direction:column;min-width:0;padding:18px 20px 16px;
  background:var(--panel);border:1px solid var(--line);border-radius:14px;
  transition:transform var(--dur-media) var(--curva-mola),box-shadow var(--dur-media),border-color var(--dur-rapida)}
.ob-item:hover{border-color:var(--brand-borda)}
.ob-item:focus-within{border-color:var(--brand)}
/* o SALTO dos blocos da tela Plano: só em quem tem mouse; no teclado, com o foco à vista dentro do bloco */
@media (hover:hover){
 .ob-item:hover{transform:translateY(-6px) scale(1.012);box-shadow:var(--sombra-alta)}
}
.ob-item:has(:focus-visible){transform:translateY(-6px) scale(1.012);box-shadow:var(--sombra-alta)}
.ob-topo{display:flex;align-items:flex-start;gap:12px;min-width:0}
.ob-topo .av{flex:none}
.ob-id{flex:1 1 auto;min-width:0}
.ob-nome{margin:0;font-family:var(--titulo);font-size:16.5px;font-weight:600;line-height:1.3;letter-spacing:-.005em}
.ob-nome a{color:var(--ink);text-decoration:none}
.ob-nome a::after{content:"";position:absolute;inset:0;border-radius:14px}   /* o bloco inteiro abre a ficha */
.ob-nome a:focus-visible{outline:none}
.ob-item:hover .ob-nome a{color:var(--brand-2)}
.ob-sub{margin:2px 0 0;font-size:12.5px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* a situação numa pílula com o tom dela (o ponto do .estado continua dentro) */
.ob-topo .estado{flex:none;padding:3px 10px;border-radius:999px;background:var(--panel-2);font-size:12px}
.ob-topo .estado.b-crit{background:var(--crit-suave)}
.ob-topo .estado.b-warn{background:var(--warn-suave)}
.ob-topo .estado.b-ok{background:var(--ok-suave)}
/* as duas barras: avanço físico na tinta, custo consumido na marca */
.ob-barras{display:flex;flex-direction:column;gap:12px;margin-top:16px}
.ob-barra-l{display:flex;align-items:baseline;justify-content:space-between;gap:10px;font-size:12.5px;color:var(--muted)}
.ob-barra-l b{font-size:14px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.ob-custo .ob-barra-l b{color:var(--brand-2)}
.ob-trilho{position:relative;height:6px;margin-top:7px;border-radius:999px;background:var(--panel-2);overflow:hidden}
.ob-trilho i{position:absolute;inset:0 auto 0 0;border-radius:999px;background:var(--ink);
  transform-origin:left;animation:encher var(--dur-lenta) var(--curva-saida) 160ms backwards}
.ob-custo .ob-trilho i{background:var(--brand)}
.ob-item.entregue .ob-trilho i{background:var(--ok)}
.ob-sem{margin:0;font-size:12px;color:var(--faint)}
/* a leitura do motor, em linhas curtas (o número em negrito) */
.ob-leitura{margin:14px 0 0;padding:0;list-style:none;font-size:12.5px;line-height:1.55;color:var(--muted)}
.ob-leitura b{font-weight:600;color:var(--ink)}
.ob-fatos{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:14px 0 0;padding-top:14px;
  border-top:1px solid var(--line)}
.ob-fatos div{min-width:0}
.ob-fatos dt{font-size:11.5px;font-weight:400;color:var(--faint)}
.ob-fatos dd{margin:2px 0 0;font-size:14px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;
  white-space:nowrap}
.ob-abrir{position:relative;z-index:1;align-self:flex-end;display:inline-flex;align-items:center;gap:5px;
  margin-top:12px;font-size:12.5px;font-weight:500;color:var(--brand-2);text-decoration:none}
.ob-abrir:hover{text-decoration:underline}
.ob-abrir svg{transform:rotate(-90deg)}     /* o chev do sistema aponta para baixo; aqui é "vai" */
/* (4) tablet e celular */
@media (max-width:899.98px){
 .ob-grade{grid-template-columns:minmax(0,1fr)}
 .ob-resumo{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:18px}
}
@media (max-width:479.98px){
 .ob-resumo{padding:14px 0;row-gap:14px}
 .ob-kpi{padding:0 10px}
 .ob-kpi-v{font-size:19px}
 .ob-kpi-a{font-size:11.5px}
 .ob-painel-t{font-size:20px}
 .ob-item{padding:16px 16px 14px}
 .ob-sub{white-space:normal}      /* no celular o código, a cidade e o tipo quebram em vez de sumir no … */
 .ob-fatos{gap:8px}
}
/* fim: OBRAS EM BLOCOS (a checagem de cor literal lê este bloco) */

/* ============================================================================
   IMPORTAR PLANILHA — AS DUAS PORTAS (11/10/2026, pedidos do Miguel: "as duas
   páginas mais bonitas — tá meio embolado —, sem ficar usando muito card"; na
   2ª rodada, a área do arquivo como a de um site de enviar arquivos, o cadeado
   interativo ao lado do "Confira a prévia" e menos texto para ler).
   Obras › Importar planilha e Financeiro › Importar planilha, o mesmo desenho
   (as peças em piloto/importar_extrato.py, `form_envio`, `guia` e `dica`):
   (1) a abertura: o título da porta e UMA linha do que ela faz;
   (2) os TRÊS PASSOS num card só (a única superfície da página), TRACEJADO na
       cor da marca, com o fundo no tom suave dela, e CENTRADO (5ª rodada: "o
       card tá muito desigual — só o card pontilhado: no topo escolher a obra,
       no meio importar a planilha e embaixo a outra informação"): 1 a obra; 2 o
       botão grande "Escolher planilha" (que sobe com o mouse em cima; é desenho:
       quem recebe o clique é o <input> invisível que cobre o meio); 3 o "Ler a
       planilha", discreto até haver arquivo, com o cadeado do "nada é gravado
       agora" ao lado do título (o balão dos "i"). Um fio separa os passos;
       solto em qualquer ponto do card, o arquivo entra (o JavaScript);
   (3) o GUIA em três colunas, ícone + título + uma linha curta, separadas por
       um fio — nenhuma caixa por item; o detalhe no "i";
   (4) os outros formatos numa linha miúda, depois de um fio.
   Abaixo de 992 px o guia empilha. Só tokens.
   ========================================================================= */
.ie{display:flex;flex-direction:column;gap:22px;min-width:0}
/* (1) */
.ie-cab{max-width:80ch}
.ie-t{display:flex;align-items:center;margin:0;font-family:var(--titulo);font-size:20px;font-weight:600;
  letter-spacing:-.01em;line-height:1.3;color:var(--ink)}
.ie-t .ajuda{margin-left:8px}
.ie-t .ajuda-i{width:16px;height:16px}
.ie-s{margin:6px 0 0;font-size:14px;line-height:1.55;color:var(--muted)}
/* (2) os três passos: o card tracejado, centrado, um passo embaixo do outro */
/* (6ª rodada: "o card pontilhado tá gigante, e esse azul de fundo dá horrível — diminui esse card, deixa mais
   bonito e harmônico") no máximo 560 px, no meio da página; o tracejado na cor da marca, mais suave. (7ª
   rodada: "deixa esse card TRANSPARENTE, totalmente transparente") sem fundo nenhum: o card é só o tracejado
   sobre o fundo da página; ao arrastar um arquivo por cima, só o tracejado acende */
.ie-form{display:flex;flex-direction:column;align-items:center;width:100%;max-width:560px;margin-inline:auto;
  padding:24px 28px 26px;border:2px dashed color-mix(in srgb,var(--brand) 35%,transparent);border-radius:16px;
  background-color:transparent;text-align:center;transition:border-color var(--dur-rapida)}
.ie-form.sobre{border-color:var(--brand)}
.ie-form.pronto{border-style:solid}
.ie-passo{display:flex;flex-direction:column;align-items:center;gap:10px;width:100%;max-width:400px;min-width:0}
.ie-passo+.ie-passo{margin-top:18px;padding-top:18px;border-top:1px solid var(--line)}
.ie-rotulo{display:flex;align-items:center;justify-content:center;gap:9px;margin:0;font-size:13px;font-weight:600;
  color:var(--ink)}
.ie-n{display:inline-grid;place-items:center;flex:none;width:22px;height:22px;border-radius:50%;
  background:var(--brand-suave);font-size:12px;font-weight:700;color:var(--brand-2);font-variant-numeric:tabular-nums}
.ie-passo .form-select{width:100%;text-align:left}
/* o meio: o <input> de verdade cobre o botão e as linhas dele (clicar ou soltar ali) */
.ie-zona{position:relative;display:flex;flex-direction:column;align-items:center;gap:8px;width:100%;
  padding:4px 0;border-radius:12px}
.ie-escolher{display:inline-flex;align-items:center;gap:10px;margin-bottom:4px;padding:14px 28px;border-radius:10px;
  background:var(--brand-solido);color:var(--sobre-solido);font-family:var(--titulo);font-size:17px;font-weight:600;
  letter-spacing:-.005em;box-shadow:0 8px 22px color-mix(in srgb,var(--brand-solido) 32%,transparent);
  transition:transform var(--dur-media) var(--curva-mola),filter var(--dur-rapida),box-shadow var(--dur-media)}
.ie-escolher .ie-ico{width:22px;height:22px}
.ie-zona:hover .ie-escolher,.ie-form.sobre .ie-escolher{transform:translateY(-2px);filter:brightness(1.08);
  box-shadow:0 12px 28px color-mix(in srgb,var(--brand-solido) 40%,transparent)}
.ie-zona:active .ie-escolher{transform:translateY(0) scale(.98)}
.ie-zona-t{font-size:14px;color:var(--ink)}
.ie-zona-f{font-size:12px;color:var(--muted)}
.ie-zona-nome{font-size:13px;font-weight:600;color:var(--brand-2);overflow-wrap:anywhere}
.ie-zona-nome:empty{display:none}
.ie-zona input[type="file"]{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
.ie-zona:focus-within{outline:2px solid var(--anel);outline-offset:4px}
/* o passo 3: o cadeado é o balão dos "i"; o botão fica discreto até haver arquivo (só com o JavaScript vivo —
   sem ele, nasce cheio) */
.ie-rotulo .ajuda{margin-left:0}
.ie-dica-cadeado .ajuda-i{width:15px;height:15px;color:var(--muted)}
.ie-ler{width:100%;min-height:44px;font-weight:600}
.ie-vivo:not(.pronto) .ie-ler{--bs-btn-color:var(--brand-2);--bs-btn-border-color:var(--brand);--bs-btn-bg:transparent;
  --bs-btn-hover-bg:var(--brand-suave);--bs-btn-hover-color:var(--brand-2);--bs-btn-hover-border-color:var(--brand)}
/* (3) o guia em colunas */
.ie-guia-t{margin:0 0 12px;font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.ie-guia-grade{display:grid;grid-template-columns:repeat(3,minmax(0,1fr))}
.ie-item{display:flex;align-items:flex-start;gap:12px;min-width:0;padding:2px 24px}
.ie-item:first-child{padding-left:0}
.ie-item+.ie-item{border-left:1px solid var(--line)}
.ie-item>.ie-ico{flex:none;width:22px;height:22px;margin-top:1px;color:var(--brand)}
.ie-item h4{display:flex;align-items:center;margin:0;font-size:14px;font-weight:600;color:var(--ink)}
.ie-item p{margin:3px 0 0;font-size:13px;line-height:1.5;color:var(--muted)}
.ie-item p b{color:var(--ink);font-weight:600}
.ie-vira{color:var(--ink)}
.ie-vira::before{content:"→ ";color:var(--brand)}
/* (4) os outros formatos */
.ie-outros{display:flex;flex-wrap:wrap;align-items:center;gap:6px 26px;margin:0;padding-top:14px;
  border-top:1px solid var(--line);font-size:12.5px;line-height:1.6;color:var(--muted)}
.ie-outros>span{display:inline-flex;align-items:center;flex-wrap:wrap;gap:0 4px}
.ie-outros b{color:var(--ink);font-weight:600}
/* no celular não se arrasta arquivo: fica o botão */
@media (pointer:coarse){.ie-zona-t{display:none}}
@media (max-width:991.98px){
 .ie-form{padding:20px 16px 22px}
 .ie-guia-grade{grid-template-columns:minmax(0,1fr);gap:16px}
 .ie-item{padding:0}
 .ie-item+.ie-item{border-left:0;border-top:1px solid var(--line);padding-top:16px}
}
/* fim: IMPORTAR PLANILHA — AS DUAS PORTAS (a checagem de cor literal lê este bloco) */

/* ============================================================================
   O AVANÇO POR ETAPA NO LANÇAMENTO MENSAL (11/10/2026): recolhido embaixo do
   avanço da obra — um campo por etapa, em duas colunas, o nome em cima.
   ========================================================================= */
.lanc-etapas{margin:2px 0 4px;border:1px solid var(--line);border-radius:10px;padding:8px 10px;background:var(--ground)}
.lanc-etapas summary{cursor:pointer;font-size:13px;font-weight:600;color:var(--ink)}
.lanc-et-opc{margin-left:6px;font-size:11.5px;font-weight:400;color:var(--muted)}
.lanc-et-grade{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 10px;margin-top:10px}
.lanc-et{display:flex;flex-direction:column;gap:3px;min-width:0;margin:0;font-size:12px;color:var(--muted)}
.lanc-et span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lanc-et .form-control{padding:4px 8px;font-size:13px}
/* fim: O AVANÇO POR ETAPA NO LANÇAMENTO (a checagem de cor literal lê este bloco) */

/* ============================================================================
   O RELATÓRIO DO MÊS (13/10/2026; app.py::tela_relatorio_mes). A consultoria:
   "um relatório mensal automático, no nome dele, [...] é um documento que ele
   encaminha". A MESMA superfície com faixas da página de relatório de 23/09
   (.rel, .rel-faixa, .rel-margem, .rel-corpo — nada de cartão por bloco, "sem
   cara de IA"); aqui só o que é dele: o cabeçalho do documento (o mês, quem
   preparou), os três números do risco, as ações riscadas, o pé honesto e o
   resumo para colar. A régua do vermelho vale: .perda/.v-crit o que se perdeu
   ou vai perder com alerta; .oport/.v-ok o que ainda dá para economizar.
   NA IMPRESSÃO a folha é o relatório e nada mais (barra, abas, rodapé, botões,
   seletor, os "i" e o resumo saem), em A4 (a página nomeada `rmes`, com margem
   de 10 mm: a área útil fica acima de 700 px e as tabelas não viram os cartões
   do celular), sem a entrada em cascata (ela começa transparente e a folha
   sairia em branco) e CLARA: o JavaScript da página põe o tema claro no
   `beforeprint` e devolve o da pessoa no `afterprint`; aqui se garante o papel
   branco e a cor das bolinhas das situações.
   Cor só por token: a checagem de cor literal lê este bloco até o "fim:".
   ============================================================================ */
.rmes-cab{padding:22px 20px 18px}
.rmes-olho{margin:0;font-size:11.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.rmes-titulo{margin:4px 0 0;font-family:var(--titulo);font-size:22px;font-weight:600;letter-spacing:-.01em;
 line-height:1.25;color:var(--ink)}
.rmes-quem{margin:6px 0 0;font-size:14px;color:var(--ink)}
.rmes-quem b{font-weight:600}
.rmes-quando{margin:3px 0 0;font-size:12.5px;color:var(--muted);font-variant-numeric:tabular-nums}
.rmes-barra .form-select{width:auto;min-width:11.5rem}
.rmes-nota{flex:1 1 240px}
.rmes-tab{margin:0}
.rmes-obra{color:var(--ink);font-weight:600;text-decoration:none}
.rmes-obra:hover{color:var(--brand-2);text-decoration:underline}
.rmes-lancada{color:var(--ink)}
.rmes-lancar{display:inline-block;margin-top:3px;font-size:12.5px;color:var(--brand-2)}
.rmes-mud{color:var(--ink)}
.rmes-mud.perda{color:var(--crit-texto)}
.rmes-entregue{margin:14px 0 0}
/* os três números do risco: o desenho dos números grandes do Caixa (.rel-kpi, fio entre eles) */
.rmes-nums{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));row-gap:16px;overflow:hidden;margin-left:-16px}
.rmes-apoio{margin-top:4px;font-size:12px;color:var(--muted);line-height:1.45}
.rmes-nums .delta{font-size:12px;color:var(--muted)}
/* as ações riscadas: título e quem/quando à esquerda, o valor estimado à direita */
.rmes-acoes{list-style:none;margin:0;padding:0}
.rmes-acoes li{display:flex;justify-content:space-between;align-items:baseline;gap:6px 18px;padding:10px 0;
 border-top:1px solid var(--line)}
.rmes-acoes li:first-child{border-top:0;padding-top:0}
.rmes-acao-t{margin:0;font-size:13.5px;font-weight:600;color:var(--ink)}
.rmes-acao-m{margin:2px 0 0;font-size:12px;color:var(--muted)}
.rmes-acao-v{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.rmes-rot{display:block;font-size:11px;color:var(--muted)}
.rmes-pe{padding:16px 20px 20px;border-top:1px solid var(--line)}
.rmes-pe p{margin:0;max-width:92ch;font-size:12.5px;line-height:1.55;color:var(--muted)}
.rmes-texto{max-width:820px;font-family:var(--sans);font-size:13px;line-height:1.55;resize:vertical}
@media (max-width:700px){
 .rmes-cab{padding:18px 14px 14px}
 .rmes-titulo{font-size:19px}
 .rmes-nums{grid-template-columns:minmax(0,1fr)}
 .rmes-pe{padding:14px}
 .rmes-acoes li{flex-direction:column;align-items:flex-start}
 .rmes-acao-v{text-align:left}
}
@page rmes{size:A4;margin:10mm 10mm 12mm}
@media print{
 :root:has(#relatorio-mes),body:has(#relatorio-mes){background:var(--papel)}
 body:has(#relatorio-mes)>:not(main),body:has(#relatorio-mes) main>:not(#relatorio-mes){display:none!important}
 body:has(#relatorio-mes) .content-col{max-width:none;margin:0;padding:0}
 #relatorio-mes{page:rmes;border:0;border-radius:0;background:var(--papel);
  -webkit-print-color-adjust:exact;print-color-adjust:exact}
 #relatorio-mes,#relatorio-mes *{animation-name:none!important}
 #relatorio-mes :is(.rmes-so-tela,.rmes-barra,.ajuda){display:none!important}
 #relatorio-mes .rel-faixa{padding:14px 0 16px;break-inside:avoid-page}
 #relatorio-mes :is(.rmes-cab,.rmes-pe){padding-left:0;padding-right:0}
 #relatorio-mes tr{break-inside:avoid}
 #relatorio-mes .table :is(td,th){padding-top:6px;padding-bottom:6px}
 #relatorio-mes a{color:inherit;text-decoration:none}
}
/* O LEMBRETE DA MEDIÇÃO (13/10/2026; app.py::_lembrete_medicao): uma faixa
   discreta no alto do Radar e de Obras — ajuda, não bronca: nada de vermelho nem
   de atenção (é o mês de lançar, não um erro), o calendário na cor da marca e o
   link de lançar de cada obra. Some quando a medição entra (é conta, não estado). */
.lembrete-med{display:flex;align-items:flex-start;gap:10px;padding:10px 14px;border:1px solid var(--line);
 border-radius:8px;background:var(--panel);color:var(--ink);font-size:13px;line-height:1.5}
.lembrete-med>svg{flex:none;margin-top:2px;color:var(--brand)}
.lm-txt{min-width:0}
.lm-t{margin:0}
.lm-sub{color:var(--muted)}
.lm-lista{list-style:none;margin:4px 0 0;padding:0;display:flex;flex-direction:column;gap:2px}
.lm-lista li{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px}
.lm-obra{color:var(--ink);font-weight:600;text-decoration:none}
.lm-obra:hover{text-decoration:underline}
.lm-ult{font-size:12.5px;color:var(--muted)}
.lm-lancar{font-size:12.5px;font-weight:500;color:var(--brand-2)}
@media print{.lembrete-med{display:none}}
/* fim: O RELATÓRIO DO MÊS E O LEMBRETE DA MEDIÇÃO (a checagem de cor literal lê este bloco) */
/* ===========================================================================
   A BASE DE PREÇOS (13/10/2026; app.py, bloco A BASE DE PREÇOS DO CLIENTE)
   Cadastros › Base de preços: as fontes na ordem do cliente, a comparação com a
   obra e a busca no SINAPI, na MESMA página de relatório dos Indicadores (uma
   superfície, faixas com a margem — sem cara de IA) e com o envio do "Importar
   planilha". Cor só por token. A régua do vermelho: acima da referência é o que
   o cliente paga a mais (vermelho); abaixo, verde; em linha, neutro.
   =========================================================================== */
/* a vista que é só um aviso (sem obra, sem SINAPI) ocupa a faixa inteira */
.pc .rel-faixa.pc-so{display:block}
/* a posição da fonte, antes do nome */
.pc-pos{display:inline-block;min-width:26px;margin-right:6px;font-weight:600;color:var(--muted);
 font-variant-numeric:tabular-nums}
.pc-regra b{font-weight:600}
/* as setas da ordem: dois botões quadrados; na ponta, um espaço do mesmo tamanho */
.pc-setas{display:inline-flex;align-items:center;gap:4px}
.pc-seta-f{display:inline;margin:0}
.pc-seta{display:inline-grid;place-items:center;width:30px;height:30px;padding:0}
.pc-seta-nada{display:inline-block;width:30px;height:30px}
.pc-uf{margin-top:14px}
.pc-uf .nota{margin-left:0}
/* o par da referência: "provável" com contorno; "parecido — conferir" tracejado, na cor de atenção */
.pc-par{display:inline-block;margin-left:4px;padding:0 6px;border:1px solid var(--line);border-radius:4px;
 font-size:11px;line-height:1.6;color:var(--muted);white-space:nowrap}
.pc-par.conferir{border-style:dashed;border-color:var(--warn);color:var(--warn-texto)}
/* a comparação: colunas fixas no computador — a frase da ponderação quebra dentro da coluna dela */
@media (min-width:701px){
 .pc-comp{table-layout:fixed}
 .pc-comp .c-ins{width:21%}
 .pc-comp .c-seu{width:10%}
 .pc-comp .c-ref{width:23%}
 .pc-comp .c-dif{width:16%}
 .pc-comp .c-pond{width:30%}
 .pc-comp thead th{white-space:normal}
}
.pc-comp td,.pc-sinapi td{vertical-align:top}
.pc-comp .v{font-variant-numeric:tabular-nums;white-space:nowrap}
.pc-comp .td-sub{overflow-wrap:anywhere}
.pc-pond{display:block;font-size:12.5px;line-height:1.5;color:var(--muted)}
.pc-comp .v.perda,.pc-comp .td-sub .perda,.rel-nums .n.perda{color:var(--crit-texto)}
.pc-comp .v.oport,.pc-comp .td-sub .oport,.rel-nums .n.oport{color:var(--ok-texto)}
.pc-sem{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px;font-size:13px}
.pc-sem .td-sub{display:inline;margin-left:6px}
/* a barra de escolha (obra, estado, busca): o select no tamanho do texto, ao lado do rótulo
   (o form-select do Bootstrap tem 100% de largura e jogava o rótulo para a linha de cima) */
.pc-barra .form-select{width:auto;max-width:100%;padding-right:34px}   /* a seta do select fica fora do texto */
/* a busca do SINAPI: o campo largo; a nota da base com a medida de leitura */
.pc-q .form-control{width:260px;max-width:100%}
.pc-nota-sinapi{max-width:90ch;margin-top:0}
/* a lista: a busca, a linha em edição, o "acrescentar" e as páginas */
.pc-busca-q{width:280px;max-width:100%}
.pc-acoes{white-space:nowrap}
.pc-editando td{vertical-align:middle}
.pc-editando .form-control{min-width:70px}
.pc-desc-cel .form-control{min-width:200px}
.pc-novo{display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px 12px;width:100%;margin:0}
.pc-novo-t{flex-basis:100%;font-size:12.5px;font-weight:600;color:var(--ink)}
.pc-novo .filtro{flex-direction:column;align-items:flex-start;gap:2px}
.pc-novo-desc{flex:1 1 240px}
.pc-novo-desc .form-control{width:100%}
.pc-un{width:90px}
.pc-preco{width:120px}
.pc-paginas{display:flex;flex-wrap:wrap;align-items:center;gap:6px 16px;padding:10px 14px;font-size:12.5px;
 color:var(--muted)}
.pc-adm{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 16px;margin-top:18px}
/* o envio de uma lista: a que vai ser substituída, acima da área tracejada */
.pc-alvo{margin:0 0 14px;font-size:13px;color:var(--muted);text-align:center}
.pc-alvo b{color:var(--ink)}
/* a prévia: o que entra, as recusadas e para onde vai */
.pc-dica{margin:6px 0 0;font-size:12px;line-height:1.5;color:var(--faint)}
.pc-amostra{margin:12px 14px 0;border-top:1px solid var(--line)}
.pc-destino{min-width:0;margin:16px 14px 0;padding:12px 14px;border:1px solid var(--line);border-radius:8px}
.pc-destino legend{float:none;width:auto;margin:0 0 6px;padding:0 4px;font-size:13px;font-weight:600;color:var(--ink)}
.pc-op{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;margin-top:6px}
.pc-op label{margin:0;font-size:13px;color:var(--ink)}
.pc-op .form-control,.pc-op .form-select{flex:1 1 220px;width:auto;max-width:420px}
.pc-gravar{margin-top:14px;justify-content:flex-start}
/* no dedo, os botões de tabela crescem (bloco TOQUE): o espaço da ponta acompanha */
@media (pointer:coarse){
 .pc-seta-nada{width:44px;height:40px}
}
@media (max-width:700px){
 .pc-ordem td.pc-acao:empty{display:none}
 /* os botões da linha (editar · excluir, salvar · cancelar) juntos, à direita: sem rótulo, o flex do
    cartão os espalharia pelas pontas */
 .pc-itens td.pc-acoes{justify-content:flex-end;gap:8px}
 .pc-itens td.pc-acoes::before{display:none}
 .pc-comp td.pc-pond-cel{display:block;text-align:left}
 .pc-comp td.pc-pond-cel::before{display:block;margin-bottom:2px}
 .pc-comp td>.cel,.pc-sinapi td>.cel{margin-left:auto;min-width:0;text-align:right}
 .pc-q{flex:1 1 100%}
 .pc-q .form-control{width:100%}
 .pc-editando .form-control,.pc-desc-cel .form-control{min-width:0;max-width:62%}
 .pc-novo .filtro{flex:1 1 100%}
 .pc-un,.pc-preco{width:100%}
}
/* fim: A BASE DE PREÇOS (a checagem de cor literal lê este bloco) */

/* (13/10/2026) O RELÓGIO DA BASE SINAPI (Base de preços › SINAPI): quando a base entrou no
   Prisma e quanto falta para a próxima publicação da Caixa. Uma faixa interna da página de
   relatório, duas colunas que viram uma no celular; o contador em algarismos tabulares. */
.pc-relogio{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 28px;margin:0 0 16px;
  padding:12px 16px;border:1px solid var(--line);border-radius:10px;background:var(--panel)}
.pc-rel-item{display:flex;flex-direction:column;gap:3px;min-width:0}
.pc-rel-rot{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--muted-txt)}
.pc-rel-mes{font-size:1.02rem;color:var(--ink)}
.pc-rel-sub{font-size:12px;line-height:1.45;color:var(--muted-txt)}
.pc-rel-conta{font-variant-numeric:tabular-nums;font-weight:600;font-size:13px;color:var(--muted-txt)}
.pc-rel-conta [data-c]{font-size:1.3rem;font-weight:700;color:var(--ink)}
.pc-rel-pend{font-weight:700;font-size:13px;color:var(--warn-texto)}
@media (max-width:640px){.pc-relogio{grid-template-columns:minmax(0,1fr)}}
/* fim: O RELÓGIO DA BASE SINAPI */

/* ============================================================================
   ORÇAMENTOS E RELATÓRIOS › ANALÍTICO (18/10/2026; app.py::orcamentos_criar,
   tela_orcamentos, _orc_funil, tela_analitico e _an_numeros). O pedido do
   Miguel: as duas telas "mais bonitas, modernas, clean e profissionais"; na 2ª
   rodada, "o card do Relatórios tá ridículo", "Orçamentos tá muito simples" e
   a parte das informações "meio simples" — mais chamativa, sem encher de card.
   A resposta: NENHUMA caixa; a estrutura vem de alinhamento, de números grandes
   na cor do que eles são, de barras de proporção e de etiquetas leves. Só tokens
   (o claro, o escuro e o azul noturno pelos mesmos nomes) e prefixos próprios
   (orc-, an-): .tabela-box, .estado, .kb-mover e .fin-tots, que outras telas
   usam, não mudam.
   ========================================================================= */

/* ---- ORÇAMENTOS: os dois botões de criar, no cabeçalho ------------------- */
.orc-criar{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.orc-criar .btn{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}

/* ---- o FUNIL: cinco números soltos na página (o total e cada situação), o
        rótulo na cor da situação, e a barra do valor por baixo. Cada número é
        um botão que filtra a lista; o escolhido ganha um fundo leve da cor ---- */
.orc-funil{display:flex;flex-direction:column;gap:12px}
.orc-f-itens{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:4px}
.orc-f{--cor:var(--muted);display:flex;flex-direction:column;align-items:flex-start;gap:3px;min-width:0;
 padding:10px 14px 11px;border:0;border-radius:12px;background:transparent;color:var(--ink);text-align:left;
 cursor:pointer;transition:background-color var(--dur-rapida) var(--curva-saida)}
.orc-f.orc-f-todos{--cor:var(--brand-2)}
.orc-f.b-warn{--cor:var(--warn)}
.orc-f.b-ok{--cor:var(--ok)}
.orc-f.b-crit{--cor:var(--crit)}
.orc-f.b-novo{--cor:var(--muted)}
.orc-f:hover{background:var(--nav-on)}
/* o escolhido: um tom bem leve da cor e o número na cor — sem virar cartão */
.orc-f[aria-pressed="true"]{background:color-mix(in srgb,var(--cor) 8%,transparent)}
.orc-f[aria-pressed="true"] .orc-f-v{color:var(--cor)}
.orc-f.orc-f-todos[aria-pressed="true"] .orc-f-v{color:var(--ink)}
.orc-f:focus-visible{outline:2px solid var(--anel);outline-offset:1px}
.orc-f:disabled{cursor:default;opacity:.5;background:transparent}
.orc-f-l{display:inline-flex;align-items:center;gap:7px;font-size:11px;font-weight:600;letter-spacing:.07em;
 text-transform:uppercase;color:var(--cor)}
.orc-f-l::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--cor);flex:none}
.orc-f-v{font-size:24px;font-weight:700;letter-spacing:-.02em;line-height:1.15;font-variant-numeric:tabular-nums;
 color:var(--ink);white-space:nowrap}
.orc-f-n{font-size:12px;color:var(--faint)}
.orc-f-barra{display:flex;gap:3px;height:8px;margin:0 14px}
.orc-f-barra i{display:block;flex:0 1 auto;min-width:6px;border-radius:999px;background:currentColor}
/* o "enviado" é o cinza neutro: na barra, mais baixo, para não brilhar mais que as cores */
.orc-f-barra i.b-novo{background:color-mix(in srgb,currentColor 45%,transparent)}

/* ---- a lista: as iniciais do cliente, a descrição com a anotação embaixo, a
        data com "há quanto tempo", o valor em destaque -------------------- */
.orc-lista{margin-top:6px}
.orc-tabela td.principal{min-width:16rem;white-space:normal;line-height:1.35}
.orc-item{display:flex;align-items:center;gap:12px;min-width:0}
.orc-av{flex:none;display:grid;place-items:center;width:36px;height:36px;border-radius:10px;
 background:var(--brand-suave);color:var(--brand-2);font-size:12px;font-weight:700;letter-spacing:.03em}
.orc-txt{display:flex;flex-direction:column;gap:3px;min-width:0}
.orc-desc{color:var(--ink);font-weight:600;font-size:13.5px;text-decoration:none}
.orc-desc:hover{color:var(--brand-2);text-decoration:underline;text-underline-offset:3px}
.orc-nota{max-width:34rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:var(--faint)}
.orc-tabela td.orc-data{color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.orc-idade{display:block;margin-top:2px;font-size:11.5px;color:var(--faint)}
.orc-tabela td.orc-cli{color:var(--muted)}
.orc-tabela td.orc-valor{color:var(--ink);font-weight:700;font-size:15px;font-variant-numeric:tabular-nums;
 white-space:nowrap;letter-spacing:-.01em}
.orc-tabela .orc-uf{width:1%;text-align:center}
.orc-tabela td.orc-uf{color:var(--faint);font-size:12px;letter-spacing:.04em}
.orc-tabela .orc-acoes{width:1%;text-align:right;white-space:nowrap}
/* o filtro do funil esconde linhas: no celular a tabela vira blocos (display:block), e o
   [hidden] do navegador perderia para isso */
.orc-tabela tbody tr[hidden]{display:none}

/* ---- a SITUAÇÃO: etiqueta e seletor numa peça só — o ponto e o texto na cor
        do estado (as .b-warn/.b-novo/.b-ok/.b-crit de sempre), um fundo leve da
        mesma cor e a setinha que diz "dá para trocar". O <select> ocupa a
        etiqueta inteira (inclusive a setinha) ------------------------------ */
.orc-st{position:relative;display:inline-flex;align-items:center;gap:6px;margin:0;
 padding:2px 22px 2px 9px;border-radius:999px;font-size:12.5px;font-weight:500;line-height:1.5;
 background:color-mix(in srgb,currentColor 13%,transparent);
 transition:background-color var(--dur-rapida) var(--curva-saida)}
.orc-st::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.orc-st:hover{background:color-mix(in srgb,currentColor 22%,transparent)}
.orc-st:focus-within{outline:2px solid var(--anel);outline-offset:1px}
.orc-st select.kb-mover{appearance:none;-webkit-appearance:none;max-width:none;margin:0 -22px 0 0;
 padding:0 22px 0 0;border:0;background:transparent;color:inherit;font:inherit;cursor:pointer;outline:0}
.orc-st select.kb-mover:hover{color:inherit}
.orc-st select option{color:var(--ink);background:var(--elevado)}
.orc-st-seta{position:absolute;right:8px;top:50%;transform:translateY(-50%);display:flex;pointer-events:none}

/* ---- as AÇÕES da linha: ícones sem moldura, na cor de apoio — o passar do
        mouse dá um fundo leve (no excluir, vermelho) ------------------------ */
.orc-acoes form{display:inline;margin:0}
.orc-ac{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;margin-left:2px;
 border:0;border-radius:7px;background:transparent;color:var(--faint);cursor:pointer;text-decoration:none;
 vertical-align:middle;
 transition:background-color var(--dur-rapida) var(--curva-saida),color var(--dur-rapida) var(--curva-saida)}
.orc-ac:hover{background:var(--nav-on);color:var(--ink)}
.orc-ac-x:hover{background:var(--crit-suave);color:var(--crit)}
.orc-ac:focus-visible{outline:2px solid var(--anel);outline-offset:1px}

/* ---- ANALÍTICO, 4ª rodada (18/10/2026: "tá meio IA; deixa como se fosse um
        relatório mesmo; a parte dos filtros tá muito cardzinho"): a tela é uma
        FOLHA, como o Relatório do mês. No alto, UMA linha de controles lida como
        frase — o nome em letra de apoio e o valor em negrito, sem caixa em volta
        de cada um —, o resto dos filtros no "Mais filtros", e embaixo o
        DOCUMENTO: o cabeçalho, o resumo em demonstrativo e os lançamentos em
        livro-razão. 6ª rodada (a crítica do /impeccable): no escuro, todo campo
        mostra o fio e a setinha sem precisar passar o mouse; o foco é a marca em
        2 px; o tipo de relatório é um menu de links ----------------------------- */
.an-folha{padding:0;border:0;border-radius:0;background:transparent;box-shadow:none}
/* a linha de controles */
.an-ctl{margin:0;padding:12px 0 14px;border-bottom:1px solid var(--fio)}
.an-linha{display:flex;flex-wrap:wrap;align-items:center;gap:10px 22px}
.an-c{display:inline-flex;align-items:center;gap:8px;min-width:0;margin:0}
.an-c-r,.an-c-a{margin:0;font-size:12.5px;white-space:nowrap;color:var(--faint)}
/* o campo sem caixa: o valor em negrito sobre um fio SEMPRE à vista (no escuro, o fio só no passar do mouse
   deixava o campo invisível), a setinha desenhada (.an-seta: a do Bootstrap é escura e sumia no grafite) */
.an-in.form-select,.an-in.form-control{width:auto;min-height:32px;padding:2px 22px 2px 2px;border:0;
 border-bottom:1px solid var(--line);border-radius:0;background-color:transparent;background-image:none;
 box-shadow:none;font-size:13.5px;font-weight:600;color:var(--ink);
 transition:border-color var(--dur-rapida) var(--curva-saida),box-shadow var(--dur-rapida) var(--curva-saida)}
.an-in.form-control{padding-right:2px}
.an-in::placeholder{color:var(--faint);opacity:1}
/* a LISTA que o navegador abre: o campo é transparente e o texto é o do tema (branco no escuro); sem fundo
   próprio, as opções saíam brancas no branco (5ª rodada: "fica tudo branco e não dá pra enxergar") */
.an-in option{background-color:var(--elevado);color:var(--ink)}
.an-in:hover{border-bottom-color:var(--muted)}
/* o foco: o fio vira a marca com 2 px (o de 1 px não se via, e a busca perdia o foco para a regra dela) */
.an-ctl .an-in:focus{border-bottom-color:var(--brand);box-shadow:0 1px 0 var(--brand);outline:0}
.an-seta{display:inline-flex;flex:none;margin-left:-26px;width:18px;justify-content:center;pointer-events:none;
 color:var(--muted)}
.an-c-per .an-in{width:8.4rem;font-variant-numeric:tabular-nums}
.an-c .an-in[name="categoria"],.an-c .an-in[name="quem"]{width:9rem}
/* a busca ocupa o que sobra da linha (encolhe antes de quebrar) e o "Aplicar" fecha a ponta direita */
.an-c-busca{flex:1 1 8rem;gap:6px;color:var(--faint)}
.an-c-busca .an-in{flex:1 1 auto;width:auto;min-width:0;font-weight:400}
.an-aplicar{min-height:32px;padding-inline:16px}
/* o que mudou e ainda não foi aplicado: o botão com um anel da marca e o aviso logo embaixo dele (fora da
   linha: ao lado, ele empurrava o "Aplicar" para uma segunda linha) */
.an-fim{position:relative;display:inline-flex}
.an-pend{position:absolute;top:calc(100% + 3px);right:0;font-size:11.5px;font-weight:600;white-space:nowrap;
 color:var(--warn-texto)}
.an-pend:empty{display:none}
.an-pendente .an-aplicar{box-shadow:0 0 0 3px var(--anel)}
/* o TIPO DE RELATÓRIO: o valor como os outros campos, e um menu de links (o de agora marcado) */
.an-rel>summary{display:inline-flex;align-items:center;gap:8px;min-height:32px;padding:2px 2px;
 border-bottom:1px solid var(--line);list-style:none;cursor:pointer;font-size:13.5px;font-weight:600;
 color:var(--ink);transition:border-color var(--dur-rapida) var(--curva-saida)}
.an-rel>summary svg{color:var(--muted);transition:transform var(--dur-rapida) var(--curva-saida)}
.an-rel>summary:hover{border-bottom-color:var(--muted)}
.an-rel>summary:focus-visible{border-bottom-color:var(--brand);box-shadow:0 1px 0 var(--brand);outline:0}
.an-rel[open]>summary svg{transform:rotate(180deg)}
.an-rel-lista{min-width:15rem;max-height:none}
.an-rel-lista a[aria-current]{background:var(--brand-suave);color:var(--brand-2);font-weight:600}
.an-rel-lista a:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
/* o "Mais filtros": um link discreto; aberto, uma segunda linha igual à primeira */
.an-mais{margin-top:6px}
.an-mais>summary{display:inline-flex;align-items:center;gap:6px;min-height:32px;list-style:none;cursor:pointer;
 font-size:12.5px;font-weight:600;color:var(--brand-2)}
.an-mais>summary::-webkit-details-marker,.an-rel>summary::-webkit-details-marker{display:none}
.an-mais>summary svg{transition:transform var(--dur-rapida) var(--curva-saida)}
.an-mais[open]>summary svg{transform:rotate(180deg)}
.an-mais>summary:focus-visible{outline:2px solid var(--brand);outline-offset:2px;border-radius:4px}
.an-mais .an-linha{padding-top:10px}

/* ---- o DOCUMENTO (7ª rodada: "o resumo tá estranho, papagaiado; falta um destaque que dê vontade de ler e
        mostre que é uma tela de relatórios"): a história na ordem de um relatório — o cabeçalho, a RESPOSTA
        (o resultado grande e a frase que o explica, receitas × despesas em barras), o QUANDO (o movimento no
        tempo), o ONDE (as categorias) e o DETALHE (os lançamentos). Cada seção abre com um título de verdade
        (o rótulo pequeno solto no canto saiu) e um fio em cima ----------------------------------------- */
.an-doc{padding-top:26px;transition:opacity var(--dur-rapida) var(--curva-saida)}
.an-folha:has(.an-pendente) .an-doc{opacity:.55}
.an-doc-cab{margin-bottom:26px}
.an-doc-tit{margin:0;font-family:var(--titulo);font-size:24px;font-weight:600;letter-spacing:-.02em;line-height:1.2;
 color:var(--ink);text-wrap:balance}
.an-doc-per{display:block;margin-top:4px;font-size:15px;font-weight:400;letter-spacing:0;color:var(--muted)}
.an-doc-meta,.an-doc-filtros{margin:6px 0 0;font-size:12.5px;color:var(--faint)}
.an-doc-filtros{color:var(--muted)}
.an-limpar{margin-left:6px;font-weight:600;color:var(--brand-2);text-decoration:underline;text-underline-offset:3px}
.an-limpar:hover{color:var(--ink)}
.an-sec{padding-top:22px;border-top:1px solid var(--fio)}
.an-sec+.an-sec{margin-top:30px}
.an-h{margin:0;font-family:var(--titulo);font-size:18px;font-weight:600;letter-spacing:-.01em;line-height:1.3;
 color:var(--ink)}
.an-cap{margin:3px 0 0;font-size:12.5px;color:var(--faint)}
.an-sec-cab{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 16px;margin-bottom:18px}
.an-sec-cab .an-cap{margin:0}
.an-sec-cab .an-legenda{margin:0 0 0 auto}
/* as cores dos dados: receita no verde, despesa no vermelho; o EM ABERTO é a mesma cor, mais clara */
.an-rec,.an-mv-sobe{--cor:var(--ok)}
.an-des,.an-mv-desce{--cor:var(--crit)}
.an-doc i.an-r{background:var(--cor)}
.an-doc i.an-a{background:repeating-linear-gradient(135deg,var(--cor) 0 2px,transparent 2px 5px)}
.an-legenda{display:flex;flex-wrap:wrap;align-items:center;gap:4px 6px;margin:0;font-size:12px;color:var(--faint)}
.an-lg{display:inline-block;width:10px;height:10px;margin-left:10px;border-radius:2px}
.an-lg:first-child{margin-left:0}
.an-lg-rec{background:var(--ok)}
.an-lg-des{background:var(--crit)}
/* o "em aberto" da legenda: as duas cores claras lado a lado (um cinza leria como uma terceira série) */
.an-lg-ar{background:repeating-linear-gradient(135deg,var(--ok) 0 2px,transparent 2px 4px)}
.an-lg-ad{margin-left:0;background:repeating-linear-gradient(135deg,var(--crit) 0 2px,transparent 2px 4px)}

/* a RESPOSTA: o resultado em número grande na cor do sinal e a frase que diz o que ele significa; ao lado,
   receitas × despesas na mesma escala (a diferença entre as barras É o resultado) */
.an-dest{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);align-items:center;gap:22px 64px;
 padding-top:26px}
.an-dest-cab{display:flex;align-items:center;gap:6px}
.an-pdf .an-dest-cab .ajuda{display:none}
.an-dest-v{margin:6px 0 0;font-family:var(--titulo);font-size:48px;font-weight:600;letter-spacing:-.03em;line-height:1.1;
 font-variant-numeric:tabular-nums;white-space:nowrap;color:var(--ink)}
.an-dest-v.an-pos{color:var(--ok)}
.an-dest-v.an-neg{color:var(--crit)}
.an-dest-txt{max-width:34rem;margin:12px 0 0;font-size:14px;line-height:1.6;color:var(--muted)}
.an-dest-txt b{font-weight:600;white-space:nowrap;color:var(--ink)}
.an-cmp{display:flex;flex-direction:column;gap:18px}
.an-cmp-l{display:grid;grid-template-columns:5.5rem minmax(0,1fr) auto;align-items:center;gap:5px 16px}
.an-cmp-n{font-size:13.5px;font-weight:600;color:var(--ink)}
.an-cmp-barra{display:flex;height:14px;overflow:hidden;border-radius:3px;background:var(--line)}
.an-cmp-barra i{display:block;flex:none;height:100%}
.an-cmp-v{font-size:15px;font-weight:700;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;
 color:var(--ink)}
.an-cmp-s{grid-column:2/-1;font-size:12px;color:var(--faint)}

/* o QUANDO: receitas para cima e despesas para baixo de um fio, uma coluna por semana ou por mês */
/* a escala: o valor da barra mais alta logo acima do gráfico, e um fio tracejado na altura dele */
.an-mv-plot{position:relative}
.an-mv-esc{display:block;margin-bottom:3px;font-size:11px;font-variant-numeric:tabular-nums;color:var(--faint)}
.an-mv{--alt:112px;position:relative;display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:0;
 margin:0;padding:0;list-style:none}
.an-mv::before{content:"";position:absolute;top:var(--alt);right:0;left:0;border-top:1px solid var(--line)}
.an-mv>li{display:flex;min-width:0}
.an-mv-c{position:relative;display:flex;flex:1 1 auto;flex-direction:column;min-width:0;border-radius:6px;
 text-decoration:none;
 transition:background-color var(--dur-rapida) var(--curva-saida)}
a.an-mv-c:hover{background:var(--nav-on)}
a.an-mv-c:hover .an-mv-x{color:var(--ink)}
a.an-mv-c:focus-visible{outline:2px solid var(--brand);outline-offset:0}
.an-mv-sobe,.an-mv-desce{display:flex;height:var(--alt)}
.an-mv-sobe{flex-direction:column-reverse;border-top:1px dashed var(--line)}
.an-mv-desce{flex-direction:column;border-bottom:1px dashed var(--line)}
/* a barra fina e centrada na coluna (a coluna inteira pesava como um bloco) */
.an-mv-sobe i,.an-mv-desce i{display:block;flex:none;align-self:center;width:min(64%,34px)}
.an-mv-x{margin-top:8px;font-size:11px;text-align:center;white-space:nowrap;font-variant-numeric:tabular-nums;
 color:var(--faint)}
.an-mv-v{min-height:16px;margin-top:2px;font-size:11px;font-weight:600;text-align:center;white-space:nowrap;
 font-variant-numeric:tabular-nums;color:var(--muted)}
.an-mv-v.an-pos{color:var(--ok)}
.an-mv-v.an-neg{color:var(--crit)}
.an-mv-muito>li:nth-child(even) .an-mv-x{visibility:hidden}
.an-mv-muito .an-mv-v{display:none}
.an-mv-dica{position:absolute;bottom:calc(100% + 6px);left:50%;z-index:6;display:none;flex-direction:column;gap:1px;
 padding:7px 10px;border:1px solid var(--line);border-radius:8px;background:var(--elevado);box-shadow:var(--sombra-alta);
 font-size:12px;font-weight:400;white-space:nowrap;font-variant-numeric:tabular-nums;color:var(--ink);
 pointer-events:none;transform:translateX(-50%)}
.an-mv-dica b{font-weight:600}
a.an-mv-c:hover .an-mv-dica,a.an-mv-c:focus-visible .an-mv-dica{display:flex}
.an-mv>li:nth-child(-n+2) .an-mv-dica{left:0;transform:none}
.an-mv>li:nth-last-child(-n+2) .an-mv-dica{right:0;left:auto;transform:none}

/* o ONDE: para onde foi o dinheiro e de onde veio — cada categoria com a barra, o valor e a fatia; um clique
   filtra o relatório nela */
.an-compo{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr));gap:28px 64px}
.an-rk{display:flex;flex-direction:column;gap:2px;margin:14px 0 0;padding:0;list-style:none}
.an-rk-l{display:grid;grid-template-columns:minmax(0,1fr) auto 3rem;align-items:baseline;gap:5px 12px;margin:0 -8px;
 padding:7px 8px;border-radius:8px;text-decoration:none;color:var(--ink);
 transition:background-color var(--dur-rapida) var(--curva-saida)}
a.an-rk-l:hover{background:var(--nav-on);color:var(--ink)}
a.an-rk-l .an-rk-n{text-decoration:underline dotted var(--faint);text-underline-offset:4px}
a.an-rk-l:hover .an-rk-n{text-decoration:underline solid currentColor}
a.an-rk-l:focus-visible{outline:2px solid var(--brand);outline-offset:0}
.an-rk-n{min-width:0;overflow:hidden;font-size:13.5px;font-weight:500;text-overflow:ellipsis;white-space:nowrap}
.an-rk-v{font-size:13.5px;font-weight:600;font-variant-numeric:tabular-nums;white-space:nowrap}
.an-rk-p{font-size:12px;text-align:right;font-variant-numeric:tabular-nums;color:var(--faint)}
.an-rk-bloco{max-width:46rem}
.an-rk-barra{grid-column:1/-1;display:flex;height:6px;overflow:hidden;border-radius:3px;background:var(--line)}
.an-rk-barra i{display:block;flex:none;height:100%}
.an-doc .an-rk-barra i.an-r{background:color-mix(in srgb,var(--cor) 60%,var(--muted))}
.an-rk-ab{grid-column:1/-1;font-size:12px;color:var(--faint)}

/* o DETALHE: os LANÇAMENTOS — o título, quantos, e a personalização à direita */
.an-box .tabela-head{align-items:center;padding:0 0 12px}
.an-box .tabela-head .n{font-size:12.5px;color:var(--faint)}

/* ---- a personalização no cabeçalho dos lançamentos: botões leves, os menus
        abrindo para dentro da tela ----------------------------------------- */
.an-perso{gap:6px}
.an-btn-leve{--bs-btn-color:var(--muted);--bs-btn-bg:transparent;--bs-btn-border-color:var(--line);
 --bs-btn-hover-color:var(--ink);--bs-btn-hover-bg:var(--nav-on);--bs-btn-hover-border-color:var(--line);
 --bs-btn-active-color:var(--ink);--bs-btn-active-bg:var(--nav-on);--bs-btn-active-border-color:var(--line);
 display:inline-flex;align-items:center;gap:6px;min-height:32px;border-radius:999px}
.an-cont{font-weight:400;color:var(--faint)}
.an-colunas[open]>summary,.an-salvar-menu[open]>summary{background:var(--nav-on);color:var(--ink)}
.an-col-lista,.an-salvar-lista{left:auto;right:0;max-height:none;padding:12px 14px;gap:10px}
.an-col-lista{min-width:min(27rem,86vw)}
.an-salvar-lista{min-width:min(21rem,86vw)}
.an-col-grade{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2px 16px}
.an-col{display:flex;align-items:center;gap:8px;margin:0;padding:4px 6px;border-radius:6px;
 font-size:13px;color:var(--ink);cursor:pointer}
.an-col:hover{background:var(--nav-on)}
.an-col input{margin:0;accent-color:var(--brand-solido)}
.an-col-pe{display:flex;justify-content:flex-end;padding-top:10px;border-top:1px solid var(--fio)}
.an-w-meus{width:11rem;border-radius:999px}
.an-salvar{display:flex;align-items:center;gap:6px;margin:0}
.an-salvar .form-control{flex:1 1 auto;min-width:0}
.an-excluir{display:inline;margin:0}
.an-btn-x{--bs-btn-color:var(--faint);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;
 --bs-btn-hover-color:var(--crit);--bs-btn-hover-bg:var(--crit-suave);--bs-btn-hover-border-color:transparent;
 display:inline-flex;align-items:center;gap:5px}
.an-dica{margin:0;font-size:12px;color:var(--faint)}

/* ---- a tabela em LIVRO-RAZÃO: só o texto, o número à direita, o valor na cor
        do sinal (e com o sinal de menos na despesa), o "em aberto" no tom de
        alerta e o resultado do período no pé, sob a coluna do valor ----------- */
.an-tabela td{font-variant-numeric:tabular-nums}
/* só a descrição e a observação quebram linha: as colunas curtas (datas, tipo, categoria,
   obra, fornecedor, status, valores) ficam numa linha só — faltando largura, a tabela rola
   de lado dentro da área dela, como sempre (no celular a tabela vira blocos e o texto quebra) */
@media (min-width:701px){.an-tabela td:not([data-l="Descrição"]):not([data-l="Observação"]){white-space:nowrap}}
.an-tabela td[data-l="Descrição"]{min-width:15rem;white-space:normal;line-height:1.4;color:var(--ink);font-weight:500}
.an-tabela td[data-l="Observação"]{min-width:12rem;white-space:normal;line-height:1.4}
.an-tabela td[data-l="Tipo"],.an-st.an-conf{color:var(--muted)}
.an-st.an-aberto{font-weight:500;color:var(--warn-texto)}
.an-tabela tfoot td{padding-top:11px;border-top:1px solid var(--line);border-bottom:0;background:transparent;
 font-weight:700;color:var(--ink)}
.an-tabela tfoot .an-tot-r{text-align:right;font-size:12.5px;font-weight:600;color:var(--muted)}
.an-tabela tfoot .an-tot-v.an-pos{color:var(--ok)}
.an-tabela tfoot .an-tot-v.an-neg{color:var(--crit)}

/* ---- o EXPORTAR (no cabeçalho da página): primeiro ESTE RELATÓRIO, a obra da tela, com os dois formatos
        em destaque; embaixo, "Outra obra" — uma linha por obra, as duas saídas ao lado, um clique ---- */
.an-exp-btn{display:inline-flex;align-items:center;gap:6px}
.an-exp-lista{min-width:min(24rem,90vw);max-height:none;padding:14px 12px 10px;gap:4px}
.an-exp-t{margin:0 4px;font-size:14px;font-weight:600;color:var(--ink)}
.an-exp-d{margin:0 4px 6px;font-size:12.5px;color:var(--faint)}
.an-exp-este{display:flex;gap:8px;margin:2px 4px 4px}
.an-exp-lista .an-exp-b{display:inline-flex;flex:1 1 0;align-items:center;justify-content:center;gap:7px;
 min-height:36px;padding:6px 14px;border:1px solid var(--line);border-radius:999px;font-size:13px;font-weight:600;
 text-decoration:none;color:var(--ink);
 transition:background-color var(--dur-rapida) var(--curva-saida),border-color var(--dur-rapida) var(--curva-saida)}
.an-exp-lista .an-exp-b:hover{border-color:var(--brand);background:var(--brand-suave);color:var(--ink)}
.an-exp-lista .an-exp-t.an-exp-outra{margin-top:10px;padding-top:12px;border-top:1px solid var(--fio);
 font-size:12.5px;color:var(--muted)}
.an-exp-obras{max-height:16rem;overflow:auto;margin:0;padding:0;list-style:none}
.an-exp-o{display:flex;align-items:center;gap:6px;padding:5px 4px 5px 8px;border-radius:8px}
.an-exp-o+.an-exp-o{border-top:1px solid var(--fio)}
.an-exp-o:hover{background:var(--nav-on)}
.an-exp-n{flex:1 1 auto;min-width:0;overflow:hidden;font-size:13px;text-overflow:ellipsis;white-space:nowrap;color:var(--ink)}
.an-exp-lista .an-exp-a{display:inline-flex;flex:none;align-items:center;gap:5px;padding:4px 9px;border-radius:999px;
 font-size:12px;font-weight:600;text-decoration:none;color:var(--brand-2);
 transition:background-color var(--dur-rapida) var(--curva-saida),color var(--dur-rapida) var(--curva-saida)}
.an-exp-lista .an-exp-a:hover{background:var(--brand-suave);color:var(--brand-2)}
/* o anel do foco na marca cheia (o --anel, translúcido, ficava abaixo de 3:1 no escuro) */
.an-exp-lista .an-exp-a:focus-visible,.an-exp-lista .an-exp-b:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

/* ---- o PDF: a página do documento, sempre clara, A4 deitada (página com nome:
        só ela imprime assim; a barra de cima some na impressão) e o número da
        página no rodapé de cada folha --------------------------------------- */
.an-pdf{page:an-paisagem;background:var(--panel);color:var(--ink);-webkit-print-color-adjust:exact;print-color-adjust:exact}
.an-pdf .an-dest,.an-pdf .an-mov,.an-pdf .an-compo{break-inside:avoid}
.an-pdf-barra{position:sticky;top:0;z-index:5;display:flex;align-items:center;gap:14px;padding:10px 24px;
 border-bottom:1px solid var(--line);background:var(--ground);font-size:13px;color:var(--muted)}
.an-pdf-folha{max-width:1100px;margin:0 auto;padding:28px 24px 40px}
.an-pdf-pe{margin:28px 0 0;font-size:11.5px;color:var(--faint)}
.an-pdf .an-tabela th,.an-pdf .an-tabela td{padding:7px 8px;font-size:12px}
@page an-paisagem{@bottom-right{content:"Página " counter(page) " de " counter(pages);font-family:system-ui,sans-serif;
 font-size:8pt}size:A4 landscape;margin:12mm 12mm 15mm}
@media print{
 .an-pdf-barra{display:none}
 .an-pdf-folha{max-width:none;padding:0}
 .an-pdf .an-tabela thead{display:table-header-group}
 .an-pdf .an-tabela tr{break-inside:avoid}
}

/* ---- no celular: tudo empilha, os campos dividem a linha ------------------ */
@media (max-width:700px){
 .orc-f-itens{grid-template-columns:repeat(2,minmax(0,1fr))}
 .orc-f.orc-f-todos{grid-column:1/-1}
 .orc-f-v{font-size:20px}
 .orc-nota{max-width:none;white-space:normal}
 /* a data e o "há quanto tempo" juntos, à direita, como os outros valores do bloco */
 .orc-tabela td.orc-data{justify-content:flex-end;gap:8px}
 .orc-tabela td.orc-data::before{margin-right:auto}
 .orc-idade{display:inline;margin-top:0}
 /* (6ª rodada, a crítica do /impeccable: "a primeira tela do celular é só controle") o DOCUMENTO começa
    pelo que ele diz — o título e o resumo — e os controles vêm logo depois, antes dos lançamentos. Só a
    ordem na tela muda; os controles continuam todos lá */
 .an-folha{display:flex;flex-direction:column;padding:4px 0 76px}
 .an-doc{display:contents}
 .an-folha>:not(.an-doc){order:3}
 .an-doc-cab{order:1;margin:6px 0 4px}
 .an-dest{order:2;margin-top:14px}
 .an-folha>.an-ctl{margin-top:22px;border-top:1px solid var(--fio);border-bottom:0}
 .an-mov,.an-compo,.an-box{order:4}
 .an-sec+.an-sec{margin-top:22px}
 /* o pé da tabela: o resultado como os outros valores do bloco (o nome pelo data-l) */
 .an-tabela tfoot,.an-tabela tfoot tr{display:block}
 .an-tabela tfoot td:empty,.an-tabela tfoot .an-tot-r{display:none}
 .an-tabela tfoot td{border-top:0}
 .an-tabela tfoot tr{padding:6px 14px;border-top:1px solid var(--line)}
 /* cada controle numa linha, o nome à esquerda e o valor ocupando o resto */
 .an-linha{gap:8px 16px}
 .an-c{width:100%}
 .an-c-r{min-width:5.5rem}
 .an-c .an-in,.an-c-per .an-in,.an-c-busca .an-in{flex:1 1 0;width:auto;min-width:0}
 .an-c-busca{margin-left:0}
 /* o período: o nome em cima e as duas datas dividindo a linha (com o nome ao lado, não cabem) */
 .an-c-per{flex-wrap:wrap;row-gap:2px}
 .an-c-per .an-c-r:first-child{flex-basis:100%}
 .an-fim,.an-aplicar{width:100%}
 .an-doc-tit{font-size:20px}
 .an-doc-per{font-size:14px}
 /* a resposta empilha (o número, a frase, as barras); o gráfico mais baixo e, com muitas colunas, um rótulo
    sim, outro não */
 .an-dest{grid-template-columns:minmax(0,1fr);gap:20px}
 .an-dest-v{font-size:34px}
 .an-cmp-l{grid-template-columns:4.6rem minmax(0,1fr) auto;column-gap:10px}
 .an-cmp .an-legenda{padding-left:0}
 .an-sec-cab .an-legenda{margin-left:0}
 .an-mv{--alt:72px}
 .an-mv-denso>li:nth-child(even) .an-mv-x{visibility:hidden}
 .an-mv-cheio .an-mv-v{display:none}
 .an-mv a.an-mv-c .an-mv-dica{display:none}
 .an-compo{gap:26px}
 .an-perso{width:100%;margin-left:0}
 .an-col-lista,.an-salvar-lista{left:0;right:auto}
 .an-col-grade{grid-template-columns:minmax(0,1fr)}
 /* o rápido na linha toda; embaixo, o manual e o "i" */
 .orc-criar{width:100%}
 .orc-criar .btn{flex:1 1 auto;justify-content:center}
 .orc-criar .btn-primary{flex-basis:100%}
 /* a tabela vira blocos (a regra geral do celular): UF e Ações voltam a ocupar a linha,
    com o valor à direita como as outras — a largura mínima do computador não vale aqui */
 .orc-tabela .orc-uf,.orc-tabela .orc-acoes{width:100%;text-align:right}
 .orc-tabela td.orc-acoes{justify-content:flex-end;gap:4px}
 .orc-tabela td.orc-acoes::before{margin-right:auto}
}
/* no dedo: os campos na letra de 16 px (abaixo disso o iPhone dá zoom) e os alvos
   de toque com 40-44 px — a régua do bloco TOQUE */
@media (pointer:coarse){
 .an-in.form-select,.an-in.form-control{font-size:16px;min-height:44px}
 .an-aplicar,.an-btn-leve,.an-mais>summary,.an-rel>summary{min-height:44px}
 .an-exp-lista .an-exp-a{min-height:40px}
 .an-exp-lista .an-exp-b{min-height:44px}
 .orc-ac{width:40px;height:40px}
 /* o seletor da situação: o TOQUE dá 44 px a todo .kb-mover — aqui ele é etiqueta, e 36
    px de alvo bastam sem virar um botão gordo */
 .orc-st{padding-block:0}
 .orc-st select.kb-mover{min-height:36px}
}
/* fim: ORÇAMENTOS E RELATÓRIOS › ANALÍTICO (a checagem de cor literal lê este bloco) */

/* ============ COMO A OBRA É ACOMPANHADA (19/10/2026) ============
   A chavinha "esta obra vai medir o avanço físico" no cadastro; desligada, o
   ALERTA EM VERMELHO (o que a obra não vai ter, o que continua tendo, o termo e
   o "li e aceito"). Na ficha da obra só financeira, o cartão com as mesmas
   listas. O vermelho é só o do alerta (é aviso de perda: a previsão); o cartão
   da ficha fica neutro — a obra não está "mal", ela só não tem previsão. */
.acomp{border:1px solid var(--line);border-radius:8px;padding:12px 14px;margin:2px 0 0;background:var(--panel)}
.acomp-chave{display:grid;grid-template-columns:auto 1fr;column-gap:10px;align-items:center;padding-left:0;margin:0}
.acomp-chave .form-check-input{float:none;margin:0;width:2.4em;height:1.3em;cursor:pointer;
  background-color:var(--panel-2);border-color:var(--line)}
.acomp-chave .form-check-input:checked{background-color:var(--brand-solido);border-color:var(--brand-solido)}
.acomp-chave .form-check-input:focus{box-shadow:0 0 0 3px var(--brand-suave);border-color:var(--brand)}
.acomp-chave .form-check-label{font-weight:600;color:var(--ink);cursor:pointer}
.acomp-chave .form-text{grid-column:2}
.acomp-alerta{margin-top:12px;display:flex;flex-direction:column;gap:10px}
.acomp-t{margin:0;font-weight:600;color:var(--crit-texto);font-size:14px}
.acomp-cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:12px 22px}
.acomp-cols > div{min-width:0}
.acomp-h{margin:0 0 4px;font-size:11.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.acomp-nao,.acomp-sim{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:4px;font-size:12.5px;line-height:1.45}
.acomp-nao li,.acomp-sim li{position:relative;padding-left:18px}
.acomp-nao li::before{content:"✕";position:absolute;left:0;top:0;color:var(--crit-texto);font-weight:600}
.acomp-sim li::before{content:"✓";position:absolute;left:0;top:0;color:var(--ok-texto);font-weight:600}
.acomp-card .card-h .st{font-size:11.5px;color:var(--faint);white-space:nowrap}
.acomp-card .acomp-cols{margin-top:12px}
.acomp-troca{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin-top:14px;padding-top:12px;
  border-top:1px solid var(--line)}
.acomp-troca .form-text{min-height:0;flex:1 1 220px}
/* a bolinha da chavinha: o Bootstrap a desenha com um SVG de cor fixa (some no escuro) — aqui ela é um
   gradiente com as variáveis do tema, e anda de um lado para o outro com a escolha */
.acomp-chave .form-check-input{background-image:radial-gradient(circle at .65em 50%,var(--faint) .42em,transparent .46em)}
.acomp-chave .form-check-input:checked{background-image:radial-gradient(circle at calc(100% - .65em) 50%,var(--sobre-solido) .42em,transparent .46em)}
@media (pointer:coarse){.acomp-chave .form-check-input{width:2.9em;height:1.6em}}

/* ============ A CIRCULAR DA OBRA SÓ FINANCEIRA (19/10/2026, 2ª rodada) ============
   Orçado × pago por etapa em volta, interativo: o gráfico à esquerda, o detalhe da
   etapa escolhida à direita (no celular, embaixo). A forma é na cor do DINHEIRO da
   Circular do Radar (a marca); a faixa entre 100% e 120% do orçado é a de "passou
   do orçado". A etapa escolhida: raio e anel na tinta, o nome sublinhado com a cor
   de seleção do sistema (a mesma da barra) — o vermelho dos DADOS é outro, o da faixa. */
.cf-corpo{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:8px 28px;align-items:start;
  padding:4px 16px 16px}
.cf-graf{position:relative;width:100%;max-width:580px;justify-self:center;aspect-ratio:540/360;margin:2.4em 0 2.6em}
.cf-graf svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.cf-faixa{fill:var(--crit-suave)}
.cf-anel{fill:none;stroke:var(--line);stroke-dasharray:2 4}
.cf-anel.cheio{stroke:var(--muted);stroke-dasharray:none;stroke-width:1.2}
.cf-raio{stroke:var(--line)}
.cf-raio.sel{stroke:var(--ink);stroke-width:1.4}
.cf-area{fill:var(--brand);fill-opacity:.14;stroke:var(--brand);stroke-width:2;stroke-linejoin:round}
.cf-pt{fill:var(--brand);stroke:var(--panel);stroke-width:2}
.cf-pt.passou{fill:var(--crit)}
.cf-pt.economizou{fill:var(--ok)}
.cf-pt.não-começou{fill:var(--faint)}
.cf-pt.borda{stroke:var(--crit);stroke-width:3}
.cf-pt.sel{r:7.5;stroke:var(--ink);stroke-width:2}
.cf-alvo{fill:transparent;cursor:pointer}
.cf-abas{position:absolute;inset:0;pointer-events:none}
/* (width:max-content: o rótulo da direita não encolhe até a borda do desenho — sem isso o nome quebrava em
   'Fabricação / dos...') */
.cf-aba{position:absolute;pointer-events:auto;display:flex;flex-direction:column;gap:1px;width:max-content;
  max-width:8.5em;
  padding:3px 6px 4px;border:0;border-radius:6px;background:transparent;color:var(--ink);font:inherit;
  font-size:12px;line-height:1.25;cursor:pointer}
.cf-aba.dir{transform:translate(0,-50%);text-align:left;align-items:flex-start}
.cf-aba.esq{transform:translate(-100%,-50%);text-align:right;align-items:flex-end}
.cf-aba.cima{transform:translate(-50%,-100%);text-align:center;align-items:center}
.cf-aba.baixo{transform:translate(-50%,0);text-align:center;align-items:center}
.cf-aba:hover{background:var(--panel-2)}
.cf-aba:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
.cf-nome{font-weight:500;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  overflow-wrap:anywhere;text-decoration:underline;text-decoration-color:transparent;text-decoration-thickness:2px;
  text-underline-offset:3px}
.cf-aba[aria-selected="true"] .cf-nome{font-weight:600;text-decoration-color:var(--selecao)}
.cf-n{font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
.cf-n.perda{color:var(--crit-texto)}
.cf-n.oport{color:var(--ok-texto)}
.cf-detalhes{min-width:0;align-self:center;display:flex;flex-direction:column;gap:10px}
.cf-det{display:flex;flex-direction:column;gap:12px;padding:16px 0 4px;
  animation:cf-entrar var(--dur-media) var(--curva-saida) backwards}
.cf-det:focus-visible{outline:2px solid var(--brand);outline-offset:4px;border-radius:4px}
/* (a entrada do detalhe: o único movimento do gráfico — o bloco geral de menos-movimento zera a duração) */
@keyframes cf-entrar{from{opacity:0;transform:translateY(6px)}}
.cf-det-topo{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:space-between;gap:4px 12px;
  padding-bottom:10px;border-bottom:1px solid var(--line)}
.cf-det-topo h3{margin:0;font-size:17px;font-weight:600;color:var(--ink);text-wrap:balance}
.cf-selo{font-size:12px;font-weight:500;color:var(--muted)}
.cf-selo.perda{color:var(--crit-texto)}
.cf-selo.oport{color:var(--ok-texto)}
.cf-fatos{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px 16px;margin:0}
.cf-fatos dt{font-size:11.5px;font-weight:500;color:var(--muted)}
.cf-fatos dd{margin:2px 0 0;font-size:15px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;
  overflow-wrap:anywhere}
.cf-apoio{margin:0;font-size:12px;color:var(--faint)}
.cf-sub-t{margin:4px 0 0;font-size:11.5px;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:var(--muted)}
.cf-pags{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.cf-pags li{display:grid;grid-template-columns:3.2em minmax(0,1fr) auto;gap:10px;align-items:baseline;
  padding:7px 0;border-top:1px solid var(--line);font-size:13px}
.cf-pags li:first-child{border-top:0}
.cf-pags .d{color:var(--faint);font-variant-numeric:tabular-nums}
.cf-pags .o{color:var(--ink);min-width:0;overflow-wrap:anywhere}
.cf-pags .o small{display:block;font-size:11.5px;color:var(--muted)}
.cf-pags .v{font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.cf-mais,.cf-vazio{margin:0;font-size:12.5px;color:var(--muted)}
.cf-ir{align-self:flex-start;display:inline-flex;align-items:center;gap:4px;font-size:13px}
.cf-ir svg{transform:rotate(-90deg)}
.cf-nota{margin:0}
@media (max-width:820px){.cf-corpo{grid-template-columns:minmax(0,1fr)}.cf-graf{max-width:520px}}
@media (max-width:520px){.cf-aba{max-width:7.4em;font-size:11.5px}.cf-fatos{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (pointer:coarse){.cf-alvo{r:18}}

/* ============ AS ALAVANCAS DE UMA ETAPA (19/10/2026) ============
   O COMO de uma ação de etapa: o caminho (comprar melhor, contratar melhor...), o
   que fazer e o valor quando o dado sustenta; cada uma abre o número e o passo a
   passo. Na lista de ações (econ-alav) e no detalhe da etapa da ficha (cf-alav). */
.alavancas{list-style:none;margin:6px 0 2px;padding:0;display:flex;flex-direction:column;border-top:1px solid var(--line)}
.alav{border-bottom:1px solid var(--line)}
.alav summary{list-style:none;display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:4px 10px;
  align-items:baseline;padding:7px 2px;cursor:pointer}
.alav summary::-webkit-details-marker{display:none}
.alav summary:focus-visible{outline:2px solid var(--brand);outline-offset:1px;border-radius:4px}
.alav-c{font-size:11px;font-weight:600;color:var(--muted);white-space:nowrap}
.alav[data-caminho="comprar"] .alav-c{color:var(--brand-2)}
.alav[data-caminho="hora"] .alav-c{color:var(--warn-texto)}
.alav[data-caminho="dado"] .alav-c,.alav[data-caminho="proxima"] .alav-c{color:var(--faint)}
.alav-t{font-size:13px;font-weight:500;color:var(--ink);min-width:0;overflow-wrap:anywhere}
.alav summary:hover .alav-t{text-decoration:underline;text-decoration-color:var(--line);text-underline-offset:3px}
.alav-v{font-size:12.5px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;
  text-align:right;display:flex;flex-direction:column;line-height:1.2}
.alav-v.oport{color:var(--ok-texto)}
.alav-v small{font-size:11px;font-weight:400;color:var(--muted)}
.alav-corpo{padding:0 2px 9px;display:flex;flex-direction:column;gap:4px}
.alav-f{margin:0;font-size:12.5px;color:var(--ink)}
.alav-como{margin:0;font-size:12.5px;color:var(--muted)}
.econ-alav{margin-top:8px}
@media (max-width:520px){.alav summary{grid-template-columns:minmax(0,1fr) auto}.alav-c{grid-column:1/-1}}
