/* ============================================================================
   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;
  --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;
  --graf-area-topo:.40;--graf-area-base:.06;--graf-gap:.26;
  /* 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;
  /* 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;
  --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-gap:.34;
  --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;
  --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;
}

: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);
  /* 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}
.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 */
.nav-item .conta{background:var(--crit-solido);color:var(--sobre-solido);font-size:10.5px;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}
.top .av{width:24px;height:24px;font-size:10px;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:10.5px;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.) */
@media(max-width:1439.98px){.marca .by{display:none}}
@media(max-width:1279.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.) */
.chip-empresa .nome{display:block;max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(min-width:1280px) and (max-width:1365.98px){.menu-conta .nome,.chip-empresa .nome{max-width:104px}}
/* 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.) */
@media(min-width:992px) and (max-width:1159.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}
.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:10.5px;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:10.5px;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}
.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 em degraus,
   ritmo esperado pontilhado) são finas e 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 as amostras do orçado (tinta
   cheia) e do ritmo (anel) seguem os tokens --barra-* do cartão noturno. */
.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}
.legend-inline i.pontilhado{height:0;border-top:2px dotted currentColor;background:none}
.graf-tip .sw.orcado{--sw:var(--barra-ink)}
.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.
   ========================================================================= */
.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);border-left-width:3px}
.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:10px;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:10px;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.
   ========================================================================= */
.ajuda{position:relative;display:inline-flex;align-items:center;vertical-align:middle;margin-left:5px;cursor:help;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% + 9px);transform:translateX(-50%);
  width:max-content;max-width:310px;z-index:60;background:var(--elevado);color:var(--muted);
  border:1px solid var(--line);border-radius:8px;box-shadow:var(--sombra-alta);
  padding:11px 13px;font-size:12.5px;font-weight:400;line-height:1.5;text-align:left;
  text-transform:none;letter-spacing:0;font-style:normal;white-space:normal;
  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:4px;font-size:12.5px;color:var(--ink);font-weight:600}
@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)}
.ajuda-bolha::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);
  border:6px solid transparent;border-top-color:var(--line)}
.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:6px;transform:none}
@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}
}

/* ========================= 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-fgrupo{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.rel-flab{font-size:12px;color:var(--muted)}
.rel-datas{font-size:12px;color:var(--faint);font-variant-numeric:tabular-nums}
/* o período em botões (a mesma chavinha .visao-troca do Radar) + o "Intervalo", que abre as datas */
.rel-periodo>details{padding:0;position:relative}
.rel-periodo>details>summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:4px;
 padding:4px 10px;border-radius:6px;color:var(--muted);transition:background-color var(--dur-rapida),color var(--dur-rapida)}
.rel-periodo>details>summary::-webkit-details-marker{display:none}
.rel-periodo>details>summary:hover{background:var(--nav-on);color:var(--ink)}
.rel-periodo>details>summary.atual{background:var(--brand-suave);color:var(--brand-2);font-weight:500}
.rel-periodo>details>summary:focus-visible{outline:2px solid var(--anel);outline-offset:1px}
.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:230px}
.fx-ent{fill:var(--brand)}
.fx-sai{fill:var(--cost)}
.fx-col.aberto{fill-opacity:.18;stroke-width:1px}
.fx-ent.aberto{stroke:var(--brand)}
.fx-sai.aberto{stroke:var(--cost)}
.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-tip .sw.tinta{--sw:var(--barra-ink)}
.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)}

/* 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)}
@layer reforma-prisma{
 /* 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)}
.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:10px;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: um link sob cada número; o painel abre logo abaixo dos números, na
   largura inteira, UM de cada vez. Ele é uma faixa rebaixada (o fundo da
   página, sem borda nem sombra) — não um cartão: é o detalhe que desce do
   número, e some quando se fecha. Os outros números ficam a meia força
   enquanto um painel está aberto (a gramática do filtro cruzado). 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.
   Movimento: a altura desliza no JS (módulo COMO CHEGAMOS do _JS_CASCA); aqui,
   só o surgir do conteúdo novo. Sem JavaScript, o painel abre por :target.
   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)}
.como-abre[aria-expanded="true"]{color:var(--ink);box-shadow:inset 0 -2px 0 var(--brand)}
.como-abre[aria-expanded="true"]:hover{text-decoration:none}
.como-abre[aria-expanded="true"] .como-seta{transform:rotate(45deg) translate(-2px,-2px)}
/* 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}
/* com um painel aberto, os outros números a meia força (voltam no passar do mouse) */
.res-num .rel-kpi{transition:opacity var(--dur-rapida) var(--curva-saida)}
.res-num.como-aberto .rel-kpi:not(.como-on){opacity:.5}
.res-num.como-aberto .rel-kpi:not(.como-on):hover{opacity:1}

/* o lugar dos painéis e o painel: fechado não ocupa nada */
.como{position:relative}
.como-painel{display:none;margin-top:18px;padding:18px 20px 16px;border-radius:8px;background:var(--ground);
 scroll-margin-top:120px}
.como-painel.on,.como:not(.js) .como-painel:target{display:block}
.como-painel:focus{outline:none}
.como-painel.entra{animation:surgir var(--dur-media) var(--curva-saida)}
.como-painel.saindo{opacity:0;transition:opacity var(--dur-rapida) var(--curva-entrada)}
.como-cab{display:flex;align-items:baseline;justify-content:space-between;gap:6px 16px;flex-wrap:wrap;margin-bottom:14px}
.como-tit{font-family:var(--titulo);font-size:15px;font-weight:600;letter-spacing:-.01em;line-height:1.35;
 color:var(--ink);margin:0}
.como-fechar{font-size:12.5px;color:var(--brand-2);text-decoration:none;white-space:nowrap}
.como-fechar:hover{text-decoration:underline}

/* o corpo: a conta à esquerda, o onde e o porquê à direita, separados por um fio */
.como-corpo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:0 28px}
.como-col{display:flex;flex-direction:column;gap:20px;min-width:0}
.como-col+.como-col{border-left:1px solid var(--fio);padding-left:28px}
.como-parte{min-width:0}
.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}
.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}
/* o que não se sabe: na largura inteira, embaixo das duas colunas */
.como-nao-sabe{margin-top:18px;padding-top:14px;border-top:1px solid var(--fio)}
.como-avisos{margin-top:4px}

/* 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:991.98px){
 .como-corpo{grid-template-columns:minmax(0,1fr)}
 .como-col+.como-col{border-left:0;padding-left:0;border-top:1px solid var(--fio);padding-top:18px;margin-top:18px}
}
@media (max-width:700px){
 .como-painel{padding:14px 12px 12px;margin-top:14px}
 .como-tit{font-size:14px}
 .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%}
}
/* no papel, as quatro contas saem abertas (o painel é o que explica o número) */
@media print{
 .como-painel{display:block!important;background:transparent;padding:12px 0 0}
 .como-abre,.como-fechar{display:none}
}
/* fim: COMO CHEGAMOS NESSE VALOR (a checagem de cor literal lê este bloco) */

/* ============================================================================
   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}
.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:10.5px;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:10.5px;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}
.lu-tirados,.lu-falha{margin:10px 0 0;padding:8px 10px;border-left:3px solid var(--warn);border-radius:0 6px 6px 0;
  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)}
.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)
   A tela do diretor (tela_plano, no app.py): os planos em três colunas, o
   atual marcado, o preço grande 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; a coluna do plano atual ganha o contorno da marca (--brand) e o
       fundo do item ativo (--nav-on). Nada de sombra, degradê ou selo;
   (2) as seis partes de cada coluna (nome, resumo, preço, nota, a marca ou o
       "fale com a Lumiset", 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, só sem o alinhamento entre elas;
   (3) "Plano atual" é uma ETIQUETA (pílula na tinta da marca), não um botão;
       o que se clica é o link de cada coluna (29/09, tarde), que leva ao
       aviso "Em desenvolvimento" — mudar de plano ainda é conversa com a
       Lumiset;
   (4) a faixa de contexto, sobre o fundo da página: fatos separados por um fio
       (o período de teste, as obras), o atalho para o plano e uso da Lumina e,
       quando a central não respondeu, o aviso de que o plano não foi marcado;
   (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.
   ========================================================================= */
.pl{display:flex;flex-direction:column;gap:16px;max-width:1180px;min-width:0}
/* (4) o contexto */
.pl-contexto{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px 28px;min-width:0}
.pl-aviso-l{flex:0 0 100%;min-width:0}
.pl-aviso{margin:0;max-width:96ch;font-size:13px;line-height:1.55;color:var(--muted)}
.pl-aviso-t{color:var(--ink);font-weight:600}
.pl-aviso-t::before{content:"";display:inline-block;width:7px;height:7px;margin-right:7px;border-radius:50%;
  background:var(--warn);vertical-align:.08em}
.pl-fatos{display:flex;flex-wrap:wrap;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{margin-left:auto;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}
/* (1)(2) as três colunas, numa superfície só */
.pl-planos{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));background:var(--panel);
  border:1px solid var(--line);border-radius:8px}
.pl-col{grid-row:span 6;display:grid;grid-template-rows:subgrid;align-content:start;min-width:0;
  padding:24px 24px 28px;position:relative}
.pl-col+.pl-col{border-left:1px solid var(--line)}
.pl-col.atual{background:var(--nav-on);outline:2px solid var(--brand);outline-offset:-1px;border-radius:8px;z-index:1}
.pl-nome{margin:0;font-family:var(--titulo);font-size:18px;font-weight:600;letter-spacing:-.01em;line-height:1.3;
  color:var(--ink)}
.pl-resumo{margin:6px 0 0;max-width:46ch;font-size:13px;line-height:1.5;color:var(--muted)}
.pl-preco{margin:20px 0 0;display:flex;flex-direction:column;gap:4px}
.pl-valor{font-family:var(--titulo);font-size:34px;font-weight:600;letter-spacing:-.02em;line-height:1.05;
  color:var(--ink);white-space:nowrap;font-variant-numeric:tabular-nums}
.pl-moeda{margin-right:5px;font-size:.5em;letter-spacing:0;vertical-align:.62em}
.pl-consulta{font-size:26px;line-height:1.3}
.pl-unid{font-size:12.5px;color:var(--muted)}
.pl-nota{margin:6px 0 0;font-size:12.5px;font-weight:500;color:var(--ink)}
/* (3) a marca do plano atual — etiqueta, não botão — e o link de cada coluna
   (29/09, tarde — "se o cliente clicar em qualquer plano, tem que aparecer em
   desenvolvimento"): "Escolher este plano" na tinta da marca e, na coluna
   atual, ao lado da etiqueta, "Ajustar este plano" neutro. O link enche o
   resto da linha, como os botões da referência. A coluna clicada troca o link
   pelo AVISO "Em desenvolvimento": a caixa com o fio da marca à esquerda — é
   informação, não perigo (nada de vermelho nem de atenção) —, na linha toda. */
/* (align-self:start: com o aviso, a linha da grade fica mais alta — os links das outras
   colunas ficam no alto dela, onde estavam antes do clique, em vez de descer para o meio) */
.pl-acao{margin:18px 0 0;min-height:26px;display:flex;flex-wrap:wrap;align-items:center;align-self:start;
  gap:8px 10px;font-size:12.5px;line-height:1.45;color:var(--muted)}
.pl-atual{display:inline-flex;align-items:center;gap:6px;padding:3px 11px 3px 8px;border-radius:999px;
  background:var(--brand-suave);color:var(--brand-2);font-size:12.5px;font-weight:600;line-height:1.5}
.pl-escolher{flex:1 1 auto;min-width:0}
.pl-dev{flex:1 1 100%;min-width:0;padding:9px 12px 10px;border-left:3px solid var(--brand);border-radius:0 6px 6px 0;
  background:var(--brand-suave)}
.pl-dev:focus{outline:0}      /* o foco ao abrir é para o leitor de tela; a caixa já se destaca */
.pl-dev-t{margin:0;font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--brand-2)}
.pl-dev-txt{margin:3px 0 0;font-size:13px;line-height:1.5;color:var(--ink)}
.pl-dev-txt b{font-weight:600}
.pl-inclui{margin-top:20px;padding-top:20px;border-top:1px solid var(--line)}
.pl-inclui-t{margin:0;font-size:13px;font-weight:600;color:var(--ink)}
.pl-itens{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:9px}
.pl-itens li{display:grid;grid-template-columns:16px minmax(0,1fr);gap:9px;align-items:start;font-size:13px;
  line-height:1.45;color:var(--ink)}
.pl-itens svg{margin-top:1px;color:var(--brand)}
/* (5) tablet e celular: as colunas empilham; a 700 px, os fatos também */
@media (max-width:991.98px){
 .pl-planos{grid-template-columns:minmax(0,1fr)}
 .pl-col{padding:20px 18px 24px}
 .pl-col+.pl-col{border-left:0;border-top:1px solid var(--line)}
 .pl-atalho{margin-left:0}
}
@media (max-width:700px){
 .pl-fatos{flex-direction:column;gap:12px}
 .pl-fato{padding:0;border-left:0}
 .pl-valor{font-size:30px}
}
/* (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}
}
/* 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) */
