/* ===========================================================================
   CSS DA ACADEMIA DO ESTRUTURADOR — o que o app declara por cima do design system.

   Vivia em 19 blocos <style> espalhados pelo index.html. Saiu daqui em 2026-07-27,
   junto com a IIFE, porque o arquivo unico era a causa raiz das colisoes entre as
   3 sessoes.

   ORDEM IMPORTA — e foi preservada. Os blocos estao aqui na MESMA sequencia em que
   apareciam no documento, e este arquivo e carregado DEPOIS de assets/propulsor-ui.css.
   Isso mantem a precedencia: o CSS do app vence o do design system em empate de
   especificidade. Inverter a ordem quebraria o tema v3 inteiro em silencio.
   =========================================================================== */

/* ---- bloco 0 (vinha da linha 18 do index.html) ---- */
  /* ajustes específicos da VCV sobre o design system Propulsor */
  .vcv-kpi strong{font-variant-numeric:tabular-nums}
  .vcv-matrix{border-collapse:collapse;width:100%;font-variant-numeric:tabular-nums}
  .vcv-matrix th,.vcv-matrix td{border:1px solid var(--pui-border);padding:6px 10px;font-size:var(--ts-6);text-align:right}
  .vcv-matrix thead th{background:var(--pui-surface-muted);color:var(--pui-text-soft);font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.03em;white-space:nowrap}
  .vcv-matrix thead th:first-child,.vcv-matrix td.d{text-align:left;white-space:nowrap}
  .vcv-matrix tr.band td{background:var(--pui-surface-muted);font-weight:700;font-size:var(--ts-2);letter-spacing:.06em;text-transform:uppercase;color:var(--pui-text-soft)}
  .neg{color:var(--pui-danger)} .pos{color:var(--pui-success)}
  .vcv-flux{border-collapse:collapse;width:100%;font-size:var(--ts-5);font-variant-numeric:tabular-nums}
  .vcv-flux th,.vcv-flux td{border:1px solid var(--pui-border);padding:4px 8px;text-align:right;white-space:nowrap}
  .vcv-flux thead th{background:var(--pui-surface-muted);color:var(--pui-text-soft);position:sticky;top:0}
  .vcv-flux td.m{text-align:center;font-weight:600}
  .vcv-flux tfoot td{border-top:2px solid var(--pui-border-strong);font-weight:700;background:var(--pui-surface-muted)}
  /* fluxo de caixa HORIZONTAL (árvore de disciplinas) */
  .fluxo-tbl{border-collapse:separate;border-spacing:0;font-size:var(--ts-5);font-variant-numeric:tabular-nums;white-space:nowrap}
  .fluxo-tbl th,.fluxo-tbl td{padding:9px 13px;text-align:right;border-bottom:1px solid var(--pui-surface-muted)}
  .fluxo-tbl thead th{position:sticky;top:0;z-index:2;background:var(--pui-surface-muted);color:var(--pui-text-soft);font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.03em;font-weight:700}
  .fluxo-tbl .fx-lbl{text-align:left;position:sticky;left:0;z-index:1;background:var(--pui-surface);min-width:238px;border-right:1px solid var(--pui-border)}
  .fluxo-tbl thead .fx-lbl{z-index:3;background:var(--pui-surface-muted)}
  .fluxo-tbl .fx-tot{font-weight:600;color:var(--pui-text)}
  .fluxo-tbl .fx-neg{color:var(--pui-danger)}
  .fluxo-tbl tr.fx-forte>td{font-weight:700;background:var(--pui-surface-muted)}
  .fluxo-tbl tr.fx-forte>.fx-lbl{background:var(--pui-surface-muted)}
  .fluxo-tbl tr.fx-has{cursor:pointer}
  .fluxo-tbl tr.fx-has:hover>td{background:var(--ae-accent-soft)}
  .fluxo-tbl tr.fx-has:hover>.fx-lbl{background:var(--ae-accent-soft)}
  .fluxo-tbl .fx-caret{display:inline-block;width:15px;color:var(--pui-text-muted);font-size:var(--ts-1)}
  .fluxo-tbl .fx-l0>.fx-lbl{font-weight:700} .fluxo-tbl .fx-l1>.fx-lbl{font-weight:600}
  @media print{#fluxo-scroll{overflow:visible!important;max-height:none!important;border:none!important}.fluxo-tbl .fx-lbl{position:static}.fluxo-tbl thead th{position:static}}
  .fx-kpis{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-top:16px}
  .fx-kpis.fx-k4{grid-template-columns:repeat(4,1fr)}
  @media (max-width:1180px){.fx-kpis,.fx-kpis.fx-k4{grid-template-columns:repeat(3,1fr)}}
  @media (max-width:720px){.fx-kpis,.fx-kpis.fx-k4{grid-template-columns:repeat(2,1fr)}}
  .fx-kpi{background:var(--pui-surface-strong);border:1px solid var(--pui-border);border-radius:12px;padding:12px 14px}
  .fx-kpi .k-lab{font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.04em;color:var(--pui-text-muted);font-weight:700}
  .fx-kpi .k-val{font-size:var(--tn-2);font-weight:800;margin-top:3px;line-height:1.1}
  .fx-kpi .k-sub{font-size:var(--ts-3);color:var(--pui-text-soft);margin-top:3px;line-height:1.35}
  /* BLOCO 4 do plano de design: a tela do caixa responde "quanto preciso, quando, e quanto
     sobra" — esses quatro viram cartão-herói (branco, número grande, como o Resumo) e os
     outros seis continuam secundários. Antes "Exposição máxima" pesava igual a
     "Multiplicador" e nenhum número saltava. */
  .fx-kpis-hero{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin-top:16px}
  @media (max-width:1180px){.fx-kpis-hero{grid-template-columns:repeat(2,minmax(0,1fr))}}
  @media (max-width:560px){.fx-kpis-hero{grid-template-columns:1fr}}
  .fx-kpi.is-hero{background:var(--pui-surface);border:0;border-radius:18px;padding:16px 18px;
    box-shadow:0 1px 2px rgba(20,20,28,.04),0 10px 28px -16px rgba(20,20,28,.18)}
  .fx-kpi.is-hero .k-lab{font-size:var(--ts-3);color:var(--pui-text-soft)}
  .fx-kpi.is-hero .k-val{font-family:var(--ae-display);font-size:clamp(19px,2vw,25px);font-weight:800;white-space:nowrap;
    letter-spacing:-.02em;line-height:1.04;margin-top:6px;font-variant-numeric:tabular-nums}
  .fx-kpi.is-hero .k-sub{font-size:var(--ts-4);margin-top:6px}
  .sens-base-kpis{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px 22px;margin:0 0 16px;
    padding:12px 16px;background:var(--ae-accent-soft);border-radius:14px}
  .sens-base-kpis .sbk-tit{font-size:var(--ts-3);font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--ae-on-soft);margin-right:4px}
  .sens-base-kpis .sbk{display:flex;flex-direction:column;gap:1px}
  .sens-base-kpis .sbk span{font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.04em;color:var(--pui-text-soft);font-weight:700}
  .sens-base-kpis .sbk b{font-family:var(--ae-display);font-size:var(--tn-2);font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1}
  /* BLOCO 4 — piso de legibilidade: nenhum RÓTULO abaixo de 11px. Vale pro olho de seção,
     pros cabeçalhos da tabela de fluxo e pros rótulos dos cartões de indicador. */
  .fluxo-tbl th.fx-lbl,.fluxo-tbl th.fx-num,.fx-lbl,.fx-num{font-size:var(--ts-3)}
  /* ===== BLOCO 6 · item 10 — FLUXO DE CAIXA no celular =====
     A coluna do rotulo (sticky a esquerda) e fixada em min-width:238px. Num telefone
     isso e ~2/3 da largura util e sobrava uma tira pro dinheiro — que e o motivo da
     tabela existir. No celular ela cai pra 160px e o nome passa a QUEBRAR em duas
     linhas (a .fluxo-tbl e white-space:nowrap por padrao) em vez de empurrar a largura.
     O recuo por nivel da arvore e inline (padding-left) e continua valendo. */
  @media(max-width:599px){
    .fluxo-tbl .fx-lbl{width:160px;min-width:160px;max-width:160px;white-space:normal;overflow-wrap:break-word;line-height:1.3}
    .fluxo-tbl th,.fluxo-tbl td{padding:8px 9px}
    #fluxo-scroll{max-height:64vh}
  }
  .pui-kpi-card span,.pui-kpi-card small,.vcv-kpi small{font-size:var(--ts-3)}
  /* ===== BLOCO 5 do plano de design: fim do HTML cru =====
     (a) A regra que formata .ob-tbl vivia presa em [data-view-panel="obra"], mas a classe é
     usada também na TMA (3 tabelas) e na cascata do Societário — que por isso saíam CRUAS,
     com o cabeçalho padrão do navegador. Promovida pro app inteiro.
     (b) Havia 8 classes de campo (uma por tela), nenhuma com estilo de foco: quem desenhava
     o contorno ao clicar era o navegador, em azul. Agora todas usam o realce da marca. */
  .ob-tbl{width:100%;border-collapse:collapse;font-size:var(--ts-6)}
  .ob-tbl th{font-size:var(--ts-3);font-weight:700;text-transform:uppercase;letter-spacing:.03em;
    color:var(--pui-text-soft);text-align:right;padding:7px 10px;border-bottom:1px solid var(--pui-border)}
  .ob-tbl td{padding:7px 10px;border-bottom:1px solid var(--pui-surface-muted);text-align:right;color:var(--pui-text)}
  .ob-tbl th:first-child,.ob-tbl td:first-child{text-align:left}
  .ob-tbl tbody tr:last-child td{border-bottom:none}
  .ob-tbl tfoot td{border-top:1px solid var(--pui-border);border-bottom:none;font-weight:800}
  /* toda tabela larga rola dentro da própria caixa — a página nunca rola de lado */
  .vcv-scroll,.sc-tblwrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
  /* ===== BLOCO 6 · item 8 — MONTE CARLO no celular =====
     Os dois pares de cartoes do Monte Carlo usam auto-fit com minmax(340px): o trilho
     nunca encolhe abaixo de 340px, entao o cartao vazava pra fora da tela do telefone.
     Viram 1 coluna. E os SVGs (trajetorias com viewBox de 1100 de largura, histogramas
     e tornado com 520) espremidos em ~315px deixavam os rotulos com 3–6px: agora cada
     grafico ROLA dentro da propria caixa, no tamanho em que foi desenhado, com a pagina
     parada. */
  @media(max-width:599px){
    #app .pui-main [style*="minmax(340px"]{grid-template-columns:minmax(0,1fr) !important}
    #app #mc-spag,#app #mc-hist-vpl,#app #mc-hist-tir,#app #mc-tornado{overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%}
    #app #mc-spag svg{min-width:620px}
    #app #mc-hist-vpl svg,#app #mc-hist-tir svg,#app #mc-tornado svg{min-width:520px}
  }

  #app .ob-in,#app .dp-in,#app .im-in,#app .tm-in,#app .sc-in,#app .fn-in,
  #app .int-in,#app .dr-in,#app .mk-in{border-radius:10px}
  #app .ob-in:focus,#app .dp-in:focus,#app .im-in:focus,#app .tm-in:focus,#app .sc-in:focus,
  #app .fn-in:focus,#app .int-in:focus,#app .dr-in:focus,#app .mk-in:focus{outline:none;
    border-color:var(--ae-foco);box-shadow:0 0 0 3px var(--ae-accent-soft)}

  /* Cronograma: cabecalho das quatro colunas + divisoria entre eventos */
  .cr-head span{font-size:var(--ts-3);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--pui-text-muted)}
  .cr-head{border-bottom:1px solid var(--pui-border)}
  .cr-row{padding:9px 0;border-bottom:1px solid var(--pui-surface-muted)}
  .cr-row:last-child{border-bottom:none}
  /* ===== BLOCO 6 · item 8 — CRONOGRAMA no celular =====
     A linha do evento e uma grade de 4 colunas com 368px FIXOS (150+110+78 + 3 gaps).
     Dentro do cartao sobram ~315px num iPhone: o "1fr" do nome era espremido a ~71px
     e o nome do evento virava uma coluna de letras. No telefone a linha passa a 2x2 —
     nome + tipo em cima, "base + N meses" + data resultante embaixo — e o cabecalho de
     4 colunas (que tambem nao cabe) sai de cena. Complementa, sem repetir, a camada
     "BARRA DE FERRAMENTAS" mais abaixo. O Gantt ja rola sozinho (overflow-x + min-width
     760px no proprio SVG), entao nada a fazer la. */
  @media(max-width:599px){
    #app [data-view-panel="cronograma"] .cr-head{display:none !important}
    #app [data-view-panel="cronograma"] .cr-row{grid-template-columns:minmax(0,1fr) auto !important;gap:5px 10px !important;padding:11px 0}
    #app [data-view-panel="cronograma"] .cr-row>:nth-child(1){grid-area:1/1;min-width:0;line-height:1.3}
    #app [data-view-panel="cronograma"] .cr-row>:nth-child(4){grid-area:1/2;justify-self:end}
    #app [data-view-panel="cronograma"] .cr-row>:nth-child(2){grid-area:2/1;min-width:0}
    #app [data-view-panel="cronograma"] .cr-row>:nth-child(3){grid-area:2/2;justify-self:end}
  }
  /* BLOCO INTERNO unico: cartao dentro de cartao virava moldura dobrada (duas sombras no
     mesmo canto). Dentro de um cartao, o bloco se separa por FUNDO, nao por borda. */
  .pui-card .pui-card{box-shadow:none;border:0;background:var(--pui-surface-strong);border-radius:16px}
  .vcv-bloco{background:var(--pui-surface-strong);border-radius:14px;padding:11px 13px}
  /* carimbo de MODELO — mesma pílula na tela, no papel e no cartão */
  .modelo-pill{display:inline-flex;align-items:center;gap:5px;font-size:var(--ts-3);font-weight:800;
    letter-spacing:.06em;text-transform:uppercase;background:var(--ae-accent);color:var(--ae-accent-ink);
    border-radius:999px;padding:3px 10px;white-space:nowrap;vertical-align:middle}
  .modelo-pill::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ae-accent-ink);opacity:.55}
  .modelo-faixa{display:block;background:var(--ae-accent);color:var(--ae-accent-ink);
    font-size:var(--ts-5);font-weight:800;letter-spacing:.04em;padding:7px 14px;border-radius:10px;margin-bottom:12px}
  @media print{.modelo-pill,.modelo-faixa{-webkit-print-color-adjust:exact;print-color-adjust:exact}}
  /* ===== VITRINE — sala de dados (direção 2, escolhida pelo Bruno em 2026-07-30) =====
     A mesa do analista: uma linha por deal, colunas comparáveis, sobriedade como argumento.
     ⚠️ O estilo mora aqui (Design); a MARCAÇÃO nasce em acctVitrineOpen() no ade-app.js
     (Produto) — ver docs/specs/vitrine-sala-de-dados.md. Inerte até a marcação chegar.
     Tokens --pui-* apenas: a vitrine é superfície do APP e segue o tema (ao contrário do
     dossiê, que é papel). Nenhum hex cravado neste bloco — guarda em tools/tests. */
  .vit-head{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap;
    border-bottom:2px solid var(--pui-text);padding-bottom:12px}
  .vit-eyebrow{font-size:var(--ts-2);font-weight:800;letter-spacing:.16em;text-transform:uppercase;color:var(--pui-text-soft)}
  .vit-kpis{display:flex;gap:26px;text-align:right}
  .vit-kpis b{display:block;font-size:var(--tn-2);font-weight:800;letter-spacing:-.01em;white-space:nowrap}
  .vit-kpis span{font-size:var(--ts-1);letter-spacing:.08em;text-transform:uppercase;color:var(--pui-text-muted)}
  /* a tabela rola no PRÓPRIO container — lição medida na auditoria mobile de 30/07:
     tabela sem wrapper faz a página inteira panar de lado no celular */
  .vit-scroll{overflow-x:auto}
  .vit-tbl{width:100%;border-collapse:collapse;margin-top:6px;font-size:var(--ts-7)}
  .vit-tbl th{text-align:left;font-size:var(--ts-1);letter-spacing:.08em;text-transform:uppercase;
    color:var(--pui-text-muted);padding:10px 10px 6px;border-bottom:1.5px solid var(--pui-border-strong)}
  .vit-tbl td{padding:12px 10px;border-bottom:1px solid var(--pui-border);vertical-align:middle}
  .vit-tbl td.num,.vit-tbl th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
  .vit-nome b{font-weight:800}
  .vit-nome small{display:block;color:var(--pui-text-soft);font-size:var(--ts-4)}
  .vit-foot{display:flex;gap:30px;margin-top:18px;padding-top:14px;border-top:1px solid var(--pui-border);flex-wrap:wrap}
  .vit-foot b{display:block;font-size:var(--ts-10);font-weight:800}
  .vit-foot span{font-size:var(--ts-1);letter-spacing:.07em;text-transform:uppercase;color:var(--pui-text-muted)}
  .cap-ficha-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 20px}
  @media(max-width:1100px){.cap-ficha-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
  @media(max-width:620px){.cap-ficha-grid{grid-template-columns:1fr}}
  .fx-kpis-sec{margin-top:12px}
  .fx-kpis-sec .k-val{font-size:var(--tn-1);font-variant-numeric:tabular-nums}
  .fx-dlt{font-size:var(--ts-1);font-weight:700;line-height:1.2;margin-top:1px}
  .fx-dlt.fx-up{color:var(--pui-success)}.fx-dlt.fx-down{color:var(--pui-danger)}
  .fluxo-tbl td.fx-past,.fluxo-tbl th.fx-past{background:var(--pui-surface-muted)}
  .fluxo-tbl th.fx-past{background:#efe7d2}
  .fluxo-tbl td.fx-corte,.fluxo-tbl th.fx-corte{border-right:2px dashed var(--ae-corte)}
  .fx-chip{display:inline-block;margin-left:5px;padding:0 6px;border-radius:999px;background:var(--pui-info);color:var(--ae-on-primary);font-size:var(--ts-1);font-weight:700;text-transform:none;letter-spacing:0;vertical-align:1px}
  .fluxo-tbl tr.fx-noreal td.fx-past{opacity:.45}
  .vcv-scroll{max-height:420px;overflow:auto;border:1px solid var(--pui-border);border-radius:var(--pui-radius)}
  .vcv-chart svg{width:100%;height:auto}
  /* segmented: sempre numa linha só, com affordance de botão (hover/cursor/borda) */
  .pui-segmented{display:inline-flex;width:max-content;max-width:100%;flex-wrap:nowrap;overflow-x:auto;gap:4px}
  .pui-segmented button{padding:7px 18px;white-space:nowrap;cursor:pointer;font:inherit;font-size:var(--ts-7);font-weight:650;transition:background .12s ease,color .12s ease}
  .pui-segmented button:hover:not(.is-active){background:rgba(255,255,255,.7);color:var(--pui-text)}
  .pui-segmented button.is-active{border:1px solid var(--pui-border);color:var(--pui-primary)}
  /* contexto sob os KPIs (barra + legenda) */
  .kpi-ctx{margin-top:4px;width:100%}
  .kpi-ctx .trk{height:5px;border-radius:99px;background:var(--pui-surface-muted);overflow:hidden}
  .kpi-ctx .trk>div{height:100%;border-radius:99px;background:var(--ae-chart);transition:width .35s ease}
  .kpi-ctx em{display:block;font-style:normal;font-size:var(--ts-3);color:var(--pui-text-muted);margin-top:4px}
  .kpi-fc{display:none;font-style:normal;font-size:var(--ts-4);font-weight:700;color:var(--pui-primary);margin-top:3px}
  .kpi-alav{display:none;font-style:normal;font-size:var(--ts-4);font-weight:700;color:var(--pui-info);margin-top:2px}
  /* memorial de cálculo por indicador */
  .pui-kpi-card{position:relative}
  .kpi-info{position:absolute;top:10px;right:10px;width:24px;height:24px;border-radius:7px;border:1px solid var(--pui-border);background:var(--pui-surface);color:var(--pui-text-soft);font:italic 700 13px Georgia,serif;cursor:pointer;line-height:1;transition:all .12s}
  .kpi-info:hover{color:var(--pui-primary);border-color:var(--pui-primary);background:var(--pui-primary-soft)}
  .mm-formula{background:var(--pui-surface-muted);border:1px solid var(--pui-border);border-radius:9px;padding:11px 14px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--ts-8);margin-bottom:12px;overflow-x:auto;white-space:nowrap}
  .mm-row{display:flex;justify-content:space-between;gap:14px;padding:6px 2px;border-bottom:1px solid var(--pui-surface-muted);font-size:var(--ts-7)}
  .mm-row span{color:var(--pui-text-soft)} .mm-row b{font-variant-numeric:tabular-nums;white-space:nowrap}
  .mm-res{margin-top:10px;padding:10px 14px;border-radius:9px;background:var(--pui-primary-soft);display:flex;justify-content:space-between;font-size:var(--ts-9)}
  .mm-res b{color:var(--pui-primary);font-size:var(--ts-10)}
  /* metodologia: tabelas compactas sem scroll lateral */
  .mn-tbl{width:100%;border-collapse:collapse;font-size:var(--ts-5);table-layout:fixed}
  .mn-tbl th,.mn-tbl td{border:0;border-bottom:1px solid var(--pui-surface-muted);padding:8px 10px;text-align:right;vertical-align:middle}
  .mn-tbl thead th{border-bottom:1px solid var(--pui-border)}
  .mn-tbl tbody tr:last-child td{border-bottom:0}
  .mn-tbl th:first-child,.mn-tbl td:first-child{text-align:left;white-space:normal;overflow-wrap:break-word}
  .mn-tbl td:nth-child(2),.mn-tbl td:nth-child(3){white-space:nowrap;font-variant-numeric:tabular-nums}
  .mn-tbl thead th{background:var(--pui-surface-muted);font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.04em;color:var(--pui-text-soft);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .mn-tbl .mn-regua{display:block;font-size:var(--ts-1);color:var(--pui-text-muted);margin-top:1px}
  /* cadastro do estruturador (consulta CNPJ) */
  .me-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:10px}
  .me-cell{border:1px solid var(--pui-border);border-radius:9px;padding:9px 11px;min-width:0}
  .me-cell b{display:block;font-size:var(--ts-7);word-break:break-word}
  .me-cell span{font-size:var(--ts-1);text-transform:uppercase;letter-spacing:.05em;color:var(--pui-text-muted)}
  .me-spin{display:inline-block;width:13px;height:13px;border:2px solid rgba(255,255,255,.4);border-top-color:#fff;border-radius:50%;animation:mespin .7s linear infinite;vertical-align:-2px;margin-right:6px}
  @keyframes mespin{to{transform:rotate(360deg)}}
  .me-dyn table{border-collapse:collapse;width:100%;font-size:var(--ts-5);margin:4px 0 10px}
  .me-dyn th,.me-dyn td{border:1px solid var(--pui-border);padding:4px 8px;text-align:left;vertical-align:top;word-break:break-word}
  .me-dyn th{background:var(--pui-surface-muted);font-size:var(--ts-2);text-transform:uppercase;letter-spacing:.03em;color:var(--pui-text-soft)}
  .me-dyn .me-k{color:var(--pui-text-soft);width:38%}
  .me-dyn details{margin:4px 0;border:1px solid var(--pui-border);border-radius:8px;padding:6px 10px}
  .me-dyn summary{cursor:pointer;font-size:var(--ts-5);font-weight:650}
  .me-chip{display:inline-block;background:var(--pui-surface-muted);border-radius:99px;padding:2px 9px;font-size:var(--ts-4);margin:2px 3px 2px 0}
  .me-lbl{display:flex;flex-direction:column;gap:3px;font-size:var(--ts-3);color:var(--pui-text-soft)}
  /* ⚠️ O TÍTULO DO RÓTULO É UM FILHO SÓ. O .me-lbl acima é flex-column, então CADA filho vira
     uma linha — e um <b> solto no meio do título o parte em três. Medido em 22/08: "Cap de saída
     (± pontos)" saía em 3 linhas, com o ")" sozinho na terceira; eram 6 rótulos assim. Título com
     qualquer tag inline (<b>, <em>) vai DENTRO de .me-lbl-t. */
  .me-lbl-t{display:block}
  .me-lbl input{padding:8px 10px;border:1px solid var(--pui-border);border-radius:8px;font:inherit;font-size:var(--ts-8)}
  .estr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(235px,1fr));gap:12px}
  .estr-cardi{cursor:pointer;transition:box-shadow .15s,transform .05s;padding:14px 16px}
  .estr-cardi:hover{box-shadow:var(--pui-shadow-md);transform:translateY(-1px)}
  .estr-cardi.is-ativo{border-color:var(--ae-chart-dark);background:var(--ae-accent-soft);box-shadow:0 0 0 3px var(--ae-accent-soft)}
  .estr-add{border:1.5px dashed var(--pui-border-strong);border-radius:14px;background:none;cursor:pointer;font:inherit;font-size:var(--ts-7);font-weight:650;color:var(--pui-text-soft);min-height:110px;transition:all .12s}
  .estr-add:hover{color:var(--pui-primary);border-color:var(--pui-primary);background:var(--pui-primary-soft)}
  /* Monte Carlo — dual slider do filtro pós-hoc */
  /* Monte Carlo — feedback do botão "Rodar simulação": espera, bloqueio e erro */
  @keyframes mc-spin{to{transform:rotate(360deg)}}
  .mc-spin{width:13px;height:13px;flex:0 0 13px;box-sizing:border-box;border-radius:50%;border:2px solid currentColor;border-top-color:transparent;opacity:.85;animation:mc-spin .7s linear infinite;display:inline-block;vertical-align:-2px;margin-right:7px}
  @media (prefers-reduced-motion:reduce){.mc-spin{animation-duration:2.4s}}
  #mc-aviso{display:none;gap:12px;align-items:center;flex-wrap:wrap;padding:13px 15px;border-radius:16px;margin-bottom:14px;font-size:var(--ts-6);line-height:1.5}
  #mc-aviso .mc-av-txt{flex:1 1 240px;min-width:0}
  #mc-aviso.is-bloqueio{background:var(--ae-accent-soft);border:1px solid var(--ae-chart-dark);color:var(--ae-on-soft)}
  #mc-aviso.is-rodando{background:var(--pui-surface-strong);border:1px solid var(--pui-border-strong);color:var(--pui-text)}
  #mc-aviso.is-erro{background:var(--pui-surface-strong);border:1px solid var(--pui-danger);color:var(--pui-danger)}
  .mcf{position:relative;height:26px}
  .mcf .trk{position:absolute;top:11px;left:0;right:0;height:4px;border-radius:99px;background:var(--pui-surface-muted)}
  .mcf .sel{position:absolute;top:11px;height:4px;border-radius:99px;background:var(--pui-primary)}
  .mcf input[type=range]{position:absolute;left:0;right:0;top:5px;width:100%;margin:0;background:none;pointer-events:none;-webkit-appearance:none;appearance:none;height:16px}
  .mcf input[type=range]::-webkit-slider-thumb{pointer-events:auto;-webkit-appearance:none;appearance:none;width:15px;height:15px;border-radius:50%;background:var(--pui-primary);border:2.5px solid #fff;box-shadow:0 0 0 1px rgba(26,24,20,.25);cursor:pointer}
  .mcf input[type=range]::-moz-range-thumb{pointer-events:auto;width:12px;height:12px;border-radius:50%;background:var(--pui-primary);border:2.5px solid #fff;box-shadow:0 0 0 1px rgba(26,24,20,.25);cursor:pointer}
  .pui-view{display:none} .pui-view.is-active{display:block}
  /* login (mock) */
  .vcv-login{position:fixed;inset:0;display:grid;place-items:center;background:var(--pui-bg);z-index:50;padding:20px}
  .vcv-login .box{width:100%;max-width:404px;background:var(--pui-surface);border:1px solid var(--pui-border);border-radius:20px;box-shadow:0 1px 2px rgba(20,20,28,.04),0 16px 44px -20px rgba(20,20,28,.20);padding:38px 34px 32px}
  .vcv-login .logo{width:60px;height:60px;border-radius:16px;margin-bottom:4px;background:var(--pui-primary);color:var(--ae-on-primary);display:grid;place-items:center;font-weight:800;font-size:var(--tn-2);margin-bottom:14px}
  .vcv-login h1{font-size:var(--tn-3);margin:0 0 3px} .vcv-login .lead{color:var(--pui-text-soft);font-size:var(--ts-7);margin:0 0 22px}
  /* o h1 do login virou a MARCA: sem tamanho de fonte (não há texto dentro), largura fixa
     em px porque o lockup é arte, não tipografia — e altura automática, para a proporção
     5,9:1 do arquivo mandar. `--ae-ink` faz a inversão do tema sozinha. */
  .vcv-login h1.ae-lockup{width:216px;margin:0 0 14px;color:var(--ae-ink);font-size:0;line-height:0}
  .vcv-login h1.ae-lockup svg{display:block;width:100%;height:auto}
  .vcv-login .pui-field{margin-bottom:13px} .vcv-login .full{width:100%;justify-content:center;margin-top:6px}
  .vcv-login .alt{text-align:center;font-size:var(--ts-6);color:var(--pui-text-soft);margin-top:14px}
  /* Links da área de acesso: --pui-primary virou preto (=texto), então link precisa de sublinhado da marca pra existir. */
  #login a,#modalForgot a,#modalReset a{color:var(--ae-ink);font-weight:700;text-decoration:underline;text-decoration-color:var(--ae-chart-dark);text-decoration-thickness:2px;text-underline-offset:3px;border-radius:5px;padding:0 2px;transition:background .15s ease,text-decoration-color .15s ease}
  #login a:hover,#modalForgot a:hover,#modalReset a:hover{background:var(--ae-accent-soft);text-decoration-color:var(--ae-ink)}
  /* o realce amarelo suave sozinho dava 1,10 — ele PINTA a área, não MARCA a borda. Fica como
     reforço; quem diz "é aqui que o teclado está" é o anel. */
  #login a:focus-visible,#modalForgot a:focus-visible,#modalReset a:focus-visible{outline:2px solid var(--ae-foco);outline-offset:2px;background:var(--ae-accent-soft)}
  .vcv-login .mock{font-size:var(--ts-3);color:var(--pui-text-muted);text-align:center;margin-top:16px;border-top:1px solid var(--pui-border);padding-top:12px}
  .vcv-ver-label{color:var(--pui-text-muted);font-size:var(--ts-5);white-space:nowrap}
  /* pipeline de projetos */
  .vcv-pipeline{min-height:100vh;background:var(--pui-bg)}
  .pipe-top{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:13px 26px;background:var(--pui-surface-strong);border-bottom:1px solid var(--pui-border);position:sticky;top:0;z-index:10}
  .pipe-top .brand{display:flex;align-items:center;gap:10px;font-weight:700}
  .pipe-top .brand .logo{width:32px;height:32px;border-radius:8px;background:var(--pui-primary);color:var(--ae-on-primary);display:grid;place-items:center;font-weight:800}
  /* Menu da conta (avatar → dropdown): tira os botões utilitários da barra pra ela não quebrar linha */
  .pui-usermenu{position:relative}
  .pui-usermenu>.pui-avatar{border:0;padding:0}
  .pui-menu{position:absolute;top:calc(100% + 10px);right:0;min-width:242px;background:var(--pui-surface-strong);border:1px solid var(--pui-border);border-radius:14px;box-shadow:0 16px 40px rgba(20,18,14,.18);padding:6px;z-index:60;display:flex;flex-direction:column;gap:2px}
  .pui-menu[hidden]{display:none}
  .pui-menu-id[hidden],.pui-menu-item[hidden],.pui-menu-sep[hidden]{display:none}
  /* #app é display:grid (.pui-app) e isso vencia o atributo [hidden] → o app de
     viabilidade renderizava ABAIXO do portfólio e aparecia ao rolar. Força esconder. */
  #app[hidden]{display:none !important}
  /* Projeto vazio: o Resumo mostra só o cabeçalho + o banner (nenhum número herdado do seed).
     O card do DNA fica visível MESMO vazio — o DNA vem antes dos números. */
  /* no Resumo vazio só sobrevivem o cabeçalho, o guia de primeiro uso, o aviso de
     "nada calculado" e o cartão do DNA — o resto seria KPI sem número. */
  [data-view-panel="resumo"].rv-vazio>:not(.pui-page-head):not(#pu-guia):not(#resumo-vazio):not(#res-dna-card){display:none !important}
  /* BLOCO 6 - estado vazio com SAIDA. Mesmo principio do Resumo: sem o dado que
     alimenta a tela, os cartoes vazios somem e sobra UM bloco dizendo o que falta. */
  [data-view-panel="fluxo"].fx-vazio>:not(.pui-page-head):not(#fluxo-kpis){display:none !important}
  .pui-empty>span{max-width:560px;font-size:var(--ts-6);line-height:1.55}
  .pui-empty .pui-button{margin-top:14px}
  /* Acao impossivel tem que PARECER impossivel. */
  .pui-button:disabled,.pui-button[disabled]{opacity:.42;box-shadow:none;transform:none}
  .pui-button:disabled:hover,.pui-button[disabled]:hover{opacity:.42;transform:none}
  /* "Carregando..." em texto cru fazia a tela pular quando o dado chegava:
     o placeholder agora tem ALTURA e ocupa o espaco do conteudo final. */
  .pui-load{display:grid;place-items:center;align-content:center;gap:12px;min-height:220px;padding:24px;text-align:center;font-size:var(--ts-6);color:var(--pui-text-soft);background:var(--pui-surface-strong);border:1px dashed var(--pui-border);border-radius:16px}
  .pui-load::before{content:"";width:26px;height:26px;border-radius:50%;border:2.5px solid var(--pui-border-strong);border-top-color:var(--ae-chart-dark);animation:pui-load-spin .85s linear infinite}
  @keyframes pui-load-spin{to{transform:rotate(360deg)}}
  @media (prefers-reduced-motion:reduce){.pui-load::before{animation:none}}
  /* Módulo 00 · DNA do produto (Diagnóstico de Vocação) */
  .dna-q{display:block;margin-bottom:12px}
  .dna-q>span{display:flex;justify-content:space-between;gap:8px;align-items:baseline;font-size:var(--ts-3);font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--pui-text-soft);margin-bottom:5px}
  .dna-q>span small{font-weight:500;text-transform:none;letter-spacing:0;color:var(--pui-text-muted);text-align:right}
  .dna-q textarea{width:100%;box-sizing:border-box;resize:vertical;padding:9px 11px;font:inherit;font-size:var(--ts-8);line-height:1.45;color:var(--pui-text);background:var(--ae-field);border:1px solid var(--pui-border);border-radius:var(--pui-radius-sm);outline:none;transition:border-color 160ms ease}
  .dna-q textarea:focus{border-color:var(--pui-border-strong)}
  .dna-q.dna-falta textarea{border-color:var(--pui-danger)}
  .dna-guard{border:1px dashed var(--pui-border-strong);border-radius:var(--pui-radius-sm);background:var(--pui-surface-muted);padding:12px 14px;font-size:var(--ts-6);line-height:1.55;color:var(--pui-text-soft);margin-top:4px}
  .dna-hist-item{display:flex;gap:10px;align-items:baseline;font-size:var(--ts-6);color:var(--pui-text-soft);padding:7px 0;border-top:1px solid var(--pui-border)}
  .dna-hist-item b{white-space:nowrap;color:var(--pui-text)}
  #dna-badge.is-def,#res-dna-badge.is-def{background:rgba(31,138,84,.14);color:var(--pui-success,var(--pui-success))}
  /* Acesso antecipado: selo discreto e clicável (abre o convite ao feedback).
     Enquadramento deliberado — "acesso antecipado", não "beta/em obras": a
     precisão dos números NÃO é provisória; o que evolui é o produto em volta. */
  .ae-early{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--pui-border-strong);background:var(--pui-surface-muted);color:var(--pui-text-soft);border-radius:999px;padding:3px 10px;font-size:var(--ts-3);font-weight:700;letter-spacing:.03em;cursor:pointer;font-family:inherit;white-space:nowrap;transition:border-color .12s,color .12s}
  .ae-early:hover{border-color:var(--pui-primary);color:var(--pui-primary)}
  .ae-early::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--ae-chart,#fbd545);flex:0 0 auto}
  @media(max-width:599px){.ae-early{display:none}}
  /* Estado do salvamento no servidor (auditoria #7): "Salvando… / Salvo às… / Falha" */
  #save-status{font-size:var(--ts-5);color:var(--pui-text-soft);white-space:nowrap;padding:6px 10px;border-radius:8px;background:var(--pui-surface-muted)}
  #save-status.is-err{color:var(--ae-on-primary);background:var(--pui-danger);cursor:pointer;font-weight:600}
  /* VIEWER somente leitura (auditoria #8): campos inertes DE VERDADE + ações de escrita somem.
     Vale pro app e pros overlays (config do workspace, aproximações, planos etc.). */
  body.is-viewer #app input:not([type=search]),body.is-viewer #app select,body.is-viewer #app textarea,
  body.is-viewer .vcv-overlay input,body.is-viewer .vcv-overlay select,body.is-viewer .vcv-overlay textarea{
    pointer-events:none;background:var(--pui-surface-muted) !important;color:var(--pui-text-soft)}
  body.is-viewer #btn-salvar-versao,body.is-viewer #btn-novo-projeto,body.is-viewer #btn-reset-demo,
  body.is-viewer .proj-card .pui-icon-button,body.is-viewer [data-mcsave],body.is-viewer #rv-sugeridas,
  body.is-viewer #rv-modelo,body.is-viewer #apx-add,body.is-viewer [data-apx-del],body.is-viewer #sc-add,
  body.is-viewer #o-add-fase,body.is-viewer #btn-nova-linha,body.is-viewer #cr-salvar,body.is-viewer #pe-excluir,
  body.is-viewer #pe-salvar,body.is-viewer #np-criar,body.is-viewer #ws-logo-btn,body.is-viewer #dna-definir{display:none !important}
  /* ===== IMPRESSÃO (PDF): qualquer view ATIVA do app imprime como documento. =====
     Entradas: "Exportar" (Resumo) e "Imprimir dossiê" (Captação) — mas vale pra
     qualquer tela via Ctrl/Cmd+P. Princípios: só o conteúdo (zero chrome de app),
     cards viram blocos com borda fina que não quebram no meio, tabelas abrem por
     inteiro (nada de scroll interno em papel), cores/barras preservadas. */
  @media print{
    @page{size:A4;margin:12mm}
    /* PAPEL É BRANCO. Quem estiver no modo escuro imprime na paleta CLARA — senão o
       estruturador gasta um cartucho por página e o banco recebe um documento cinza.
       Reposta aqui porque este bloco vem ANTES do bloco do tema escuro no arquivo, e
       @media print não vence [data-tema] por si só: quem repõe é o !important. */
    html[data-tema="escuro"]{
      --pui-bg:#eeedf1 !important; --pui-surface:#ffffff !important;
      --pui-surface-strong:#f7f7f9 !important; --pui-surface-muted:#eaeaee !important;
      --pui-text:#1f1f23 !important; --pui-text-soft:#3f424a !important; --pui-text-muted:#55585f !important;
      --pui-border:#e7e7eb !important; --pui-border-strong:#dadae0 !important;
      --pui-primary:#1e1e22 !important; --pui-primary-strong:#000000 !important; --pui-primary-soft:#ededf1 !important;
      --pui-success:#085c3a !important; --pui-success-soft:#e7f6ee !important;
      --pui-danger:#a52734 !important;  --pui-danger-soft:#fbe6e9 !important;
      --pui-warning:#714b07 !important; --pui-warning-soft:#fbf0d2 !important;
      --pui-info:#3a5fd9 !important;    --pui-info-soft:#e7ecfb !important;
      --ae-field:#ffffff !important; --ae-ink:#1e1e22 !important; --ae-accent-soft:#fef4ce !important;
      color-scheme:light !important;
    }
    html[data-tema="escuro"] .leaflet-tile{filter:none !important}
    html,body{background:#fff !important}
    /* chrome do app fora do papel */
    .pui-sidebar,.pui-topbar,.pipe-top,#pend-panel,#save-status,.ae-early,
    .kpi-info,.vcv-overlay,.pui-menu,#support-bar,.vcv-side-back,
    #app .pui-button,#app .pui-icon-button,#app .pui-select,#app select,
    .pui-segmented,details.vcv-info{display:none !important}
    body{padding-top:0 !important}
    #app.pui-app{display:block !important;height:auto !important;overflow:visible !important}
    #app .pui-main{padding:0 !important;overflow:visible !important;height:auto !important}
    /* papel branco de documento (o fundo creme do app fica na tela) */
    #app.pui-app,#app .pui-main,.pui-view{background:#fff !important}
    /* o seletor some no print, o rótulo "Status" não pode ficar órfão */
    #app .pui-page-head label{display:none !important}
    .pui-view{display:none !important}
    .pui-view.is-active{display:block !important}
    /* cabeçalho do documento (só existe no papel) */
    #print-head{display:block !important;border-bottom:2px solid #1f1f23;padding:0 0 10px;margin:0 0 16px}
    #print-head .ph-marca{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#65686f;display:flex;align-items:center;gap:6px}
    /* A MARCA NO PAPEL — tinta de papel, nunca o amarelo. É a regra 10 do pacote e a mesma
       lição que o dossiê já tinha aprendido duas vezes: o amarelo ILUMINA, não escreve.
       #1f1f23 é o mesmo valor que o dossiê chama de --dk e que a régua deste cabeçalho já
       usa na borda de baixo — a marca entra na tinta que a folha já tinha. */
    #print-head .ph-marca .ade-marca{width:14px;height:14px;flex:0 0 auto;color:#1f1f23}
    #print-head .ph-proj{font-size:20px;font-weight:700;font-family:var(--ae-display,Georgia,serif);margin:2px 0}
    #print-head .ph-meta{font-size:11px;color:#65686f}
    /* cards = blocos de documento */
    .pui-card{box-shadow:none !important;border:1px solid #d8d2c6 !important;break-inside:avoid;page-break-inside:avoid}
    /* KPIs em 2 colunas no A4: 4 na linha corta o último card na borda */
    .pui-kpi-grid,.vcv-grid-4{grid-template-columns:repeat(2,1fr) !important}
    .pui-kit-grid,.vcv-grid-2{grid-template-columns:1fr 1fr !important}
    /* linguagem de tela fica na tela (chips clicáveis, "clique p/ montar…",
       o toggle "ativar" e os "?" de tooltip) */
    #fn-cat,[data-view-panel="funding"] .pui-card-head span,
    [data-fnon],label:has([data-fnon]),.pui-help{display:none !important}
    /* tabelas abrem por inteiro no papel (sem scroll interno) */
    .vcv-scroll,.pui-table-wrap,#app .pui-main [style*="overflow"]{overflow:visible !important;max-height:none !important}
    #app .pui-main table{min-width:0 !important;width:100% !important;font-size:9.5px}
    #app .pui-main th,#app .pui-main td{padding:4px 6px !important}
    tr{break-inside:avoid}
    /* cores e barras existem no papel (senão os gráficos saem brancos) */
    *{-webkit-print-color-adjust:exact !important;print-color-adjust:exact !important}
    svg,.vcv-chart{max-width:100% !important}
    a{text-decoration:none;color:inherit}
  }
  #print-head{display:none}
  /* ===== DOSSIÊ DE CAPTAÇÃO — documento de investimento (só existe no papel).
     Não é a tela impressa: é um documento editorial montado na hora do PDF,
     na régua de um business plan (capa → produto → vocação → números →
     estrutura & convite → quem estrutura + disclaimer). ===== */
  #dossie-doc{display:none}
  @media print{
    body.print-dossie #app,body.print-dossie #pipeline,body.print-dossie #adminScreen,body.print-dossie #print-head{display:none !important}
    body.print-dossie #dossie-doc{display:block !important}
    body.print-dossie,body.print-dossie html{background:#fff !important}
  }
  /* ===== A IDENTIDADE DO DOSSIÊ SAIU DO @media print (30/07, modo apresentação) =====
     Regra sem media aplica em TODAS as mídias: na impressão o resultado é IDÊNTICO
     (provado por PDF antes/depois, 11 folhas iguais) e na tela continua inerte, porque
     #dossie-doc é display:none fora dos dois modos. O que isso destrava: o modo
     APRESENTAÇÃO (body.apresenta, bloco ao fim desta seção) veste o MESMO CSS do papel
     — uma identidade, duas rendições. Só @page e as chaves body.print-dossie ficam
     no print de verdade. */
    #dossie-doc .dd-page{background:#fff}
    /* v3 no PAPEL: neutros frios + acento em dois níveis — o amarelo de marca é ilegível como TEXTO
       impresso, então --da (texto/eyebrow) é o âmbar escuro e --dab (régua/barra) é o amarelo. */
    /* ESCALA DO PAPEL (design, 2026-07-29). O documento tinha 16 tamanhos de fonte
       (8,5 · 9 · 9,5 · 10 · 10,5 · 11 · 12 · 12,5 · 13 · 15 · 19 · 20 · 26 · 30 · 34 · 44)
       e 17 valores de espaçamento — assinatura de papel afinado ponto a ponto, que é por
       que ele nunca pareceu tipografado.
       DUAS escalas, de propósito: num documento financeiro, NÚMERO não é texto grande —
       é outra categoria de informação, e ganha régua própria.
       ⚠️ --t3 (12px) é o CORPO e NÃO se mexe: a régua de 850 chars/seção foi calibrada
       nele (40692a7) e as medições estão travadas como fixture em dossie-narrativa-cabe.
       ⚠️ --t4 (13px) é o h3 e também não sobe: o h3 entra no "cromo fixo" de 84,8 mm do
       mesmo modelo. h3 maior faria aquele guarda prever MENOS do que a folha gasta — que
       é exatamente o conforto falso que ele nasceu para matar. Ganha peso, não tamanho. */
    #dossie-doc{--dk:#1f1f23;--ds:#65686f;--da:#8a5a0f;--dab:#fbd545;--dl:#e7e7eb;--dc:#f7f7f9;
      --dpos:#085c3a;--dneg:#a52734;
      --t1:9.5px;--t2:11px;--t3:12px;--t4:13px;--t5:15px;--t6:22px;--t7:40px;
      --n1:20px;--n2:30px;--n3:34px;
      color:var(--dk);font-size:var(--t3);line-height:1.5}
    /* PAGINAÇÃO POR CONTEÚDO, não uma folha por seção. Medido em 2026-07-26: com
       quebra forçada, 5 das 7 folhas ficavam mais da METADE vazias (a última, 73%)
       enquanto a dos números estourava. Agora cada seção fica inteira (break-inside)
       e as curtas dividem folha — documento denso, que é o que vai pro banco. */
    /* 28/07: `break-inside:avoid` na SEÇÃO foi longe demais. Ele só deixa duas seções
       dividirem folha quando cabem juntas — e, medido na demonstração, os pares davam
       104%, 111%, 116%. Resultado: seis seções entre 38% e 54% de tinta, cada uma com a
       folha inteira reservada. Deixando a seção FLUIR, o branco só sobra no fim do
       documento; o que não pode partir (tabela, KPI, gráfico) já se protege sozinho na
       regra abaixo, e o título nunca fica órfão por causa do `break-after:avoid`. */
    #dossie-doc .dd-page{break-inside:auto;padding:2mm 0;margin-bottom:9mm}
    #dossie-doc .dd-head,#dossie-doc h2,#dossie-doc h3,#dossie-doc .dd-secn{break-after:avoid}
    #dossie-doc .dd-capa{break-after:page;margin-bottom:0}
    /* "Os números" abria folha à força (`.dd-num{break-before:page}`, 26/07). Enquanto
       TODA seção abria folha, isso era grátis. Depois que o documento passou a fluir,
       virou a única folha com pouca tinta: a anterior parava em 45% esperando a quebra.
       Medido em PDF: 9 folhas com a quebra, 8 sem. O Bruno reabriu a decisão em 28/07 e
       escolheu as 8 — o capítulo continua inconfundível pela barra de cabeçalho, pelo
       eyebrow e pelo H2, que é como um memorando marca capítulo. A regra saiu inteira em
       vez de virar regra inerte: `break-inside:auto` já vem de `.dd-page`.
       A capa segue sendo a ÚNICA quebra de folha forçada do documento. */
    #dossie-doc .dd-kpis,#dossie-doc .dd-chart{break-inside:avoid}
    /* ===== TABELA LONGA PODE PARTIR (29/07, decisão do Bruno vendo o Fonseca Neto) =====
       `table` saiu da lista acima. Motivo, medido no documento REAL dele: a tabela de fluxo
       tem QUINZE linhas (2025→2039). Protegida, ela não cabia na metade de folha que sobrava
       e pulava inteira — deixando "Os números" com os KPIs, a composição de custos e depois
       METADE DA FOLHA VAZIA. Foi o preço que apareceu quando o piso entrou.
       Simulei o caso dele na demonstração (alonguei o fluxo para 15 linhas): protegida dá
       **11 folhas**, com uma de 505 caracteres; podendo partir dá **10**, e aquela folha vai
       para 1.215. Recupera exatamente a folha que o piso tinha custado.
       ⚠️ `auto` NÃO força quebra: tabela que cabe continua inteira. Só parte quem não cabe —
       e num documento financeiro uma tabela de quinze anos atravessando folhas com o
       cabeçalho repetido é o NORMAL, não o defeito. É o que o leitor espera.
       As quatro linhas abaixo é que tornam a quebra legível, e nenhuma é opcional: */
    /* a matriz de sensibilidade e a decomposição da nota são BLOCO DE LEITURA, não lista —
       partir uma matriz 5×5 é destruí-la */
    #dossie-doc .dd-sens,#dossie-doc .dd-bank{break-inside:avoid}
    /* linha nunca parte no meio */
    #dossie-doc tr{break-inside:avoid}
    /* o cabeçalho SE REPETE na folha seguinte — sem isso a continuação vira números sem
       nome de coluna. Conferido no PDF: a folha seguinte abre com ANO/RECEITA/CUSTOS/... */
    #dossie-doc thead{display:table-header-group}
    /* ...e o rodapé NÃO se repete: `table-footer-group` imprimiria "Total" no pé de TODA
       folha da tabela, e um total parcial lido como total é erro grave num dossiê. */
    #dossie-doc tfoot{display:table-row-group}
    /* 29/07 — AS UNIDADES DE SENTIDO (o Bruno viu o sintoma: "quebrou o mesmo assunto de
       maneira que não devia"). A regra acima protege os objetos DUROS. O que partia eram
       os blocos que carregam UM assunto, e ninguém os tinha marcado como unidade.
       Medido no dossiê da demonstração, com as regras do @media print numa caixa de
       186×273mm (calibragem: 2.170mm ÷ 273 = 7,95 → 8 folhas de conteúdo, que é a
       medição em PDF real de 28/07):
         · o bloco preto do CONVITE (60mm) — o pedido de capital — rachava entre as
           folhas 7 e 8, com o fundo preto partido na dobra;
         · o .dd-big das credenciais rachava entre 8 e 9;
         · "Como o projeto se financia" abria com 19mm de folha (93% já usada): entravam
           cabeçalho, eyebrow e H2, e os 201mm do capítulo caíam na folha seguinte.
       CUSTO MEDIDO DE PROTEGER TUDO ISTO: **zero folha** — 9 antes, 9 depois. E "Quem
       estrutura" passou a abrir com 265mm de folha em vez de 40.
       As GRADES entram porque são o primeiro bloco de um capítulo, e é por elas que o
       capítulo "vaza" para a folha anterior. Medidas as quatro do documento: 30, 137,
       112 e 201mm — todas menores que a folha útil, então o avoid nunca é descartado.
       ⚠️ Bloco MAIOR que a folha faz o navegador ignorar a regra: se um dia uma grade
       passar de 273mm, ela volta a partir e nenhum teste percebe. É o limite conhecido. */
    #dossie-doc .dd-convite,#dossie-doc .dd-big,#dossie-doc .dd-bank,
    #dossie-doc .dd-leitura,#dossie-doc .dd-conc,#dossie-doc .dd-comp,
    #dossie-doc .dd-obs,#dossie-doc .dd-sint,#dossie-doc .dd-disc{break-inside:avoid}
    /* ⚠️ AS GRADES SAÍRAM DESTA LISTA no fim do mesmo dia (29/07), por decisão do Bruno
       vendo o papel: "deixa a grade partir também".
       Elas tinham entrado de manhã com o motivo escrito acima — "é por elas que o capítulo
       vaza para a folha anterior". Esse motivo MORREU quando o piso entrou: agora quem
       impede o capítulo de começar apertado é o `--dd-piso`, e ele faz isso melhor, porque
       age no capítulo inteiro em vez de num bloco dele.
       E proteger a grade tinha um custo que só a impressão do Bruno revelou: quando ela
       não cabia, ela PULAVA a folha e deixava a abertura do capítulo órfã atrás — título,
       um parágrafo, e 55% de papel vazio. Foi a folha mais feia do documento inteiro, e
       ela nasceu da minha correção da manhã. Meia correção devolve o defeito noutro lugar.
       MEDIDO antes de tirar: com o piso em 130mm o resultado é IDÊNTICO com ou sem a
       proteção (10 folhas, mesma tinta folha a folha) — hoje a regra nunca dispara. Para
       ver o que ela faz quando dispara, baixei o piso a 40mm de propósito: a folha 3 foi
       de 682 para 1.095 caracteres de tinta, e a grade partida ficou CORRETA — a coluna da
       esquerda para onde a folha acaba, a lista da direita fecha inteira, e a continuação
       retoma limpa na folha seguinte. Conferido no PDF, não no raciocínio.
       Regra inerte não fica: este projeto já tirou a `.dd-num` pelo mesmo motivo. */
    #dossie-doc .dd-page:last-child{margin-bottom:0}
    /* ===== O PISO DE ABERTURA DE CAPÍTULO (2026-07-29) =====
       O Bruno, com o dossiê impresso na mão: "as divisões dos temas ainda estão se
       misturando nas páginas". Medido no PDF real: de 8 capítulos, **5 começavam no meio
       de uma folha já ocupada**, e um deles abria no rodapé com só o título e um parágrafo.
       É o preço — não medido na época — da decisão de 28/07 que tirou a quebra por seção
       para transformar 9 folhas em 8.

       O que este bloco faz: reserva `--dd-piso` de altura INDIVISÍVEL no topo de todo
       capítulo e devolve o espaço por margem negativa. Se não couber o piso na folha
       corrente, o navegador empurra o pseudo-elemento — e o capítulo inteiro vai junto,
       porque ele é o primeiro filho. Visualmente nada muda: a margem negativa cancela a
       altura reservada.

       Por que 130mm: medido em PDF real, o resultado é o MESMO em qualquer valor entre
       120 e 180mm (10 folhas, 5 de 8 capítulos abrindo limpo, zero folha magra). Abaixo
       de 90mm o ganho some; em 210mm ele colapsa no "todo capítulo abre folha", que custa
       2 folhas. 130 fica no meio do platô, longe das duas bordas.

       ⚠️ CUSTO HONESTO, e ele encosta na decisão de 28/07: isto empurra branco para o pé
       de algumas folhas. A diferença é que a CONTAGEM DE FOLHAS NÃO SOBE — medido: 10
       antes, 10 depois. O branco é redistribuído, não acrescentado, e passa a ficar no fim
       de um capítulo (onde lê como respiro) em vez de no meio (onde lê como confusão). */
    #dossie-doc{--dd-piso:130mm}
    #dossie-doc .dd-page::before{content:"";display:block;height:var(--dd-piso);
      margin-bottom:calc(var(--dd-piso) * -1);break-inside:avoid}
    /* a capa já força quebra depois de si; reservar piso nela não faz nada e só
       atrapalharia se um dia a capa deixasse de quebrar */
    #dossie-doc .dd-capa::before{content:none}

    /* ===== AS PARTES — o nível acima do capítulo (2026-07-29) =====
       Escolha do Bruno entre cinco montagens comparadas em PDF real. As quatro partes são
       as quatro perguntas que o investidor faz, na ordem: o negócio · os números · o
       capital · quem estrutura. Com elas, dois capítulos dividindo uma folha passa a ser
       HIERARQUIA e não acidente — que era a queixa original.
       ⚠️ O estilo mora aqui (Design); a MARCAÇÃO `.dd-parte` é montada no `montarDossie()`
       do `ade-app.js`, que é da sessão de Produto — ver docs/specs/dossie-partes.md.
       Enquanto ela não chega, estas regras ficam inertes e não afetam nada. */
    #dossie-doc .dd-parte{break-before:page;break-after:avoid;margin:0 0 8mm;
      padding-bottom:4mm;border-bottom:3px solid var(--dk)}
    #dossie-doc .dd-parte .pt-n{font-size:var(--t1);font-weight:800;letter-spacing:.22em;
      text-transform:uppercase;color:var(--da)}
    #dossie-doc .dd-parte .pt-t{font-size:var(--n3);font-weight:800;letter-spacing:-.03em;
      line-height:1;margin:2mm 0 1.5mm}
    #dossie-doc .dd-parte .pt-d{font-size:var(--t4);color:var(--ds)}
    /* o capítulo que abre a parte não repete a barra de cabeçalho: a parte já identifica a
       folha, e três níveis de título seguidos empilham sem dizer mais nada */
    #dossie-doc .dd-parte + .dd-page > .dd-head{display:none}
    #dossie-doc .dd-parte + .dd-page::before{content:none}
    /* ===== PROSPECTO DO INVESTIDOR — curva + três perguntas (híbrida, Bruno 2026-07-29) =====
       A página responde as três perguntas de quem entra (quando o dinheiro entra · quando
       volta · quanto rende) com a curva do saldo no projeto como mapa dos três momentos.
       ⚠️ O estilo mora aqui (Design); a MARCAÇÃO (.dd-jornada com o SVG da curva + os três
       .dd-perg) nasce no `montarDossie()` do `ade-app.js`, da sessão de Produto — ver
       docs/specs/dossie-prospecto-investidor.md. Inertes até a marcação chegar. */
    #dossie-doc .dd-jornada{margin:3mm 0 0}
    #dossie-doc .dd-jornada svg{width:100%;height:auto;display:block}
    /* cada pergunta é um BLOCO DE LEITURA: título, resposta e explicação não se separam */
    #dossie-doc .dd-perg{margin:5mm 0 0;border-top:2px solid var(--dk);padding-top:2.5mm;break-inside:avoid}
    #dossie-doc .dd-perg .q{font-size:var(--t5);font-weight:800;letter-spacing:-.01em}
    /* o número da pergunta veste a cor da zona correspondente na curva:
       1 aporta (vinho) · 2 devolve (cinza) · 3 resultado (verde) */
    #dossie-doc .dd-perg .q .pn-1{color:var(--dneg)}
    #dossie-doc .dd-perg .q .pn-2{color:var(--ds)}
    #dossie-doc .dd-perg .q .pn-3{color:var(--dpos)}
    #dossie-doc .dd-perg .a{font-size:var(--n2);font-weight:800;letter-spacing:-.02em;margin:1.5mm 0 1mm}
    /* resposta que é FRASE, não número ("o capital próprio não volta a zero no horizonte"):
       em --n2 ela virava manchete de duas linhas com o <small> quebrando no meio.
       O montarDossie marca `.a.frase` quando a resposta não tem número — medido no demo
       com o defeito do §5.2 exposto (bc8cead). */
    #dossie-doc .dd-perg .a.frase{font-size:var(--t6);line-height:1.25}
    #dossie-doc .dd-perg .a small{font-size:var(--t4);font-weight:800;color:var(--ds);letter-spacing:0}
    #dossie-doc .dd-perg p{font-size:var(--t3);line-height:1.55;margin:0;max-width:150mm}
    /* A NOTA DO SHORTFALL SAI DA CÉLULA. Medido no QA de 30/07: dentro da coluna SÓCIO
       (a mais estreita) ela quebrava a cada 1-3 palavras por 6 linhas, inflava a linha
       para 3x a altura e partia valores monetários no meio — na tabela de decisão do
       investidor. O contrato: o montarDossie move a nota para um <p class="dd-shortfall">
       logo APÓS a tabela da cascata (marcação = Produto; ver qa-dossie-pos-cascata.md). */
    #dossie-doc .dd-shortfall{font-size:var(--t2);line-height:1.55;margin:2mm 0 0;
      padding:2mm 0 2mm 3mm;border-left:3px solid var(--dneg);color:var(--dk);break-inside:avoid}
    #dossie-doc .dd-shortfall b{color:var(--dneg);white-space:nowrap}
    /* ===== IDENTIDADE EM TODA FOLHA (QA de 30/07: 4 folhas circulavam sem marca nem
       numeração num documento confidencial) =====
       `position:fixed` repete por página na impressão do Chrome — MAS SÓ com bottom:0.
       ⚠️ MEDIDO NO PDF REAL: qualquer offset NEGATIVO (-5mm, -9mm) joga o rodapé pro
       TOPO da folha, atravessando o conteúdo — não é "ajuste fino", é o modo de falha.
       bottom:0 = borda inferior da mancha; transparente de propósito (se um dia uma
       folha 100% cheia encostar, os dois textos ficam visíveis — nada some em silêncio).
       Conferido nas 11 folhas do demo, capa inclusive (cai ABAIXO do rodapé dela), com
       a contagem de páginas intacta. A MARCAÇÃO é 1 linha do Produto:
       document.getElementById('dossie-doc').dataset.ddRodape =
         nome (+ ' · MODELO' se ehModelo) + ' · confidencial'
       — via dataset (DOM API, sem injeção). Sem o atributo, nada renderiza. O rodapé
       mora no #dossie-doc (não no body) para herdar a ESCALA do papel (--t1). */
    #dossie-doc[data-dd-rodape]::after{content:attr(data-dd-rodape);
      position:fixed;left:0;right:0;bottom:0;font-size:var(--t1);font-weight:700;
      letter-spacing:.08em;text-transform:uppercase;color:var(--ds);text-align:center}
    /* capa */
    #dossie-doc .dd-capa{display:flex;flex-direction:column;min-height:255mm}
    #dossie-doc .dd-capa-marca{font-size:var(--t3);font-weight:800;letter-spacing:.14em;text-transform:uppercase;color:var(--ds);border-bottom:2px solid var(--dk);padding-bottom:10px}
    #dossie-doc .dd-capa-mid{flex:1;display:flex;flex-direction:column;justify-content:center;gap:6mm}
    #dossie-doc .dd-capa-eyebrow{font-size:var(--t4);font-weight:800;letter-spacing:.22em;text-transform:uppercase;color:var(--da)}
    #dossie-doc .dd-capa-titulo{font-size:var(--t7);line-height:1.02;font-weight:800;letter-spacing:-.03em}
    #dossie-doc .dd-capa-sub{font-size:var(--t4);color:var(--ds)}
    #dossie-doc .dd-capa-tese{border-left:4px solid var(--dab);padding:4mm 0 4mm 6mm;font-size:var(--t6);line-height:1.45;font-style:italic}
    /* O PEDIDO na capa. Ele já existia no dossiê, mas só na 4ª folha ("O convite") —
       e quem recebe um dossiê de CAPTAÇÃO abre a capa querendo saber quanto se pede.
       Mesma fonte do convite (necessidade máx. de capital próprio), sem número novo. */
    #dossie-doc .dd-capa-pedido{border:1.5px solid var(--dk);padding:5mm 6mm;display:flex;
      align-items:baseline;gap:6mm;flex-wrap:wrap}
    #dossie-doc .dd-capa-pedido .pd-lab{font-size:var(--t1);font-weight:800;letter-spacing:.18em;
      text-transform:uppercase;color:var(--da);width:100%}
    #dossie-doc .dd-capa-pedido .pd-val{font-size:var(--n3);
      font-weight:800;letter-spacing:-.02em;line-height:1;white-space:nowrap}
    #dossie-doc .dd-capa-pedido .pd-txt{font-size:var(--t3);color:var(--ds);line-height:1.5;flex:1;min-width:60mm}
    #dossie-doc .dd-capa-pedido .pd-txt b{color:var(--dk)}
    #dossie-doc .dd-capa-foot{display:flex;justify-content:space-between;font-size:var(--t2);color:var(--ds);border-top:1px solid var(--dl);padding-top:8px}
    /* seções internas */
    #dossie-doc .dd-secn{font-size:var(--t2);font-weight:800;letter-spacing:.18em;text-transform:uppercase;color:var(--da);margin:0 0 2mm}
    #dossie-doc h2{font-size:var(--t6);font-weight:800;letter-spacing:-.025em;margin:0 0 6mm;line-height:1.15}
    #dossie-doc h3{font-size:var(--t4);font-weight:800;letter-spacing:-.01em;margin:0 0 3mm}
    #dossie-doc .dd-head{display:flex;justify-content:space-between;align-items:baseline;border-bottom:2px solid var(--dk);padding-bottom:6px;margin-bottom:8mm;font-size:var(--t2);color:var(--ds)}
    #dossie-doc .dd-head b{color:var(--dk)}
    /* carimbo no cabeçalho de cada página — precisa sobreviver ao "economizar tinta"
       do driver, por isso é BORDA + texto escuro, não fundo cheio de amarelo */
    #dossie-doc .dd-modelo{display:inline-block;margin-left:3mm;padding:0.4mm 2mm;border:1px solid var(--da);
      color:var(--da);font-size:var(--t1);font-weight:800;letter-spacing:.1em;text-transform:uppercase;vertical-align:1px}
    #dossie-doc .dd-grid2{display:grid;grid-template-columns:1fr 1fr;gap:6mm}
    #dossie-doc .dd-grid3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:5mm}
    #dossie-doc .dd-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:4mm}
    #dossie-doc .dd-kpi{border-top:3px solid var(--dab);background:var(--dc);padding:4mm}
    #dossie-doc .dd-kpi b{display:block;font-size:var(--n1);font-weight:800;letter-spacing:-.01em;white-space:nowrap}
    /* ===== SEM DADO NÃO É ZERO — E TRAVESSÃO NÃO É RESPOSTA (design, 2026-08-16) =====
       O `—` do papel foi uma decisão CERTA e está registrada no montador: com o VGV enlatado
       morto, um estudo sem linha de venda passou a imprimir "VGV R$ 0", que é honesto quanto à
       origem e falso quanto ao fato — o projeto não vale zero, ele não tem produto lançado. O
       travessão consertou a mentira.
       🔴 O QUE ELE NÃO FAZ É FALAR. Medido em 16/08 nos três projetos da demonstração: o
       preenchido sai com 1 marca de ausência; os outros dois saem com 8 marcas e SETE travessões
       seco — e os dois primeiros estão NA CAPA, no VGV e na TIR. É a primeira coisa que o banco
       vê, e ela não diz o que falta nem o que custa faltar. A landing promete em público, desde
       hoje, que quando o produto não sabe ele DIZ; o papel era a única superfície que ainda
       respondia com um traço.
       ⚠️ O motivo é DERIVADO do estudo, nunca escrito à mão — em Cupira, `linhas.length === 0`,
       então a frase é "sem linha de venda" porque é literalmente isso que falta.
       A régua do desenho: a lacuna tem de ler como DELIBERADA, não como falha de renderização —
       e não pode gritar. Fica na escala do rótulo (--t2), no cinza do texto secundário, e quebra
       linha: `.dd-kpi b` é `nowrap`, e uma frase ali estouraria o cartão. */
    /* ⚠️ `text-transform:none` é a linha que faz a diferença entre lacuna e alarme: o bloco da
       capa impõe caixa alta aos seus <b>, e "SEM LINHA DE VENDA" GRITA — medido na primeira
       renderização. A lacuna tem de ser lida como nota do autor, não como erro do sistema. */
    #dossie-doc .dd-vazio{display:inline-block;font-size:var(--t2);font-weight:700;line-height:1.3;
      letter-spacing:0;color:var(--ds);white-space:normal;max-width:34mm;vertical-align:baseline;
      text-transform:none}
    #dossie-doc .dd-big b .dd-vazio{font-size:var(--t3);max-width:46mm}
    /* ⚠️ A ESPECIFICIDADE, e ela custou uma rodada: `.dd-vazio` É um <span>, e o bloco da capa
       tem `#dossie-doc .dd-big span{text-transform:uppercase}` — (1,1,1) contra os (1,1,0) da
       regra base acima. Ela vencia, e a lacuna saía gritada. Os dois seletores abaixo são
       (1,3,0) e ganham por especificidade, sem precisar de `!important`. */
    #dossie-doc .dd-big b .dd-vazio,#dossie-doc .dd-kpi b .dd-vazio{text-transform:none}
    /* rótulo com 2 linhas reservadas: sem isto, "Exposição máx. c/ funding" quebrava
       e empurrava o valor 18px abaixo dos vizinhos — num quadro de 8, dois saíam da linha */
    #dossie-doc .dd-kpi span{font-size:var(--t1);text-transform:uppercase;letter-spacing:.07em;color:var(--ds);
      display:block;min-height:2.4em;line-height:1.2}
    #dossie-doc .dd-kpi small{display:block;font-size:var(--t1);color:var(--ds);margin-top:1mm}
    #dossie-doc table{width:100%;border-collapse:collapse;font-size:var(--t2)}
    #dossie-doc th{text-align:left;font-size:var(--t1);text-transform:uppercase;letter-spacing:.06em;color:var(--ds);border-bottom:2px solid var(--dk);padding:2mm 2.5mm}
    #dossie-doc td{padding:2.2mm 2.5mm;border-bottom:1px solid var(--dl)}
    /* NUNCA quebrar um valor em duas linhas: o "−" ficava numa linha e o número na
       outra (28 células assim na página dos números), e um negativo lido como
       positivo num documento que vai pro banco é erro grave, não estética. */
    #dossie-doc .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
    #dossie-doc tfoot td{border-top:2px solid var(--dk);border-bottom:0;font-weight:800}
    /* o confronto entre o preço do mix e a referência da praça: fica logo abaixo do
       parágrafo de localização, com peso de nota — é leitura, não KPI */
    #dossie-doc .dd-comp{margin:2mm 0 0;font-size:var(--t3);line-height:1.5;color:var(--ds);
      border-left:2px solid var(--dl);padding-left:3mm}
    #dossie-doc .dd-comp b{color:var(--dk)}
    /* matriz de sensibilidade no papel: sem fundo colorido (25 células chapadas gastam
       cartucho e não orientam) — quem orienta é a leitura embaixo. O centro é marcado. */
    #dossie-doc .dd-sens{width:100%;border-collapse:collapse;font-size:var(--t3)}
    #dossie-doc .dd-sens th,#dossie-doc .dd-sens td{border:1px solid var(--dl);padding:2mm 2.5mm}
    #dossie-doc .dd-sens thead th{background:var(--dc);font-size:var(--t2);text-transform:uppercase;letter-spacing:.04em;color:var(--ds)}
    #dossie-doc .dd-sens tbody th{background:var(--dc);font-size:var(--t2);color:var(--ds)}
    #dossie-doc .dd-sens .dd-base{font-weight:800;background:var(--dc);outline:1.5px solid var(--dab);outline-offset:-1.5px}
    #dossie-doc .dd-leitura{margin:4mm 0 0;font-size:var(--t4);line-height:1.55;
      border-left:3px solid var(--dab);padding-left:4mm}
    /* bancabilidade decomposta: rótulo + barra + quanto de quanto */
    #dossie-doc .dd-bank{width:100%;border-collapse:collapse;font-size:var(--t3);margin-top:2mm}
    #dossie-doc .dd-bank td{border-bottom:1px solid var(--dl);padding:2mm 2mm 2mm 0;vertical-align:middle}
    #dossie-doc .dd-bank td small{display:block;font-size:var(--t1);color:var(--ds);margin-top:.5mm}
    /* ⚠️ A BARRA DE BANCABILIDADE MOSTRAVA 0/25 COMO BARRA CHEIA (achado em PDF real,
   29/07). Duas coisas com o mesmo nome de classe: `.dd-bar` da composição de custos
   (onde o <i> é o RÓTULO, com `display:flex` no pai e `flex:0 0 26mm` no filho) e
   `.dd-bank .dd-bar` (onde o <td> é o trilho e o <i> é o PREENCHIMENTO, com a
   proporção escrita na marcação como `style="width:0%"`).
   O <td> herdava `display:flex`, o <i> virava item flex, e **flex-basis vence width**
   — então os 26mm ganhavam do 0% inline. Medido: as cinco barras com 98,27px
   idênticos (26mm), incluindo as de nota ZERO. Num documento de captação, uma barra
   cheia onde a nota é 0 não é deselegante: é falsa.
   `display:table-cell` devolve a célula ao contexto de tabela; sem contexto flex, o
   `flex` do filho não vale e o width inline manda. O trilho cinza entra para que
   nota zero apareça como trilho VAZIO, e não como ausência de desenho. */
    #dossie-doc .dd-bank .dd-bar{display:table-cell;width:38%;
      background:linear-gradient(var(--dc),var(--dc)) left center/calc(100% - 2mm) 2.4mm no-repeat}
    #dossie-doc .dd-bank .dd-bar i{flex:none;max-width:100%}
    #dossie-doc .dd-bank .dd-bar i{display:block;height:2.4mm;background:var(--dab);border-radius:1.2mm}
    #dossie-doc .dd-bank .num{width:16mm;font-weight:800}
    #dossie-doc .dd-bank .dd-de{font-weight:400;color:var(--ds)}
    #dossie-doc .dd-bank .dd-bank-tot td{border-top:1.5px solid var(--dk);border-bottom:0;font-weight:800;padding-top:2.5mm}
    /* marcos: mês à esquerda, o que acontece à direita — lista, não gráfico (gráfico de
       Gantt em meia folha vira borrão; a data é o que o leitor procura) */
    #dossie-doc .dd-marcos{width:100%;border-collapse:collapse;font-size:var(--t3)}
    #dossie-doc .dd-marcos td{border-bottom:1px solid var(--dl);padding:1.8mm 2mm}
    #dossie-doc .dd-marcos td.num{width:22mm;color:var(--dk);font-weight:700}  /* data e ancora, nao destaque */
    /* "O que está de pé": item à esquerda, situação à direita. Pendente NÃO some e NÃO
       vira vermelho de erro — é estado, não defeito; quem some com pendência num dossiê
       de captação transforma silêncio em surpresa na due diligence. */
    #dossie-doc .dd-pe{width:100%;border-collapse:collapse;font-size:var(--t3)}
    #dossie-doc .dd-pe td{border-bottom:1px solid var(--dl);padding:1.8mm 2mm;vertical-align:top}
    #dossie-doc .dd-pe td:first-child{color:var(--dk)}
    #dossie-doc .dd-st{text-align:right;white-space:nowrap;font-weight:700}
    #dossie-doc .dd-st.is-ok{color:var(--dpos)}  /* status e DADO: verde semantico, nao ambar de marca */
    #dossie-doc .dd-st.is-pend{color:var(--ds);font-weight:400;font-style:italic}
    #dossie-doc .dd-cont{font-size:var(--t2);font-weight:400;color:var(--ds);margin-left:2mm}
    #dossie-doc .dd-obs{font-size:var(--t2);line-height:1.5;color:var(--dk);background:var(--dc);
      border-left:3px solid var(--dab);padding:2mm 3mm !important}
    /* CONCILIAÇÃO — a linha que liga dois números da mesma folha que não se falavam
       (receita × VGV, capital aportado × exposição máxima). Discreta de propósito: é
       resposta a uma pergunta previsível, não alerta. Quem precisa dela já parou de ler
       para fazer a conta de cabeça, e é essa parada que a linha evita. */
    #dossie-doc .dd-conc{margin:3mm 0 0;font-size:var(--t2);line-height:1.55;color:var(--ds);
      border-top:1px solid var(--dl);padding-top:2.5mm}
    #dossie-doc .dd-conc b{color:var(--dk)}
    /* premissas: valor à direita, ORIGEM sempre visível — premissa sem origem é opinião */
    #dossie-doc .dd-prem{width:100%;border-collapse:collapse;font-size:var(--t3)}
    #dossie-doc .dd-prem th{text-align:left;font-size:var(--t2);text-transform:uppercase;letter-spacing:.04em;
      color:var(--ds);border-bottom:1.5px solid var(--dk);padding:0 2mm 1.5mm}
    #dossie-doc .dd-prem td{border-bottom:1px solid var(--dl);padding:2mm}
    #dossie-doc .dd-prem .num{text-align:right;font-weight:700;white-space:nowrap}
    #dossie-doc .dd-fonte{font-size:var(--t2);color:var(--ds)}
    /* índice — numera CAPÍTULO, à esquerda. À direita ficaria onde o olho procura número
       de página, que é justamente o que ele não é (ver o comentário em montarDossie). */
    #dossie-doc .dd-idx{width:100%;border-collapse:collapse;font-size:var(--t4)}
    #dossie-doc .dd-idx td{border-bottom:1px solid var(--dl);padding:2.4mm 2mm}
    #dossie-doc .dd-idx td small{display:block;font-size:var(--t2);color:var(--ds);margin-top:.6mm}
    #dossie-doc .dd-idx-n{width:12mm;color:var(--da);font-weight:800;font-variant-numeric:tabular-nums;
      vertical-align:top}
    /* saída do investidor */
    #dossie-doc .dd-saida{width:100%;border-collapse:collapse;font-size:var(--t3);margin-top:2mm}
    #dossie-doc .dd-saida td{border-bottom:1px solid var(--dl);padding:1.8mm 2mm}
    #dossie-doc .dd-saida .num{text-align:right;white-space:nowrap;font-weight:700}
    #dossie-doc .dd-q{margin-bottom:5mm;break-inside:avoid}
    #dossie-doc .dd-q b{display:block;font-size:var(--t1);text-transform:uppercase;letter-spacing:.1em;color:var(--da);margin-bottom:1mm}
    #dossie-doc .dd-q p{margin:0;font-size:var(--t4);line-height:1.55}
    #dossie-doc .dd-sint{background:var(--dc);border-left:4px solid var(--dab);padding:4mm 5mm;font-size:var(--t4);font-style:italic;line-height:1.5;margin-top:5mm}
    #dossie-doc .dd-bar{display:flex;align-items:center;gap:3mm;margin-bottom:2.4mm;font-size:var(--t2)}
    /* rótulo 34mm + valor 26mm + gaps 6mm == a largura da coluna: o trilho ficava
       com ZERO e as barras simplesmente não existiam. Medido antes de mexer. */
    /* o rótulo da barra ganhou sublinha (qual grandeza ela mostra: total captado × total
       aportado × exposição máxima). Sem isso a proporção parecia estrutura de capital e
       podia estar comparando um total com um pico.
       ⚠️ A LARGURA CONTINUA 26mm. Alarguei para 32mm na primeira tentativa e o
       `dossie-papel.test.mjs` reprovou: já houve um defeito de 34mm que ZERAVA o trilho, e
       32 espremia de ~27mm para ~21mm. A sublinha desce uma linha dentro dos 26mm — o
       rótulo já quebrava em duas linhas de qualquer jeito. */
    #dossie-doc .dd-bar>i{font-style:normal;width:26mm;flex:0 0 26mm;color:var(--dk);line-height:1.2}
    #dossie-doc .dd-bar>i small{display:block;font-size:var(--t1);color:var(--ds);font-weight:400}
    #dossie-doc .dd-bar .trk{flex:1 1 auto;min-width:18mm;height:5mm;background:var(--dc);border-radius:2px;overflow:hidden}
    #dossie-doc .dd-bar .trk b{display:block;height:100%;background:var(--dab)}
    #dossie-doc .dd-bar em{font-style:normal;width:25mm;flex:0 0 25mm;text-align:right;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
    /* o viewBox 1100×300 cabe em 174mm como uma faixa de ~47mm: o texto do gráfico
       encolhe junto e fica ilegível no papel. Como o SVG escala, subir o corpo do
       texto DENTRO do viewBox devolve tamanho legível na folha. */
    #dossie-doc .dd-chart svg{width:100%;height:auto}
    #dossie-doc .dd-chart svg text{font-size:13px}
    #dossie-doc .dd-big{display:grid;grid-template-columns:repeat(3,1fr);gap:5mm;text-align:center;margin:6mm 0}
    /* O ambar de MARCA saiu daqui (29/07). Estes tres numeros sao a camada de DADO — na
   capa deste dossie eram o VGV, a TIR de 4,9% (abaixo da TMA) e o lucro; no convite,
   um lucro de -R$ 601.496. Numero negativo pintado com a cor de destaque da marca, em
   documento que vai a comite. A regra de camadas de 24/07 valia na tela e nao no papel.
   ⚠️ Verde/vermelho por SINAL depende de classe na marcacao (montarDossie, em
   ade-app.js) — nao e CSS. Fica combinado com a sessao de Produto; ate la, tinta. */
    #dossie-doc .dd-big b{display:block;font-size:var(--n2);font-weight:800;letter-spacing:-.02em;color:var(--dk)}
    #dossie-doc .dd-big b.is-neg{color:var(--dneg)}
    #dossie-doc .dd-big b.is-pos{color:var(--dpos)}
    #dossie-doc .dd-big span{font-size:var(--t1);text-transform:uppercase;letter-spacing:.08em;color:var(--ds)}
    /* O CONVITE (29/07). Usava #d9ae62 / #e8c98c / #bdb4a4 — creme e latao do visual
   DESCARTADO em 2026-07-24, sobrevivendo no bloco que pede o capital.
   E ha um sentido nisto: na v3, PRETO e a cor de ACAO. O convite e literalmente a acao
   do documento — o unico lugar do dossie onde o preto esta certo por significado. So
   precisava falar a lingua nova: regua amarela de marca, numero em branco. */
    #dossie-doc .dd-convite{background:var(--dk);color:#fff;padding:7mm 8mm;margin-top:6mm;border-left:5px solid var(--dab)}
    #dossie-doc .dd-convite .dd-secn{color:var(--dab)}
    #dossie-doc .dd-convite b{color:#fff}
    #dossie-doc .dd-convite .dd-big b{color:#fff}
    #dossie-doc .dd-convite .dd-big b.is-neg{color:#f2a0a8}  /* vermelho que sobrevive ao fundo preto */
    #dossie-doc .dd-convite .dd-big span{color:#a9abb2}
    #dossie-doc .dd-disc{font-size:var(--t1);color:var(--ds);line-height:1.55;border-top:1px solid var(--dl);padding-top:4mm;margin-top:8mm}
    #dossie-doc .dd-check{display:inline-block;margin:0 4mm 2mm 0;font-size:var(--t2)}
    #dossie-doc .dd-check::before{content:"✓ ";color:var(--da);font-weight:800}
  /* ===== MODO APRESENTAÇÃO (Bruno, 30/07 — "algo dentro do próprio projeto para ser
     usado em reuniões") =====
     O dossiê É a apresentação: mesmos capítulos, mesma identidade, refluídos pra
     paisagem — sala escura, folha iluminada, um capítulo por slide. Deliberadamente
     de um tema só: sala de projeção é escura nos dois temas do app; a luz é o papel.
     ⚠️ A MARCAÇÃO é do Produto (docs/specs/modo-apresentacao.md): botão "Apresentar"
     na Captação, body ganha .apresenta, o capítulo ativo ganha .is-ativa, rodapé
     .ap-rodape, ← → ↓ ESC. Sem a classe no body, nada disto existe. */
  body.apresenta{overflow:hidden;background:#101014}
  body.apresenta #app,body.apresenta #pipeline,body.apresenta #adminScreen{display:none!important}
  body.apresenta #dossie-doc{display:block!important;position:fixed;inset:0;
    background:radial-gradient(120% 90% at 50% 0%,#1b1b21 0%,#101014 70%)}
  body.apresenta #dossie-doc .dd-page{display:none!important}
  body.apresenta #dossie-doc .dd-page::before{content:none}
  body.apresenta #dossie-doc .dd-page.is-ativa{display:block!important;background:#fff;
    position:absolute;top:46%;left:50%;transform:translate(-50%,-50%);
    width:min(88vw,1180px);max-height:84vh;overflow:auto;box-sizing:border-box;
    scrollbar-width:none;padding:10mm 14mm;border-radius:4px;
    box-shadow:0 40px 120px rgba(0,0,0,.55),0 0 0 1px rgba(255,255,255,.04)}
  /* a capa é a única seção com altura de folha travada — no slide ela vira ABERTURA:
     solta a trava e o flex dela centra o miolo na própria caixa */
  body.apresenta #dossie-doc .dd-capa.is-ativa{display:flex!important;min-height:0;height:74vh}
  /* rodapé da sala: projeto · carimbo · posição · dicas. A marcação MONTA ele DENTRO
     do #dossie-doc — é de lá que ele herda a escala do papel (--t2) */
  body.apresenta #dossie-doc .ap-rodape{position:fixed;left:0;right:0;bottom:0;z-index:10;
    display:flex;justify-content:space-between;align-items:center;padding:10px 22px;
    font-size:var(--t2);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#8b8d96}
  body.apresenta #dossie-doc .ap-rodape .ap-modelo{color:#fbd545}
  .pui-menu-id{padding:9px 11px 11px;border-bottom:1px solid var(--pui-border);margin:2px 4px 4px;display:flex;flex-direction:column;gap:3px}
  /* ===== RENDA "EM BREVE" (decisão do Bruno, 2026-08-01) =====
     O ADE passa a atender ativo de renda; o motor ainda não existe — o que entra é a
     SINALIZAÇÃO (mesma prática do catálogo de integrações, 04/07). Dois eixos na tela:
     FORMA (Vertical · Horizontal, o que o motor calcula) × DESTINO (Vender · Operar).
     As opções de renda são grupo rotulado + itens DESABILITADOS: não podem virar
     projeto, porque o `tipo` roteia o motor (Vertical→massa · Horizontal→lote).
     (CSS de TELA — fica depois do .pui-menu-id, fora do recorte do papel.) */
  .renda-breve{display:flex;gap:10px;align-items:flex-start;margin-top:10px;padding:10px 12px;
    border:1.5px dashed var(--pui-border-strong);border-radius:10px;
    font-size:var(--ts-5);color:var(--pui-text-soft);line-height:1.5}
  .renda-breve .pui-badge{flex:0 0 auto;background:var(--ae-accent);color:var(--ae-accent-ink)}
  .renda-breve b{color:var(--pui-text)}
  .ps-grupo{font-size:var(--ts-1);font-weight:800;letter-spacing:.08em;text-transform:uppercase;
    color:var(--pui-text-muted);padding:8px 11px 4px;display:flex;gap:8px;align-items:center}
  .ps-grupo .ps-breve{background:var(--ae-accent);color:var(--ae-accent-ink);letter-spacing:.04em}
  .pui-select-menu button:disabled{opacity:.5;cursor:not-allowed}
  .pui-menu-id b{font-size:var(--ts-6);color:var(--pui-text);word-break:break-all;line-height:1.3}
  .pui-menu-id span{font-size:var(--ts-3);color:var(--pui-text-soft)}
  .pui-menu-item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;background:none;border:0;border-radius:9px;padding:10px 11px;font-size:var(--ts-7);font-weight:500;color:var(--pui-text);cursor:pointer;font-family:inherit;transition:background .12s}
  .pui-menu-item:hover{background:var(--pui-surface-muted)}
  .pui-menu-item [data-icon],.pui-menu-item svg{width:16px;height:16px;flex:0 0 auto;opacity:.7}
  .pui-menu-item-danger{color:var(--pui-danger);font-weight:600}
  .pui-menu-item-danger:hover{background:color-mix(in srgb,var(--pui-danger) 12%,transparent)}
  .pui-menu-sep{height:1px;background:var(--pui-border);margin:4px 6px}
  .pipe-wrap{max-width:1180px;margin:0 auto;padding:22px 26px 60px}
  .proj-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px;margin-top:18px}
  .proj-card{cursor:pointer;transition:box-shadow .15s,transform .05s}
  .proj-card:hover{box-shadow:var(--pui-shadow-md);transform:translateY(-1px)}
  .proj-card .ph{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
  .proj-card h3{font-size:var(--tn-2);margin:0;line-height:1.22;font-family:var(--ae-display);font-weight:650;letter-spacing:-.01em}
  .proj-card .pf.pf-2{align-items:flex-end}
  .proj-card .pf-lbl{font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.05em;color:var(--pui-text-muted);font-weight:700;line-height:1}
  .proj-card .pf-vgv{font-size:var(--tn-1);font-weight:800;color:var(--pui-text);line-height:1.15;margin-top:4px;font-variant-numeric:tabular-nums}
  .proj-card .pf-na{font-size:var(--ts-7);font-weight:600;color:var(--pui-text-muted);line-height:1.15;margin-top:4px}
  .proj-card .pf-cid{font-size:var(--ts-5);color:var(--pui-text-soft);display:flex;align-items:center;gap:5px;margin-top:4px}
  .proj-card .pf-cid .pui-icon{width:13px;height:13px;flex:0 0 auto}
  .proj-card .pg-mover{max-width:180px;font:inherit;font-size:var(--ts-5);font-weight:600;padding:4px 10px;border:1px solid var(--pui-border-strong);border-radius:999px;background:var(--pui-surface-strong);color:var(--pui-text-soft);cursor:pointer}
  .proj-card .pg-mover:focus{outline:none;border-color:var(--ae-foco);box-shadow:0 0 0 3px var(--ae-accent-soft)}
  .proj-card .loc{color:var(--pui-text-soft);font-size:var(--ts-6);margin:8px 0 14px;display:flex;align-items:center;gap:6px}
  .proj-card .loc i{width:15px;height:15px}
  .proj-card .pf{display:flex;align-items:center;justify-content:space-between;border-top:1px solid var(--pui-border);padding-top:12px;font-size:var(--ts-6);color:var(--pui-text-soft)}
  /* ===== FAIXAS DA HOME (caminho B da reavaliação Canivete × página principal,
     2026-07-26): o nível do NEGÓCIO tinha uma gaveta e o nível do empreendimento
     tinha 19 itens de menu. Em vez de mais botão na topbar (decisão de 20/07 —
     topbar enxuta), a home ganha CONTEÚDO: estado do negócio, praças e trilho. ===== */
  .hm-faixa{margin-top:26px}
  .hm-faixa-head{display:flex;align-items:baseline;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:10px}
  .hm-faixa-head .hm-sub{font-size:var(--ts-5);color:var(--pui-text-soft)}
  .hm-link{background:none;border:0;padding:0;font:inherit;font-size:var(--ts-6);font-weight:700;color:var(--pui-text);cursor:pointer;display:inline-flex;align-items:center;gap:5px;border-bottom:1.5px solid var(--ae-chart);line-height:1.5}
  .hm-link:hover{color:var(--ae-chart-dark);border-bottom-color:var(--ae-chart-dark)}
  .hm-link:focus-visible{outline:2px solid var(--ae-foco);outline-offset:3px;border-radius:3px}
  /* estado do negócio — 4 números que a home nunca teve */
  .hm-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}
  .hm-kpi{background:var(--pui-surface);border-radius:16px;padding:14px 16px;box-shadow:0 1px 2px rgba(20,20,28,.04),0 10px 26px -18px rgba(20,20,28,.20)}
  .hm-kpi .k-lab{font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.05em;color:var(--pui-text-soft);font-weight:700;line-height:1}
  .hm-kpi .k-val{font-family:var(--ae-display);font-size:clamp(19px,1.9vw,24px);font-weight:800;letter-spacing:-.02em;line-height:1.15;margin-top:7px;font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .hm-kpi .k-val.is-vazio{font-size:var(--ts-10);font-weight:700;color:var(--pui-text-muted)}
  .hm-kpi .k-sub{font-size:var(--ts-4);color:var(--pui-text-soft);margin-top:3px;line-height:1.35}
  /* praças — o preço vem do banco do workspace/curadoria, SEM chamada de rede */
  .hm-pracas{display:grid;grid-template-columns:repeat(auto-fill,minmax(215px,1fr));gap:12px}
  .hm-praca{background:var(--pui-surface);border:1px solid var(--pui-border);border-radius:14px;padding:12px 14px;text-align:left;font:inherit;cursor:pointer;transition:box-shadow .15s,transform .05s;display:flex;flex-direction:column}
  .hm-praca:hover{box-shadow:var(--pui-shadow-md);transform:translateY(-1px)}
  .hm-praca:focus-visible{outline:2px solid var(--ae-foco);outline-offset:2px}
  /* a tarja tem LINHA PRÓPRIA e altura reservada: sem isso, um nome longo
     ("Balneário Camboriú") quebrava em duas linhas e desalinhava a fileira */
  .hm-praca .p-tarja{height:16px;margin-bottom:5px;display:flex;align-items:center}
  .hm-praca .p-nome{font-size:var(--ts-9);font-weight:700;color:var(--pui-text);line-height:1.25}
  .hm-praca .p-grupo{font-size:var(--ts-3);color:var(--pui-text-muted);margin-top:2px}
  .hm-praca .p-preco{font-size:var(--ts-9);font-weight:800;color:var(--pui-text);margin-top:auto;padding-top:8px;font-variant-numeric:tabular-nums}
  .hm-praca .p-preco small{font-size:var(--ts-3);font-weight:600;color:var(--pui-text-soft)}
  .hm-praca .p-sem{font-size:var(--ts-5);font-weight:600;color:var(--pui-text-muted);margin-top:auto;padding-top:8px}
  .hm-praca.is-minha{border-color:var(--ae-chart);background:var(--ae-accent-soft)}
  /* ⚠️ PAR DE TOKEN ERRADO (medido no escuro, 29/07: contraste 1,05 — o selo sumia).
     `--ae-on-soft` e a tinta do `--ae-accent-soft`, que VIRA marrom escuro no tema escuro;
     por isso a tinta clareia (#2a2100 -> #f3dc93). Mas o fundo aqui e `--ae-chart`, o
     amarelo da marca, que NAO vira — e amarelo com tinta clara nao se le.
     A tinta do amarelo estavel e `--ae-accent-ink`, que tambem nao vira. Corrigido na regra
     base, e nao com um remendo so no escuro: o par certo vale nos dois temas. */
  .hm-aqui{font-size:var(--ts-1);font-weight:800;text-transform:uppercase;letter-spacing:.05em;padding:2px 7px;border-radius:999px;background:var(--ae-chart);color:var(--ae-accent-ink);white-space:nowrap}
  /* trilho de captação */
  .hm-trilho{background:var(--pui-surface);border:1px solid var(--pui-border);border-radius:16px;padding:16px 18px;display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}
  .hm-trilho .t-txt{flex:1;min-width:240px}
  .hm-trilho .t-tit{font-size:var(--ts-9);font-weight:700;line-height:1.3}
  .hm-trilho .t-sub{font-size:var(--ts-6);color:var(--pui-text-soft);margin-top:3px;line-height:1.45}
  @media(max-width:599px){.hm-kpis,.hm-pracas{grid-template-columns:1fr}}
  /* ===== ESTADO EM FORMA, NÃO EM EMOJI (2026-07-26) =====
     🟢🟡🔴 são desenhados pelo SISTEMA OPERACIONAL de quem abre: mudam de forma entre
     Mac, Windows e Android, trazem cor própria que não é a da paleta, e destoam dos 41
     ícones de linha do sistema. Estado vira ponto na cor semântica do design system.
     Nunca aparecem sozinhos — sempre com o texto ao lado, pra não depender de cor. */
  /* SELO DE LEGENDA — a marca colorida que diz "esta cor é esta série" (design, 2026-07-29).
     Até aqui isso era um CARACTERE: ▮ ▬ ●. Três problemas de uma vez — o desenho muda com
     a fonte, a largura muda com o sistema operacional, e a cor só se aplica PINTANDO O
     TEXTO. Foi exatamente assim que a legenda do Monte Carlo acabou com um `#1f1f23`
     cravado num <b>: no tema escuro, o selo do "caso base" ficava invisível.
     Sendo um elemento de verdade, a cor entra por `--sw` e pode ser token. Quem não
     tem cor própria cai no cinza de apoio. */
  .leg-sw{display:inline-block;width:14px;height:3px;border-radius:2px;vertical-align:middle;
    background:var(--sw,var(--pui-text-soft));margin-right:3px;flex:0 0 auto}
  .leg-sw.is-ponto{width:9px;height:9px;border-radius:50%}
  /* AVISO EM PROSA — o ícone do sistema no lugar do emoji ⚠️.
     ⚠️ com o seletor U+FE0F é desenhado pelo SISTEMA OPERACIONAL: medido em canvas, ele
     ignora a cor pedida (202 cores na amostra, todas amarelas, quando se pediu vermelho)
     e é 5px mais largo que o glifo de texto. O ícone do sprite herda `currentColor` e
     acompanha o tema. Como o sistema de ícones SUBSTITUI o <i data-icon> por um <svg>,
     estilo e classe postos no <i> se perdem — o alinhamento tem de vir do contexto. */
  .ae-aviso .pui-icon{width:15px;height:15px;vertical-align:-3px;flex:0 0 auto}
  /* ÍCONE PEQUENO EM CONTROLE QUE NÃO É BOTÃO DE ÍCONE (pedido da sessão de Produto, 29/07).
     O `.pui-icon-button` já dimensiona o ícone; estes três lugares não são botão de ícone e
     herdariam os 18px do padrão — num chip de 11px de texto, isso estoura a pílula.
     São duas medidas porque são dois pesos de contexto, não porque faltou decidir:
       · `sm` (13px) — botão ghost e pílula com rótulo, onde o ícone acompanha texto de 12px;
       · `xs` (11px) — o × de fechar chip, que é o menor controle do app.
     A regra mira `.pui-icon` porque o sistema SUBSTITUI o `<i data-icon>` por um
     `<svg class="pui-icon">`: classe posta no `<i>` se perde, e só o contexto sobrevive.
     ⚠️ E o aviso que a própria sessão de Produto levantou, porque vale mais que o tamanho:
     quando o `✕` era o ÚNICO conteúdo do botão, ele era o **nome acessível**. O `ic()`
     devolve `<svg aria-hidden="true">` — trocar sem pôr `aria-label`/`title` na mesma linha
     deixa o botão anunciando só "botão", e a suíte fica verde por cima. */
  .ae-ico-sm{--ae-ico:13px}
  .ae-ico-xs{--ae-ico:11px}
  .ae-ico-sm .pui-icon,.ae-ico-xs .pui-icon{width:var(--ae-ico);height:var(--ae-ico);
    vertical-align:-.14em;flex:0 0 auto}
  .leg-sw.is-bloco{width:10px;height:10px;border-radius:2px}
  .est-dot{display:inline-block;width:10px;height:10px;border-radius:50%;flex:0 0 10px;vertical-align:0}
  .est-dot.is-ok{background:var(--pui-success)}
  .est-dot.is-med{background:var(--pui-warning)}
  .est-dot.is-ruim{background:var(--pui-danger)}
  .est-dot.is-neutro{background:var(--pui-text-muted)}
  /* no bloco de veredito o ponto é o "ícone" grande — vale um anel pra ter presença */
  .vcv-vd-icon .est-dot{width:26px;height:26px;box-shadow:0 0 0 5px var(--pui-surface-muted)}

  /* ============================================================================
     A MARCA — a alavanca (pacote ade-marca/, 07/08)
     ============================================================================
     A marca NÃO é um ícone, e as duas linguagens não se misturam:
       ícone → desenho de LINHA, 24×24, stroke 2, fill none, classe .pui-icon
       marca → desenho PREENCHIDO, 64×64, sem traço,        classe .ade-marca
     Por isso a regra abaixo repõe `fill` e zera `stroke`: se a marca herdasse
     `.pui-icon`, ela sairia como um contorno vazado — que é o oposto do desenho.

     COR SEMPRE POR TOKEN (regra 9 do pacote): `currentColor` faz a marca obedecer
     a quem a hospeda. Onde ela veste --ae-ink, vira preta no claro e AMARELA no
     escuro sozinha — a mesma inversão do CTA, pela mesma razão (preto sobre preto
     some). Nunca cravar cor aqui: acento de cor própria some num dos temas. */
  .ade-marca{display:block;width:100%;height:100%;fill:currentColor;stroke:none}
  /* o campo amarelo: a regra 10 do pacote permite o amarelo como CAMPO, nunca como
     traço da marca. É o que a caixa do menu e a do topo já eram — muda o que está
     dentro dela, não ela. */
  .ade-marca-campo{display:grid;place-items:center;background:var(--ae-accent);color:var(--ae-accent-ink)}
  .ade-marca-campo>.ade-marca{width:68%;height:68%}
  /* nas caixas de marca do app (menu e topo do portfólio) a alavanca entra no lugar da
     LETRA — mesma caixa amarela, outro conteúdo. 76% deixa o respiro que a letra tinha;
     a 100% o desenho encosta na borda do quadrado e some a forma do apoio. */
  .pui-logo-mark>.ade-marca,.pipe-top .brand .logo>.ade-marca{width:76%;height:76%}

  /* ---- TELA DE CARGA · "as cargas pousam" (pacote §4) ----------------------------
     A tradução que faz este bloco funcionar: a spec do pacote está em `em`, e o desenho
     está em unidades de fonte (UPM 1000). Então 1em = 1000 unidades do viewBox, e o
     −.6em/−.7em da queda viram −600/−700 aqui. Mesmos tempos, mesma curva, uma volta só.
     ⚠️ A SAÍDA NÃO DEPENDE DE JAVASCRIPT. `forwards` + `visibility:hidden` tiram a tela do
     caminho por conta própria, e `pointer-events:none` vale desde o primeiro quadro — se o
     script de 1 MB falhar ou demorar, ninguém fica preso atrás de uma marca bonita. */
  #ade-boot{
    position:fixed; inset:0; z-index:120; display:grid; place-items:center;
    background:var(--pui-bg); color:var(--ae-ink); pointer-events:none;
    animation:ade-boot-sai 2.2s ease 1 forwards;
  }
  #ade-boot svg{width:min(280px,46vw); height:auto; display:block}
  /* as duas massas são os dois <rect> do logotipo — a geometria não muda, só se move */
  #ade-boot svg rect:nth-of-type(1){animation:ade-d1 5.6s cubic-bezier(.34,1.35,.45,1) 1}
  #ade-boot svg rect:nth-of-type(2){animation:ade-d2 5.6s cubic-bezier(.34,1.35,.45,1) 1}
  @keyframes ade-d1{0%{transform:translateY(-600px);opacity:0}
    6%{opacity:1}13%,100%{transform:translateY(0);opacity:1}}
  @keyframes ade-d2{0%,8%{transform:translateY(-700px);opacity:0}
    14%{opacity:1}23%,100%{transform:translateY(0);opacity:1}}
  @keyframes ade-boot-sai{0%,68%{opacity:1;visibility:visible}
    100%{opacity:0;visibility:hidden}}
  /* quem pediu menos movimento vê a marca parada e a tela sair antes — não é o mesmo que
     "sem tela": a palavra ainda assina a abertura. */
  @media(prefers-reduced-motion:reduce){
    #ade-boot{animation-duration:.7s}
    #ade-boot svg rect:nth-of-type(1),#ade-boot svg rect:nth-of-type(2){animation:none}
  }
  /* nunca no papel — a regra é do pacote, e o papel não tem abertura */
  @media print{#ade-boot{display:none !important}}
  .fase-Estudo{background:var(--pui-info-soft);color:var(--pui-info)}
  .fase-Emaprovacao{background:var(--pui-warning-soft);color:var(--pui-warning)}
  .fase-Aprovado{background:var(--pui-primary-soft);color:var(--pui-primary)}
  .fase-Lancado{background:var(--pui-success-soft);color:var(--pui-success)}
  .back-pipe{display:inline-flex;align-items:center;gap:6px;background:none;border:none;cursor:pointer;font:inherit;color:var(--pui-text-soft);font-size:var(--ts-7);padding:4px 4px}
  .back-pipe:hover{color:var(--pui-text)}
  .proj-name{font-weight:700;font-size:var(--ts-9)}
  .vcv-overlay{position:fixed;inset:0;background:rgba(18,24,32,.42);display:grid;place-items:center;z-index:60;padding:20px}
  .vcv-overlay[hidden]{display:none}
  .vcv-overlay-box{width:100%;max-width:430px;position:relative}
  /* voltar ao pipeline (sidebar) */
  .vcv-side-back{display:flex;align-items:center;gap:8px;width:100%;background:var(--pui-primary-soft);color:var(--pui-primary);border:none;border-radius:8px;padding:9px 12px;font:inherit;font-weight:600;font-size:var(--ts-7);cursor:pointer;margin:2px 0 10px}
  .vcv-side-back:hover{background:rgba(14,86,100,.16)}
  .vcv-side-back i{width:16px;height:16px;flex:0 0 auto}
  .vcv-side-proj{display:flex;align-items:flex-start;gap:9px;padding:0 4px 12px;border-bottom:1px solid var(--pui-border);margin-bottom:10px}
  .vcv-side-proj .pin{width:30px;height:30px;border-radius:7px;background:var(--pui-surface-muted);display:grid;place-items:center;flex:0 0 auto;color:var(--pui-text-soft)}
  .vcv-side-proj .pin i{width:16px;height:16px}
  .vcv-side-proj strong{display:block;font-size:var(--ts-7);line-height:1.25}
  .vcv-side-proj span{font-size:var(--ts-3);color:var(--pui-text-soft)}
  /* ===== Camada "Academia do Estruturador" v3 (off-white + amarelo + Plus Jakarta Sans) ===== */
  :root{
    --pui-font:'Plus Jakarta Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif;
    --pui-bg:#eeedf1; --pui-surface:#ffffff; --pui-surface-strong:#f7f7f9; --pui-surface-muted:#eaeaee;
    /* TINTA — os três níveis foram RE-ESPAÇADOS em 2026-07-27, não só escurecidos.
       Medido nas 19 telas: o `muted` antigo (#9da0a8) dava 2,18 a 2,62 de contraste — o
       mínimo legível é 4,5 — e sozinho respondia por 299 dos 365 elementos ilegíveis do
       tema claro. Escurecer só ele o deixaria igual ao `soft` antigo (#65686f) e a
       hierarquia de três níveis viraria dois. Os dois desceram juntos.
       PIOR CASO de cada nível (sobre a faixa #eaeaee, a superfície mais escura):
         texto 13,69 · médio 8,38 · claro 5,94 — mínimo 4,5.
       Escolha do Bruno entre dois tons; este é o mais escuro dos dois. Ele adensa a
       moldura do app (menu e topo), o que era o preço conhecido. */
    --pui-text:#1f1f23; --pui-text-soft:#3f424a; --pui-text-muted:#55585f;
    --pui-border:#e7e7eb; --pui-border-strong:#dadae0;
    --pui-primary:#1e1e22; --pui-primary-strong:#000000; --pui-primary-soft:#ededf1;
    /* SEMÁFORO — escurecido o suficiente para passar sobre o fundo MAIS CLARO em que cada
       um aparece (o verde vive sobre o próprio `success-soft`; o vermelho, sobre cinza).
       Continuam verde, vermelho e âmbar — mudou o tom, não a cor. */
    --pui-success:#085c3a; --pui-success-soft:#e7f6ee;
    --pui-danger:#a52734; --pui-danger-soft:#fbe6e9;
    --pui-warning:#714b07; --pui-warning-soft:#fbf0d2;
    --pui-info:#3a5fd9; --pui-info-soft:#e7ecfb;
    --pui-radius:14px; --pui-radius-sm:10px;
    --ae-ink:#1e1e22; /* CTA preto */
    --ae-accent:#fbd545; --ae-accent-soft:#fef4ce; --ae-accent-ink:#2a2100; /* amarelo de marca */
    --ae-chart:#fbd545; --ae-chart-dark:#e7b400; /* gráficos: amarelo */
    /* ANEL DE FOCO — token próprio, e a razão é a mesma que o PAPEL já ensinou duas vezes:
       o acento tem DOIS níveis, porque o amarelo de marca ILUMINA, não MARCA. Medido em
       06/08 nas quatro superfícies claras, contra o piso de 3,0 de elemento gráfico
       (WCAG 1.4.11) — o anel que existia era invisível para quem navega por teclado:
         --ae-accent      #fbd545 → 1,23 fundo · 1,43 cartão
         --ae-accent-soft #fef4ce → 1,10 (o halo não é sinal, é decoração)
         --ae-chart-dark  #e7b400 → 1,65 fundo · 1,92 cartão   ← o idioma que a casa usava
       O âmbar escuro é o MESMO valor que o papel chama de --da: 4,93 a 5,92 no claro.
       No escuro o amarelo volta a mandar (9,98 a 12,87) — é a marca lida do outro lado,
       exatamente como --ae-ink. Uma família, dois níveis, um anel só. */
    --ae-foco:#8a5a0f;
    /* 🔴 A FRONTEIRA DO DADO (14/08). O ponto em que o apurado acaba e a projeção começa era
       marcado de TRÊS jeitos: linha vermelha na obra, troca de traço no fluxo, borda amarela na
       tabela. O vermelho era erro de significado — `--pui-danger` é a cor de FALHA neste app, e o
       corte não é falha: é o limite do que se sabe. Das três, a TABELA já estava certa, então o
       token aponta para a cor dela em vez de inventar uma quarta.
       🔴 MEDIDO NO BROWSER, e por isso NÃO é `--ae-chart-dark` cru: aquele amarelo dá 1,92:1
       sobre branco. Serve de preenchimento de barra; não serve de rótulo — e o rótulo "Payback"
       do fluxo está nesse 1,92 desde sempre, invisível para quem lê de longe. A guarda de
       contraste não pega: ela lê a FOLHA DE ESTILO, e estes rótulos são `fill` em SVG montado no
       JS. `#8a5a0f` é o âmbar que esta casa já provou legível — foi por ele que o anel de foco
       trocou, pela mesma medição. */
    --ae-corte:#8a5a0f;
    --ae-display:'Plus Jakarta Sans',system-ui,sans-serif;
    /* ===== ESCALA TIPOGRÁFICA DA TELA (06/08) =====
       Até aqui a tela não tinha régua: 262 declarações de `font-size` em 24 valores soltos,
       escolhidos um a um. O papel sempre teve (--t1..--t7), e é de lá que vem a forma desta.
       DUAS RÉGUAS, pela mesma razão do dossiê: num documento financeiro NÚMERO não é texto
       grande, é outra categoria de informação — e ganha escala própria.
       ⚠️ O PASSO DE 0,5 NA BANDA DENSA É DELIBERADO, e é o achado da medição: 10,5 · 11,5 ·
       12,5 · 13,5 somam 84 declarações, um terço do total. Não são ruído — são a régua real de
       uma interface densa, onde meio pixel separa a legenda do rótulo. Colapsá-los em passos
       inteiros é outra decisão, maior, e mexeria em 84 lugares de uma vez.
       O QUE FICA DE FORA, de propósito: `font-size` que dimensiona GLIFO (ícone de veredito,
       ícone do banner societário) não é tipografia, é tamanho de desenho; e a tabela do PAPEL
       (9,5px) obedece à régua da folha, não à da tela. */
    --ts-1:10px;   --ts-2:10.5px; --ts-3:11px;  --ts-4:11.5px; --ts-5:12px;
    --ts-6:12.5px; --ts-7:13px;   --ts-8:13.5px;--ts-9:14px;   --ts-10:15px;
    --tn-1:17px;   --tn-2:20px;   --tn-3:23px;  --tn-4:28px;   --tn-5:34px;
    /* CAMPO DE DIGITAÇÃO tem token próprio, separado da superfície do cartão. No claro os
       dois são branco e ninguém nota; no escuro o campo precisa ser MAIS FUNDO que o
       cartão, senão a caixa some e sobra a borda. */
    --ae-field:#ffffff;
    /* TINTA SOBRE O AMARELO SUAVE. Separada de --ae-accent-ink de propósito: aquela é a
       tinta sobre o amarelo FORTE (pílula MODELO, faixa do dossiê, logo, CTA no escuro) e
       tem de ser escura sempre. Esta acompanha o tema — no escuro o amarelo suave vira um
       marrom fundo, e tinta escura sobre ele dá contraste 1,25 (medido). */
    --ae-on-soft:#2a2100;
    /* TINTA SOBRE O PRETO DE AÇÃO. No escuro o --pui-primary inverte (vira quase branco),
       e a tinta branca cravada ao lado dele virava branco sobre branco. */
    --ae-on-primary:#ffffff;
  }
  body{background:var(--pui-bg) !important}
  .pui-backdrop-texture{display:none !important}
  #app.pui-app{background:transparent;border:0;box-shadow:none}
  .pui-sidebar{background:var(--pui-surface-strong)}
  .pui-main{padding:24px 30px 64px}
  .pui-topbar{justify-content:space-between;max-width:2400px;margin:0 auto 26px}
  .pui-view{max-width:2400px;margin-left:auto;margin-right:auto}
  .pui-card{box-shadow:0 1px 3px rgba(20,20,28,.05);border-color:var(--pui-border);border-radius:18px;background:var(--pui-surface)}
  .pui-card::before{display:none !important}
  .pui-page-head{margin-bottom:14px}
  .pui-page-head h1{font-family:var(--ae-display);font-weight:800;font-size:clamp(24px,2.7vw,34px);letter-spacing:-.025em}
  .pui-page-head p{font-size:var(--ts-8)}
  .pui-eyebrow{font-size:var(--ts-3);color:var(--pui-text-muted);letter-spacing:.08em}
  /* CTAs pretos + marca */
  .pui-button-primary{background:var(--ae-ink);border-color:var(--ae-ink)}
  .pui-button-primary:hover{background:#38383f;border-color:#38383f}
  .pui-logo-mark,.vcv-login .logo,.pipe-top .brand .logo{background:var(--ae-accent) !important;color:var(--ae-accent-ink) !important}
  .pui-sidebar-brand a span:not(.pui-logo-mark){font-family:var(--ae-display);font-weight:600}
  .vcv-login h1{font-family:var(--ae-display);font-weight:800;letter-spacing:-.025em}
  /* 820 numa fonte que vai até 800 não satura: o navegador ENGORDA por conta própria (medido em
     06/08 — 268,68 px contra 267,67 px na mesma frase). Negrito sintético borra o desenho em vez
     de usar a instância real da fonte variável. Este é o ÚNICO dos quatro seletores com 820 que
     existe no app (6 na tela); os outros três são componentes que a casa não usa.
     Corrigido AQUI, e não no propulsor: o design system herdado não se edita — se veste. */
  .pui-nav-section-title{font-weight:800}
  .pui-nav-section-title span{letter-spacing:.09em}
  .pui-kpi-grid,.pui-kit-grid{gap:16px}
  .pui-kpi-grid{margin-bottom:22px}
  .pui-view>.pui-card,.pui-view>article.pui-card,.pui-view>.pui-kit-grid{margin-top:18px}
  .pui-kpi-card span{color:var(--pui-text-muted);font-size:var(--ts-6)}
  .pui-kpi-card strong{font-size:clamp(22px,2.4vw,30px)}
  .pui-kpi-card{gap:6px}
  .vcv-info{background:var(--pui-surface);border-left-width:3px}
  .pui-card-head h3{font-size:var(--ts-10)}
  /* topo: controles compactos numa linha (evita o select esticar com width:100%) */
  .pui-topbar .pui-action-row{flex-wrap:nowrap}
  .pui-topbar .pui-select{width:auto}
  .pui-topbar .vcv-ver-label{margin-left:4px}
  /* Pendências (checklist guiado, avançado) */
  /* Painel da Trilha: ancorado no botão do topo (bico), elevação em camadas do DS,
     cabeçalho+barra fixos e rolagem só na lista — não é mais um balão solto. */
  #pend-panel{position:fixed;right:20px;top:58px;z-index:80;width:min(380px,calc(100vw - 32px));background:var(--pui-surface);border:1px solid var(--pui-border-strong);border-radius:20px;box-shadow:0 1px 2px rgba(20,20,28,.04),0 28px 64px -26px rgba(20,20,28,.34);padding:16px 18px 14px}
  #pend-panel::before{content:'';position:absolute;top:-7px;right:106px;width:13px;height:13px;background:var(--pui-surface);border-left:1px solid var(--pui-border-strong);border-top:1px solid var(--pui-border-strong);border-radius:4px 0 0 0;transform:rotate(45deg)}
  #pend-list{max-height:min(58vh,520px);overflow:auto;overscroll-behavior:contain;padding-right:2px}
  .pend-head{display:flex;justify-content:space-between;align-items:flex-start;gap:8px;margin-bottom:10px}
  .pend-bar{height:7px;background:var(--pui-surface-muted);border-radius:999px;overflow:hidden}
  /* Verde = "tudo certo". Enquanto faltar marco, a barra fica âmbar (em andamento). */
  .pend-fill{height:100%;width:0;background:var(--ae-chart-dark);border-radius:999px;transition:width .35s ease,background-color .3s ease}
  .pend-fill.is-done{background:var(--pui-success)}
  .pend-grp{font-size:var(--ts-1);font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--pui-text-muted);margin:12px 0 4px}
  .pend-item{display:flex;align-items:center;gap:9px;padding:6px 2px;border-bottom:1px dashed var(--pui-surface-muted);font-size:var(--ts-6)}
  .pend-item:last-child{border-bottom:0}
  .pend-ok{width:17px;height:17px;border-radius:50%;flex:0 0 17px;display:inline-flex;align-items:center;justify-content:center;font-size:var(--ts-2);font-weight:800;background:var(--pui-success-soft);color:var(--pui-success)}
  .pend-todo{background:var(--pui-surface-muted);color:var(--pui-text-muted);font-weight:700}
  .pend-lbl{flex:1;min-width:0}
  .pend-lbl small{display:block;color:var(--pui-text-muted);font-size:var(--ts-2)}
  .pend-item.done .pend-lbl{color:var(--pui-text-soft)}
  .pend-go{border:0;background:none;color:var(--pui-success);font:inherit;font-size:var(--ts-4);font-weight:700;cursor:pointer;white-space:nowrap;padding:3px 6px;border-radius:6px}
  .pend-go:hover{background:var(--pui-success-soft)}
  #pend-pct.pend-done{color:var(--pui-success)}
  /* ===== v3: camada de componentes (pills + ativo amarelo + soft) — override do propulsor, sem editar o DS compartilhado ===== */
  :root{ --pui-rainbow:var(--ae-accent); --pui-rainbow-alpha:1; --ae-accent-strong:#ecc22c; }
  .pui-nav-item.is-active::before,.pui-tabs .is-active::after,.pui-modal-panel::before,.pui-card::before{background:var(--ae-accent)!important;animation:none!important}
  .pui-loader{background:var(--ae-accent)!important}
  .pui-button,.pui-icon-button{border-radius:999px}
  .pui-button-primary{background:var(--ae-ink)!important;border-color:var(--ae-ink)!important;color:#fff!important;box-shadow:0 6px 16px rgba(20,20,28,.16)}
  .pui-button-primary:hover{background:#38383f!important;border-color:#38383f!important}
  .pui-button-secondary{background:var(--pui-surface-muted);border-color:var(--pui-border-strong);color:var(--pui-text)}
  .pui-button-secondary:hover{background:var(--pui-surface);border-color:var(--ae-ink)}
  .pui-button-ghost{background:var(--pui-surface);border-color:var(--pui-border-strong);color:var(--pui-text)}
  /* o anel é OUTLINE, não box-shadow: box-shadow no foco apagava a elevação do CTA (a regra
     antiga tinha !important e substituía a sombra inteira). Outline não ocupa espaço e não
     disputa com a elevação. O halo suave fica como reforço, nunca como o sinal. */
  .pui-button:focus-visible,.pui-icon-button:focus-visible{outline:2px solid var(--ae-foco);outline-offset:2px}
  /* ===== O PISO: uma língua de foco só =====
     Medido em 06/08 com Tab de VERDADE (45 tabulações, foco por código não serve — ver abaixo):
     dos 12 tipos que o teclado alcança, só TRÊS tinham anel desenhado por nós. Os outros nove
     — os 19 itens do menu, o logo, os "?" dos KPIs, o select nativo, o voltar — caíam no anel
     PADRÃO DO NAVEGADOR (`auto 1px rgb(229,151,0)` no Chrome), que muda de forma e de cor em
     cada navegador e não é nosso. Não estavam mudos; estavam falando outra língua.
     `:where()` tem especificidade ZERO de propósito: isto é piso, não lei. Qualquer regra de
     foco desta casa continua vencendo sem precisar de !important.
     ⚠️ PARA MEDIR ISTO DE NOVO: `:focus-visible` NÃO casa com `el.focus()` por código — o
     navegador só considera teclado o que veio do teclado. Uma varredura que foca por código
     mede zero anéis e conclui que está tudo quebrado. Foi o que aconteceu na primeira
     tentativa. Tab de verdade, e com transição neutralizada antes de ler. */
  :where(a[href],button,input,select,textarea,summary,[tabindex]:not([tabindex="-1"])):focus-visible{
    outline:2px solid var(--ae-foco); outline-offset:2px;
  }
  .pui-icon-button{border-color:var(--pui-border-strong)}
  .pui-icon-button:hover{color:var(--ae-ink);border-color:var(--ae-ink)}
  .pui-card{border-radius:20px;box-shadow:0 1px 2px rgba(20,20,28,.04),0 8px 24px -12px rgba(20,20,28,.10)}
  .pui-kpi-card strong{font-family:var(--ae-display);font-weight:800;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.05}
  .pui-select-button{border-radius:999px;padding:0 16px}
  .pui-select-menu{border-radius:16px}
  .pui-select-menu button.is-selected{color:var(--ae-on-soft)!important;background:var(--ae-accent-soft)!important}
  .pui-select-menu button:hover{color:var(--ae-ink);background:var(--pui-surface-muted)}
  .pui-field input,.pui-field select,.pui-field textarea,.pui-search input,.pui-select-search,.pui-select-button,.pui-input{border-radius:12px}
  .pui-field input:focus,.pui-field select:focus,.pui-field textarea:focus,.pui-search input:focus,.pui-select-search:focus,.pui-select-button:focus-visible,.pui-input:focus{border-color:var(--ae-foco)!important;box-shadow:0 0 0 3px var(--ae-accent-soft)!important}
  /* v3 · formulario: campo e campo — select nativo, pui-select e input com a MESMA caixa */
  .pui-field .pui-select{width:100%}
  .pui-field .pui-select-button{border-radius:12px;padding:0 12px;font-weight:500;font-size:var(--ts-9)}
  .pui-field input:disabled,.pui-field select:disabled{background-color:var(--pui-surface-strong);color:var(--pui-text-muted);cursor:not-allowed}
  #modalNovo .pui-field select,#modalProjEdit .pui-field select{appearance:none;-webkit-appearance:none;-moz-appearance:none;padding:0 34px 0 12px;font-weight:500;font-size:var(--ts-9);background-color:var(--ae-field);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2365686f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 12px center;background-size:15px 15px}
  /* grupos do formulario (Identificacao · Premissas) */
  .ae-fgrp{display:grid;gap:12px}
  .ae-fgrp+.ae-fgrp{margin-top:4px;padding-top:16px;border-top:1px solid var(--pui-border)}
  .ae-fgrp-h{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;font-size:var(--ts-3);font-weight:800;text-transform:uppercase;letter-spacing:.07em;color:var(--pui-text-muted)}
  .ae-fgrp-h em{font-size:var(--ts-3);font-style:normal;font-weight:600;text-transform:none;letter-spacing:0;color:var(--pui-text-muted)}
  .ae-frow{display:grid;grid-template-columns:1fr 1fr;gap:12px}
  @media(max-width:560px){.ae-frow{grid-template-columns:1fr!important}}
  /* interruptor "é um empreendimento modelo" (modal de editar) */
  .pe-modelo{display:flex;gap:10px;align-items:flex-start;cursor:pointer;font-size:var(--ts-7);line-height:1.45}
  .pe-modelo input{width:auto;margin:2px 0 0;flex:0 0 auto}
  .pe-modelo b{display:block;font-weight:600}
  .pe-modelo small{display:block;margin-top:2px;font-size:var(--ts-4);color:var(--pui-text-soft)}
  /* travado = a marca veio do sistema e é pegajosa; o texto de ajuda explica por quê */
  .pe-modelo:has(input:disabled){cursor:default}
  .pe-modelo:has(input:disabled) b{color:var(--pui-text-soft)}
  .pui-tabs{border-radius:999px;background:var(--pui-surface-muted)}
  .pui-tabs button{border-radius:999px}
  .pui-tabs .is-active::after{display:none!important}
  .pui-tabs button.is-active{background:var(--ae-ink);color:var(--ae-on-primary);box-shadow:none}
  .pui-nav-item{border-radius:999px}
  .pui-nav-item:hover:not(.is-active){background:var(--pui-primary-soft);color:var(--pui-text)}
  .pui-nav-item.is-active{background:var(--ae-ink);color:var(--ae-on-primary)}
  .pui-nav-item.is-active .pui-icon,.pui-nav-item.is-active svg{color:var(--ae-on-primary)}
  .pui-nav-item.is-active::before{display:none!important}
  .pui-badge{font-weight:700}
  .pui-badge.is-accent,.pui-badge-accent{background:var(--ae-accent);border-color:var(--ae-accent);color:var(--ae-accent-ink)}
  .pui-segmented{border-radius:999px;background:var(--pui-surface-muted);padding:4px}
  .pui-segmented button{border-radius:999px}
  .pui-segmented button.is-active,.pui-segmented button.on,.pui-segmented button[aria-selected="true"]{background:var(--ae-accent)!important;color:var(--ae-accent-ink)!important;border-color:var(--ae-accent)!important;box-shadow:none}
  .pui-segmented button:hover:not(.is-active):not(.on){background:var(--pui-surface);color:var(--ae-ink)}
  .pui-table tbody tr:hover,.pui-table tbody tr.is-highlighted{background:var(--ae-accent-soft)!important}
  .pui-table tbody tr:hover td:first-child,.pui-table tbody tr.is-highlighted td:first-child{box-shadow:inset 3px 0 0 var(--ae-accent)!important}
  .pui-table tbody tr.is-selected{background:var(--ae-accent-soft)}
  .vcv-matrix tbody tr:hover,.vcv-flux tbody tr:hover{background:var(--ae-accent-soft)!important}
  .pui-table-wrap,.vcv-scroll{border-radius:16px}
  .pui-modal-panel{border-radius:20px}
  .pui-modal-panel::before{display:none!important}
  .vcv-overlay-box{border-radius:20px}
  /* v3 · escolha do modelo de demonstracao: cartao clicavel de verdade */
  .dp-opts{display:grid;grid-template-columns:1fr 1fr;gap:12px}
  .dp-opt{display:grid;gap:10px;justify-items:start;text-align:left;padding:16px;font:inherit;color:var(--pui-text);background:var(--pui-surface);border:1px solid var(--pui-border);border-radius:16px;box-shadow:0 1px 2px rgba(20,20,28,.04),0 8px 24px -14px rgba(20,20,28,.14);cursor:pointer;transition:transform .16s ease,border-color .16s ease,box-shadow .16s ease}
  .dp-opt:hover:not(:disabled){transform:translateY(-2px);border-color:var(--ae-ink);box-shadow:0 1px 2px rgba(20,20,28,.05),0 16px 30px -16px rgba(20,20,28,.28)}
  .dp-opt:focus-visible{outline:0;border-color:var(--ae-foco);box-shadow:0 0 0 3px var(--ae-accent-soft)}
  .dp-opt-ico{display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:12px;background:var(--pui-surface-muted);color:var(--pui-text-soft);transition:background .16s ease,color .16s ease}
  .dp-opt-ico svg{width:19px;height:19px}
  .dp-opt:hover:not(:disabled) .dp-opt-ico{background:var(--ae-accent-soft);color:var(--ae-on-soft)}
  .dp-opt-tit{font-family:var(--ae-display);font-size:var(--ts-10);font-weight:800;letter-spacing:-.01em}
  .dp-opt-txt{font-size:var(--ts-5);font-weight:500;line-height:1.5;color:var(--pui-text-soft)}
  .dp-opt-cta{display:inline-flex;align-items:center;gap:6px;font-size:var(--ts-3);font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--pui-text-muted)}
  .dp-opt-cta i{font-style:normal;transition:transform .16s ease}
  .dp-opt:hover:not(:disabled) .dp-opt-cta,.dp-opt:focus-visible .dp-opt-cta{color:var(--ae-ink)}
  .dp-opt:hover:not(:disabled) .dp-opt-cta i{transform:translateX(3px)}
  .dp-opt:disabled{cursor:default;opacity:.5}
  .dp-opt.is-loading{opacity:1;border-color:var(--ae-chart-dark);box-shadow:0 0 0 3px var(--ae-accent-soft)}
  .dp-opt.is-loading .dp-opt-ico{background:var(--ae-accent-soft);color:var(--ae-on-soft)}
  .dp-opt.is-loading .dp-opt-cta{color:var(--ae-on-soft)}
  .dp-msg{display:flex;align-items:center;gap:8px;margin-top:14px;font-size:var(--ts-6);font-weight:600;color:var(--pui-text-soft)}
  .dp-msg-erro{color:var(--pui-danger)}
  .dp-spin{flex:0 0 14px;width:14px;height:14px;border-radius:50%;border:2px solid var(--ae-accent-soft);border-top-color:var(--ae-chart-dark);animation:dpspin .7s linear infinite}
  @keyframes dpspin{to{transform:rotate(360deg)}}
  @media(max-width:560px){.dp-opts{grid-template-columns:1fr}}
  .pui-modal-actions .pui-button,.pui-modal-close{border-radius:999px}
  .pui-switch input:checked+span{background:var(--ae-accent)!important;border-color:var(--ae-accent)!important}
  .pui-switch input:checked+span::before{background:var(--ae-ink)}
  .pui-progress span{background:var(--ae-accent)}
  .vcv-info{border-left-color:var(--ae-accent)!important}
  /* v3: chips/estados ativos por tela -> amarelo */
  .mk-chip.on,.int-chip.on,.fn-chip.on{border-color:var(--ae-accent)!important;background:var(--ae-accent-soft)!important;color:var(--ae-on-soft)!important}
  .dr-pasta.is-ativa{background:var(--ae-accent-soft)!important;color:var(--ae-on-soft)!important}
  .cnv-badge.jur{background:var(--ae-accent-soft)!important;color:var(--pui-warning)!important}
  .ms-tipos .is-active,.ms-tipos button.on,.ms-tipo.on,.ms-tipo.is-active{background:var(--ae-accent)!important;color:var(--ae-accent-ink)!important;border-color:var(--ae-accent)!important}
  .sc-idx{background:var(--ae-accent-soft)!important;color:var(--ae-on-soft)!important}

  /* ===== BLOCO 2 do plano de design (auditoria 2026-07-24): o PRETO volta a ser só AÇÃO =====
     O v3 fez --pui-primary virar preto (cor de clique), mas o preto continuou pintando
     rótulo, barra de gráfico, selo e contorno — o olho é puxado pra coisa que não clica.
     Aqui cada uso volta pra camada certa: rótulo = neutro legível · série de gráfico =
     amarelo de marca · selo = cor semântica. Detalhe em docs/specs/plano-design-v3.md. */

  /* A FONTE DA MARCA no app inteiro. O <body> carrega .pui-font-inter (seletor de fonte do DS
     compartilhado), que redeclara --pui-font e ANULAVA o valor v3 do :root — resultado: só o
     que pedia --ae-display explicitamente (h1, número do KPI) saía em Plus Jakarta Sans; corpo,
     botão e navegação continuavam em Inter. Redeclarar aqui, com especificidade maior, sem
     tocar no CSS compartilhado. */
  body.pui-font-inter{--pui-font:'Plus Jakarta Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif}

  /* rótulo de indicador legível: --pui-text-muted (#9da0a8) dá 2,6:1 no branco (reprova AA) */
  .pui-kpi-card span,.fx-kpi .k-lab,.kpi-ctx em,.res-tbl th{color:var(--pui-text-soft)}

  /* o DS compartilhado define success/warning/info mas NÃO danger — sem esta regra o pior
     estado (ex.: "1 de 9 essenciais" no Data Room) caía no cinza neutro do selo padrão */
  .pui-badge-danger{color:var(--pui-danger);background:var(--pui-danger-soft);border-color:rgba(210,59,73,.20)}

  /* barras de gráfico pintadas com a cor de AÇÃO parecem botão desligado -> série amarela */
  #caniveteScreen .fx-meter i,[data-view-panel="captacao"] .fx-meter i,#cnvInvestidor .iv-bar{background:var(--ae-chart)}

  /* "Aprovado" estava com o cinza de desabilitado (herdou --pui-primary-soft) */
  .fase-Aprovado{background:var(--pui-success-soft);color:var(--pui-success)}

  /* navegação: hover quase inexistente e "Voltar ao portfólio" da cor do próprio fundo */
  .pui-nav-item:hover:not(.is-active){background:var(--ae-accent-soft);color:var(--pui-text)}
  .vcv-side-back{background:var(--pui-surface);color:var(--pui-text);border:1px solid var(--pui-border-strong)}
  .vcv-side-back:hover{background:var(--ae-accent-soft);border-color:var(--ae-accent)}

  /* sobras da paleta quente (bege/creme/petróleo) que ficam encardidas ao lado do cinza frio */

  /* o "ƒ" do memorial era a ÚNICA serifa da interface (Georgia) */
  .kpi-info{font-family:var(--pui-font)!important;font-style:italic!important;font-weight:800!important;font-size:var(--ts-7)!important}
  .kpi-info:hover{color:var(--ae-on-soft);border-color:var(--ae-accent);background:var(--ae-accent-soft)}

  /* grades balanceadas (sem KPI órfão "3+1") */
  .vcv-grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .vcv-grid-4{grid-template-columns:repeat(4,minmax(0,1fr)) !important}
  /* responsivo: ganha/perde colunas conforme a largura, sem órfão */
  @media(min-width:1700px){.vcv-grid-2{grid-template-columns:repeat(4,minmax(0,1fr))}}
  @media(max-width:1280px){.vcv-grid-4{grid-template-columns:repeat(2,minmax(0,1fr)) !important}}
  @media(max-width:1024px){.pui-kpi-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.pui-kit-grid,.vcv-grid-2{grid-template-columns:1fr !important}}
  @media(max-width:680px){.pui-kpi-grid,.vcv-grid-4{grid-template-columns:1fr !important}}
  /* ===== BARRA DE FERRAMENTAS ≠ AÇÕES DE FORMULÁRIO (raiz do mobile quebrado) =====
     O design system (propulsor-ui.css @≤680px) empilha TODA .pui-action-row em
     coluna com .pui-button{width:100%}. Pra ações de modal/formulário isso é
     certo — pra BARRA DE FERRAMENTAS é o que fazia a topbar do app ter 199px de
     altura no celular (e o "Status/Exportar" do Resumo virar duas faixas).
     Aqui as barras voltam a ser linha e os botões ao tamanho do conteúdo.
     Na régua do DS (680px), não na do app (599px) — senão 600–680px fica quebrado. */
  @media(max-width:680px){
    #app .pui-topbar .pui-action-row,
    #app .pui-page-head .pui-action-row{flex-direction:row;align-items:center;flex-wrap:wrap}
    #app .pui-topbar .pui-button,
    #app .pui-page-head .pui-button,
    #app .pui-page-head .pui-select{width:auto}
    /* O min-width:210px do seletor de versão (inline no HTML) sozinho já obrigava
       a topbar a quebrar em 3 faixas no tablet pequeno. Solto ele. */
    #app .pui-topbar #sel-versao{min-width:0 !important;max-width:150px}
  }
  /* responsivo tablet (iPad): sidebar = trilho de ícones AO LADO do conteúdo (não empilha no topo) — consistente com o desktop */
  @media(max-width:920px) and (min-width:600px){
    #app.pui-app,#app.pui-app.is-sidebar-collapsed{grid-template-columns:72px minmax(0,1fr);overflow:hidden}
    #app .pui-sidebar{min-height:100%;padding:16px 8px;border-right:1px solid var(--pui-border);border-bottom:0}
    #app .pui-nav{grid-template-columns:1fr}
    #app .pui-nav-item{justify-content:center;padding-left:0;padding-right:0}
    #app .pui-nav-label,#app .pui-sidebar-brand a span:not(.pui-logo-mark),#app .pui-sidebar-foot,#app .pui-sidebar-toggle,#app .pui-nav-section-title{display:none}
    #app .pui-main{padding:18px 18px 56px}
  }
  /* ===== CELULAR (<600px): layout dedicado. A sidebar vira um TRILHO horizontal
     rolável no topo e o conteúdo ocupa a largura toda. Escopado só a telefone —
     não afeta desktop/tablet. Legibilidade: fontes e alvos de toque maiores. ===== */
  @media(max-width:599px){
    /* App: uma coluna, nav em cima, conteúdo embaixo em largura total */
    #app.pui-app,#app.pui-app.is-sidebar-collapsed{grid-template-columns:1fr !important;grid-template-rows:auto minmax(0,1fr);overflow:visible}
    #app .pui-sidebar{flex-direction:row;align-items:center;gap:4px;min-height:auto;height:auto;padding:7px 8px;border-right:0;border-bottom:1px solid var(--pui-border);overflow-x:auto;-webkit-overflow-scrolling:touch;position:sticky;top:0;z-index:20;background:#fbf9f3}
    #app .pui-sidebar-brand,#app .vcv-side-proj,#app .pui-sidebar-foot,#app .pui-sidebar-toggle,#app .pui-nav-section-title{display:none}
    #app .pui-nav{display:flex;flex-direction:row;grid-template-columns:none;gap:3px;flex-wrap:nowrap}
    /* width:auto é OBRIGATÓRIO: o DS define .pui-nav-item{width:100%} (certo pra
       sidebar vertical). No trilho horizontal isso fazia cada item medir 100% da
       faixa (1386px!) — a navegação inteira virava ~28.000px e o celular não
       conseguia trocar de tela. flex:0 0 auto sozinho não resolve: flex-basis:auto
       cai justamente no width. */
    #app .pui-nav-item{flex:0 0 auto;width:auto;flex-direction:column;gap:3px;padding:7px 9px;font-size:var(--ts-1);line-height:1.1;white-space:nowrap;text-align:center;border-radius:9px}
    #app .pui-nav-item .pui-nav-label{display:block;font-size:var(--ts-1)}
    #app .pui-nav-item [data-icon],#app .pui-nav-item svg{width:19px;height:19px}
    #app .vcv-side-back{flex:0 0 auto;width:auto;margin:0 4px 0 0;padding:7px 11px}
    #app .vcv-side-back .pui-nav-label{display:none}
    #app .pui-main{padding:16px 14px 80px}
    /* Legibilidade: sobe o piso das fontes miúdas do conteúdo */
    #app .pui-page-head p{font-size:var(--ts-9)}
    #app .pui-card{padding:16px}
    /* Topbar do app: UMA LINHA só (era 199px de altura — metade do iPhone gasta
       antes do conteúdo). O nome do projeto trunca; o seletor de versão perde o
       min-width:210px fixo (que travava a linha num viewport de 375px);
       "Salvar versão" fica só com o ícone; o sino (que não tem função nenhuma) sai. */
    #app .pui-topbar{flex-wrap:nowrap;gap:8px;align-items:center}
    #app .pui-topbar>.pui-action-row:first-child{flex:1 1 auto;min-width:0}
    #app .pui-topbar .proj-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
    #app .pui-topbar>.pui-action-row:last-child{flex:0 0 auto;gap:6px}
    #app .pui-topbar #btn-salvar-versao .btn-lbl{display:none}
    #app .pui-topbar #btn-salvar-versao{padding-left:11px;padding-right:11px}
    /* Some no celular: o sino não tem função nenhuma e o seletor de versão é
       controle avançado (o app abre no "Rascunho atual"). Os dois juntos comiam
       o espaço do NOME DO PROJETO, que ficava em "Re…" — e saber em que
       empreendimento se está vale mais no telefone que trocar de snapshot.
       As versões seguem inteiras no desktop e no Comparar versões. */
    #app .pui-topbar #btn-sino,
    #app .pui-topbar #sel-versao{display:none}
    /* Botão em cabeçalho de card não quebra no meio da palavra ("Abrir / DNA") */
    #app .pui-card-head{flex-wrap:wrap;gap:10px}
    #app .pui-card-head .pui-button{white-space:nowrap}
    /* Header do PORTFÓLIO: marca em cima, ações embaixo em largura total */
    .pipe-top{flex-wrap:wrap;gap:10px;padding:12px 14px}
    .pipe-top .pui-action-row{width:100%;flex-wrap:wrap;gap:8px}
    .pipe-top .pui-search{min-width:0 !important;flex:1 1 100%}
    .pipe-top .pui-button{flex:1 1 auto;justify-content:center}
    .pipe-top .pui-usermenu{flex:0 0 auto}
    .pipe-wrap{padding-left:14px;padding-right:14px}
    /* Modais viram "folha" que sobe de baixo (bottom sheet) — cabe na tela do celular */
    .vcv-overlay{align-items:flex-end;padding:0}
    .vcv-overlay-box{max-width:100% !important;width:100%;max-height:92vh;overflow:auto;border-radius:18px 18px 0 0;padding:20px 16px}
    /* Tabelas largas rolam dentro da própria caixa, sem estourar a página.
       O min-width só vale pra quem TEM caixa rolante (.vcv-scroll/.pui-table-wrap):
       aplicado a toda tabela, ele esticava também as soltas — a .res-tbl do card
       "Retorno do investimento" ia a 520px, empurrava o card pra 554 e criava
       scroll horizontal na página inteira. Tabela solta = fluida. */
    #app .pui-main table{min-width:0;width:100%}
    #app .pui-main .vcv-scroll table,
    #app .pui-main .pui-table-wrap table{min-width:520px;width:auto}
    .vcv-scroll,.pui-view [style*="overflow"]{max-width:100%}
  }
  /* tabelinhas do dashboard */
  .ob-tot{font-variant-numeric:tabular-nums}
  .res-tbl{width:100%;border-collapse:collapse}
  .res-tbl th{font-size:var(--ts-3);color:var(--pui-text-muted);text-transform:uppercase;letter-spacing:.02em;font-weight:700;padding:5px 6px;border-bottom:1px solid var(--pui-border)}
  .res-tbl td{padding:6px 6px;border-bottom:1px solid var(--pui-surface-muted);font-size:var(--ts-6)}
  .res-bar{display:flex;align-items:center;gap:10px;margin-bottom:9px;font-size:var(--ts-6)}
  .res-bar .lab{width:96px;color:var(--pui-text-soft)}
  .res-bar .trk{flex:1;background:var(--pui-surface-muted);border-radius:5px;height:18px;overflow:hidden}
  .res-bar .val{width:118px;text-align:right;font-weight:700;font-variant-numeric:tabular-nums}
  .res-bar .pc{width:46px;text-align:right;color:var(--pui-text-muted);font-size:var(--ts-3)}

/* ---- bloco 1 (vinha da linha 1116 do index.html) ---- */
      #adminScreen .adm-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:var(--pui-space-4)}
      #adminScreen .adm-kpis .pui-card{padding:16px 18px}
      #adminScreen .adm-kpis strong{font-size:var(--tn-4);line-height:1.1}
      #adminScreen .adm-kpis .pui-card>div{font-size:var(--ts-3);color:var(--pui-text-muted);text-transform:uppercase;letter-spacing:.05em;margin-top:2px}
      #adminScreen .adm-sec{margin-bottom:var(--pui-space-4)}
      #adminScreen .adm-2col{display:grid;grid-template-columns:1fr 1fr;gap:var(--pui-space-4);align-items:start}
      #adminScreen #adm-lista{overflow:auto}
      #adminScreen #adm-lista th,#adminScreen #adm-lista td{padding:9px 10px;border-bottom:1px solid var(--pui-border)}
      #adminScreen #adm-lista thead th{border-bottom:2px solid var(--pui-border);position:sticky;top:0;background:var(--pui-surface)}
      #adminScreen #adm-audit{overflow:auto;max-height:420px}
      #adminScreen .adm-busca{position:relative;min-width:260px;flex:1;max-width:380px}
      #adminScreen .adm-busca input{width:100%;box-sizing:border-box;padding:9px 12px;font:inherit;font-size:var(--ts-8);border:1px solid var(--pui-border);border-radius:var(--pui-radius-sm);background:var(--ae-field);outline:none}
      #adminScreen .adm-busca input:focus{border-color:var(--pui-border-strong)}
      @media(max-width:920px){#adminScreen .adm-2col{grid-template-columns:1fr}}
      @media(max-width:599px){#adminScreen .adm-kpis{grid-template-columns:repeat(2,1fr)}}

/* ---- bloco 2 (vinha da linha 1236 do index.html) ---- */
      /* .mk-chip vale TAMBÉM no #modalMkCfg: o modal vive FORA do #mercadoScreen no DOM —
         escopado só na tela, o chip .on ficava sem estilo no gerenciador e o toggle de
         grupo parecia morto (bug do Bruno em produção, 2026-07-20). */
      #mercadoScreen .mk-chips,#modalMkCfg .mk-chips{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:var(--pui-space-4);align-items:center}
      #mercadoScreen .mk-chip,#modalMkCfg .mk-chip{border:1px solid var(--pui-border);background:var(--pui-surface);border-radius:999px;padding:6px 14px;font-size:var(--ts-6);cursor:pointer;font-family:inherit;display:inline-flex;gap:7px;align-items:center}
      #mercadoScreen .mk-chip i,#modalMkCfg .mk-chip i{font-style:normal;width:9px;height:9px;border-radius:3px;display:inline-block;background:var(--pui-border)}
      #mercadoScreen .mk-chip.on,#modalMkCfg .mk-chip.on{border-color:var(--pui-primary);color:var(--pui-primary);background:var(--pui-primary-soft);font-weight:700}
      #mercadoScreen .mk-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
      #mercadoScreen .mk-card{position:relative;border-top:3px solid var(--pui-border)}
      #mercadoScreen .mk-card h3{font-size:var(--ts-10);margin:0}
      #mercadoScreen .mk-card .mk-reg{font-size:var(--ts-3);color:var(--pui-text-soft)}
      #mercadoScreen .mk-kv{display:flex;justify-content:space-between;font-size:var(--ts-6);padding:5px 0;border-bottom:1px solid var(--pui-surface-muted)}
      #mercadoScreen .mk-kv b{font-variant-numeric:tabular-nums}
      #mercadoScreen .mk-preco{margin-top:8px;font-size:var(--ts-5);color:var(--pui-text-soft)}
      #mercadoScreen .mk-preco b{color:var(--pui-text);font-size:var(--ts-10)}
      #mercadoScreen .mk-rm{position:absolute;top:10px;right:10px;width:24px;height:24px;color:var(--pui-danger)}
      /* emprego (CAGED, economia inteira) = destaque do card */
      #mercadoScreen .mk-emp{display:flex;justify-content:space-between;align-items:center;gap:10px;margin:10px 0 4px;padding:8px 10px;background:var(--pui-surface-muted);border-radius:10px}
      #mercadoScreen .mk-emp .mk-emp-t{font-size:var(--ts-2);color:var(--pui-text-soft);text-transform:uppercase;letter-spacing:.03em;display:block}
      #mercadoScreen .mk-emp b{font-size:var(--tn-1);font-variant-numeric:tabular-nums;line-height:1.2}
      #mercadoScreen .mk-emp small{display:block;font-size:var(--ts-3);color:var(--pui-text-soft)}
      #mercadoScreen .mk-rank{position:absolute;top:-12px;right:10px;background:var(--pui-primary);color:var(--ae-on-primary);font-size:var(--ts-3);font-weight:700;border-radius:999px;padding:2px 9px}
      /* skeleton: percepção de velocidade enquanto IBGE/CAGED respondem */
      #mercadoScreen .mk-skel{display:inline-block;width:58px;height:12px;border-radius:6px;vertical-align:middle;background:linear-gradient(90deg,var(--pui-surface-muted) 25%,#e7ebee 50%,var(--pui-surface-muted) 75%);background-size:200% 100%;animation:mkskel 1.2s linear infinite}
      @keyframes mkskel{from{background-position:200% 0}to{background-position:-200% 0}}
      @media(max-width:599px){#mercadoScreen .mk-grid{grid-template-columns:1fr}}
      /* Página da cidade (Fatia 2) */
      #mercadoScreen #mk-ordenar-wrap{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:-4px 0 14px}
      /* A PRAÇA ABERTA, marcada na grade (07/08). Com a grade viva embaixo do painel, o
         cartão da praça que está aberta ficava idêntico aos outros 115 — e a referência de
         "onde eu estava" se perdia de novo, por outro caminho.
         O anel é a TINTA do tema, não o acento: acento aqui competiria com a cor do grupo
         regional, que é o que a faixa de cima já diz. */
      /* 🔴 `hidden` TEM DE VENCER QUALQUER `display` QUE A GENTE DECLARE — 11/08.
         O atributo `hidden` do HTML só esconde porque a folha do NAVEGADOR diz `[hidden]{display:none}`,
         e essa regra tem especificidade zero. Bastou eu escrever `#mercadoScreen .mk-mapa{display:grid}`
         — id + classe — para ela vencer, e o painel do mapa passou a aparecer SEMPRE: um bloco branco
         vazio de 540px no meio do Mercado, em produção, entre os filtros e a grade.
         Os outros painéis (`#mk-city`, `#mk-regiao`, `#mk-comparar-painel`) escapavam por acidente:
         nenhum deles declara `display` no próprio elemento, só nos filhos. Acidente não é regra.
         Esta linha é a regra, e vale para todo painel desta tela — inclusive os que ainda não existem.
         É a mesma recomendação que a especificação do HTML faz para folhas que mexem em `display`. */
      /* ⚠️ E O ESCUDO PRECISA DAS DUAS FORMAS — aprendido do jeito caro, duas vezes em dois dias.
         `#mercadoScreen [hidden]` (COM espaço) é combinador descendente: cobre os filhos e NÃO
         cobre o próprio `#mercadoScreen`. Em 11/08, o bloco 2 escreveu `#mercadoScreen{display:grid}`
         — id com display, especificidade (1,0,0) — e a TELA INTEIRA passou a aparecer mesmo com
         `hidden`: 900px pendurados no pé do portfólio, começando em y=1272. Ou seja, exatamente a
         queixa que abriu esta frente ("rolando para baixo aparecem elementos de outras páginas"),
         cometida de novo por mim, pelo outro lado. Um espaço num seletor.
         A casa já tinha o precedente escrito na linha 295 (`#app[hidden]`), com o mesmo sintoma
         registrado; eu não olhei. As duas formas, agora, no mesmo lugar. */
      #mercadoScreen[hidden],#mercadoScreen [hidden]{display:none !important}

      /* ===== A SUPERFÍCIE NÃO CRESCE — bloco 2 do plano (11/08) =====
         O Bruno: "se der scroll para baixo aparecem elementos de outras páginas". Não havia
         vazamento de outra tela — varri a árvore e zero elementos fora do `#mercadoScreen`
         ocupavam espaço. O que havia era a PÁGINA crescendo: 1.706px na grade, 2.317px com o
         mapa aberto, 4.889px com uma praça aberta — 5,4 telas. Onze blocos numa coluna, seis
         deles abrindo empurrando os de baixo.
         Aqui a tela passa a ter ALTURA FIXA e a rolagem vai para dentro: o cabeçalho fica preso
         e só o conteúdo corre.

         🔴 ESCOPADO NO ID, NUNCA NA CLASSE. `.vcv-pipeline{min-height:100vh}` (linha 283) veste
         CINCO telas — portfólio, admin, mercado, canivete e aproximações. Mexer nela para
         resolver o Mercado quebraria quatro telas que não pediram nada. O mesmo vale para
         `.pipe-wrap`, `.pipe-top` e o `body`.

         🔴 `100dvh`, NÃO `100vh`. No iOS o `vh` conta a barra do navegador como se ela nunca
         recolhesse, então `100vh` é maior que a tela e a superfície "que não cresce" nasce com
         rolagem. O `dvh` é a altura viva.

         🔴 `minmax(0,1fr)` NÃO É ENFEITE. Filho de grid não encolhe abaixo do próprio conteúdo
         por padrão (`min-height:auto`): sem o `minmax(0,…)` a linha de baixo cresceria até caber
         a grade inteira, o `overflow` nunca entraria em ação e a página voltaria a crescer — com
         o agravante de o defeito parecer "o CSS não pegou".

         E o `padding` lateral guarda a coluna de 1.180px que a tela já tinha, agora por dentro
         do rolador: assim a barra de rolagem fica na borda da janela, e não flutuando no meio. */
      #mercadoScreen{height:100dvh;min-height:0;display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden}
      /* ⚠️ O `+26px` NÃO É CHUTE, e tirá-lo muda a tela. A regra original era
         `max-width:1180px` MAIS `padding:22px 26px` — ou seja, a coluna de conteúdo sempre teve
         **1.128px**, não 1.180. Ao virar rolador de largura total eu recriei a margem pelo
         padding e esqueci os 26 de cada lado: o conteúdo foi para 1.165px, e 37px bastaram para
         a `mk-grid` (que é `auto-fill`) encaixar uma QUARTA coluna. Medido na tela, não deduzido.
         Este bloco é sobre ALTURA; largura mudando junto seria efeito colateral disfarçado de
         decisão de design. */
      /* ⚠️ `both-edges`, NÃO só `stable`. Com `stable` a goteira é reservada só à DIREITA, e a
         coluna centrada por padding escorrega meia barra (~7,5px) para a esquerda — desalinhada
         do cabeçalho, que não tem goteira. `both-edges` reserva dos dois lados e a centragem
         volta a fechar. Em macOS com barra sobreposta a diferença é zero; em Windows/Linux (ou
         macOS com "mostrar barras sempre") são 15px de deslocamento visível. */
      #mercadoScreen .pipe-wrap{max-width:none;margin:0;min-height:0;overflow-y:auto;overflow-x:hidden;
        scrollbar-gutter:stable both-edges;
        padding:22px max(26px,calc((100% - 1180px)/2 + 26px)) 60px}
      /* o cabeçalho deixa de precisar de `sticky`: ele é a linha `auto` do grid, e não rola mais */
      #mercadoScreen .pipe-top{position:static}
      /* 🔴 E O CELULAR PRECISA DA SUA LINHA, senão a regra acima o atropela.
         A folha já tinha `@media(max-width:599px){ .pipe-wrap{padding-left:14px;padding-right:14px} }`
         (linha ~1406). Minha regra é `#mercadoScreen .pipe-wrap` — id+classe, (1,1,0) — e vence a
         de lá, que é só classe. Resultado: no telefone o conteúdo do Mercado passou a 26px da
         borda enquanto o cabeçalho continua a 14px, desalinhado, e a coluna útil caiu de 347px
         para 323px (−7%) justamente onde cada pixel conta. Media query depois, e com o mesmo
         escopo, para ganhar por ordem sem precisar de `!important`. */
      @media(max-width:599px){
        #mercadoScreen .pipe-wrap{padding:22px 14px 60px}
      }

      /* ===== AS TRÊS COLUNAS — bloco 3 do plano (11/08) =====
         O mapa deixa de ser o 5º de onze blocos e vira o CHÃO da tela. É a forma que as quatro
         referências de geomarketing que o Bruno mandou compartilham, e a que ele reconheceu de
         imediato quando o mapa apareceu.

         🔵 O ATALHO QUE ENCURTOU ESTE BLOCO: o trilho já existia. O módulo do mapa desenha
         `.mkmapa-painel` (290px: recorte · camada · legenda · rótulo) MAIS `.mkmapa-tela` lado a
         lado dentro do próprio `#mk-mapa`. Ou seja, "trilho + mapa" já é um elemento só — este
         bloco não constrói trilho nenhum, só põe esse elemento e a lista lado a lado.

         🔴 E A COLUNA DA DIREITA NÃO É NOVA MARCAÇÃO: é a mesma `#mk-grid`, com os mesmos
         `.mk-card` que o JS já monta. Trocar a grade de 3 colunas por uma coluna de linhas é
         CSS. Inventar marcação nova aqui significaria mexer no `renderMkGrid` — 42 linhas de
         gigante compartilhado — e quebrar `mkCityMarcaCard`, que procura `.mk-card` pelo
         `data-mkcity`. O que muda é a forma; a identidade dos elementos fica.

         As colunas rolam POR DENTRO, independentes: `minmax(0,…)` e `min-height:0` outra vez,
         pelo mesmo motivo do bloco 2 — filho de grid não encolhe abaixo do conteúdo sozinho. */
      #mercadoScreen .pipe-wrap{
        display:grid;
        grid-template-columns:minmax(0,1fr) 340px;
        grid-template-rows:auto auto auto minmax(0,1fr) auto;
        padding:0;overflow:hidden;column-gap:0;row-gap:0;scrollbar-gutter:auto}
      #mercadoScreen .pui-page-head{grid-column:1/-1;grid-row:1;padding:14px 22px 2px;margin:0}
      /* o título encolhe porque o assunto da tela agora é o mapa, não o título. Numa superfície
         de altura travada, cada 40px de cabeçalho sai do mapa. */
      #mercadoScreen .pui-page-head h1{font-size:var(--ts-13);margin:0}
      #mercadoScreen .pui-page-head p{margin:2px 0 0;max-width:78ch}
      #mercadoScreen #mk-grupos{grid-column:1/-1;grid-row:2;padding:8px 22px 0}
      #mercadoScreen #mk-ordenar-wrap{grid-column:1/-1;grid-row:3;padding:8px 22px 10px}
      /* 🔴 O RODAPÉ DE FONTES ROLA POR DENTRO, e isso é escolha, não corte.
         Medido: ele ocupava 113px — 13% de uma tela que agora tem altura fixa, roubados do mapa.
         Apagá-lo não era opção: "o rótulo nomeia a base" é regra da casa, e a procedência de
         cada número tem de estar NA TELA, não num link. Então ele fica inteiro, alcançável por
         rolagem dentro da própria faixa, ocupando 3 linhas em vez de 6. Nada de informação sai. */
      #mercadoScreen #mk-fontes{grid-column:1/-1;grid-row:5;margin:0;padding:8px 22px;
        max-height:52px;overflow-y:auto;
        border-top:1px solid var(--pui-border);background:var(--pui-surface)}

      /* o mapa: coluna da esquerda, permanente, sem cartão em volta — ele É a superfície */
      #mercadoScreen .mk-mapa{grid-column:1;grid-row:4;min-height:0;min-width:0;height:100%;
        margin:0;border:0;border-top:1px solid var(--pui-border-strong);border-radius:0}
      #mercadoScreen .mkmapa-tela{min-height:0;height:100%}
      #mercadoScreen .mkmapa-painel{max-height:none}

      /* a lista: coluna da direita, rolando por dentro, cartão virando linha */
      #mercadoScreen .mk-grid{grid-column:2;grid-row:4;display:flex;flex-direction:column;gap:8px;
        min-height:0;min-width:0;overflow-y:auto;padding:12px;
        border-top:1px solid var(--pui-border-strong);border-left:1px solid var(--pui-border);
        background:var(--pui-surface)}
      #mercadoScreen .mk-grid .mk-card{padding:10px 12px}
      #mercadoScreen .mk-grid .mk-card h3{font-size:var(--ts-8)}
      /* 🔴 os painéis de detalhe ocupam a coluna do MAPA e deixam a lista de pé — é a decisão de
         05/08 (`DECISIONS.md:175`) aplicada à geometria nova: o contexto não some ao abrir. */
      /* o `padding-top` de 52px abre o lugar da volta flutuante: sem ele o botão cobria a
         primeira linha do painel (visto na tela: ele em cima do "TERRITÓRIO"). Item de grid que
         flutua não empurra nada — quem tem de abrir espaço é o vizinho. */
      #mercadoScreen #mk-city,#mercadoScreen #mk-comparar-painel,
      #mercadoScreen #mk-nota-painel,#mercadoScreen #mk-regiao{
        grid-column:1;grid-row:4;min-height:0;overflow-y:auto;padding:52px 18px 14px;margin:0;
        border-top:1px solid var(--pui-border-strong);background:var(--pui-bg)}
      /* 🔴 A CAIXA TEM O TAMANHO DO CONTEÚDO E FICA CENTRADA — e mora AQUI porque esta regra tem
         dois IDs e cravava `margin:0`, matando qualquer centragem escrita mais abaixo. Foi o que
         me custou uma rodada: eu escrevia a largura num seletor mais fraco e ela não pegava.
         `overflow-y:auto` fica: é ele que faz do painel o ÚNICO contêiner de rolagem. */
      #mercadoScreen #modalMkCfg{grid-column:1/-1;grid-row:4;min-height:0;overflow-y:auto;
        margin:0 auto;max-width:760px;width:100%}
      /* 🔵 a volta ao mapa flutua sobre o painel de detalhe, na mesma célula do grid: itens de
         grid na mesma célula se empilham, então ela NÃO empurra o conteúdo nem rouba altura de
         uma tela que agora tem altura fixa. */
      /* laçar: o botão fica no canto do mapa; o formulário cobre o pé da coluna do mapa */
      #mercadoScreen #mk-lacar{grid-column:1;grid-row:4;align-self:start;justify-self:end;
        margin:10px;z-index:5;box-shadow:var(--pui-shadow-1,0 1px 3px rgba(0,0,0,.18))}
      #mercadoScreen #mk-laco-form{grid-column:1;grid-row:4;align-self:end;justify-self:stretch;
        margin:0;z-index:6;padding:12px 14px;background:var(--pui-surface);
        border-top:1px solid var(--pui-border-strong);
        display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
      #mercadoScreen #mk-laco-form .lc-conta{flex:1;min-width:220px;font-size:var(--ts-4);color:var(--pui-text-soft)}
      #mercadoScreen #mk-laco-form .lc-conta b{display:block;font-size:var(--ts-6);color:var(--pui-text)}
      #mercadoScreen #mk-laco-form .lc-regra{display:block;margin-top:3px;font-size:var(--ts-2);color:var(--pui-text-muted)}

      /* o convite para guardar um município que ainda não é praça (bloco 5) */
      #mercadoScreen .mk-convite{display:flex;gap:14px;align-items:center;flex-wrap:wrap;
        margin:10px 0 4px;padding:12px 14px;border-radius:12px;
        border:1px dashed var(--pui-border-strong);background:var(--pui-surface)}
      #mercadoScreen .mk-convite > div{flex:1;min-width:240px}
      #mercadoScreen .mk-convite b{display:block;font-size:var(--ts-6)}
      #mercadoScreen .mk-convite span{display:block;font-size:var(--ts-4);color:var(--pui-text-soft);margin-top:3px}
      #mercadoScreen #mk-voltar-mapa{grid-column:1;grid-row:4;align-self:start;justify-self:start;
        margin:10px;z-index:5;box-shadow:var(--pui-shadow-1,0 1px 3px rgba(0,0,0,.18))}

      /* ===== O CELULAR — bloco 6 (11/08) =====
         🔴 MEDIDO ANTES DE DESENHAR, em 375×812, com a regra ingênua de "mapa em cima, lista
         embaixo": o CROMO comia 673px dos 812 — cabeçalho 149 + título 142 + chips 163 +
         ordenar 167 + fontes 52 —, sobravam 139px para dividir entre mapa e lista, e o Leaflet
         mediu **375×0**. Mapa de altura zero não é mapa pequeno: é mapa que não existe.
         Os chips sozinhos ocupavam 163px porque quebravam em quatro linhas.

         Duas decisões, e a segunda é a que resolve:
         (a) o cromo encolhe — chips e ordenar passam a rolar na horizontal, numa linha só, e a
             frase de apresentação sai (ela é contexto, e no telefone contexto que come 1/6 da
             tela é o oposto de contexto);
         (b) MAPA E LISTA SE ALTERNAM. Em 375px, mostrar os dois dá ~250px para cada um, e 250px
             de mapa não se lê nem se navega. Um de cada vez, com um alternador — que é o que
             qualquer app de mapa faz no telefone, e pela mesma razão. */
      @media(max-width:860px){
        /* SEIS linhas: o alternador tem a sua. Ele estava na linha do "Ordenar por" e os dois
           se desenhavam por cima um do outro — itens de grid na mesma célula se empilham, e foi
           exatamente o que aconteceu (visto na tela: "Mapa | Lista" sobre a palavra "ordem"). */
        #mercadoScreen .pipe-wrap{grid-template-columns:minmax(0,1fr);
          grid-template-rows:auto auto auto auto minmax(0,1fr) auto}
        #mercadoScreen .mk-mapa,#mercadoScreen .mk-grid{grid-column:1;grid-row:5;border-left:0}
        #mercadoScreen #mk-city,#mercadoScreen #mk-comparar-painel,
        #mercadoScreen #mk-nota-painel,#mercadoScreen #mk-regiao{grid-column:1;grid-row:5}
        #mercadoScreen #mk-voltar-mapa,#mercadoScreen #mk-lacar{grid-row:5}
        #mercadoScreen #mk-laco-form{grid-row:5}
        #mercadoScreen #mk-fontes{grid-row:6}
        /* o cabeçalho da tela em UMA linha: `.pipe-top` é compartilhada por cinco telas e a
           regra de celular dela empilha os botões em largura total — 290px de cabeçalho numa
           superfície de altura fixa. Escopado no id, as outras quatro seguem como estavam. */
        #mercadoScreen .pipe-top{flex-wrap:nowrap;gap:8px;padding:8px 14px}
        /* ⚠️ e `flex-direction:row` explícito: medido, a `.pui-action-row` resolve para `column`
           no celular (regra de outra faixa), e `flex-wrap:nowrap` sozinho não desempilha nada —
           nowrap numa coluna continua sendo uma coluna. */
        #mercadoScreen .pipe-top .pui-action-row{width:auto;flex-direction:row;flex-wrap:nowrap;
          align-items:center;gap:6px}
        /* ⚠️ `width:auto;min-width:0` explícitos: medido, os dois botões vinham travados em 201px
           cada (largura herdada da faixa de celular compartilhada) e o segundo saía 197px para
           fora da janela — cortado pelo `overflow:hidden` da superfície, que esconde o estouro
           em vez de mostrá-lo. `flex:0 0 auto` sozinho não desfaz largura declarada. */
        #mercadoScreen .pipe-top .pui-button{flex:0 0 auto;width:auto;min-width:0;
          padding:5px 10px;font-size:var(--ts-3)}
        #mercadoScreen .pipe-top .btn-lbl{display:none}
        /* o alternador tem linha própria */
        #mercadoScreen .mk-mob{display:inline-flex;gap:0;grid-column:1;grid-row:4;
          justify-self:start;align-self:center;margin:0 0 8px 14px;
          border:1px solid var(--pui-border-strong);border-radius:999px;overflow:hidden}
        #mercadoScreen .mk-mob button{border:0;background:var(--pui-surface);color:var(--pui-text-soft);
          font:inherit;font-size:var(--ts-4);font-weight:650;padding:6px 16px;cursor:pointer}
        #mercadoScreen .mk-mob button[aria-pressed="true"]{background:var(--pui-text);color:var(--pui-surface)}
        /* 🔴 quem manda na alternância é o atributo, não o JS mexendo em style — o bloco 0 tirou
           o display inline do Mercado justamente para a folha voltar a ter a última palavra. */
        #mercadoScreen[data-mob="mapa"] .mk-grid{display:none}
        #mercadoScreen[data-mob="lista"] .mk-mapa{display:none}
        /* o cromo encolhe: uma linha que rola, em vez de quatro que empilham */
        #mercadoScreen #mk-grupos,#mercadoScreen #mk-ordenar-wrap{flex-wrap:nowrap;overflow-x:auto;
          scrollbar-width:none;padding-bottom:2px}
        #mercadoScreen #mk-grupos::-webkit-scrollbar,#mercadoScreen #mk-ordenar-wrap::-webkit-scrollbar{display:none}
        #mercadoScreen #mk-grupos > *,#mercadoScreen #mk-ordenar-wrap > *{flex:0 0 auto}
        #mercadoScreen .pui-page-head{padding:10px 14px 0}
        #mercadoScreen .pui-page-head p{display:none}
        #mercadoScreen .pui-page-head h1{font-size:var(--ts-11)}
      }
      @media(min-width:861px){ #mercadoScreen .mk-mob{display:none} }

      /* ===== O MAPA DO MERCADO (10/08) =====
         Painel à esquerda, mapa ocupando o resto — a forma que as quatro referências que o Bruno
         mandou compartilham, e que ele reconheceu de imediato. O mapa NÃO tem base de rua no
         recorte de país e de estado: a informação é a mancha, e rua por baixo de coroplético é
         ruído. A base entra quando o recorte descer ao terreno. */
      /* ⚠️ ATUALIZADO EM 11/08 (bloco 3): a premissa desta regra morreu. Ela nasceu quando o mapa
         era um PAINEL que se abria dentro de uma página que crescia — daí o cartão em volta
         (borda, cantos, margem) e o piso de 540px, que era a altura que ele "pedia".
         Hoje o mapa é o CHÃO da tela: ocupa a linha `minmax(0,1fr)` do grid da superfície e a
         altura vem de lá. O piso de 540px agora ATRAPALHA — em janela baixa ele estoura a linha
         e empurra a coluna para fora da área rolável (medido: linha de 500,9px com o mapa
         insistindo em 540). O cartão em volta também sai: superfície não tem moldura. */
      #mercadoScreen .mk-mapa{display:grid;grid-template-columns:290px 1fr;
        overflow:hidden;background:var(--pui-surface);min-height:0}
      /* 🔴 NO CELULAR O `.mk-mapa` VIRA DUAS LINHAS, e elas precisam ser DECLARADAS.
         Com `grid-template-columns:1fr` e dois filhos, o grid cria duas linhas `auto` — e
         `height:100%` de linha automática resolve para ZERO. Medido: a tela do mapa em 0px e o
         Leaflet reportando 375×0, com o contêiner do mapa tendo 429px de altura disponível.
         Altura zero não é mapa pequeno: é mapa que não existe, e sem erro nenhum. */
      /* 🔴 E AS LINHAS SÃO EM `fr`, NÃO `auto` + `max-height`. Medido: com
         `grid-template-rows:auto minmax(0,1fr)` e um teto de 40% no trilho, o grid resolveu
         `427,852px 0px` — a linha `auto` dimensiona pela CONTRIBUIÇÃO DE CONTEÚDO do item, que
         ignora o `max-height`, então o trilho reservou a área inteira e sobrou zero para o mapa.
         O elemento ficava com 171px (o teto funcionava nele) e a LINHA continuava com 428.
         `2fr / 3fr` reparte 40/60 sem depender de conteúdo nenhum, e o `minmax(0,…)` é o de
         sempre: sem ele o filho não encolhe abaixo do próprio conteúdo e o overflow não entra. */
      @media(max-width:860px){
        #mercadoScreen .mk-mapa{grid-template-columns:1fr;
          grid-template-rows:minmax(0,2fr) minmax(0,3fr)}
      }
      #mercadoScreen .mkmapa-painel{border-right:1px solid var(--pui-border);padding:12px;overflow:auto;
        max-height:none;min-width:0;min-height:0}
      /* ⚠️ ATUALIZADO EM 11/08 (bloco 6). O `max-height:none` nasceu quando a página crescia: no
         celular, deixar o trilho inteiro empilhado acima do mapa era razoável porque bastava
         rolar. Numa superfície de altura FIXA ele passou a comer a área toda — medido: trilho
         com 428px dos 429 disponíveis, e a tela do mapa em ZERO. O teto volta, agora relativo
         à tela (`38dvh`), e o trilho rola por dentro. */
      /* ⚠️ E O TETO É RELATIVO À ÁREA DE CONTEÚDO, não à janela. `38dvh` parecia razoável e não
         era: 38% de 812px são 309px, mas a área que sobra depois do cromo é 429px — o trilho
         ficava com 309 e o mapa com 119. Percentual do PAI mede o espaço que existe de verdade;
         percentual da janela mede um espaço que o cromo já gastou.
         40% de 429 = 172px de trilho (que rola por dentro) e 257px de mapa. */
      @media(max-width:860px){#mercadoScreen .mkmapa-painel{border-right:0;
        border-bottom:1px solid var(--pui-border);max-height:none;min-height:0;overflow:auto}}
      /* ⚠️ o Leaflet precisa de ALTURA declarada: contêiner sem altura mede zero e o mapa nasce
         invisível — o modo de falha mais silencioso que esta biblioteca tem.
         A altura continua declarada, e agora vem do grid: `height:100%` de uma linha que é
         `minmax(0,1fr)` da superfície. O piso fixo de 540px saiu porque ele brigava com a linha
         em janela baixa; `min-height:0` é o que PERMITE a caixa encolher e rolar por dentro. */
      #mercadoScreen .mkmapa-tela{min-height:0;height:100%;background:var(--pui-surface-muted)}
      #mercadoScreen .mkmapa-rot{display:block;font-size:var(--ts-1);font-weight:800;letter-spacing:.12em;
        text-transform:uppercase;color:var(--pui-text-muted);margin-bottom:6px}
      #mercadoScreen .mkmapa-abas{display:flex;gap:5px;flex-wrap:wrap;margin-bottom:12px}
      #mercadoScreen .mkmapa-aba{font:inherit;font-size:var(--ts-4);font-weight:700;padding:5px 12px;
        border-radius:999px;cursor:pointer;border:1px solid var(--pui-border-strong);
        background:var(--pui-surface);color:var(--pui-text-soft)}
      #mercadoScreen .mkmapa-aba:hover{border-color:var(--pui-text);color:var(--pui-text)}
      #mercadoScreen .mkmapa-aba.on{background:var(--pui-text);color:var(--pui-bg);border-color:var(--pui-text)}
      #mercadoScreen .mkmapa-campo{margin-top:10px}
      #mercadoScreen .mkmapa-campo label{display:block;font-size:var(--ts-2);font-weight:700;
        color:var(--pui-text-muted);margin-bottom:4px}
      #mercadoScreen .mkmapa-campo select{width:100%;font:inherit;font-size:var(--ts-4);padding:7px 9px;
        border-radius:8px;border:1px solid var(--pui-border-strong);background:var(--ae-field);color:var(--pui-text)}
      /* 🔴 A DEFINIÇÃO DA MÉTRICA, colada no seletor. Sem ela a legenda mostrava "% ao ano" e
         nada dizia de QUE número era aquele por cento — cobrança do Bruno em 10/08. */
      #mercadoScreen .mkmapa-defin{margin-top:7px;padding:8px 10px;background:var(--pui-surface-muted);
        border-radius:9px;border-left:3px solid var(--ae-foco)}
      #mercadoScreen .mkmapa-defin b{display:block;font-size:var(--ts-4);margin-bottom:2px}
      #mercadoScreen .mkmapa-defin span{display:block;font-size:var(--ts-3);color:var(--pui-text-soft);line-height:1.45}
      #mercadoScreen .mkmapa-defin i{display:block;font-style:normal;font-size:var(--ts-2);
        color:var(--pui-text-muted);margin-top:4px}
      #mercadoScreen .mkmapa-legtit{margin:12px 0 5px;font-size:var(--ts-2);font-weight:800;color:var(--pui-text)}
      #mercadoScreen .mkmapa-legtit em{font-style:normal;font-weight:600;color:var(--pui-text-muted)}
      #mercadoScreen .mkmapa-rampa{display:flex;height:11px;border-radius:4px;overflow:hidden;margin-bottom:5px}
      #mercadoScreen .mkmapa-rampa i{flex:1}
      #mercadoScreen .mkmapa-legenda{font-size:var(--ts-2);color:var(--pui-text-soft)}
      #mercadoScreen .mkmapa-legenda div{display:flex;align-items:center;gap:7px;padding:1.5px 0;
        font-variant-numeric:tabular-nums}
      #mercadoScreen .mkmapa-legenda i{width:13px;height:11px;border-radius:3px;flex:none}
      #mercadoScreen .mkmapa-pontos{margin-top:9px;padding-top:8px;border-top:1px solid var(--pui-border)}
      #mercadoScreen .mkmapa-fonte{font-size:var(--ts-2);color:var(--pui-text-muted);margin:10px 0 0;line-height:1.42}
      /* o marcador é um divIcon: sem fundo nem borda do Leaflet */
      .mkmapa-pin{background:none;border:0}
      .mkmapa-dica{font-size:var(--ts-4);line-height:1.35}

      /* ===== O TERRITÓRIO (superfície 1, 10/08) =====
         O painel do território é o ÚNICO bloco do Mercado com fundo forte e faixa de cor: ele
         não é mais um cartão entre os 116, é a moldura em que os 116 são lidos. A faixa usa a
         cor que o próprio usuário deu ao grupo — a mesma que já marca o topo de cada cartão,
         para que a ligação território→partes se leia sem legenda.
         O acento da marca fica FORA daqui de propósito: ele já é a cor do "ativo" no app, e
         aqui competiria com a cor do grupo, que é a informação. */
      #mercadoScreen .mk-terr{margin-bottom:var(--pui-space-4);padding:22px 24px;
        background:var(--pui-surface-strong);border:1px solid var(--pui-border-strong)}
      #mercadoScreen .mk-terr-cab{margin-bottom:16px}
      #mercadoScreen .mk-terr-olho{display:block;font-size:var(--ts-2);font-weight:800;letter-spacing:.14em;
        text-transform:uppercase;color:var(--pui-text-muted);margin-bottom:4px}
      #mercadoScreen .mk-terr-nome{display:flex;align-items:center;gap:10px;margin:0 0 6px;
        font-size:var(--tn-2);letter-spacing:-.02em;line-height:1.1}
      #mercadoScreen .mk-terr-nome i{flex:none;width:14px;height:14px;border-radius:4px;font-style:normal}
      #mercadoScreen .mk-terr-partes{margin:0;font-size:var(--ts-5);color:var(--pui-text-soft);line-height:1.6}
      /* o nome de uma parte é um BOTÃO, não um enfeite: clicar abre a praça */
      #mercadoScreen .mk-terr-lnk{font:inherit;font-weight:700;color:var(--pui-text);background:none;border:0;
        padding:0;cursor:pointer;border-bottom:1px solid var(--pui-border-strong);border-radius:0}
      #mercadoScreen .mk-terr-lnk:hover{border-bottom-color:var(--pui-text)}
      /* separador por BORDA de célula, não pelo truque do gap de 1px sobre fundo cinza: com 7
         números numa grade de 5 colunas a cauda vazia da última linha pintava de cinza e
         parecia célula quebrada. */
      #mercadoScreen .mk-terr-num{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
        gap:0;background:var(--pui-surface);border:1px solid var(--pui-border);border-radius:var(--pui-radius-sm);overflow:hidden}
      #mercadoScreen .mk-terr-kpi{padding:12px 14px;display:flex;flex-direction:column;gap:2px;
        border-right:1px solid var(--pui-border);border-bottom:1px solid var(--pui-border)}
      #mercadoScreen .mk-terr-kpi .k{font-size:var(--ts-4);color:var(--pui-text-soft)}
      #mercadoScreen .mk-terr-kpi .k i{font-style:normal;color:var(--pui-text-muted)}
      #mercadoScreen .mk-terr-kpi .v{font-size:var(--tn-1);font-variant-numeric:tabular-nums;line-height:1.15}
      /* 🔴 O MODO DE AGREGAÇÃO É PARTE DO NÚMERO, não nota de rodapé: fica colado nele. */
      #mercadoScreen .mk-terr-kpi .m{font-size:var(--ts-2);color:var(--pui-text-muted);line-height:1.35}
      #mercadoScreen .mk-terr-kpi.mudo .v{font-size:var(--ts-6);color:var(--pui-text-muted);font-weight:600}
      #mercadoScreen .mk-terr-carregando{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;
        background:var(--pui-surface);border:1px dashed var(--pui-border-strong);border-radius:var(--pui-radius-sm)}
      #mercadoScreen .mk-terr-carregando p{margin:0;font-size:var(--ts-5);color:var(--pui-text-soft)}
      #mercadoScreen .mk-terr-vazio{margin:0;font-size:var(--ts-6);color:var(--pui-text-soft)}
      #mercadoScreen .mk-terr-bloco{margin-top:18px;padding-top:16px;border-top:1px solid var(--pui-border)}
      #mercadoScreen .mk-terr-bloco h3{margin:0 0 4px;font-size:var(--ts-9)}
      #mercadoScreen .mk-terr-cap{margin:0 0 10px;font-size:var(--ts-4);color:var(--pui-text-soft);line-height:1.55}
      #mercadoScreen .mk-terr-tab{width:100%;border-collapse:collapse;font-size:var(--ts-5)}
      #mercadoScreen .mk-terr-tab th,#mercadoScreen .mk-terr-tab td{padding:8px 10px;text-align:left;
        border-bottom:1px solid var(--pui-border);vertical-align:top}
      #mercadoScreen .mk-terr-tab thead th{font-size:var(--ts-2);text-transform:uppercase;letter-spacing:.05em;
        color:var(--pui-text-muted);font-weight:800;white-space:nowrap}
      #mercadoScreen .mk-terr-tab thead th i{font-style:normal;text-transform:none;letter-spacing:0;font-weight:600}
      #mercadoScreen .mk-terr-tab tbody th{font-weight:700;cursor:pointer}
      #mercadoScreen .mk-terr-tab tbody tr:hover{background:var(--pui-surface-muted)}
      #mercadoScreen .mk-terr-tab .num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
      #mercadoScreen .mk-terr-na{color:var(--pui-text-muted)}
      /* a fatia da parte no território: TRILHO visível, senão a barra flutua num cantinho da
         célula alinhada à direita e a proporção deixa de ser legível */
      #mercadoScreen .mk-terr-share{margin-top:5px;height:4px;border-radius:2px;
        background:var(--pui-surface-muted);overflow:hidden}
      #mercadoScreen .mk-terr-share i{display:block;height:100%;background:var(--pui-text-soft)}
      #mercadoScreen .mk-terr-sharel{display:block;font-size:var(--ts-1);color:var(--pui-text-muted);margin-top:3px}
      #mercadoScreen .mk-terr-pend{display:flex;flex-direction:column;gap:7px;margin-bottom:10px}
      #mercadoScreen .mk-terr-pl{display:grid;grid-template-columns:minmax(120px,1fr) 3fr auto;gap:10px;align-items:center;font-size:var(--ts-5)}
      #mercadoScreen .mk-terr-pl b{font-variant-numeric:tabular-nums}
      #mercadoScreen .mk-terr-bar{height:8px;border-radius:4px;background:var(--pui-surface-muted);overflow:hidden}
      #mercadoScreen .mk-terr-bar i{display:block;height:100%;background:var(--pui-info)}
      @media(max-width:599px){
        #mercadoScreen .mk-terr{padding:16px 14px}
        #mercadoScreen .mk-terr-num{grid-template-columns:1fr 1fr}
        #mercadoScreen .mk-terr-pl{grid-template-columns:minmax(90px,1fr) 2fr auto;font-size:var(--ts-4)}
      }
      /* AS PRAÇAS IRMÃS — as outras partes do mesmo território, ao lado da leitura. */
      #mercadoScreen .mk-irmas{margin-top:12px;padding-top:10px;border-top:1px solid var(--pui-border)}
      #mercadoScreen .mk-irmas-rot{display:block;font-size:var(--ts-2);font-weight:800;letter-spacing:.06em;
        text-transform:uppercase;color:var(--pui-text-muted);margin-bottom:7px}
      #mercadoScreen .mk-irmas-fita{display:flex;gap:7px;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}
      #mercadoScreen .mk-irma{flex:0 0 auto;cursor:pointer;font:inherit;font-size:var(--ts-4);font-weight:700;
        padding:6px 13px;border-radius:999px;border:1px solid var(--pui-border-strong);
        background:var(--pui-surface);color:var(--pui-text-soft)}
      #mercadoScreen .mk-irma:hover{border-color:var(--ae-ink);color:var(--pui-text)}
      /* a parte que se está lendo fica marcada e SEM cursor de clique — clicar nela não faz nada */
      #mercadoScreen .mk-irma.is-atual{background:var(--pui-text);color:var(--pui-bg);
        border-color:var(--pui-text);cursor:default}
      #mercadoScreen .mk-card.is-aberta{outline:2px solid var(--pui-text);outline-offset:-1px;
        background:var(--pui-surface-strong)}
      #mercadoScreen .mk-grid .mk-card{cursor:pointer;transition:box-shadow .12s,transform .12s}
      #mercadoScreen .mk-grid .mk-card:hover{box-shadow:0 4px 16px rgba(0,0,0,.09);transform:translateY(-1px)}
      #mk-city .mk-city-head{display:flex;align-items:center;gap:14px;margin-bottom:16px;flex-wrap:wrap}
      #mk-city .mk-city-sec{margin-bottom:var(--pui-space-4)}
      #mk-city .mk-city-sec .pui-card-head h3{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
      #mk-city .mk-city-2col{display:grid;grid-template-columns:1fr 1fr;gap:var(--pui-space-4)}
      #mk-city .mk-badge{font-size:var(--ts-5);font-weight:700;padding:2px 10px;border-radius:999px;background:var(--pui-surface-muted)}
      @media(max-width:820px){#mk-city .mk-city-2col{grid-template-columns:1fr}}
      /* Comparação lado a lado (Fatia 3) — no mobile a tabela ROLA, não espreme */
      #mk-comparar-painel .mk-cmp{border-collapse:separate;border-spacing:0;width:100%;min-width:520px;font-size:var(--ts-6)}
      #mk-comparar-painel .mk-cmp th,#mk-comparar-painel .mk-cmp td{padding:8px 12px;border-bottom:1px solid var(--pui-surface-muted);white-space:nowrap}
      #mk-comparar-painel .mk-cmp thead th{border-bottom:2px solid var(--pui-border);font-size:var(--ts-5);position:sticky;top:0;background:var(--pui-surface);z-index:1}
      #mk-comparar-painel .mk-cmp tbody tr:hover{background:var(--pui-surface-muted)}
      /* 🔴 A PRIMEIRA COLUNA GRUDA (achado 9 do desenho de território). Rolar para a segunda
         entidade escondia o NOME DA MÉTRICA, e o leitor ficava com uma coluna de números sem
         rótulo. Era ruim com 13 praças; com território virando coluna a tabela só GANHA colunas,
         então deixou de ser incômodo e virou defeito. `border-collapse:separate` acima é o preço:
         com `collapse`, a borda da célula grudada não acompanha a rolagem no WebKit. */
      /* ⚠ E A COLUNA GRUDADA PRECISA DE TETO. Medido: com `white-space:nowrap` herdado, o rótulo
         mais longo ("Deslocamento longo · % dos ocupados que gasta mais de meia hora…") esticava
         a primeira coluna para ~700px — e, grudada, ela passou a ocupar a viewport inteira: a
         tabela virou uma lista de nomes de métrica sem um número à vista. Rolar resolvia antes
         porque a coluna saía da tela; agora ela não sai. Teto + quebra de linha. */
      #mk-comparar-painel .mk-cmp .cmp-rot{position:sticky;left:0;z-index:2;text-align:left;
        font-weight:600;background:var(--pui-surface);box-shadow:1px 0 0 var(--pui-border);
        white-space:normal;max-width:240px;min-width:150px}
      #mk-comparar-painel .mk-cmp thead .cmp-rot{z-index:3}
      #mk-comparar-painel .mk-cmp tbody tr:hover .cmp-rot{background:var(--pui-surface-muted)}
      #mk-comparar-painel .mk-cmp .cmp-col{text-align:right;vertical-align:bottom}
      #mk-comparar-painel .mk-cmp .cmp-sub{display:block;font-weight:400;font-size:var(--ts-2);color:var(--pui-text-soft)}
      /* a coluna do TODO se distingue da coluna da PARTE: elas não são a mesma coisa lida em
         escalas diferentes por acaso — comparar as duas exige saber qual é qual */
      #mk-comparar-painel .mk-cmp .cmp-terr{background:var(--pui-surface-strong)}
      #mk-comparar-painel .mk-cmp .cmp-olho{display:block;font-size:var(--ts-1);font-weight:800;
        letter-spacing:.12em;text-transform:uppercase;color:var(--pui-text-muted)}
      #mk-comparar-painel .mk-cmp .cmp-v{text-align:right;font-variant-numeric:tabular-nums}
      #mk-comparar-painel .mk-cmp .cmp-top{font-weight:700;color:var(--pui-success)}
      #mk-comparar-painel .mk-cmp .cmp-top .pui-icon{width:13px;height:13px;vertical-align:-2px;margin-right:3px}
      #mk-comparar-painel .mk-cmp .cmp-na{text-align:right;color:var(--pui-text-muted)}
      /* AUSÊNCIA DECLARADA, e ela precisa PARECER diferente de um número: hachura leve, itálico
         e o mesmo cinza do "sem dado" do papel. O que não pode é passar por célula esquecida. */
      #mk-comparar-painel .mk-cmp .cmp-semregra{text-align:right;font-style:italic;
        font-size:var(--ts-3);color:var(--pui-text-muted);
        background:repeating-linear-gradient(135deg,transparent 0 5px,var(--pui-surface-muted) 5px 6px)}

/* ---- bloco 3 (vinha da linha 1355 do index.html) ---- */
      #caniveteScreen .cnv-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
      #caniveteScreen .cnv-tool h3{font-size:var(--ts-10);margin:8px 0 4px}
      #caniveteScreen .cnv-tool p{font-size:var(--ts-6);color:var(--pui-text-soft);margin:0 0 12px;min-height:52px}
      #caniveteScreen .cnv-badge{display:inline-block;font-size:var(--ts-2);font-weight:700;text-transform:uppercase;letter-spacing:.04em;border-radius:999px;padding:3px 10px}
      #caniveteScreen .cnv-badge.ok{background:var(--pui-success-soft);color:var(--pui-success)}
      #caniveteScreen .cnv-badge.soon{background:var(--pui-surface-muted);color:var(--pui-text-soft)}
      #caniveteScreen .cnv-badge.jur{background:var(--pui-warning-soft);color:var(--pui-warning)}
      #caniveteScreen .cnv-num{font-size:var(--ts-3);color:var(--pui-text-muted);font-variant-numeric:tabular-nums}
      /* Ficha de Captação */
      #caniveteScreen .fx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px 14px}
      #caniveteScreen .fx-sec{margin:20px 0 8px;padding-bottom:6px;border-bottom:2px solid var(--pui-border);display:flex;justify-content:space-between;align-items:baseline}
      #caniveteScreen .fx-sec h3{font-size:var(--ts-8);margin:0;text-transform:uppercase;letter-spacing:.04em}
      #caniveteScreen .fx-sec small{color:var(--pui-text-muted);font-size:var(--ts-3)}
      #caniveteScreen .fx-grid label{display:flex;flex-direction:column;gap:3px;font-size:var(--ts-3);color:var(--pui-text-soft)}
      #caniveteScreen .fx-grid input,#caniveteScreen .fx-grid select,#caniveteScreen .fx-grid textarea{padding:8px 10px;border:1px solid var(--pui-border);border-radius:8px;font:inherit;font-size:var(--ts-7);background:var(--ae-field);width:100%}
      #caniveteScreen .fx-grid textarea{min-height:64px;resize:vertical}
      #caniveteScreen .fx-wide{grid-column:1/-1}
      #caniveteScreen .fx-item{border:1px solid var(--pui-border);border-radius:10px;padding:12px 14px;display:flex;justify-content:space-between;align-items:center;gap:10px;margin-bottom:8px;flex-wrap:wrap}
      #caniveteScreen .fx-meter{height:6px;border-radius:3px;background:var(--pui-surface-muted);overflow:hidden;flex:1;min-width:80px}
      #caniveteScreen .fx-meter i{display:block;height:100%;background:var(--pui-primary)}
      #caniveteScreen .fx2-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:8px 12px;margin-top:8px}
      #caniveteScreen .fx2-grid label{display:flex;flex-direction:column;gap:3px;font-size:var(--ts-3);color:var(--pui-text-soft)}
      #caniveteScreen .fx2-grid input,#caniveteScreen .fx2-grid select{padding:8px 10px;border:1px solid var(--pui-border);border-radius:8px;font:inherit;font-size:var(--ts-7);background:var(--ae-field);width:100%}
      #caniveteScreen .tpl-item{border:1px solid var(--pui-border);border-radius:10px;padding:13px 15px;margin-bottom:10px;display:flex;gap:10px;align-items:center;flex-wrap:wrap}
      @media(max-width:599px){#caniveteScreen .cnv-grid,#caniveteScreen .fx-grid,#caniveteScreen .fx2-grid{grid-template-columns:1fr}}

/* ---- bloco 4 (vinha da linha 1414 do index.html) ---- */
          #cnvPropostas .pp-grid{display:grid;grid-template-columns:minmax(0,360px) 1fr;gap:14px;align-items:start}
          #cnvPropostas .pp-in{display:flex;flex-direction:column;gap:3px;font-size:var(--ts-3);color:var(--pui-text-soft)}
          #cnvPropostas .pp-in input,#cnvPropostas .pp-in select{padding:7px 9px;border:1px solid var(--pui-border);border-radius:8px;font:inherit;font-size:var(--ts-6);background:var(--ae-field);width:100%}
          #cnvPropostas .pp-2{display:grid;grid-template-columns:1fr 1fr;gap:8px 10px}
          #cnvPropostas .pp-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px 10px}
          #cnvPropostas .pp-sec{font-size:var(--ts-3);font-weight:800;text-transform:uppercase;letter-spacing:.05em;color:var(--pui-text-muted);margin:14px 0 6px;padding-top:10px;border-top:1px solid var(--pui-surface-muted)}
          #cnvPropostas .pp-seg{display:inline-flex;border:1px solid var(--pui-border);border-radius:9px;overflow:hidden}
          #cnvPropostas .pp-seg button{border:0;background:var(--pui-surface);padding:6px 12px;font:inherit;font-size:var(--ts-5);cursor:pointer}
          #cnvPropostas .pp-seg button.on{background:var(--pui-primary);color:var(--ae-on-primary);font-weight:700}
          #cnvPropostas .pp-tirs{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px}
          #cnvPropostas .pp-tir{border:1px solid var(--pui-border);border-radius:12px;padding:12px 14px;background:var(--pui-surface)}
          #cnvPropostas .pp-tir .t{font-size:var(--ts-2);text-transform:uppercase;letter-spacing:.05em;color:var(--pui-text-soft)}
          #cnvPropostas .pp-tir .v{font-family:var(--ae-display);font-size:var(--tn-3);font-weight:700}
          #cnvPropostas .pp-tir .s{font-size:var(--ts-2);color:var(--pui-text-muted)}
          #cnvPropostas .pp-kv{display:flex;justify-content:space-between;gap:10px;padding:6px 0;border-bottom:1px solid var(--pui-surface-muted);font-size:var(--ts-6)}
          #cnvPropostas .pp-kv b{font-variant-numeric:tabular-nums}
          @media(max-width:840px){#cnvPropostas .pp-grid{grid-template-columns:1fr}}

/* ---- bloco 5 (vinha da linha 1456 do index.html) ---- */
          #cnvInvestidor .iv-grid{display:grid;grid-template-columns:minmax(0,340px) 1fr;gap:14px;align-items:start}
          #cnvInvestidor.iv-apres .iv-grid{grid-template-columns:1fr}
          #cnvInvestidor.iv-apres .iv-config,#cnvInvestidor.iv-apres .iv-loc-sliders{display:none}
          #cnvInvestidor .iv-sl{display:block;margin-bottom:10px}
          #cnvInvestidor .iv-sl .iv-lab{display:flex;justify-content:space-between;font-size:var(--ts-3);color:var(--pui-text-soft);margin-bottom:2px}
          #cnvInvestidor .iv-sl .iv-lab b{color:var(--pui-primary);font-variant-numeric:tabular-nums}
          #cnvInvestidor .iv-sl input[type=range]{width:100%}
          #cnvInvestidor .iv-sl .iv-sub{font-size:var(--ts-2);color:var(--pui-text-muted);margin-top:1px}
          #cnvInvestidor .iv-seg{display:inline-flex;border:1px solid var(--pui-border);border-radius:9px;overflow:hidden}
          #cnvInvestidor .iv-seg button{border:0;background:var(--pui-surface);padding:6px 13px;font:inherit;font-size:var(--ts-5);cursor:pointer}
          #cnvInvestidor .iv-seg button.on{background:var(--pui-primary);color:var(--ae-on-primary);font-weight:700}
          #cnvInvestidor .iv-hero{font-family:var(--ae-display);font-weight:700}
          #cnvInvestidor .iv-mcards{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:10px;margin-top:14px}
          #cnvInvestidor .iv-row{display:flex;justify-content:space-between;gap:10px;padding:7px 0;border-bottom:1px solid var(--pui-surface-muted);font-size:var(--ts-6)}
          #cnvInvestidor .iv-row b{font-variant-numeric:tabular-nums}
          #cnvInvestidor .iv-bar{height:10px;border-radius:999px;background:var(--pui-primary);transition:width .4s cubic-bezier(.2,.7,.3,1)}
          #cnvInvestidor .iv-bar.off{background:var(--pui-border);opacity:.6}
          @media(max-width:840px){#cnvInvestidor .iv-grid{grid-template-columns:1fr}}

/* ---- bloco 6 (vinha da linha 1556 do index.html) ---- */
        /* tela cheia PRÓPRIA do mapa (overlay do app — não depende da Fullscreen API) */
        #mapa-wrap.mapa-full{position:fixed;inset:0;z-index:300;background:#eeedf1;padding:14px;display:flex;flex-direction:column}
        #mapa-wrap.mapa-full #mapa-svg{flex:1;max-height:none;border-radius:10px}

/* ---- bloco 7 (vinha da linha 1567 do index.html) ---- */
      #apx-form{display:grid;grid-template-columns:1.3fr 1fr 1.1fr .8fr 1fr auto;gap:8px;align-items:end;background:var(--pui-surface-muted);border-radius:10px;padding:12px;margin-bottom:14px}
      #apx-form label{display:flex;flex-direction:column;gap:3px;font-size:var(--ts-2);color:var(--pui-text-soft);text-transform:uppercase;letter-spacing:.03em}
      #apx-form input,#apx-form select{padding:7px 9px;border:1px solid var(--pui-border);border-radius:7px;font:inherit;font-size:var(--ts-7);background:var(--ae-field)}
      #apx-lista table{width:100%;border-collapse:collapse;font-size:var(--ts-7)}
      #apx-lista th,#apx-lista td{padding:8px 9px;border-bottom:1px solid var(--pui-border);text-align:left;vertical-align:middle}
      #apx-lista thead th{font-size:var(--ts-2);color:var(--pui-text-muted);text-transform:uppercase;letter-spacing:.04em;border-bottom:2px solid var(--pui-border)}
      #apx-lista select{padding:4px 6px;border:1px solid var(--pui-border);border-radius:6px;font:inherit;font-size:var(--ts-5);background:var(--ae-field)}
      @media(max-width:760px){#apx-form{grid-template-columns:1fr 1fr}}

/* ---- bloco 8 (vinha da linha 2357 do index.html) ---- */
          /* flex em vez de grid: colunas escondidas por aba (display:none) colapsam sozinhas */
          [data-view-panel="massa"] .ms-wrap{display:flex;flex-wrap:wrap;gap:14px;align-items:flex-start}
          [data-view-panel="massa"] .ms-wrap .ms-form{flex:0 0 244px}
          [data-view-panel="massa"] .ms-wrap .ms-view{flex:1 1 360px}
          [data-view-panel="massa"] .ms-wrap .ms-out{flex:0 0 244px}
          /* ABAS do estudo de massa (Terreno → Ambiental → Legislação → Urbanístico → Custos → Resultado) */
          [data-view-panel="massa"] #ms-abas{display:flex;gap:2px;flex-wrap:wrap;margin-top:var(--pui-space-4);border-bottom:1px solid var(--pui-border);padding-bottom:0}
          [data-view-panel="massa"] #ms-abas button{padding:9px 15px;border:1px solid transparent;border-bottom:none;border-radius:9px 9px 0 0;background:transparent;font:inherit;font-size:var(--ts-7);cursor:pointer;color:var(--pui-text-soft);position:relative;top:1px}
          [data-view-panel="massa"] #ms-abas button:hover{background:rgba(0,0,0,.03)}
          [data-view-panel="massa"] #ms-abas button.is-active{background:var(--pui-surface);border-color:var(--pui-border);color:var(--pui-primary);font-weight:700}
          [data-view-panel="massa"] .ms-aba-vazia{padding:22px 14px;color:var(--pui-text-muted);font-size:var(--ts-6);line-height:1.6;border:1px dashed var(--pui-border);border-radius:10px;margin-top:var(--pui-space-4)}
          [data-view-panel="massa"] .ms-hide-tab{display:none!important} /* esconde por aba; o hidden do msalt continua valendo por conta própria */
          [data-view-panel="massa"] .ms-form label.lei-campo{flex-direction:column;align-items:stretch;gap:3px}
          [data-view-panel="massa"] .ms-form label.lei-campo input,[data-view-panel="massa"] .ms-form label.lei-campo select{width:100%;text-align:left}
          [data-view-panel="massa"] .ms-form h4,[data-view-panel="massa"] .ms-out h4{font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.08em;color:var(--pui-text-muted);margin:12px 0 6px;padding-bottom:4px;border-bottom:1px solid var(--pui-border)}
          [data-view-panel="massa"] .ms-form h4:first-child{margin-top:0}
          [data-view-panel="massa"] .ms-form label{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:4px 0;font-size:var(--ts-5);color:var(--pui-text-soft)}
          [data-view-panel="massa"] .ms-form label[hidden]{display:none} /* o display:flex acima venceria o hidden do modo metros×pavimentos */
          [data-view-panel="massa"] #lt-view{height:600px;min-height:600px;align-self:start;position:sticky;top:12px} /* formulário do loteamento é comprido — a prancha não estica junto, gruda no scroll */
          [data-view-panel="massa"] #ms-tipos{display:flex;gap:8px;margin-top:var(--pui-space-4)}
          [data-view-panel="massa"] #ms-tipos button{padding:7px 14px;border:1px solid var(--pui-border);border-radius:999px;background:var(--pui-surface);font:inherit;font-size:var(--ts-6);cursor:pointer;color:var(--pui-text-soft)}
          [data-view-panel="massa"] #ms-tipos button.is-active{background:var(--pui-primary);border-color:var(--pui-primary);color:var(--ae-on-primary);font-weight:600}
          [data-view-panel="massa"] .ms-form input{width:74px;padding:4px 7px;font-size:var(--ts-5);text-align:right;border:1px solid var(--pui-border);border-radius:6px;background:var(--ae-field);font:inherit;font-variant-numeric:tabular-nums}
          [data-view-panel="massa"] .ms-view{position:relative;min-height:430px;border:1px solid var(--pui-border);border-radius:12px;overflow:hidden;background:var(--pui-surface-strong)}
          [data-view-panel="massa"] .ms-view canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
          [data-view-panel="massa"] .ms-legend{position:absolute;left:10px;bottom:10px;font-size:var(--ts-2);background:rgba(255,255,255,.8);border:1px solid var(--pui-border);border-radius:7px;padding:8px 10px}
          [data-view-panel="massa"] .ms-legend div{display:flex;align-items:center;gap:7px;margin:2px 0}
          [data-view-panel="massa"] .ms-legend .sw{width:11px;height:11px;border-radius:3px;flex:none}
          [data-view-panel="massa"] .ms-ctrl{position:absolute;right:10px;bottom:10px;font-size:var(--ts-1);color:var(--pui-text-muted);background:rgba(255,255,255,.8);border:1px solid var(--pui-border);border-radius:7px;padding:5px 8px}
          [data-view-panel="massa"] .ms-out .row{display:flex;justify-content:space-between;gap:10px;font-size:var(--ts-5);margin:4px 0}
          [data-view-panel="massa"] .ms-out .row b{font-variant-numeric:tabular-nums;font-weight:600}
          /* BLOCO 4: potencial do envelope e VGV indicativo sao o motivo da tela existir. */
          [data-view-panel="massa"] .ms-out .row.big{align-items:baseline}
          [data-view-panel="massa"] .ms-out .row.big b{font-family:var(--ae-display);font-size:var(--tn-3);font-weight:800;letter-spacing:-.02em;line-height:1.1;font-variant-numeric:tabular-nums}
          [data-view-panel="massa"] .ms-out .row.big span{font-weight:700}
          [data-view-panel="massa"] .ms-flag{margin-top:8px;padding:7px 9px;border-radius:6px;font-size:var(--ts-3);line-height:1.45}
          [data-view-panel="massa"] .ms-flag.warn{background:var(--pui-danger-soft);border:1px solid rgba(210,59,73,.32);color:var(--pui-danger)}
          [data-view-panel="massa"] .ms-flag.ok{background:var(--pui-success-soft);border:1px solid rgba(18,146,92,.32);color:var(--pui-success)}
          [data-view-panel="massa"] .ms-flag.err{background:var(--pui-danger-soft);border:1px solid rgba(210,59,73,.5);color:var(--pui-danger);font-weight:600}
          @media (max-width:1100px){[data-view-panel="massa"] .ms-wrap{grid-template-columns:1fr}[data-view-panel="massa"] .ms-view{min-height:340px}}
          /* ===== BLOCO 6 · item 9 — ESTUDO DE MASSA no celular =====
             .ms-form e .ms-out sao flex:0 0 244px — NAO crescem. Num telefone com ~315px
             uteis dentro do cartao, a aba Resultado mostrava o quadro de areas preso em
             244px com uma faixa morta de ~71px do lado. E a prancha do loteamento e
             height:600px + position:sticky: ocupava a tela quase inteira e grudava no
             topo, deixando o formulario de loteamento impossivel de usar.
             No telefone: tudo em UMA coluna de largura cheia; a prancha volta a rolar
             junto com a pagina, com 320px de altura (position:relative — nao static, senao
             o canvas absoluto perde a referencia); e as 6 abas viram um trilho horizontal
             rolavel em vez de 3 linhas empilhadas. */
          @media(max-width:599px){
            [data-view-panel="massa"] .ms-wrap{gap:12px}
            [data-view-panel="massa"] .ms-wrap .ms-form,
            [data-view-panel="massa"] .ms-wrap .ms-out,
            [data-view-panel="massa"] .ms-wrap .ms-view{flex:1 1 100%;min-width:0}
            [data-view-panel="massa"] .ms-view{min-height:300px}
            [data-view-panel="massa"] #lt-view{position:relative;top:auto;height:320px;min-height:320px}
            [data-view-panel="massa"] #ms-abas{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:1px}
            [data-view-panel="massa"] #ms-abas button{flex:0 0 auto;white-space:nowrap;padding:9px 12px}
            [data-view-panel="massa"] #ms-tipos{flex-wrap:wrap;gap:6px}
            [data-view-panel="massa"] .ms-form label{gap:10px}
            [data-view-panel="massa"] .ms-form label>span{flex:1 1 auto;min-width:0}
            [data-view-panel="massa"] .ms-form input{width:96px}
          }

/* ---- bloco 9 (vinha da linha 2660 do index.html) ---- */
          [data-view-panel="obra"] .ob-in{padding:6px 8px;border:1px solid var(--pui-border);border-radius:6px;font:inherit;font-size:var(--ts-6);width:100%;box-sizing:border-box;background:var(--ae-field)}
          [data-view-panel="obra"] .ob-tbl{width:100%;border-collapse:collapse;font-size:var(--ts-6)}
          [data-view-panel="obra"] .ob-tbl th{font-size:var(--ts-3);font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--pui-text-soft);text-align:right;padding:7px 10px;border-bottom:1px solid var(--pui-border)}
          [data-view-panel="obra"] .ob-tbl th:first-child,[data-view-panel="obra"] .ob-tbl td:first-child{text-align:left}
          [data-view-panel="obra"] .ob-tbl td{padding:7px 10px;border-bottom:1px solid var(--pui-surface-muted);text-align:right;color:var(--pui-text)}
          [data-view-panel="obra"] .ob-tbl tfoot td{border-top:1px solid var(--pui-border);border-bottom:none}
          [data-view-panel="obra"] .ob-tot{font-weight:700;color:var(--pui-primary)}
          [data-view-panel="obra"] .ob-cv{height:84px;background:var(--pui-surface-muted);border-radius:8px;overflow:hidden}
          [data-view-panel="obra"] .ob-cost{border:1px solid var(--pui-border);border-radius:10px;padding:12px 14px;margin-bottom:12px}
          [data-view-panel="obra"] .ob-cost-h{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}
          [data-view-panel="obra"] .ob-cost-h h4{margin:0;font-size:var(--ts-8)}
          [data-view-panel="obra"] .ob-grid{display:grid;gap:8px;align-items:end}
          [data-view-panel="obra"] .ob-grid label{font-size:var(--ts-3);color:var(--pui-text-soft);display:flex;flex-direction:column;gap:3px}
          /* ---- OUTROS CUSTOS DA OBRA: um esqueleto de colunas para os 5 blocos ----
             O template mora AQUI, uma vez. Nenhum bloco pode ter o seu próprio
             grid-template-columns inline: era isso que fazia "Início" cair em 5 x diferentes
             e a caixa de Verba de um bloco ficar em cima da caixa de % do bloco de baixo. */
          [data-view-panel="obra"] .ob-cost>.ob-grid{grid-template-columns:1.25fr 1.1fr 1.1fr 1.5fr .85fr .85fr 1fr}
          /* célula sem campo: ocupa a coluna e não empurra ninguém */
          [data-view-panel="obra"] .ob-vazio{visibility:hidden}
          /* texto explicativo que ocupa uma coluna do esqueleto */
          [data-view-panel="obra"] .ob-nota{justify-content:flex-end;font-style:italic;color:var(--pui-text-muted)}
          /* valor que o app calcula (não se digita) e escolha que o bloco não oferece */
          [data-view-panel="obra"] .ob-calc,[data-view-panel="obra"] .ob-fixo{background:var(--pui-surface-muted);color:var(--pui-text-soft);border-style:dashed;line-height:1.35;min-height:31px;display:flex;align-items:center}
          [data-view-panel="obra"] .ob-calc{font-variant-numeric:tabular-nums;font-weight:600;color:var(--pui-text)}
          /* CAMPO EM USO × CAMPO IGNORADO — o "Usar" decide qual conta. Sem esta marca dá
             para digitar num campo que o cálculo não lê, e o número some sem aviso. */
          [data-view-panel="obra"] .ob-grid label.is-off{opacity:.42}
          [data-view-panel="obra"] .ob-grid label.is-off .ob-in{background:var(--pui-surface-muted)}
          [data-view-panel="obra"] .ob-grid label.is-on{color:var(--pui-text);font-weight:700}
          /* AMARELO, não preto: preto é o foco do teclado (borda escura + anel), e as duas
             marcas juntas fariam parecer que o cursor está onde não está. */
          [data-view-panel="obra"] .ob-grid label.is-on .ob-in{background:var(--ae-accent-soft);box-shadow:inset 0 -2px 0 var(--ae-accent-strong)}
          /* sub-bloco: composição de UM campo do esqueleto, não uma linha de campos irmãos */
          [data-view-panel="obra"] .ob-sub{margin:10px 0 0;padding:10px 12px;border-left:2px solid var(--pui-border);background:var(--pui-surface-muted);border-radius:0 8px 8px 0}
          [data-view-panel="obra"] .ob-sub.is-off{opacity:.42}
          [data-view-panel="obra"] .ob-sub-h{font-size:var(--ts-2);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--pui-text-soft);margin-bottom:7px}
          [data-view-panel="obra"] .ob-sub-grid{grid-template-columns:repeat(4,minmax(0,1fr));max-width:640px}
          @media(max-width:1180px){
            /* 7 colunas viram 4: Usar/Verba/%/extra em cima, prazo embaixo — mas a ORDEM
               e o alinhamento entre os blocos continuam os mesmos. */
            [data-view-panel="obra"] .ob-cost>.ob-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
          }
          @media(max-width:719px){
            [data-view-panel="obra"] .ob-cost>.ob-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
            [data-view-panel="obra"] .ob-sub-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
            /* a célula vazia FICA: tem altura zero (não gasta linha) e, ocupando a sua vaga
               na grade, mantém "Início" na mesma linha em todos os blocos também aqui.
               A nota vira uma linha inteira em vez de espremer — ela explica o bloco. */
            [data-view-panel="obra"] .ob-nota{grid-column:1/-1;justify-content:flex-start}
          }

/* ---- bloco 10 (vinha da linha 2811 do index.html) ---- */
            .or-tbl{border-collapse:collapse;font-size:var(--ts-5);font-variant-numeric:tabular-nums;white-space:nowrap}
            .or-tbl th,.or-tbl td{border:1px solid var(--pui-border);padding:5px 9px;text-align:right}
            .or-tbl th{background:var(--pui-surface-muted);color:var(--pui-text-soft);font-size:var(--ts-2);text-transform:uppercase;letter-spacing:.03em}
            .or-tbl th:first-child,.or-tbl td:first-child{text-align:left;position:sticky;left:0;background:var(--pui-surface);font-weight:600;z-index:1}
            .or-tbl th:first-child{background:var(--pui-surface-muted)}
            .or-tbl input{width:92px;padding:3px 6px;border:1px solid var(--pui-border);border-radius:5px;font:inherit;text-align:right;background:var(--pui-surface-strong)}
            .or-fc{color:var(--pui-text-muted)}

/* ---- bloco 11 (vinha da linha 2982 do index.html) ---- */
[data-view-panel="despesas"] .dp-in{padding:6px 8px;border:1px solid var(--pui-border);border-radius:6px;font:inherit;font-size:var(--ts-6);width:100%;box-sizing:border-box;background:var(--ae-field)}[data-view-panel="despesas"] .dpc{border:1px solid var(--pui-border);border-radius:10px;padding:12px 14px;margin-bottom:12px}[data-view-panel="despesas"] .dpg{display:grid;gap:8px;align-items:end}[data-view-panel="despesas"] .dpg label{font-size:var(--ts-3);color:var(--pui-text-soft);display:flex;flex-direction:column;gap:3px}

/* ---- bloco 12 (vinha da linha 3006 do index.html) ---- */
[data-view-panel="impostos"] .im-in{padding:7px 9px;border:1px solid var(--pui-border);border-radius:7px;font:inherit;font-size:var(--ts-7);width:100%;box-sizing:border-box;background:var(--ae-field)}

/* ---- bloco 13 (vinha da linha 3053 do index.html) ---- */
          [data-view-panel="tma"] .tm-in{padding:7px 9px;border:1px solid var(--pui-border);border-radius:7px;font:inherit;font-size:var(--ts-7);width:100%;box-sizing:border-box;background:var(--ae-field)}
          .pui-help{display:inline-flex;align-items:center;justify-content:center;width:15px;height:15px;border-radius:50%;background:var(--pui-border);color:var(--pui-text-soft);font-size:var(--ts-1);font-weight:700;cursor:help;position:relative;margin-left:4px;vertical-align:middle}
          /* ⚠️ A AJUDA TAMBÉM ABRE POR FOCO, não só por :hover. Varredura de 22/08: as 8 dicas
             do app só abriam com o mouse em cima — sem tabindex, sem :focus, sem toque. No celular e
             no teclado elas NUNCA abriam, e o texto de uma delas é literalmente "pra quem é leigo,
             recomendamos...". A ajuda escrita para o leigo era a que o leigo não conseguia abrir. */
          .pui-help:hover::after,.pui-help:focus::after,.pui-help:focus-visible::after{content:attr(data-tip);position:absolute;bottom:140%;left:50%;transform:translateX(-50%);background:var(--pui-text);color:var(--ae-on-primary);padding:9px 11px;border-radius:8px;font-size:var(--ts-4);font-weight:400;width:250px;z-index:60;line-height:1.55;text-align:left;box-shadow:0 6px 18px rgba(0,0,0,.22)}
          .pui-help:hover::before,.pui-help:focus::before,.pui-help:focus-visible::before{content:"";position:absolute;bottom:128%;left:50%;transform:translateX(-50%);border:6px solid transparent;border-top-color:var(--pui-text);z-index:60}
          .vcv-info{border:1px solid var(--pui-border);border-left:3px solid var(--pui-primary);border-radius:10px;margin-bottom:16px;overflow:hidden;background:var(--pui-surface-muted)}
          .vcv-info>summary{cursor:pointer;padding:12px 16px;font-weight:600;font-size:var(--ts-8);list-style:none;display:flex;align-items:center;gap:8px}
          .vcv-info>summary::-webkit-details-marker{display:none}
          .vcv-info[open]>summary{border-bottom:1px solid var(--pui-border)}
          .vcv-info .vcv-info-body{padding:14px 16px;font-size:var(--ts-7);line-height:1.65}
          /* o cartão da régua escolhida pesa mais que os três de apoio */
          .tma-kpis .vcv-kpi.is-heroi{background:var(--ae-accent-soft);box-shadow:0 1px 2px rgba(20,20,28,.04),0 10px 28px -16px rgba(20,20,28,.22)}
          .tma-kpis .vcv-kpi.is-heroi strong{font-size:clamp(28px,3vw,38px)}
          .vcv-verdict{border-radius:12px;padding:16px 18px;display:flex;gap:16px;align-items:flex-start;border:1px solid var(--pui-border)}
          .vcv-verdict .vcv-vd-icon{font-size:30px;line-height:1}

/* ---- bloco 14 (vinha da linha 3166 do index.html) ---- */
[data-view-panel="societario"] .sc-in{padding:5px 7px;border:1px solid var(--pui-border);border-radius:6px;font:inherit;font-size:var(--ts-6);box-sizing:border-box;background:var(--ae-field);width:100%}[data-view-panel="societario"] .sc-tblwrap{overflow-x:auto;-webkit-overflow-scrolling:touch}[data-view-panel="societario"] .sc-tblwrap table{min-width:1180px}[data-view-panel="societario"] .spe-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px}[data-view-panel="societario"] .spe-grid label{display:flex;flex-direction:column;gap:5px;font-size:var(--ts-3);font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--pui-text-soft)}[data-view-panel="societario"] .spe-grid label input{text-transform:none;font-weight:400;letter-spacing:0}[data-view-panel="societario"] .sc-banner{display:flex;flex-wrap:wrap;align-items:center;gap:12px 22px;padding:14px 18px;border:1.5px solid;border-radius:12px;margin-bottom:16px}[data-view-panel="societario"] .sc-banner .scb-ico{font-size:24px;line-height:1;font-weight:700}[data-view-panel="societario"] .sc-banner .scb-metric{display:flex;flex-direction:column;gap:1px;min-width:112px}[data-view-panel="societario"] .sc-banner .scb-metric>span:first-child{font-size:var(--ts-2);font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--pui-text-soft)}[data-view-panel="societario"] .sc-banner .scb-metric b{font-size:var(--tn-2);font-weight:800;letter-spacing:-.01em;line-height:1.15}[data-view-panel="societario"] .sc-banner .scb-msg{flex:1 1 240px;font-size:var(--ts-6);line-height:1.45;color:var(--pui-text)}[data-view-panel="societario"] .sc-card{border:1px solid var(--pui-border);border-radius:12px;padding:14px 16px;margin-bottom:12px;background:var(--ae-field)}[data-view-panel="societario"] .sc-card-head{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin-bottom:12px}[data-view-panel="societario"] .sc-card-head .sc-idx{width:26px;height:26px;flex:none;border-radius:50%;background:var(--pui-surface-muted);color:var(--pui-text-soft);font-size:var(--ts-5);font-weight:700;display:flex;align-items:center;justify-content:center}[data-view-panel="societario"] .sc-card-head .sc-in-nome{flex:1 1 160px;font-weight:600}[data-view-panel="societario"] .sc-card-head .sc-in-papel{flex:0 1 160px}[data-view-panel="societario"] .sc-idgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:10px 12px;margin-bottom:12px}[data-view-panel="societario"] .sc-idgrid label,[data-view-panel="societario"] .sc-econ .sc-pct{display:flex;flex-direction:column;gap:4px;font-size:var(--ts-2);font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--pui-text-soft)}[data-view-panel="societario"] .sc-idgrid label input,[data-view-panel="societario"] .sc-idgrid label select{text-transform:none;font-weight:400;letter-spacing:0}[data-view-panel="societario"] .sc-econ{display:flex;flex-wrap:wrap;align-items:flex-end;gap:12px 18px;padding:12px 14px;border-radius:10px;background:var(--pui-surface-muted)}[data-view-panel="societario"] .sc-econ .sc-pct{width:104px}[data-view-panel="societario"] .sc-econ .sc-pct input{text-align:right;font-weight:700;font-size:var(--ts-10)}[data-view-panel="societario"] .sc-econ .sc-prio{margin-left:auto}[data-view-panel="societario"] .sc-prio-detail{margin-top:10px;padding-top:10px;border-top:1px dashed var(--pui-border)}[data-view-panel="societario"] .sc-prio-detail .sc-pd-lbl{font-size:var(--ts-2);font-weight:700;text-transform:uppercase;letter-spacing:.03em;color:var(--pui-text-soft);margin-bottom:2px}[data-view-panel="societario"] .sc-fescard{border:1px dashed var(--pui-border);border-radius:12px;padding:11px 16px;margin-bottom:10px;background:var(--pui-surface-muted);display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px}
/* ===== BLOCO 6 · item 10 — SOCIETARIO no celular =====
   RAIZ DO BUG: a camada mobile do topo neutraliza o min-width de TODA tabela do
   conteudo (#app .pui-main table{min-width:0;width:100%}) e so devolve a caixa
   rolante pra .vcv-scroll e .pui-table-wrap. Como essa regra tem ID, ela vencia o
   [data-view-panel="societario"] .sc-tblwrap table{min-width:1180px} — resultado:
   as 10 colunas da cascata (capital, recebido, lucro, multiplo, TIR, MTIR, VPL, ROE)
   eram ESMAGADAS numa tela de 375px em vez de rolar. Aqui .sc-tblwrap volta a ser
   caixa rolante: a cascata mantem os 1180px de desenho e rola no dedo DENTRO do
   cartao — a pagina continua sem scroll lateral. As demais .sc-tblwrap (cenarios,
   comparativo) rolam com o piso de 520px da propria camada mobile.
   A tira de metricas acima da tabela (3 colunas fixas) vira 2 + 1 de largura cheia. */
@media(max-width:599px){
  #app .pui-main .sc-tblwrap{max-width:100%}
  #app .pui-main .sc-tblwrap table{min-width:520px;width:auto}
  #app [data-view-panel="societario"] .sc-tblwrap table{min-width:1180px;width:auto}
  #app [data-view-panel="societario"] #sc-wf-body>div:first-child{grid-template-columns:1fr 1fr !important}
  #app [data-view-panel="societario"] #sc-wf-body>div:first-child>div:last-child{grid-column:1/-1}
  #app [data-view-panel="societario"] .sc-econ .sc-prio{margin-left:0}
}

/* ---- bloco 15 (vinha da linha 3230 do index.html) ---- */
[data-view-panel="funding"] .fn-in{padding:7px 9px;border:1px solid var(--pui-border);border-radius:7px;font:inherit;font-size:var(--ts-7);width:100%;box-sizing:border-box;background:var(--ae-field)}[data-view-panel="funding"] .fn-src{border:1px solid var(--pui-border);border-radius:10px;padding:12px 14px;margin-bottom:0}[data-view-panel="funding"] .fn-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px}[data-view-panel="funding"] .fn-grid label{font-size:var(--ts-3);color:var(--pui-text-soft);display:flex;flex-direction:column;gap:3px}.vcv-info-body h4{margin:12px 0 4px;font-size:var(--ts-6);color:var(--pui-primary);text-transform:uppercase;letter-spacing:.03em}[data-view-panel="funding"] .fn-cat{display:flex;flex-wrap:wrap;gap:6px}[data-view-panel="funding"] .fn-chip{border:1px solid var(--pui-border);background:var(--ae-field);border-radius:999px;padding:5px 11px;font-size:var(--ts-5);cursor:pointer;display:inline-flex;gap:6px;align-items:center}[data-view-panel="funding"] .fn-chip:hover{border-color:var(--pui-primary);color:var(--pui-primary)}[data-view-panel="funding"] .fn-chip i{font-style:normal;width:9px;height:9px;border-radius:3px;display:inline-block}[data-view-panel="funding"] .fn-badge{font-size:var(--ts-1);padding:1px 7px;border-radius:999px;font-weight:600;white-space:nowrap}[data-view-panel="funding"] .fn-ck{display:flex;gap:6px;align-items:center;font-size:var(--ts-5);margin-bottom:3px;cursor:pointer}[data-view-panel="funding"] .fn-ck input{width:auto;margin:0}[data-view-panel="funding"] .fn-wf-row{display:flex;align-items:center;gap:8px;margin-bottom:7px;font-size:var(--ts-6)}[data-view-panel="funding"] .fn-bank-row{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--ts-6);padding:4px 0;border-bottom:1px solid var(--pui-surface-muted)}
/* ===== FUNDING: as 6 vagas fixas do cartão de instrumento =====
   Os cartões se empilham na mesma lista, e cada instrumento tem os seus parâmetros. Com a
   grade dimensionada pelo NÚMERO de campos, a coluna da esquerda lia, descendo:
   "% do custo de obra" (espera 80) · "Valor (R$)" (espera 2.000.000) · "Aporte (R$)".
   Agora são sempre 6 vagas em 3 colunas × 2 linhas: quanto · custo · lucro / entra · sai ·
   contratação. Todo cartão tem a mesma altura e a mesma leitura. */
/* as caixas encostam no fim da célula: no celular "Custos de contratação (%)" quebra em
   duas linhas e, sem isto, empurrava a sua caixa 16px abaixo da vizinha na mesma linha */
[data-view-panel="funding"] .fn-grid{align-items:end}
[data-view-panel="funding"] .fn-box{position:relative;display:block}
[data-view-panel="funding"] .fn-box .fn-in{padding-right:38px;text-align:right;font-variant-numeric:tabular-nums}
[data-view-panel="funding"] .fn-un{position:absolute;right:9px;top:50%;transform:translateY(-50%);font-style:normal;font-size:var(--ts-2);font-weight:600;color:var(--pui-text-muted);pointer-events:none;letter-spacing:.02em}
/* vaga que o instrumento não usa: o travessão diz "não tem", diferente de "está zerado" */
[data-view-panel="funding"] .fn-vazio{justify-content:flex-end}
/* mesma caixa do .fn-in (padding + borda + fonte), para a altura acompanhar sozinha se
   o campo mudar — número mágico aqui sairia do lugar no primeiro ajuste de padding */
[data-view-panel="funding"] .fn-vazio .fn-nao{display:flex;align-items:center;justify-content:center;padding:7px 9px;border:1px solid transparent;font-size:var(--ts-7);line-height:1.5;box-sizing:border-box;color:var(--pui-text-muted);opacity:.5}

/* ===== BLOCO 6 · item 8 — FUNDING no celular =====
   Tres coisas estouravam a largura: (a) #fn-list e a grade da bancabilidade usam
   auto-fit com minmax(360px/290px) — auto-fit NAO encolhe abaixo do minimo, entao
   o cartao vazava pra fora da tela; (b) a cascata de distribuicao (.fn-wf-row) soma
   215px de rotulo + 120px de valor + barra = ~350px de largura minima; (c) .fn-grid
   e uma grade de 3 campos numericos. No telefone: 1 coluna, cascata em 2 linhas
   (rotulo + valor em cima, barra embaixo) e campos em 2 colunas. */
@media(max-width:599px){
  #app [data-view-panel="funding"] #fn-list{grid-template-columns:minmax(0,1fr) !important}
  #app [data-view-panel="funding"] [style*="minmax(290px"]{grid-template-columns:minmax(0,1fr) !important}
  #app [data-view-panel="funding"] .fn-grid{grid-template-columns:1fr 1fr !important}
  #app [data-view-panel="funding"] .fn-wf-row{flex-wrap:wrap;gap:5px 10px;margin-bottom:13px}
  #app [data-view-panel="funding"] .fn-wf-row>div:first-child{width:auto !important;flex:1 1 auto;min-width:0;line-height:1.3}
  #app [data-view-panel="funding"] .fn-wf-row>div:nth-child(2){flex:1 1 100% !important;order:3}
  #app [data-view-panel="funding"] .fn-wf-row>div:last-child{width:auto !important;flex:0 0 auto}
}

/* ---- bloco 16 (vinha da linha 3322 do index.html) ---- */
[data-view-panel="inteligencia"] .int-in{padding:8px 11px;border:1px solid var(--pui-border);border-radius:8px;font:inherit;font-size:var(--ts-7);width:100%;box-sizing:border-box;background:var(--ae-field)}[data-view-panel="inteligencia"] .int-chip{border:1px solid var(--pui-border);background:var(--ae-field);border-radius:999px;padding:5px 12px;font-size:var(--ts-5);cursor:pointer;display:inline-block}[data-view-panel="inteligencia"] .int-chip:hover,[data-view-panel="inteligencia"] .int-chip.on{border-color:var(--pui-primary);color:var(--pui-primary);background:var(--pui-surface-muted)}[data-view-panel="inteligencia"] .int-chips{display:flex;flex-wrap:wrap;gap:6px}[data-view-panel="inteligencia"] .int-res{border:1px solid var(--pui-border);border-radius:8px;margin-top:6px;overflow:hidden}[data-view-panel="inteligencia"] .int-res div{padding:7px 11px;font-size:var(--ts-7);cursor:pointer;border-bottom:1px solid var(--pui-surface-muted)}[data-view-panel="inteligencia"] .int-res div:hover{background:var(--pui-surface-muted)}[data-view-panel="inteligencia"] .int-vrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;font-size:var(--ts-5)}[data-view-panel="inteligencia"] .int-gauge{font-size:var(--tn-5);font-weight:800;line-height:1}[data-view-panel="inteligencia"] .int-pin{padding:5px 7px;border:1px solid var(--pui-border);border-radius:6px;font:inherit;font-size:var(--ts-5);margin-right:4px;box-sizing:border-box}

/* ---- bloco 17 (vinha da linha 3356 do index.html) ---- */
          [data-view-panel="dataroom"] .dr-pasta{display:flex;align-items:center;gap:8px;padding:8px 12px;border-radius:8px;cursor:pointer;font-size:var(--ts-7);color:var(--pui-text-soft)}
          [data-view-panel="dataroom"] .dr-pasta:hover{background:var(--pui-surface-muted)}
          [data-view-panel="dataroom"] .dr-pasta.is-ativa{background:var(--pui-primary-soft);color:var(--pui-primary);font-weight:650}
          [data-view-panel="dataroom"] .dr-pasta .n{margin-left:auto;font-size:var(--ts-3);color:var(--pui-text-muted);font-variant-numeric:tabular-nums}
          [data-view-panel="dataroom"] .dr-sub{padding-left:26px}
          [data-view-panel="dataroom"] .dr-doc{display:flex;align-items:center;gap:12px;padding:10px 6px;border-bottom:1px solid var(--pui-surface-muted);flex-wrap:wrap}
          [data-view-panel="dataroom"] .dr-doc:hover{background:rgba(26,24,20,.02)}
          [data-view-panel="dataroom"] .dr-ico{width:34px;height:34px;border-radius:8px;background:var(--pui-surface-muted);display:grid;place-items:center;font-size:var(--ts-1);font-weight:800;color:var(--pui-text-soft);flex:0 0 auto}
          [data-view-panel="dataroom"] .dr-in{padding:8px 10px;border:1px solid var(--pui-border);border-radius:8px;font:inherit;font-size:var(--ts-7);background:var(--ae-field)}
          [data-view-panel="dataroom"] .dr-prov{display:inline-flex;align-items:center;gap:4px;font-size:var(--ts-1);font-weight:700;padding:1px 8px;border-radius:999px;background:var(--pui-surface-muted);color:var(--pui-text-soft);white-space:nowrap}
          [data-view-panel="dataroom"] .dr-acao{opacity:0;transition:opacity .12s;display:flex;gap:4px}
          [data-view-panel="dataroom"] .dr-doc:hover .dr-acao{opacity:1}
          [data-view-panel="dataroom"] .dr-doc{border-radius:8px;padding:10px}

/* ---- bloco 18 (vinha da linha 3402 do index.html) ---- */
          [data-view-panel="captacao"] .capt-trilha{display:flex;gap:8px;flex-wrap:wrap}
          [data-view-panel="captacao"] .capt-step{flex:1;min-width:150px;display:flex;align-items:center;gap:10px;text-align:left;background:var(--pui-surface);border:1px solid var(--pui-border);border-radius:10px;padding:11px 13px;cursor:pointer;font-family:inherit;transition:border-color .12s,background .12s}
          [data-view-panel="captacao"] .capt-step:hover{border-color:var(--pui-border-strong);background:var(--pui-surface-muted)}
          [data-view-panel="captacao"] .capt-step.done{border-color:rgba(31,138,84,.4);background:rgba(31,138,84,.05)}
          [data-view-panel="captacao"] .capt-k{font-size:var(--ts-3);font-weight:800;color:var(--pui-text-muted);letter-spacing:.04em}
          [data-view-panel="captacao"] .capt-l{flex:1;font-size:var(--ts-7);font-weight:650;color:var(--pui-text);line-height:1.25}
          [data-view-panel="captacao"] .capt-l small{display:block;font-size:var(--ts-3);font-weight:400;color:var(--pui-text-soft)}
          [data-view-panel="captacao"] .capt-ck{font-size:var(--ts-10);font-weight:800}
          [data-view-panel="captacao"] .capt-step.done .capt-ck{color:var(--pui-success,var(--pui-success))}
          [data-view-panel="captacao"] .capt-step:not(.done) .capt-ck{color:var(--pui-text-muted)}
          [data-view-panel="captacao"] .capt-bar{height:8px;border-radius:999px;background:var(--pui-surface-muted);overflow:hidden;margin:2px 0 0}
          [data-view-panel="captacao"] .capt-bar>i{display:block;height:100%;background:var(--pui-success,var(--pui-success));transition:width .3s}
          [data-view-panel="captacao"] .capt-dna-row{display:grid;grid-template-columns:150px 1fr;gap:12px;padding:9px 0;border-bottom:1px solid var(--pui-surface-muted);font-size:var(--ts-8)}
          [data-view-panel="captacao"] .capt-dna-row b{font-size:var(--ts-3);color:var(--pui-text-soft);text-transform:uppercase;letter-spacing:.04em;font-weight:700}
          [data-view-panel="captacao"] .capt-dna-sint{margin-top:12px;padding:12px 14px;background:var(--pui-surface-muted);border-radius:8px;font-size:var(--ts-8);line-height:1.5;color:var(--pui-text)}
          [data-view-panel="captacao"] .capt-dna-empty{padding:14px;border:1px dashed var(--pui-border-strong);border-radius:8px;background:var(--pui-surface-muted);font-size:var(--ts-7);color:var(--pui-text-soft)}
          /* Ficha de captação (60 campos) — mesmo desenho da lâmina original do Canivete */
          [data-view-panel="captacao"] .fx-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:10px 14px}
          [data-view-panel="captacao"] .fx-sec{margin:20px 0 8px;padding-bottom:6px;border-bottom:2px solid var(--pui-border);display:flex;justify-content:space-between;align-items:baseline}
          [data-view-panel="captacao"] .fx-sec h3{font-size:var(--ts-8);margin:0;text-transform:uppercase;letter-spacing:.04em}
          [data-view-panel="captacao"] .fx-sec small{color:var(--pui-text-muted);font-size:var(--ts-3)}
          [data-view-panel="captacao"] .fx-grid label{display:flex;flex-direction:column;gap:3px;font-size:var(--ts-3);color:var(--pui-text-soft)}
          [data-view-panel="captacao"] .fx-grid input,[data-view-panel="captacao"] .fx-grid select,[data-view-panel="captacao"] .fx-grid textarea{padding:8px 10px;border:1px solid var(--pui-border);border-radius:8px;font:inherit;font-size:var(--ts-7);background:var(--ae-field);width:100%}
          [data-view-panel="captacao"] .fx-grid textarea{min-height:64px;resize:vertical}
          [data-view-panel="captacao"] .fx-wide{grid-column:1/-1}
          [data-view-panel="captacao"] .fx-meter{height:6px;border-radius:3px;background:var(--pui-surface-muted);overflow:hidden}
          [data-view-panel="captacao"] .fx-meter i{display:block;height:100%;background:var(--pui-primary)}
          @media(max-width:599px){[data-view-panel="captacao"] .fx-grid{grid-template-columns:1fr}}
          /* print: coberto pelo CSS global de impressão (ver bloco @media print no topo) */
          /* Celular: rótulo em cima do valor — o grid de 150px+resto deixava ~150px
             pro texto do DNA num card de 313px, espremendo tudo em coluna estreita. */
          @media(max-width:599px){[data-view-panel="captacao"] .capt-dna-row{grid-template-columns:1fr;gap:2px;padding:10px 0}}

/* ---- PRIMEIRO USO: do zero ao número que fecha (2026-07-27) ----
   Quem cria o primeiro empreendimento cai numa tela com 19 itens de menu e nenhum
   número. O estado vazio já era honesto ("nada calculado ainda"), mas dava DUAS
   instruções concorrentes — "preencha terreno, obra e vendas" e, logo abaixo,
   "comece por aqui: o DNA" — e nenhuma dizia quantos passos são nem o que sai no fim.
   Os 3 passos abaixo são exatamente os que `viabOk` da espinha de estruturação
   exige: mesma regra, uma fonte só. */
.pu-guia{border:1px solid var(--ae-chart);background:linear-gradient(180deg,var(--ae-accent-soft),var(--pui-surface) 60%);
  border-radius:18px;padding:20px 22px;margin-bottom:var(--pui-space-4)}
.pu-guia .pu-eyebrow{font-size:var(--ts-3);font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:var(--ae-on-soft)}
.pu-guia h3{font-family:var(--ae-display);font-size:var(--tn-2);font-weight:700;letter-spacing:-.015em;margin:4px 0 2px}
.pu-guia .pu-sub{font-size:var(--ts-7);color:var(--pui-text-soft);margin:0 0 16px}
/* 🔴 O PASSO 0 ENTROU (17/08), e a grade diz o que ele é. Quatro colunas IGUAIS achatariam a
   distinção: o DNA não é um quarto do trabalho — ele não entra na conta, e os três que fazem o
   número fechar continuam sendo três. Então o zero ganha coluna mais estreita e vira preâmbulo,
   não parcela. Era `repeat(3,…)` cravado: com o quarto passo, o último caía para a segunda linha. */
.pu-passos{display:grid;grid-template-columns:.72fr repeat(3,minmax(0,1fr));gap:10px;margin-bottom:14px}
@media(max-width:1080px){.pu-passos{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:620px){.pu-passos{grid-template-columns:1fr}}
/* o zero é o passo que não conta: a borda tracejada o marca como preâmbulo sem tirá-lo do trilho */
.pu-passo.is-zero{border-style:dashed}
/* A LACUNA DO FORMULÁRIO, dita na tela (17/08). Substitui dois `alert()` do navegador — que
   falavam com a voz do sistema operacional e, pior, bloqueavam o motor da página. Fica em
   vermelho semântico e no tamanho do rótulo: ela informa, não repreende. */
.np-erro{margin:5px 0 0;font-size:var(--ts-4);line-height:1.4;color:var(--pui-danger);font-weight:600}
/* A série que não foi lida, dita no lugar do número (17/08). Mesma doutrina da lacuna do dossiê:
   o traço não diz o que falta. Aqui ela ocupa o slot do VALOR, então precisa descer de escala —
   senão "série não lida" compete com os números vizinhos e o quadro perde a leitura. */
.mac-vazio{display:inline-block;font-size:var(--ts-4);font-weight:700;line-height:1.3;
  color:var(--pui-text-soft);white-space:normal;letter-spacing:0}
.pu-passo{display:flex;gap:11px;align-items:flex-start;text-align:left;background:var(--pui-surface);
  border:1px solid var(--pui-border);border-radius:13px;padding:12px 14px;font:inherit;cursor:pointer;
  transition:box-shadow .15s,transform .05s}
.pu-passo:hover{box-shadow:var(--pui-shadow-md);transform:translateY(-1px)}
.pu-passo:focus-visible{outline:2px solid var(--ae-foco);outline-offset:2px}
.pu-passo .n{flex:0 0 24px;height:24px;border-radius:50%;display:grid;place-items:center;font-size:var(--ts-4);
  font-weight:800;background:var(--pui-surface-muted);color:var(--pui-text-soft)}
.pu-passo .t{display:block;font-size:var(--ts-8);font-weight:700;line-height:1.25}
.pu-passo .d{display:block;font-size:var(--ts-4);color:var(--pui-text-soft);margin-top:2px;line-height:1.35}
/* o passo da vez: é o único com peso — sem isso os 3 competem e ninguém sabe onde clicar */
.pu-passo.is-agora{border-color:var(--ae-chart-dark);box-shadow:0 0 0 3px var(--ae-accent-soft)}
/* mesmo par errado de `.hm-aqui` (fundo amarelo estavel + tinta que clareia no escuro).
   Este NAO aparecia na varredura do navegador: o guia de primeiro uso so existe em projeto
   vazio, e a demonstracao tem dados. Foi a auditoria de PARES no CSS que pegou. */
.pu-passo.is-agora .n{background:var(--ae-chart);color:var(--ae-accent-ink)}
.pu-passo.is-feito .n{background:var(--pui-success);color:var(--ae-on-primary)}
.pu-passo.is-feito .t{color:var(--pui-text-soft);text-decoration:line-through;text-decoration-thickness:1px}
.pu-guia .pu-fim{font-size:var(--ts-6);color:var(--pui-text);background:var(--pui-surface-strong);
  border-radius:11px;padding:10px 13px;margin-bottom:14px;line-height:1.5}
.pu-guia .pu-acoes{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.pu-guia .pu-ou{font-size:var(--ts-5);color:var(--pui-text-muted)}
@media(max-width:719px){.pu-passos{grid-template-columns:1fr}}

/* =========================================================================
   MODO ESCURO
   =========================================================================
   Vem POR ÚLTIMO no arquivo de propósito: o `:root` da camada v3 aparece duas vezes
   acima (linhas ~558 e ~633), e `[data-tema]` empata em especificidade com `:root`.
   Quem chega depois vence — se este bloco subir, metade da paleta volta a ser clara.

   Só troca TOKEN. Nenhuma regra de layout muda, e é por isso que o modo escuro coube
   num bloco: as 65 cores brancas que estavam cravadas viraram --pui-surface (cartão) ou
   --ae-field (campo) antes disto existir. Cravar cor nova aqui embaixo é como o tema
   volta a quebrar de um lado só.

   O QUE NÃO SEGUE O TEMA, de propósito:
   - o DOSSIÊ (#dossie-doc) tem a sua própria paleta de papel (--dk/--ds/--dl/--dc);
   - a IMPRESSÃO devolve a paleta clara (ver o bloco @media print logo abaixo): papel é
     branco, e imprimir a tela escura gastaria a tinta do estruturador. */
html[data-tema="escuro"]{
  --pui-bg:#141417; --pui-surface:#1c1c20; --pui-surface-strong:#232329; --pui-surface-muted:#2a2a31;
  --pui-text:#f1f1f4; --pui-text-soft:#a9acb4; --pui-text-muted:#7d8088;
  --pui-border:#2f2f36; --pui-border-strong:#3d3d46;
  /* o "preto de ação" inverte: no escuro quem se destaca do fundo é o claro */
  --pui-primary:#f1f1f4; --pui-primary-strong:#ffffff; --pui-primary-soft:#2a2a31;
  --pui-success:#3ecf8e; --pui-success-soft:#12291f;
  --pui-danger:#f2717d;  --pui-danger-soft:#33191d;
  --pui-warning:#e0a63a; --pui-warning-soft:#332a12;
  --pui-info:#8098ee;    --pui-info-soft:#1c2340;
  /* campo MAIS FUNDO que o cartão — no escuro é o que faz a caixa existir */
  --ae-field:#101013;
  /* CTA: no claro é o preto da marca; no escuro, preto sobre preto some, então quem
     manda é o amarelo. É a mesma marca, lida do outro lado. */
  --ae-ink:#fbd545;
  --ae-accent-soft:#3b3211;
  --ae-on-soft:#f3dc93;
  --ae-on-primary:#141417;
  /* o anel de foco vira o amarelo de marca: no escuro ele é o que mais se destaca do fundo
     (12,87 medido), pela mesma razão que --ae-ink inverte aqui */
  --ae-foco:var(--ae-accent);
  --ae-corte:var(--ae-accent);   /* o corte acompanha o amarelo virado, como o foco */
  color-scheme:dark;  /* barra de rolagem, seletor de data e afins acompanham */
}
/* o texto do CTA acompanha o fundo virado (a regra clara crava color:#fff !important) */
html[data-tema="escuro"] .pui-button-primary{color:var(--ae-accent-ink)!important;box-shadow:0 6px 16px rgba(0,0,0,.4)}
html[data-tema="escuro"] .pui-button-primary:hover{background:var(--ae-accent-strong)!important;border-color:var(--ae-accent-strong)!important}
/* sombra clara não existe no escuro: o que separa camadas é a borda */
html[data-tema="escuro"] .pui-card{box-shadow:none}
html[data-tema="escuro"] #pend-panel{box-shadow:0 1px 2px rgba(0,0,0,.5),0 28px 64px -26px rgba(0,0,0,.8)}
/* o mapa nasce claro (azulejo do Leaflet) e queimaria a vista no escuro */
html[data-tema="escuro"] .leaflet-tile{filter:invert(1) hue-rotate(180deg) brightness(.92) contrast(.92)}
/* ---- e os CONTROLES do mapa, que o filtro dos azulejos nao alcanca (medido 29/07) ----
   O `invert` acima vale so para `.leaflet-tile`. Os controles sao marcacao do vendor por
   cima: zoom, camadas, escala e atribuicao ficavam BRANCOS sobre o mapa escurecido — quatro
   ilhas claras medidas na tela do Estudo de Massa —, e o link da atribuicao dava contraste
   3,35 (o minimo e 4,5). Nao da para inverte-los junto: inverter um botao branco produz um
   botao preto sem relacao com a paleta. Entao eles VESTEM o tema, como qualquer superficie. */
html[data-tema="escuro"] .leaflet-bar a,
html[data-tema="escuro"] .leaflet-control-layers,
html[data-tema="escuro"] .leaflet-popup-content-wrapper,
html[data-tema="escuro"] .leaflet-popup-tip{background:var(--pui-surface);color:var(--pui-text);border-color:var(--pui-border)}
html[data-tema="escuro"] .leaflet-bar{border-color:var(--pui-border-strong)}
html[data-tema="escuro"] .leaflet-bar a:hover{background:var(--pui-surface-muted)}
html[data-tema="escuro"] .leaflet-bar a.leaflet-disabled{background:var(--pui-surface-strong);color:var(--pui-text-muted)}
html[data-tema="escuro"] .leaflet-control-attribution,
html[data-tema="escuro"] .leaflet-control-scale-line{background:rgba(28,28,32,.82);color:var(--pui-text-muted);border-color:var(--pui-border)}
html[data-tema="escuro"] .leaflet-control-attribution a{color:var(--pui-info)}

/* ---- A TINTA DOS GRAFICOS (medido 29/07, em contraste real) ----
   A paleta categorica dos graficos vive no JS, e e uma rampa desenhada para fundo CLARO:
   amarelo da marca, depois `#1f1f23` (quase preto), depois cinzas cada vez mais claros.
   No escuro, exatamente UMA das seis cores morre — e ela e a mais forte da rampa:
     · tela Fluxo ....... os 6 rotulos de valor do grafico ("38,2 mi", "−23,5 mi" ...)
                         saiam com contraste 1,03 sobre o cartao. Sumiam.
     · tela Resumo ...... 2 fatias do donut de custos (Terreno, Coordenacao de vendas),
                         mesmo 1,03.
     · as linhas de grade (mesma tinta a 6%) sumiam junto.
   Atributo de apresentacao (fill=/stroke= na marcacao) e a camada de MENOR prioridade do
   SVG — existe exatamente para que o CSS possa tematizar por cima. Nao e remendo: e o
   mecanismo. O mapeamento e o principio, nao o gosto: o preto de tinta do tema claro vira
   a TINTA FORTE do tema escuro.
   ⚠️ Casa com o valor literal. Se o JS trocar `#1f1f23` por outro tom, esta regra para de
   casar EM SILENCIO e o defeito volta — por isso ha assert guardando o par (ver
   tools/tests/modo-escuro.test.mjs).
   ⚠️ Na IMPRESSAO isto se resolve sozinho: o bloco @media print repoe --pui-text para
   #1f1f23, entao `fill:var(--pui-text)` volta a ser tinta escura sobre papel branco.
   O `#65686f` da mesma rampa foi MEDIDO em 3,04 — passa no minimo de 3:1 para elemento
   grafico nao textual, e ficou como esta: mexer nele mexeria na ordem da rampa. */
html[data-tema="escuro"] svg [fill="#1f1f23"]{fill:var(--pui-text)}
html[data-tema="escuro"] svg [stroke="#1f1f23"]{stroke:var(--pui-text)}
/* ⚠️ E A EXCECAO, QUE EU MESMO PRECISEI DEPOIS DE QUEBRAR (29/07, no mesmo dia).
   As duas regras acima casam por VALOR, e por isso alcancam qualquer SVG da tela — inclusive
   um que nao e grafico. O mapa do Metodo (`#mapa-svg`, no Canivete) desenha o PROPRIO papel
   claro (a paleta MC tem paper:#eeedf1 e card:#ffffff) e escreve nele com a mesma tinta
   #1f1f23. Resultado da minha "correcao": no escuro o titulo "O Ciclo do Estruturador" passou
   de contraste 14,09 para 1,03 — texto quase branco sobre papel branco. Eu apaguei o mapa
   tentando salvar o grafico.
   O mapa e da MESMA especie do dossie: um DOCUMENTO com paleta de papel propria, nao uma
   superficie do app. Documento nao segue o tema — e a mesma regra que ja vale para
   #dossie-doc, agora escrita para o mapa.
   Conferido em varredura de tela: `#mapa-svg` e o UNICO SVG do app que pinta papel proprio
   (procurei por retangulo claro ocupando o quadro inteiro, em todas as telas). Se aparecer
   um segundo, o assert em tools/tests/tema-escuro.test.mjs cai. */
html[data-tema="escuro"] #mapa-svg svg [fill="#1f1f23"]{fill:#1f1f23}
html[data-tema="escuro"] #mapa-svg svg [stroke="#1f1f23"]{stroke:#1f1f23}
/* O DOSSIÊ é o outro documento com papel próprio — e o comentário acima já dizia isso,
   mas a contrarregra dele nunca tinha sido escrita, porque na tela ele vive em
   display:none. Só que a remarcação por VALOR também vale NA IMPRESSÃO: imprimir com o
   app no escuro computava stroke rgb(241,241,244) — tinta quase branca — nos 5 elementos
   `#1f1f23` da curva clonada (medido em 29/07 com data-tema cravado no harness de PDF).
   Vale também para a curva da jornada do investidor, que nasce com a mesma tinta. */
html[data-tema="escuro"] #dossie-doc svg [fill="#1f1f23"]{fill:#1f1f23}
html[data-tema="escuro"] #dossie-doc svg [stroke="#1f1f23"]{stroke:#1f1f23}
/* interruptor do tema no topo */
.ae-tema{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}
.ae-tema .pui-icon{width:17px;height:17px}

/* ---- design system: os brancos que ele crava ----
   O propulsor-ui.css é COMPARTILHADO (white-label) e não se edita daqui. Ele tem 16
   `background:#fff` cravados, e no escuro cada um vira uma ilha branca. O de
   .pui-table-wrap era o pior: pintava a tabela de branco com o texto claro por cima —
   TIR, VPL e payback ficavam invisíveis (razão de contraste 1,13, medida).
   Estas linhas repõem o mesmo branco no tema claro (--pui-surface = #fff) e acompanham
   no escuro. Se o design system ganhar um branco novo, ele reaparece aqui. */
.pui-table-wrap,.pui-modal-panel,.pui-drawer-panel,.pui-pipe article,.pui-pipe header span,
.pui-upload-list div,.pui-vertical-timeline .pui-icon,.pui-icon-button,
.pui-segmented button.is-active,.pui-tabs button.is-active,.pui-donut::before{background:var(--pui-surface)}
.pui-control select,.pui-field select,.pui-field input,.pui-select-button,
.pui-search input,.pui-field textarea{background:var(--ae-field)}
.pui-switch span::before,
.pui-temp-control input[type="range"]::-webkit-slider-thumb{background:var(--pui-surface-strong)}
.pui-temp-control input[type="range"]::-moz-range-thumb{background:var(--pui-surface-strong)}
/* o texto pequeno de apoio não passava em contraste no escuro (3,61 a 4,30 medidos, o
   mínimo é 4,5). Clareado só no escuro — no claro ele já passa e mudar mexeria na marca. */
html[data-tema="escuro"]{--pui-text-muted:#9ea1a9}
/* componentes do design system que cravam tinta branca sobre o preto de ação */
.pui-ai-note__score,.pui-client-avatar,
.pui-app.is-sidebar-collapsed .pui-sidebar-toggle{color:var(--ae-on-primary)}
/* ---- design system: os brancos TRANSLÚCIDOS ----
   Além dos 16 `#fff`, o propulsor-ui.css tem 11 `rgba(255,255,255,.9x)` — véus. No claro
   ninguém percebe (véu branco sobre fundo claro); no escuro cada um vira um retângulo
   leitoso. O menu de seleção era o pior: painel branco com o item escolhido em amarelo
   claro por cima (contraste 1,05, medido). Popup opaco lê melhor que véu, nos dois temas. */
.pui-select-menu,.pui-flyout,.pui-nav-submenu,.pui-app.is-sidebar-collapsed .pui-nav-submenu,
.pui-bulk-bar,.pui-preview-toolbar,.pui-drawer-section,.pui-drawer-actions,.pui-kit{background:var(--pui-surface)}
/* item escolhido do menu: no escuro o amarelo suave é fundo, não tinta */
html[data-tema="escuro"] .pui-select-menu button.is-selected{background:var(--ae-accent-soft)}

/* ---- PERMUTA: os dois lugares, e o aviso quando discordam ----
   A aba Negociação anota a permuta; a aba Outros custos é onde a permuta FORA vira
   dinheiro. Dava para preencher a primeira, ver "Valor permutado" aparecer, e fechar o
   estudo com a permuta externa custando R$ 0 — sem erro nenhum na tela. */
[data-view-panel="terreno"] .tp-onde{font-size:var(--ts-5);line-height:1.55;color:var(--pui-text-soft);margin-top:8px}
[data-view-panel="terreno"] .tp-onde a{color:var(--pui-text);text-decoration:underline;text-underline-offset:2px;cursor:pointer}
[data-view-panel="terreno"] .tp-alerta{margin-top:8px;padding:9px 11px;border-radius:9px;font-size:var(--ts-6);line-height:1.5;
  background:var(--pui-warning-soft);border-left:3px solid var(--pui-warning);color:var(--pui-text)}

/* ===== HIGIENE MOBILE (design, 2026-07-30 — bloco escolhido pelo Bruno) =====
   Auditoria medida em 375px, view a view (as 20): o documento NÃO pana de lado (algo já
   clipa o html) — o defeito real era PIOR: conteúdo mais largo que a tela ficava CORTADO
   E INALCANÇÁVEL. Medido antes do conserto: terreno 570px · despesas 524px · obra 483px
   numa tela de 375 (a tabela de áreas da obra perdia as últimas colunas para sempre).
   Correção da minha própria hipótese de 30/07 ("a página pana") — registrada aqui porque
   a spec da vitrine repetiu a hipótese errada; o conserto (.vit-scroll) vale igual.
   Três mecanismos, iterados AO VIVO no browser antes de virar arquivo:
   · grade que não encolhe: `1fr` não desce abaixo do min-content do conteúdo — vira
     minmax(0,1fr), e o card ganha rolagem própria para o que ainda assim não couber;
   · flex sem min-width:0 (cards de despesas): rolagem própria no .dpc;
   · tabela crua em painel: vira bloco rolável — a MESMA lição do fluxo-tabela e da
     .vit-scroll da vitrine, agora como rede de segurança para todas.
   Tablet (768) conferido limpo sem regra nenhuma — por isso o corte é 620. */
@media(max-width:620px){
  .pui-kit-grid{grid-template-columns:minmax(0,1fr)!important}
  .pui-kit-grid>*{min-width:0}
  .pui-card{min-width:0;overflow-x:auto}
  .dpc{min-width:0;overflow-x:auto}
  [data-view-panel] table{display:block;overflow-x:auto;max-width:100%}
  /* o X do modal ficava 3px fora da tela: a caixa (max-width:440 inline) estourava os 375 */
  .vcv-overlay-box{max-width:calc(100vw - 20px)!important}
}


/* ============================================================================
   SELOS DE PROCEDÊNCIA + RÉGUA DE LEITURAS (design, 2026-08-04)
   ============================================================================
   Vocabulário aprovado pelo Bruno: o eixo é a EVIDÊNCIA, não o crachá.

   DUAS COISAS INDEPENDENTES, e essa separação é o desenho inteiro:
     · SELO       — COMO o número foi obtido. É propriedade do NÚMERO.
     · ASSINATURA — DE QUEM ele veio. É propriedade da PESSOA/ORIGEM.

   ⚠️ SEGUNDA VERSÃO. A primeira inventou um chip próprio — 10,5px, canto de 5px,
   borda sempre visível, glifo de texto (◆◇◈▣). Ficou feio porque era um objeto
   ESTRANGEIRO ao lado dos componentes da casa. A página da praça JÁ TEM o idioma
   para "de onde veio este dado": `.mk-badge` — pílula silenciosa, raio 999px, sem
   borda, sobre `--pui-surface-muted`. O selo ocupa exatamente esse lugar semântico,
   então ele HERDA essa forma em vez de competir com ela.

   E a identidade sai de MARCA DESENHADA EM CSS, não de glifo de fonte: quatro
   formas (disco cheio · anel · anel com miolo · quadrado) que o navegador desenha
   com precisão, no mesmo tamanho, sem depender de qual fonte tem qual símbolo.
   Continua valendo a regra: forma carrega a identidade, cor é reforço.
   ============================================================================ */

.selo{
  display:inline-flex; align-items:center; gap:6px;
  padding:3.5px 10px; border-radius:999px;              /* a pílula da casa */
  font-size:var(--ts-4); font-weight:700; line-height:1; white-space:nowrap;
  background:var(--pui-surface-muted); color:var(--pui-text-soft);
  vertical-align:1px;
}
/* a MARCA — 4 formas distintas, desenhadas, não digitadas */
.selo::before{ content:""; width:7px; height:7px; border-radius:50%; flex:0 0 auto }
.selo .n{ font-weight:500; opacity:.72 }                 /* "· 30 anúncios" */

/* MEDIDO — disco CHEIO. É o único com observação real atrás, e a tinta plena diz
   isso sem precisar de cor de destaque. */
.selo-medido{ color:var(--pui-text) }
.selo-medido::before{ background:currentColor }

/* INFORMADO — ANEL vazado. Alguém digitou: mesma pílula, marca oca. Não é pior,
   é outra coisa — e o vazio da marca é o que diz "sem observação atrás". */
.selo-informado::before{ box-shadow:inset 0 0 0 1.6px currentColor }

/* CONFERIDO — anel COM MIOLO: duas leituras que concordam, desenhadas como tal.
   Único que usa o acento da marca, porque é o único ganho por corroboração. */
.selo-conferido{ color:var(--ae-accent-ink,#2a2100); background:var(--ae-accent-soft,#fef4ce) }
.selo-conferido::before{
  width:5px; height:5px; margin:1px; background:currentColor;
  box-shadow:0 0 0 2px var(--ae-accent-soft,#fef4ce), 0 0 0 3.4px currentColor;
}
html[data-tema="escuro"] .selo-conferido{
  color:var(--ae-chart,#fbd545); background:rgba(251,213,69,.13);
}
html[data-tema="escuro"] .selo-conferido::before{
  box-shadow:0 0 0 2px rgba(251,213,69,.13), 0 0 0 3.4px currentColor;
}

/* REFERÊNCIA ADE — QUADRADO. Forma diferente das três redondas: é a única que não
   vem de ninguém do lado de fora, vem da curadoria da casa. */
.selo-ade::before{ border-radius:2px; background:currentColor }

/* SUGERIDO — LOSANGO vazado. A quarta procedência da §4.3 dos Termos ("premissa sugerida pela
   Plataforma, substituível pelo Usuário"), que existia na cláusula e não tinha forma.
   🔴 Ela NÃO é a Referência ADE: a sugerida é ponto de partida esperando ser trocada; a
   referência é a casa AFIRMANDO um número. Juntar as duas no quadrado seria a confusão mais
   cara das três alternativas — foi por isso que o Bruno escolheu o losango em 12/08.
   Vazado como o "informado" (ninguém observou nada atrás), girado porque vem da casa. */
.selo-sugerido::before{
  border-radius:1px; transform:rotate(45deg);
  box-shadow:inset 0 0 0 1.6px currentColor;
}

/* ASSINATURA — a PESSOA ao lado do dado, nunca dentro dele. Texto puro, sem pílula:
   se ela virasse chip, competiria com o selo e desfaria a separação inteira. */
.selo-por{ font-size:var(--ts-4); color:var(--pui-text-muted); margin-left:7px; white-space:nowrap }
.selo-por .fundador{ color:var(--ae-chart-dark,#e7b400); font-weight:700; margin-left:1px }
html[data-tema="escuro"] .selo-por .fundador{ color:var(--ae-chart,#fbd545) }

/* ---------------------------------------------------------------------------
   RÉGUA DE LEITURAS — o que a cascata hoje calcula e joga fora.
   Entrega de graça uma informação que o app não dá: o espalhamento da praça.
   --------------------------------------------------------------------------- */
.lt-abre{
  display:inline-flex; align-items:center; gap:6px; margin-top:7px;
  font-size:var(--ts-4); color:var(--pui-text-soft); font-weight:600;
  background:none; border:0; padding:2px 0; cursor:pointer;
}
.lt-abre::before{
  content:""; width:5px; height:5px; border-right:1.6px solid currentColor;
  border-bottom:1.6px solid currentColor; transform:rotate(45deg) translate(-1px,-1px);
  opacity:.7; transition:transform .15s ease;
}
.lt-abre:hover{ color:var(--pui-text) }
.lt-abre[aria-expanded="true"]::before{ transform:rotate(225deg) translate(-2px,-2px) }

.lt-regua{
  margin:10px 0 2px; padding:14px 12px 10px;
  background:var(--pui-surface-muted); border-radius:var(--pui-radius,8px);
}
.lt-trilho{ position:relative; height:30px }
.lt-linha{
  position:absolute; left:0; right:0; top:6px; height:3px; border-radius:999px;
  background:var(--pui-border);
}
.lt-pt{
  position:absolute; top:1px; width:13px; height:13px; margin-left:-6.5px;
  border-radius:50%; background:var(--pui-surface);
  box-shadow:inset 0 0 0 2px var(--pui-text-muted);
}
/* o que vale AGORA: cheio, maior, com halo da superfície para destacar do trilho.
   A precedência ("o teu número manda") deixa de ser regra invisível. */
.lt-pt.is-ativo{
  width:17px; height:17px; margin-left:-8.5px; top:-1px;
  background:var(--pui-text); box-shadow:0 0 0 3px var(--pui-surface-muted);
}
.lt-rot{
  position:absolute; top:19px; transform:translateX(-50%);
  font-size:var(--ts-2); color:var(--pui-text-muted); white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.lt-rot.is-ativo{ color:var(--pui-text); font-weight:700 }
.lt-legenda{
  display:flex; flex-wrap:wrap; gap:8px 14px; margin-top:14px;
  font-size:var(--ts-3); color:var(--pui-text-soft);
}
.lt-legenda .l{ display:inline-flex; align-items:center; gap:6px }

/* SÓ A SUA LEITURA, AINDA — estado digno, não vazio. Praça pequena pode nunca ter
   a segunda; a tela não pode transformar isso em promessa quebrada. */
.lt-sozinha{
  margin-top:8px; padding:9px 12px; border-radius:var(--pui-radius,8px);
  background:var(--pui-surface-muted); color:var(--pui-text-soft);
  font-size:var(--ts-4); line-height:1.4;
}

@media (max-width:620px){
  .lt-rot{ font-size:var(--ts-1) }
  .lt-legenda{ gap:7px 10px }
}

/* ============================================================================
   COR ESCOLHIDA PELO USUÁRIO IDENTIFICA — ELA É MARCA, NUNCA TINTA (design, 2026-08-04)
   ============================================================================
   Achado da varredura de contraste do Mercado: o nome do grupo regional saía com a
   cor do grupo como TINTA do texto (`<b style="color:#4ade80">`), e as cores padrão
   são tons claros — escolhidos pensando no tema escuro. No branco davam 1,74 · 2,29 ·
   2,54 · 2,77, todos abaixo do piso de 4,5. Medido no navegador, não estimado.

   É o MESMO erro que o papel já tinha ensinado duas vezes: o amarelo de marca é
   ilegível como texto, e a borda amarela sobre fundo amarelo-claro some. A regra que
   vale para os três casos: **cor que o usuário escolhe serve para IDENTIFICAR, então
   vira MARCA; o texto usa a tinta do tema.**

   Como funciona sem tocar na marcação (que é da Produto): `color` continua sendo a
   cor do grupo — é dela que o ponto herda, via `currentColor` —, e só a PINTURA do
   texto é trocada. Uma regra, sem ramificar por tema, para qualquer cor escolhida.
   ============================================================================ */
/* O cabeçalho da praça repete o rótulo do grupo num <b> SEM CLASSE, direto no
   #mk-city — por isso o segundo seletor. Conferido: é o único <b> com cor inline
   nas duas telas, então o alvo é preciso, não uma rede de arrasto. */
.mk-reg b,
#mk-city b[style*="color:#"]{
  -webkit-text-fill-color:var(--pui-text);   /* o texto usa tinta do tema... */
  display:inline-flex; align-items:center; gap:6px; vertical-align:baseline;
}
.mk-reg b::before,
#mk-city b[style*="color:#"]::before{
  content:""; width:8px; height:8px; border-radius:50%;
  background:currentColor;                    /* ...e o ponto guarda a cor do grupo */
  flex:0 0 auto;
}

/* ---------------------------------------------------------------------------
   HIGIENE MOBILE — Mercado: o "Ordenar por" empurrava a página para o lado
   ---------------------------------------------------------------------------
   Varredura de 04/08: 246 elementos com texto medidos, nos dois temas, em 375px e em
   1265px. Achou três defeitos, todos no tema claro.
   Medido em 375px: o <select> tem largura INTRÍNSECA de 361px (vem da opção mais
   longa) mais 6px de margem inline, dentro de um contêiner de 347px — a página
   passava a rolar lateralmente, que é exatamente o que a higiene mobile proíbe.
   Elemento de formulário não encolhe sozinho: precisa de `min-width:0` para poder,
   e o rótulo vira flex para o select ter para onde ceder.
   O `!important` na margem existe porque ela é `style=` inline vindo do JS, e a
   marcação é da Produto — daqui eu só posso vencer por especificidade. */
@media (max-width:620px){
  #mk-ordenar-wrap{ width:100% }
  #mk-ordenar-wrap label{
    display:flex; align-items:center; gap:6px; width:100%; min-width:0;
  }
  #mk-ordenar{
    margin-left:0 !important;      /* o gap do flex já dá o respiro */
    flex:1 1 auto; min-width:0; max-width:100%;
  }
}

/* ---------------------------------------------------------------------------
   O AMARELO DE MARCA NÃO É TINTA — terceira vez que isto aparece
   ---------------------------------------------------------------------------
   Medido na página da praça: o valor dos índices proprietários sai com
   `style="color:#e7b400"` (a faixa "média" do INT_COR) e sobre o cinza claro do
   cartão dá 1,80 — abaixo do piso 3,0 até para texto grande de 22px. No tema
   escuro o mesmo amarelo vai bem; o defeito é só no claro.

   Já corrigimos a mesma coisa no papel (o dossiê usa --da, âmbar escuro, para
   texto) e no selo Conferido (borda amarela sobre fundo amarelo-claro dava 1,74).
   A regra da casa é uma só: **amarelo de marca ilumina, não escreve.**

   ⚠️ CONSERTO DURÁVEL É NO `INT_COR` (JS, sessão Produto): a faixa devia mudar de
   passo conforme o tema, não a folha de estilo corrigir a tinta depois. Enquanto
   isso, isto aqui impede que a tela mostre número ilegível. */
html:not([data-tema="escuro"]) [style*="color:#e7b400"]{
  color:#8a5a0f !important;
}
/* O IRMÃO DO MESMO MAPA: `INT_COR.gray` ainda é '#9da0a8' — o `muted` que a casa
   APOSENTOU justamente por dar 2,18 a 2,62 de contraste (está escrito no comentário da
   paleta, mais acima neste arquivo). Ele sobrevive no JS e reaparece no número grande do
   índice sem dado, medido agora em 2,62 sobre branco. Mesma ponte, mesmo destino: o
   conserto durável é trocar o literal por token no INT_COR. */
html:not([data-tema="escuro"]) [style*="color:#9da0a8"]{
  color:var(--pui-text-muted) !important;
}

/* ---------------------------------------------------------------------------
   VARREDURA DAS TELAS ANTIGAS (2026-08-04): 17 views · 2.345 elementos · dois temas
   · 375px e 1265px. Duas falhas reais, ambas "cor literal onde os irmãos usam token".
   ⚠️ TRÊS ARMADILHAS DO MÉTODO, para quem repetir a varredura. As três produziram falha
   que não existia, e a terceira também é capaz de ESCONDER falha que existe:
     1. TRANSIÇÃO CONGELADA — com a aba do navegador OCULTA o motor congela `transition`,
        e getComputedStyle devolve a cor ANTERIOR à troca de tema. Cinco das sete "falhas"
        da primeira passada eram isso. Neutralize animação antes de ler.
     2. A TINTA PINTADA NÃO É SEMPRE `color` — onde há `-webkit-text-fill-color` (o rótulo
        de grupo usa, para a cor virar marca), `color` serve de fonte ao currentColor e
        quem pinta é o text-fill. Ler `color` acusa o que ninguém vê.
     3. ALFA PRECISA SER COMPOSTO — `rgba(31,138,84,.05)` NÃO é o verde escuro: é 5% dele
        sobre o que está atrás. Tratar como sólido inverte o diagnóstico. Foi assim que os
        passos da captação apareceram como 1,64 quando estão em 7,12.
   E, depois de tornar o medidor mais tolerante, PROVE que ele ainda pega: reintroduza um
   defeito conhecido e confira que ele acusa. Foi feito — a ponte da TMA removida devolve
   as 2 falhas, e recolocada devolve zero.
   ---------------------------------------------------------------------------

   O VEREDITO DA TMA SUMIA NO TEMA ESCURO — e ele é um AVISO
   ---------------------------------------------------------------------------
   Medido: 1,01 de contraste. Texto claro sobre fundo claro, ilegível.
   A causa é cirúrgica e vale registrar: das TRÊS variantes da caixa, duas usam token
   (`--pui-surface-muted` no neutro, `--pui-success-soft` no positivo) e só a de PERIGO
   tem hex fixo (`#fdecec`). Os tokens adaptam sozinhos — no escuro viram #2a2a31 e
   #12291f. O hex não adapta, e por isso só a variante de perigo quebra.
   Que a variante quebrada seja justamente o AVISO ("Cuidado — o projeto fica abaixo da
   sua régua") é o que torna isto grave: some a frase que existe para alertar.
   ⚠️ Conserto durável, uma palavra, no JS da Produto: '#fdecec' → 'var(--pui-danger-soft)'. */
html[data-tema="escuro"] .vcv-verdict[style*="rgb(253, 236, 236)"]{
  background:var(--pui-danger-soft) !important;
}

/* ---------------------------------------------------------------------------
   BOTÃO DESTRUTIVO NO TEMA ESCURO — branco sobre coral claro dá 2,82
   ---------------------------------------------------------------------------
   Achado na varredura dos overlays (05/08), no "Apagar para sempre" do modal de
   apagar espaço — o botão mais consequente do app.

   A causa é a mesma família das outras: **uma cor feita para ESCREVER não serve para
   PREENCHER sob texto branco.** No escuro `--pui-danger` é `#f2717d`, um coral claro,
   e ele está certo assim — é o tom que se lê como tinta sobre fundo escuro. O botão o
   usa como FUNDO com `color:#fff` inline, e a inversão quebra: 2,82 contra piso 4,5.

   Conserto: no escuro, fundo de perigo pede tinta ESCURA. Mantém o vermelho alarmante
   (que é o ponto de um botão destrutivo) e devolve a legibilidade.
   ⚠️ Durável seria o botão não fixar `color:#fff` inline — mas a marcação é da Produto,
   e aqui eu só posso vencer por especificidade. */
/* ⚠️ O seletor precisa dizer "quem usa o vermelho como FUNDO", não "quem o menciona".
   A primeira tentativa casava `[style*="--pui-danger"]` e pegou junto os botões
   FANTASMA, que usam o mesmo token como TINTA — escureci a tinta deles sobre fundo
   escuro e criei três falhas de 1,08. A varredura pegou na volta seguinte. */
html[data-tema="escuro"] .pui-button[style*="background:var(--pui-danger)"],
html[data-tema="escuro"] .pui-button[style*="background: var(--pui-danger)"]{
  color:#14141a !important;
}

/* ============================================================================
   ÁREA DE ESTUDO DO PROJETO — o painel que lista as praças alcançadas
   (bloco 3, design 2026-08-12)

   🔴 A COR AMARRA O PAINEL AO DESENHO. O violeta aqui é o MESMO do polígono no mapa
   (`MP_EST_ESTUDO`, ade-app.js) — é ele que diz, antes de qualquer rótulo, que esta lista
   pertence àquele traço e não ao lote dourado nem às camadas ambientais. Separar por FORMA e
   COR, e só depois por palavra, é a regra que o inventário de 12/08 registrou
   (`docs/specs/naturezas-do-numero.md`): sufixo de uma palavra não se percebe.

   ⚠️ E O SELO DA REGRA NÃO É ENFEITE. Ele é a única coisa na tela que diz se a lista veio de um
   traço à mão (intenção, vale o centro do município) ou de uma medição por tempo de carro
   (medida, vale o toque). Medido: sobre a mesma isócrona, uma regra devolve 10 municípios e a
   outra 2. Sem o selo, as duas listas são visualmente idênticas.
   ============================================================================ */
.mp-est{margin-top:10px}
.mp-est-vazio{font-size:var(--ts-6);color:var(--pui-text-muted);line-height:1.55;
  border-left:3px solid var(--pui-border);padding:2px 0 2px 10px}
.mp-est-topo{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--ts-7)}
.mp-est-selo{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:999px;
  background:rgba(162,89,255,.12);color:#7a3ecc;border:1px solid rgba(162,89,255,.30);
  font-size:var(--ts-4);font-weight:760;letter-spacing:.01em}
.mp-est-selo svg,.mp-est-selo i{width:13px;height:13px}
.mp-est-base{color:var(--pui-text-muted);font-size:var(--ts-5)}
.mp-est-acoes{margin-left:auto;display:flex;gap:4px}
.mp-est-acoes .pui-button{min-height:26px;padding:0 9px;font-size:var(--ts-4)}
.mp-est-porque{margin:7px 0 0;font-size:var(--ts-6);color:var(--pui-text-soft);line-height:1.55;
  border-left:3px solid rgba(162,89,255,.45);padding:2px 0 2px 10px}
.mp-est-lista{list-style:none;margin:10px 0 0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:5px}
.mp-est-lista li{display:flex;align-items:baseline;justify-content:space-between;gap:8px;
  padding:5px 9px;border:1px solid var(--pui-border);border-radius:8px;
  background:var(--pui-surface-muted);font-size:var(--ts-6)}
.mp-est-nome{font-weight:650}
/* ⚠️ O TEMA ESCURO NÃO É INVERSÃO: o violeta #7a3ecc sobre fundo escuro cai abaixo do contraste
   mínimo. Aqui a tinta clareia e o fundo escurece, mantendo a MESMA identidade de cor do
   polígono no mapa — que é o que amarra o painel ao desenho. */
html[data-tema="escuro"] .mp-est-selo{background:rgba(162,89,255,.18);color:#c9a3ff;border-color:rgba(162,89,255,.42)}
html[data-tema="escuro"] .mp-est-porque{border-left-color:rgba(162,89,255,.55)}

/* GRAU DE ALCANCE (bloco 4, 12/08) — a faixa em FORMA, não só em palavra.
   🔴 Coberta · cortada · lasca precisam se distinguir antes de serem lidas: a barra à esquerda
   engrossa conforme o município entra mais na área, e a lasca fica translúcida. Sufixo de uma
   palavra é exatamente a diferença que não se percebe — foi o achado do inventário de 12/08. */
/* ⚠️ E A BARRA ENGROSSA DE VERDADE. O comentário acima prometia isso e as três regras eram
   `4px` — só o alfa mudava, então a promessa era falsa e a diferença era só de cor, que some na
   impressão em preto e branco. Agora a espessura é o canal redundante: 6 · 4 · 2 · 1 px. */
.mp-est-lista li.is-coberta{border-left:6px solid #a259ff}
.mp-est-lista li.is-cortada{border-left:4px solid rgba(162,89,255,.55)}
.mp-est-lista li.is-lasca{border-left:2px solid rgba(162,89,255,.22);opacity:.72}
/* 🔴 a quarta faixa, que a tela não conhecia: o município toca a área, mas menos do que a grade
   de 96×96 consegue medir. Sem esta regra ela saía sem tarja nenhuma, escrita "cortada · 0,0%". */
.mp-est-lista li.is-fora{border-left:1px dashed rgba(162,89,255,.35);opacity:.6}
.mp-est-faixa{margin-left:auto;color:var(--pui-text-muted);font-size:var(--ts-3);
  text-transform:uppercase;letter-spacing:.03em}
.mp-est-frac{font-variant-numeric:tabular-nums;font-weight:700;min-width:44px;text-align:right}
.mp-est-metodo{margin:9px 0 0;font-size:var(--ts-4);color:var(--pui-text-muted);line-height:1.5}
/* a recusa não é erro: é a casa dizendo o que sabe antes de gastar o trabalho de quem usa */
.mp-est-recusa{display:flex;gap:9px;align-items:flex-start;padding:10px 12px;border-radius:10px;
  background:var(--pui-surface-muted);border:1px solid var(--pui-border);font-size:var(--ts-6)}
.mp-est-recusa svg{width:16px;height:16px;flex:0 0 auto;margin-top:2px;color:var(--pui-warning)}
.mp-est-recusa b{display:block;margin-bottom:2px}
.mp-est-recusa span{color:var(--pui-text-soft);line-height:1.55}
/* o estado da medição: erro de verdade em âmbar; "não temos isso" em tom neutro, porque
   ensinar que o app quebrou quando ele está dizendo a verdade sobre si é pior que o erro. */
.mp-est-recusa.is-erro svg{color:var(--pui-danger)}
.mp-est-saida{display:block;margin-top:5px;color:var(--pui-text-muted);font-size:var(--ts-4)}

/* ============================================================================
   FAIXA DE SUSTENTAÇÃO — a camada MEDIDA (bloco 0, design 2026-08-12)
   🔴 A cláusula 4.3 (iv) dos Termos 1.2 manda MÉTODO, FONTE e DATA colados no número. Por isso
   a procedência aqui não é rodapé cinza de 10px: é bloco próprio, com a mesma leitura do valor.
   ============================================================================ */
.fs-caixa:empty{display:none}
.fs-caixa{margin-top:9px;padding:11px 13px;border-radius:10px;
  background:var(--pui-surface-muted);border:1px solid var(--pui-border)}
.fs-topo{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--ts-4)}
.fs-linha{display:flex;gap:16px;flex-wrap:wrap;margin-top:9px}
.fs-p{display:flex;flex-direction:column;gap:1px;font-size:var(--ts-7);font-weight:700;
  font-variant-numeric:tabular-nums;color:var(--pui-text-soft)}
.fs-p i{font-style:normal;font-size:var(--ts-2);font-weight:600;text-transform:uppercase;
  letter-spacing:.05em;color:var(--pui-text-muted)}
.fs-p.is-med{color:var(--pui-text)}
.fs-proc{margin:9px 0 0;font-size:var(--ts-3);color:var(--pui-text-muted);line-height:1.55}
.fs-proc b{color:var(--pui-text-soft);font-weight:700}
/* a procedência da área MEDIDA — mesma leitura que a da faixa histórica: método, fonte, data */
.mp-est-proc{margin:8px 0 0;font-size:var(--ts-3);color:var(--pui-text-muted);line-height:1.55}
.mp-est-proc b{color:var(--pui-text-soft);font-weight:700}

/* ============================================================================
   TMA — a tabela de indicadores tem necessidade oposta à do cartão ao lado
   (design, 2026-08-13, provocado por "o layout está péssimo" do Bruno)

   🔴 MEDIDO ANTES DE DESENHAR, e a medição corrigiu o diagnóstico que me chegou. O relato
   dizia que o bloco de explicação ocupava a dobra inteira; ele é um `<details>` FECHADO de
   46 px e não ocupa nada. O defeito real é outro e é aritmético: a grade dá `555px 555px`
   às duas colunas, a tabela cabe em 521 px, e a coluna VALOR sobra com 69 px para conter
   "14,25% a.a.". Resultado: 36 células quebrando em 3 linhas, e cada linha da tabela com
   53 px de altura em vez de ~20.

   ⚠️ E O CARTÃO DA DIREITA TEM O PROBLEMA INVERSO: termina cedo e deixa vazio longo abaixo.
   Duas colunas iguais para necessidades opostas — é a largura que está errada, não o
   conteúdo. Por isso o conserto é de grade, e não de tabela: ele sobrevive a qualquer
   mudança no que as linhas mostram (a Produto está mexendo justamente nisso agora).
   ============================================================================ */
/* ⚠️ A PROPORÇÃO DA GRADE É INLINE, na marcação — e estilo inline ganha de folha de estilo.
   Eu escrevi a regra aqui primeiro e ela não pegou: 1.32fr/1fr no CSS contra 1fr/1fr inline
   dá 1fr/1fr. Corrigido onde ele mora (`index.html`), em vez de empilhar `!important` — duas
   fontes para a mesma verdade é como se perde o controle de uma folha de estilo. */
/* o número não quebra: ele é a razão de a tabela existir */
[data-view-panel="tma"] table td:nth-child(3){white-space:nowrap;font-variant-numeric:tabular-nums}
[data-view-panel="tma"] table td:nth-child(2){white-space:nowrap;hyphens:none}
/* 🔴 A MARCA E O RODAPÉ (13/08) — o segundo tempo do mesmo conserto.
   O primeiro tempo foi ARITMÉTICO (a grade dava 555px/555px para necessidades opostas). O que
   sobrou não era largura: era PROSA dentro de célula. "· SÉRIE DESCONTINUADA (não muda mais)"
   quebrava em três linhas na coluna da fonte, e "(data do arquivo)" alargava a coluna de período.
   Os dois são rótulos honestos que não podem sumir — então a célula ficou com a marca curta e a
   explicação desceu para o rodapé, uma vez em vez de três.
   ⚠️ PESO ALÉM DA COR, e não é preciosismo: esta tabela vai para o dossiê impresso, e vermelho
   sozinho vira cinza no preto e branco — o aviso mais importante da tela seria o primeiro a sumir.
   Com o `nowrap` acima, a coluna de período agora cabe na data e para de puxar largura. */
/* 🔴 `inline-block` + `nowrap` é a combinação, e a diferença entre elas é a tabela transbordando.
   MEDIDO em 13/08, no meu próprio erro: a marca vinha DENTRO de um `<span>` que envolvia a fonte
   inteira, e o `nowrap` proibiu a quebra da linha toda — a coluna foi para 461px dentro de um
   cartão de 539px e a tabela passou a transbordar. Agora o `<span>` embrulha só a MARCA: o
   `nowrap` a mantém inteira, e o `inline-block` a deixa descer para a linha de baixo como um bloco
   só, em vez de partir "SÉRIE / DESCONTINUADA" no meio. A fonte volta a quebrar normalmente. */
.tma-morta{display:inline-block;color:var(--pui-danger);font-weight:700}
/* 🔴 LARGURA REPARTIDA, e o motivo é aritmético (medido em 13/08, cartão de 540px):
   os conteúdos desta tabela pedem 222+70+68+412 = 772px para caber cada um em UMA linha. Não há
   772px. Alguma coluna vai quebrar — a decisão de projeto é QUAL, e o `table-layout:auto` decidia
   errado: ele reparte a sobra na proporção do conteúdo, então a coluna da FONTE (a maior) crescia
   até 213px enquanto o INDICADOR — que é o rótulo que se varre com o olho — ficava com 112px e
   quebrava em quatro linhas.
   Medido, com o cartão em 540px: `auto` = 466px de altura e 4 rótulos quebrados; esta repartição
   = 428px e 2, e os dois que sobram são prosa de verdade ("ERP — mercado maduro" e "CRP por
   rating (não usado no cálculo)"). Testei 140/150/160/170px: acima de 150 a fonte começa a
   quebrar mais do que o indicador melhora, e a tabela volta a crescer.
   ⚠️ Em PORCENTAGEM, não em px, porque o cartão encolhe junto com a janela: px vira transbordo
   silencioso no notebook menor — foi o que a medição a 420px mostrou. */
[data-view-panel="tma"] .tma-mkt-tbl{table-layout:fixed;width:100%}
[data-view-panel="tma"] .tma-mkt-tbl th:nth-child(1){width:30%}
[data-view-panel="tma"] .tma-mkt-tbl th:nth-child(2),
[data-view-panel="tma"] .tma-mkt-tbl th:nth-child(3){width:17%}
[data-view-panel="tma"] .tma-mkt-tbl th:nth-child(4){width:36%}
.tma-nota{margin-top:8px;display:flex;flex-direction:column;gap:4px;
  font-size:var(--ts-3);line-height:1.5;color:var(--pui-text-soft)}
.tma-nota p{margin:0}
/* 🔴 O TRILHO DE COMPLETUDE DO CARTÃO (14/08) — o eixo COMPLETUDE, na escala que cabe.
   O painel do PESTAL mostra QUAIS dimensões faltaram, com o trilho vazio na linha de cada uma.
   O cartão de KPI não tem espaço para a lista, então herda a mesma ideia numa linha: um trilho
   preenchido até a fração do peso que de fato alimentou o número.
   ⚠️ FORMA ALÉM DE TEXTO, e não é preciosismo — é a mesma exigência do dossiê impresso: a barra
   sobrevive à fotocópia, e quem lê rápido enxerga "metade" sem ler o número.
   ⚠️ E O TRILHO NÃO É BARRA DE PROGRESSO: 40% aqui não é "carregando", é "este número saiu de
   40% do peso previsto". Por isso ele fica junto da ressalva escrita, e não sozinho. */
.kpi-completude{position:relative;display:flex;align-items:center;gap:6px;margin-top:5px;
  font-size:var(--ts-1);color:var(--pui-text-muted);line-height:1.3}
.kpi-completude::before{content:"";flex:0 0 34px;height:4px;border-radius:99px;
  background:var(--pui-border)}
.kpi-completude i{position:absolute;left:0;height:4px;border-radius:99px;
  width:calc(34px * var(--frac,0));background:var(--ae-corte);font-style:normal}

/* ============================================================================
   O PAINEL DE TERRITÓRIOS (14/08) — substitui a pilha de cartões de "Cidades & grupos".
   A altura depende dos MUNICÍPIOS, nunca dos territórios: era a multiplicação que doía.
   ============================================================================ */
.mkc-barra{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:12px}
.mkc-pill{display:inline-flex;align-items:center;gap:6px;padding:5px 11px;border-radius:999px;
  border:1px solid var(--pui-border-strong);background:var(--pui-surface);cursor:pointer;
  font:inherit;font-size:var(--ts-5);color:var(--pui-text-soft)}
.mkc-pill:hover{border-color:var(--pui-text)}
.mkc-pill.on{background:var(--pui-text);color:var(--pui-surface);border-color:var(--pui-text)}
.mkc-pill i{width:9px;height:9px;border-radius:3px;flex:0 0 auto}
.mkc-pill em{font-style:normal;font-variant-numeric:tabular-nums;opacity:.7;font-size:var(--ts-3)}
/* ⚠️ tracejado e não só vermelho: a forma sobrevive ao preto e branco e a quem não vê cor */
.mkc-pill.vazio{border-style:dashed;color:var(--pui-danger)}
.mkc-pill.novo{border-style:dashed;color:var(--pui-text);font-weight:700}

.mkc-form{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:0 0 12px;
  padding:11px 13px;border:1px solid var(--pui-border-strong);border-radius:10px;
  background:var(--pui-surface-muted)}
.mkc-form input[type=text]{font:inherit;font-size:var(--ts-7);padding:6px 9px;
  border:1px solid var(--pui-border-strong);border-radius:8px;background:var(--pui-surface);
  color:var(--pui-text);min-width:190px}
.mkc-form input[type=color]{width:38px;height:32px;padding:2px;border:1px solid var(--pui-border-strong);
  border-radius:8px;background:var(--pui-surface)}
.mkc-form .diz{flex:1 1 100%;font-size:var(--ts-3);color:var(--pui-text-muted);line-height:1.45}
.mkc-form .diz b{color:var(--pui-danger)}
.mkc-perigo{color:var(--pui-danger)!important;border-color:var(--pui-danger)!important}

/* 🔴 O PAINEL USA A TELA (14/08, achado pelo Bruno). Ele herdou `max-width:680px` do modal
   antigo — que era uma PILHA DE CARTÕES estreita, e para ela a largura curta fazia sentido. Eu
   troquei o conteúdo por uma TABELA e não questionei a moldura: medido no monitor dele,
   1220px de 1900 vazios, 64% da tela desperdiçada.
   ⚠️ E o erro de método foi meu: eu fotografei o painel com `position:fixed;width:700px`
   injetado por MIM. Medi a minha própria geometria, não a real — que é exatamente a sonda que
   mente, o defeito que eu passei o dia apontando em outros lugares.
   O teto de 1180px não é enfeite: acima disso a linha fica larga demais para o olho voltar do
   fim ao começo. Abaixo dele, o painel acompanha. */
/* 🔴 A CAIXA TEM O TAMANHO DO CONTEÚDO, E FICA CENTRADA (14/08, terceira e última tentativa).
   As duas anteriores erraram pelo mesmo motivo, e o Bruno viu as duas: eu insistia em alinhar uma
   COLUNA ESTREITA dentro de uma CAIXA LARGA. Primeiro colei tudo à esquerda — deu tabelinha no
   canto de um cartão de 1900px, com dois terços de branco à direita. Antes disso tentei centrar
   cada filho — e o título ficou numa âncora e o conteúdo noutra, porque `margin-inline:auto` não
   faz nada em elemento inline (o olho-de-boi é `<span>`).
   O conteúdo desta configuração pede ~620px e não fica melhor esticado: nome de município e
   território são curtos. Então a CAIXA é do tamanho dele e se centra na célula. Branco simétrico
   dos dois lados lê como decisão; branco só de um lado lê como quebrado. É a mesma razão por que
   um diálogo de configuração não ocupa a tela inteira: ele não tem o que pôr nela. */
/* 🔴 ROLAGEM DENTRO DE ROLAGEM — apontado pelo Bruno, e é defeito meu de cabo a rabo.
   O painel JÁ É um painel rolante: `#mercadoScreen #modalMkCfg` vive em `grid-row:4` da grade do
   Mercado, com `min-height:0;overflow-y:auto`. Ou seja, a moldura que me hospeda já resolve a
   altura. Eu pus um `max-height` + `overflow:auto` DENTRO dela, e com 25 municípios as duas
   rolavam ao mesmo tempo: duas barras lado a lado, e a confirmação de apagar abrindo cortada.
   ⚠️ A regra que fica: quem rola é UM só, e é o painel. A tabela não tem altura própria — ela é
   do tamanho que é, e o painel cuida do resto. O cabeçalho grudento passa a grudar no topo do
   PAINEL, que é o contêiner de rolagem de verdade, e aí ele funciona como devia. */
.mkc-rolo{border:1px solid var(--pui-border);border-radius:10px;overflow:visible}
/* com a largura de volta, a coluna do NOME leva a sobra e o resto fica do tamanho que precisa */
.mkc-tbl th:nth-child(2),.mkc-tbl td:nth-child(2){width:250px}
.mkc-tbl th:nth-child(3),.mkc-tbl td:nth-child(3){width:44px}
.mkc-sel{width:100%;max-width:100%}
.mkc-tbl{width:100%;border-collapse:collapse;font-size:var(--ts-7)}
.mkc-tbl th{position:sticky;top:-1px;z-index:2;background:var(--pui-surface-muted);text-align:left;
  font-size:var(--ts-2);letter-spacing:.06em;text-transform:uppercase;color:var(--pui-text-muted);
  font-weight:700;padding:7px 9px;border-bottom:1px solid var(--pui-border-strong)}
.mkc-tbl td{padding:5px 9px;border-bottom:1px solid var(--pui-border)}
.mkc-tbl td.nome{font-weight:600}
.mkc-tbl td.acao{text-align:right;width:1%}
.mkc-marca{display:inline-flex;align-items:center;gap:7px}
.mkc-marca i{width:9px;height:9px;border-radius:3px;flex:0 0 auto}
.mkc-sel{font:inherit;font-size:var(--ts-5);padding:3px 6px;border:1px solid var(--pui-border-strong);
  border-radius:7px;background:var(--pui-surface);color:var(--pui-text);max-width:200px}
.mkc-sel.vago{border-style:dashed;border-color:var(--pui-danger);color:var(--pui-danger)}
.mkc-x{border:0;background:none;color:var(--pui-text-muted);cursor:pointer;font:inherit;
  font-weight:700;padding:2px 7px;border-radius:6px;line-height:1}
.mkc-x:hover{color:var(--pui-danger);background:var(--pui-surface-muted)}
.mkc-vazio{padding:14px 9px;color:var(--pui-text-muted);font-size:var(--ts-5)}
.mkc-link{font:inherit;font-size:var(--ts-5);font-weight:700;background:none;border:0;
  color:var(--pui-text);text-decoration:underline;cursor:pointer;padding:0}

/* a confirmação de apagar cidade, na própria linha */
.mkc-conf td{background:var(--pui-surface-muted);padding:12px 10px}
.mkc-conf-box{display:flex;flex-direction:column;gap:9px}
.mkc-conf-lista{display:flex;flex-direction:column;gap:5px;font-size:var(--ts-5);color:var(--pui-text-soft)}
.mkc-conf-lista label{display:flex;gap:8px;align-items:flex-start;cursor:pointer}
.mkc-conf-lista input{margin:2px 0 0;accent-color:var(--pui-danger)}
.mkc-conf-lista i{font-style:normal;color:var(--pui-text-muted)}
.mkc-conf-lista .fato{display:flex;gap:7px;color:var(--pui-text-muted)}
.mkc-conf-lista .fato::before{content:"·";font-weight:700}
.mkc-conf-lista .alerta{color:var(--pui-danger);font-weight:600}
.mkc-conf-acoes{display:flex;gap:8px;flex-wrap:wrap}

.mkc-semter{margin-top:12px;padding:9px 12px;border-radius:8px;background:var(--ae-accent-soft);
  color:var(--ae-accent-ink);font-size:var(--ts-5);line-height:1.45}
/* a régua da faixa do rank, ao lado da frase que ela dimensiona (14/08).
   ⚠ EM COLUNA, não lado a lado: a linha do ranking já é estreita, e a régua de 132px empurraria
   a frase para uma segunda linha de qualquer jeito. Empilhar é decidir isso em vez de sofrer. */
.mk-rank-faixa{display:inline-flex;flex-direction:column;gap:1px;align-items:flex-start}
.mk-rank-faixa i{font-style:normal}
.tma-nota b{color:var(--pui-text);font-weight:600}
/* o interruptor da camada autorada, e a conta que ele liga (bloco 2, 13/08).
   🔴 O interruptor fica DEPOIS do fato: quem chega lê a medição primeiro e decide se quer a
   leitura da casa. E a conta entra com tarja própria — mesma família visual do fato, natureza
   declarada pelo selo, que é a única coisa que separa "isto foi medido" de "isto nós contamos". */
.fs-liga{display:flex;align-items:center;gap:7px;margin-top:11px;
  font-size:var(--ts-3);color:var(--pui-text-soft);cursor:pointer}
.fs-liga input{margin:0;cursor:pointer}
.fs-conta{margin-top:10px;padding-top:11px;border-top:1px dashed var(--pui-border)}
.fs-conta .fs-topo{font-size:var(--ts-4)}
.fs-conta-vazia{margin:9px 0 0;font-size:var(--ts-3);color:var(--pui-text-muted)}
/* A ACUSAÇÃO (bloco 3, 13/08) — regra 4 do §4: fora da faixa, o modelo se acusa.
   🌉 O tratamento tem FORMA, não só cor: borda à esquerda e peso no texto. Dossiê se imprime,
   e impressão de dossiê é preto e branco — mesma régua do vocabulário de procedência. */
.fs-acusa{margin:9px 0 0;padding:8px 0 8px 11px;border-left:3px solid var(--pui-text-muted);
  font-size:var(--ts-3);color:var(--pui-text-soft);line-height:1.55;font-weight:500}
.fs-acusa b{color:var(--pui-text);font-weight:700}
/* por CIMA é o caso de estresse — é o que aperta o negócio, e leva a tinta de alerta */
.fs-acusa.is-alto{border-left-width:4px;border-left-color:var(--pui-danger)}
/* OS TRÊS CENÁRIOS (bloco 4) — o estudo do usuário avaliado nos três pontos MEDIDOS da faixa.
   Não é previsão, e o texto diz isso: são três leituras do modelo dele, nos pontos em que a
   história já esteve. Por isso os três têm o mesmo peso visual — nenhum é "o cenário". */
.fs-cen{margin-top:11px;padding-top:11px;border-top:1px dashed var(--pui-border)}
.fs-cen-grade{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:9px}
.fs-cen-col{display:flex;flex-direction:column;gap:2px;padding:9px 10px;border-radius:9px;
  background:var(--pui-surface);border:1px solid var(--pui-border)}
.fs-cen-col i{font-style:normal;font-size:var(--ts-2);font-weight:700;text-transform:uppercase;
  letter-spacing:.04em;color:var(--pui-text-muted)}
.fs-cen-col b{font-size:var(--ts-7);font-variant-numeric:tabular-nums;line-height:1.15}
.fs-cen-col span{font-size:var(--ts-2);color:var(--pui-text-muted)}
@media(max-width:640px){.fs-cen-grade{grid-template-columns:1fr}}
.fs-cen-nulo{margin:0;font-size:var(--ts-3);color:var(--pui-text-soft);line-height:1.55;
  border-left:3px solid var(--pui-border);padding:2px 0 2px 11px}
.fs-cen-nulo b{color:var(--pui-text)}

/* ===== PAINEL DE DADOS ECONÔMICOS (bloco 2) =====
   Tratamento visual REUTILIZADO, não inventado: o selo é o `.selo`/`.selo-medido`/`.selo-informado`
   que já existe (procedencia-core), e a tipografia sai dos tokens. O inventário da casa mediu onze
   dialetos vivos para "natureza do número" — o décimo segundo não nasce aqui. */
.dd-carimbo{font-size:var(--ts-4);color:var(--pui-text-soft);background:var(--pui-surface-2,rgba(127,127,127,.06));
  border-radius:10px;padding:10px 13px;margin-bottom:14px;line-height:1.55}
.dd-carimbo b{color:var(--pui-text)}
.dd-mesmo{display:block;margin-top:4px;font-size:var(--ts-3);color:var(--pui-text-muted)}
.dd-grade{display:grid;grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:12px}
.dd-linha{border:1px solid var(--pui-border);border-radius:12px;padding:12px 14px;background:var(--pui-surface)}
.dd-cab{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.dd-rot{font-size:var(--ts-6);font-weight:700;flex:1;min-width:0}
.dd-val{font-size:var(--ts-8);font-weight:700;color:var(--pui-text);white-space:nowrap}
/* 🔴 A PROCEDÊNCIA FICA NA MESMA PEÇA QUE O NÚMERO, e não num rodapé coletivo: janela, fonte e
   data de colheita são o que permite conferir, e conferir é o que separa dado de referência. */
.dd-proc{display:flex;flex-wrap:wrap;gap:4px 16px;margin-top:9px;font-size:var(--ts-3);color:var(--pui-text-muted)}
.dd-proc span{display:flex;flex-direction:column;gap:1px}
.dd-proc i{font-style:normal;font-size:var(--ts-2);text-transform:uppercase;letter-spacing:.04em;opacity:.72}
.dd-como{margin-top:9px;font-size:var(--ts-3)}
.dd-como summary{cursor:pointer;color:var(--pui-text-soft);font-weight:600}
.dd-como p{margin:7px 0 0;color:var(--pui-text-muted);line-height:1.6}
.dd-tit{margin:22px 0 2px;font-size:var(--ts-7)}
.dd-sub{margin:0 0 12px;font-size:var(--ts-3);color:var(--pui-text-muted);line-height:1.6;max-width:70ch}
@media (max-width:640px){ .dd-grade{grid-template-columns:1fr} }

/* ===== CICLO DE MERCADO — a sequência de confirmação (spec: docs/specs/ciclo-de-mercado.md) =====
   A ordem é a regra: os três sinais são desenhados EM FILA, com seta entre eles, porque é a
   sequência que carrega a mecânica — não os níveis. Sinal apagado fica tracejado; aceso, sólido. */
.cm-caixa{border:1px solid var(--pui-border-strong,var(--pui-border));border-radius:14px;
  padding:0 0 16px;margin:0 0 22px;background:var(--pui-surface);overflow:hidden}
.cm-topo{padding:16px 18px 0}
.cm-topo h2{margin:5px 0 0;font-size:clamp(24px,4vw,34px);letter-spacing:-.02em;line-height:1.05}
.cm-dec{margin:7px 0 0;font-size:var(--ts-5);color:var(--pui-text-soft)}
.cm-dec b{color:var(--pui-text)}
.cm-trilho{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;margin:16px 18px 0}
.cm-fase{padding:9px 10px;border-radius:9px;background:var(--pui-surface-2,rgba(127,127,127,.06));
  border:1px solid transparent;opacity:.55;min-width:0}
.cm-fase-k{display:block;font-size:var(--ts-3);font-weight:700;letter-spacing:.02em}
.cm-fase-d{display:block;font-size:var(--ts-2);color:var(--pui-text-muted);margin-top:2px;line-height:1.35}
.cm-fase.is-agora{opacity:1;background:var(--ae-accent-soft,#fef4ce);border-color:var(--ae-chart-dark,#e7b400)}
html[data-tema="escuro"] .cm-fase.is-agora{background:var(--ae-accent-soft,#2e280c);border-color:var(--ae-chart,#fbd545)}
.cm-seq{display:flex;align-items:stretch;gap:8px;margin:16px 18px 0;flex-wrap:wrap}
.cm-sinal{flex:1 1 170px;display:flex;flex-direction:column;gap:3px;padding:11px 13px;border-radius:11px;
  border:1px dashed var(--pui-border);min-width:0}
.cm-sinal.is-on{border-style:solid;border-color:var(--ae-chart-dark,#e7b400);
  background:var(--pui-surface-2,rgba(127,127,127,.05))}
.cm-sinal-n{font-size:var(--ts-2);font-weight:700;color:var(--pui-text-muted)}
.cm-sinal.is-on .cm-sinal-n{color:var(--ae-chart-dark,#e7b400)}
.cm-sinal b{font-size:var(--ts-5);display:block}
.cm-sinal-dir{font-size:var(--ts-3);color:var(--pui-text-soft);margin-left:6px}
.cm-sinal-em{font-size:var(--ts-2);color:var(--pui-text-muted)}
.cm-seta{align-self:center;color:var(--pui-text-muted);font-style:normal;font-size:var(--ts-5)}
.cm-alerta{margin:14px 18px 0;padding:10px 12px;border-left:3px solid var(--pui-danger);
  font-size:var(--ts-3);color:var(--pui-text-soft);line-height:1.55;
  background:var(--pui-surface-2,rgba(127,127,127,.05));border-radius:0 8px 8px 0}
.cm-alerta b{color:var(--pui-text)}
/* as duas leituras nunca aparecem sem tratamento distinto: a provisória é tracejada, e ela avisa */
.cm-duas{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px;margin:16px 18px 0}
.cm-leitura{display:flex;flex-direction:column;gap:3px;padding:11px 13px;border-radius:11px;
  border:1px solid var(--pui-border)}
.cm-leitura b{font-size:var(--ts-7);letter-spacing:-.01em}
.cm-leitura span:last-child{font-size:var(--ts-2);color:var(--pui-text-muted)}
.cm-leitura.is-prov{border-style:dashed;background:transparent}
.cm-nota{margin:14px 18px 0;font-size:var(--ts-3);color:var(--pui-text-muted);line-height:1.6;max-width:78ch}
.cm-nota b{color:var(--pui-text-soft)}
@media (max-width:720px){ .cm-trilho{grid-template-columns:repeat(2,1fr)} .cm-seta{display:none} }
/* a série real se identifica; a de demonstração usa a faixa MODELO que já existe */
.cm-fonte{padding:9px 18px;font-size:var(--ts-3);color:var(--pui-text-muted);
  border-bottom:1px solid var(--pui-border);background:var(--pui-surface-2,rgba(127,127,127,.05))}
.cm-fonte b{color:var(--pui-text-soft)}

/* ===== A OBRA NA PRAÇA — caixa PRÓPRIA, separada da fase de propósito =====
   Ela mede obra em andamento (CAGED), que confirma o ciclo depois do lançamento. Fundir com o
   trilho de fases faria um indicador atrasado se passar pela leitura dianteira. Por isso: borda
   própria, título próprio, e o "o que isto mede" colado. */
.ob-praca{margin:16px 18px 0;padding:13px 15px;border:1px solid var(--pui-border);border-radius:11px}
.ob-praca .cm-topo{padding:0}
.ob-praca h3{margin:4px 0 0;font-size:var(--ts-8);letter-spacing:-.01em}
.ob-praca h3 span{font-size:var(--ts-4);font-weight:400;color:var(--pui-text-soft)}
.ob-linha{display:flex;flex-wrap:wrap;gap:6px 20px;margin-top:10px}
.ob-p{display:flex;flex-direction:column;gap:1px;font-size:var(--ts-5);font-weight:600}
.ob-p i{font-style:normal;font-size:var(--ts-2);font-weight:600;text-transform:uppercase;
  letter-spacing:.04em;color:var(--pui-text-muted)}
.ob-praca .cm-nota{margin-left:0;margin-right:0}

/* ===== AS LEITURAS SECUNDÁRIAS DA OBRA =====
   Elas ficam em bloco próprio, com peso menor que a principal — infraestrutura e serviços
   especializados respondem OUTRAS perguntas, e misturá-las com edifícios foi o defeito que
   mostrava obra pública com rótulo de mercado. Hierarquia visual = hierarquia de leitura. */
.ob-sec{margin-top:14px;padding-top:12px;border-top:1px dashed var(--pui-border)}
.ob-sec-t{font-size:var(--ts-2);font-weight:700;text-transform:uppercase;letter-spacing:.06em;
  color:var(--pui-text-muted);margin-bottom:9px}
.ob-grade{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px}
.ob-cel{display:flex;flex-direction:column;gap:3px;padding:10px 12px;border-radius:9px;
  background:var(--pui-surface-2,rgba(127,127,127,.05))}
.ob-cel b{font-size:var(--ts-4)}
.ob-cel b span{font-family:ui-monospace,Menlo,monospace;font-size:var(--ts-2);font-weight:400;
  color:var(--pui-text-muted);margin-left:5px}
.ob-v{font-size:var(--ts-6);font-weight:700;font-variant-numeric:tabular-nums}
.ob-d{font-size:var(--ts-2);color:var(--pui-text-muted);line-height:1.5}
.ob-d b{color:var(--pui-text-soft)}

/* A POSIÇÃO DA PRAÇA NO CAMPO (design, 18/08). Ela mora sob o badge da Tensão e não compete
   com ele: o número grande continua sendo o 69/100; isto é a referência que faltava. */
.int-rank{margin:6px 0 2px}
.int-rank-linha{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px;font-size:var(--ts-6)}
.int-rank-linha b{font-weight:700}
.int-rank-sel{font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.06em;font-weight:700;
  color:var(--pui-text-muted);border:1px solid var(--pui-border);border-radius:5px;padding:1px 5px}
.int-rank-nota{flex:1 1 100%;font-size:var(--ts-4);color:var(--pui-text-soft);line-height:1.5;margin-top:3px}

/* ===== PEDIR AJUDA (design, 18/08) =====
   O convite convive com o motivo da recusa e NÃO compete com ele: mesma família de tamanho,
   sem cor de venda, sem sombra. Se ele gritar mais que o texto seco do motor, denuncia na
   mesma tela que ali começou a venda. */
.aj-convite{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:10px;
  padding-top:9px;border-top:1px solid var(--pui-border)}
.aj-chamada{font-size:var(--ts-4);color:var(--pui-text-soft)}
.aj-btn{font:inherit;font-size:var(--ts-4);font-weight:600;color:var(--pui-text);
  background:var(--pui-surface-strong);border:1px solid var(--pui-border);border-radius:8px;
  padding:6px 11px;cursor:pointer;min-height:32px}
.aj-btn:hover{background:var(--pui-surface-muted)}
.aj-btn:focus-visible{outline:2px solid var(--pui-focus,var(--ae-accent));outline-offset:2px}

/* A tela do que vai junto: lista LITERAL, com o valor à vista. */
.aj-modal{position:fixed;inset:0;background:rgba(0,0,0,.45);display:flex;align-items:center;
  justify-content:center;padding:20px;z-index:9000}
.aj-modal[hidden]{display:none}
.aj-caixa{background:var(--pui-surface);border:1px solid var(--pui-border);border-radius:14px;
  padding:22px;max-width:560px;width:100%;max-height:82vh;overflow:auto}
.aj-caixa h3{font-size:var(--ts-8);margin:0 0 6px}
.aj-apoio{font-size:var(--ts-4);color:var(--pui-text-soft);margin:0 0 14px;line-height:1.55}
.aj-lista{list-style:none;margin:0 0 16px;padding:0;display:flex;flex-direction:column;gap:9px}
.aj-item{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 12px;
  border:1px solid var(--pui-border);border-radius:9px;background:var(--pui-surface-strong)}
.aj-txt{display:flex;flex-direction:column;gap:2px;min-width:0}
/* item retirado continua VISÍVEL e riscado: quem tirou precisa ver o que tirou para devolver */
.aj-item.is-fora{opacity:.55}
.aj-item.is-fora .aj-val{text-decoration:line-through}
/* 🔴 O ALVO DE TOQUE DO CONTROLE DE PRIVACIDADE, medido no celular em 18/08: o rótulo tinha
   271×19px, e é ELE que recebe o toque (o `input` tem 13px). Abaixo dos 44px recomendados —
   e este não é um controle qualquer: é o que TIRA dado da mensagem. Permissão de recusar que
   não se consegue tocar é permissão teórica, e a promessa dos Termos §5.2 morreria no dedo. */
.aj-rot{font-size:var(--ts-4)}
.aj-rot{color:var(--pui-text-soft)}
.aj-val{font-size:var(--ts-5);color:var(--pui-text);word-break:break-word}
/* 🔴 É BOTÃO, e parece: a palavra é um verbo no imperativo e alguém VAI tocar nela. */
.aj-tirar{font:inherit;font-size:var(--ts-3);text-transform:uppercase;letter-spacing:.06em;
  font-weight:700;color:var(--pui-text-soft);background:transparent;
  border:1px solid var(--pui-border);border-radius:7px;padding:8px 12px;min-height:44px;
  flex:0 0 auto;cursor:pointer}
.aj-tirar:hover{background:var(--pui-surface-muted);color:var(--pui-text)}
.aj-tirar:focus-visible{outline:2px solid var(--pui-focus,var(--ae-accent));outline-offset:2px}
.aj-acoes{display:flex;gap:10px;justify-content:flex-end;flex-wrap:wrap}
.aj-fechar,.aj-enviar{font:inherit;font-size:var(--ts-5);font-weight:600;border-radius:9px;
  padding:11px 16px;cursor:pointer;min-height:44px}
.aj-fechar{background:transparent;color:var(--pui-text-soft);border:1px solid var(--pui-border)}
.aj-enviar{background:var(--pui-text);color:var(--pui-surface);border:1px solid var(--pui-text)}
/* ⚠️ NO CELULAR O "VOLTAR" FICA POR BAIXO, no lugar mais alcançável pelo polegar, e o
   "Enviar" acima. É deliberado e contra o hábito: a ação irreversível aqui manda dado do
   Workspace para fora, e o toque acidental deve cair no que NÃO envia. */
@media(max-width:520px){.aj-acoes{flex-direction:column-reverse}
  .aj-fechar,.aj-enviar{width:100%}}

/* ===== O CONVITE PERMANENTE (design, 18/08) =====
   Pedido do Bruno: presente em toda a jornada, sem incomodar. Mora no pé da barra lateral, que
   existe em todas as views e nunca cobre conteúdo — e tem peso de LINK, não de botão: quem não
   precisa não repara, quem precisa acha na hora. Se ele competisse com a navegação, viraria
   anúncio no meio do trabalho, que é exatamente o "inconveniente" que o pedido exclui. */
/* 🔴 ELE ACOMPANHA A JANELA, e isto foi medido: a barra lateral tem 2.929px com 35 itens de
   navegação e NÃO rola por dentro — ela se estende com a página. O pé dela (identidade e este
   botão) ficava em y≈2.870, ou seja, presente no HTML e invisível para quem usa. "Em todas as
   páginas" não é estar no DOM: é estar ao alcance sem procurar.
   `sticky` no rodapé da coluna resolve sem cobrir nada — a coluna da esquerda está vazia ali
   embaixo, então ele ocupa espaço que não disputa com conteúdo. */
/* 🔴 `sticky` NÃO FUNCIONA AQUI, e a causa está medida: `.pui-app` tem `overflow:hidden`, o que
   cria um contêiner de rolagem do tamanho exato do conteúdo — sticky sem janela onde grudar é
   sticky inerte. Tentei e ficou em y≈2.870, igual a antes. Por isso `fixed`, ancorado na coluna
   da barra (254px, ou 76px colapsada), que é espaço vazio ali embaixo e não disputa com nada.
   ⚠️ E só a partir de 900px: abaixo disso a barra deixa de ser coluna e vira bloco no topo —
   ali o convite já aparece na primeira dobra, e `fixed` viraria justamente o estorvo que o
   pedido exclui. */
.aj-sempre{z-index:5;
  display:flex;align-items:center;gap:9px;width:100%;min-height:44px;
  padding:9px 12px;margin-top:4px;border-radius:9px;
  border:1px solid var(--pui-border);background:var(--pui-surface);
  color:var(--pui-text-soft);font:inherit;font-size:var(--ts-4);text-align:left;cursor:pointer}
.aj-sempre:hover{background:var(--pui-surface-muted);color:var(--pui-text)}
.aj-sempre:focus-visible{outline:2px solid var(--pui-focus,var(--ae-accent));outline-offset:2px}
.aj-sempre svg,.aj-sempre i{width:16px;height:16px;flex:0 0 auto;opacity:.8}
/* na barra colapsada sobra só o ícone, centrado — o rótulo sairia cortado */
.pui-sidebar.is-collapsed .aj-sempre{justify-content:center;padding:9px 0}
.pui-sidebar.is-collapsed .aj-sempre span{display:none}

@media(min-width:900px){
  .aj-sempre{position:fixed;left:14px;bottom:14px;width:226px;
    box-shadow:0 6px 18px rgba(0,0,0,.10)}
  .pui-app.is-collapsed .aj-sempre,.pui-sidebar.is-collapsed .aj-sempre{width:48px;padding:9px 0;justify-content:center}
  .pui-app.is-collapsed .aj-sempre span,.pui-sidebar.is-collapsed .aj-sempre span{display:none}
}
html[data-tema="escuro"] .aj-sempre{box-shadow:0 6px 18px rgba(0,0,0,.45)}

/* O convite no VEREDITO DESFAVORÁVEL (design, 19/08). Ele mora no pé da caixa do crítico, depois
   dos pontos — nunca antes: quem acabou de ler "o VPL é negativo" precisa terminar de ler o que
   o estudo diz antes de ser convidado a conversar. Oferta que vem antes da explicação parece
   vender no velório. Peso igual ao do convite da recusa, sem cor de alerta: o vermelho ao lado
   já é do problema, e o convite não disputa com ele. */
.aj-convite-veredito{margin-top:10px;padding-top:9px;border-top:1px solid var(--pui-border)}

/* D3 · célula de OUTRO RECORTE na comparação de praças (Painel de Dados, 20/08).
   O sufixo textual "· UF" desaparece no meio de uma coluna de números, e é exatamente aqui
   que a diferença decide: a PNAD só mede nas capitais, então a praça de fato medida fica ao
   lado de vizinhas mostrando o número do estado. Hachura diagonal + tinta suave: distingue
   sem gritar, e não usa cor semântica (não é erro nem alerta — é OUTRA RÉGUA).
   Mínimo de propósito — o tratamento definitivo é da Design. */
.mk-cmp td.cmp-uf{
  color: var(--pui-text-soft);
  background-image: repeating-linear-gradient(45deg, transparent 0 5px, var(--pui-surface-muted) 5px 10px);
  cursor: help;
}
.mk-cmp td.cmp-uf::after{ content:'\2197'; margin-left:.3em; font-size:.85em; opacity:.7 }
