/* 00-sistema.css — tokens, tipografia e os componentes do padrão +4D
   Extraído de index.html por split_css.py.
   O NÚMERO no nome é a posição na cascata: os arquivos são
   carregados em ordem alfabética de nome, e é essa ordem que
   decide quem ganha o desempate entre regras de mesma
   especificidade. Não renumere sem conferir o que passa a
   sobrescrever o quê. */
    *,
    *::before,
    *::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    /* ══════════════════════════════════════════════════════════════════════
       SISTEMA VISUAL · DISTRITO DA INOVAÇÃO
       Tokens do design system do storymap (css/storymap.css). Tema escuro
       comprometido — não existe variante clara; o contraste é calibrado para
       leitura sobre #04090f.
       Os nomes antigos (--bg, --surface, --text, --muted, --border) foram
       mantidos como apelidos dos novos, para que as ~760 referências
       existentes herdem a paleta sem reescrita.
    ══════════════════════════════════════════════════════════════════════ */
    :root {
      /* Fundos — escala de profundidade */
      --bg:  #04090f;   /* base: body, navbar com scroll */
      --bg2: #08111f;   /* elevação 1: superfícies glass, sidebar */
      --bg3: #0d1a2e;   /* elevação 2: painéis e seções destacadas */
      --bg4: #132340;   /* elevação 3: hovers de superfície */

      /* Acentos */
      --cyan:      #38bdf8;   /* acento primário: links, bordas ativas, CTA */
      --cyan-deep: #0891b2;   /* fim do gradiente do botão primário */
      --violet:    #7c3aed;   /* só em gradientes e brilho ambiente */
      --blue:      #60a5fa;
      --indigo:    #818cf8;
      --purple:    #c084fc;

      /* Semânticas */
      --emerald: #34d399;   /* positivo, crescimento, fim do gradiente de dados */
      --live:    #22c55e;   /* dado ao vivo (pulsante) */
      --amber:   #fbbf24;   /* alerta */
      --rose:    #fb7185;   /* negativo, erro, queda */

      /* Texto e bordas */
      --t1: #dde8f8;                       /* primário — branco com viés azul */
      --t2: rgba(221,232,248,.66);         /* secundário (subido de .52: ferramenta, não página de leitura) */
      --t3: rgba(221,232,248,.45);         /* terciário (subido de .28: reprovava em contraste) */
      --slate: #b6c2d2;                    /* labels em caixa alta (clareado p/ leitura) */
      --border: rgba(120,160,220,.10);
      --glass:  rgba(8,17,31,.82);
      --glow:   rgba(56,189,248,.18);

      /* ── VIDRO ────────────────────────────────────────────────────────
         Três profundidades e duas propriedades, e é só isso: quem empilha
         superfície no painel escolhe um --glass-N e herda o resto.

         O painel tinha `backdrop-filter: blur(20px)` sobre um fundo de 94%
         de opacidade — o filtro estava lá, custava o mesmo, e não aparecia:
         não havia por onde o mapa atravessar. Baixar para 84% é o que faz o
         desfoque virar vidro, e o `saturate` é o que impede o resultado de
         parecer fumaça cinza (desfocar uma foto lava a cor dela).

         84%, e não menos: o basemap tem imagem de satélite, e o painel é
         para LER. A margem que resta o desfoque consome.

         --glass-edge é o fio de luz no topo. Vidro real tem essa aresta, e é
         ela — mais do que a transparência — que faz a superfície parecer
         ter espessura em vez de ser uma mancha translúcida. */
      --glass-blur: blur(22px) saturate(180%) brightness(1.5);
      --glass-edge: inset 0 1px 0 rgba(255,255,255,.14);
      /* BRILHO ESPECULAR — a lambida de luz que atravessa a lâmina na
         diagonal. É o que distingue vidro de "retângulo semitransparente":
         superfície translúcida sem reflexo lê como fumaça. 155° porque a luz
         do painel vem do alto à esquerda (o mesmo canto do --glass-edge). */
      --glass-sheen: linear-gradient(155deg,
        rgba(255,255,255,.075) 0%, rgba(255,255,255,.02) 34%,
        rgba(255,255,255,0) 62%);
      /* ARO DE VIDRO — borda de 1px em GRADIENTE, não em cor chapada: o vidro
         acende no canto que recebe a luz e apaga no oposto, e uma borda de cor
         única não faz isso. Aplicado com máscara (ver #panel::after). */
      --glass-rim: linear-gradient(150deg,
        rgba(255,255,255,.30) 0%, rgba(255,255,255,.05) 32%,
        rgba(255,255,255,0) 58%, rgba(56,189,248,.20) 100%);
      --glass-1: rgba(8,17,31,.62);    /* casca: painel, cabeçalho, barras   */
      --glass-2: rgba(17,29,50,.40);   /* cartão pousado sobre a casca       */
      --glass-3: rgba(24,40,68,.52);   /* o mesmo cartão em hover ou aberto  */

      /* Tipografia — Plus Jakarta Sans para títulos/display, Inter para interface */
      --display: 'Plus Jakarta Sans','Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
      --body:    'Inter','Plus Jakarta Sans',system-ui,-apple-system,sans-serif;
      --mono:    ui-monospace,'SF Mono','Cascadia Mono','Consolas',monospace;

      /* Gradiente de dados: o que diferencia um número de um título comum */
      --grad-dados: linear-gradient(135deg, var(--cyan), var(--emerald));
      --grad-btn:   linear-gradient(135deg, var(--cyan), var(--cyan-deep));
      --grad-marca: linear-gradient(135deg, var(--cyan-deep), var(--violet));

      /* ── Apelidos legados (não usar em código novo) ── */
      --surface:  var(--bg2);
      --surface2: var(--bg3);
      --text:     var(--t1);
      --muted:    var(--slate);

      /* Altura do header — quem se ancora nele usa esta variável.
         74 → 56px. Os 18px vinham quase todos da marca em DUAS linhas
         ("Distrito da Inovação" sobre "Dados Urbanos"): era ela que definia a
         altura, e todo o resto — busca, navegação, ícones — ficava centrado
         numa faixa maior do que precisava. Com a marca numa linha só, a faixa
         cabe em 56 sem apertar nada — mas 56 ficou apertado demais na tela, e
         64 é onde a faixa deixa de parecer espremida sem voltar a desperdiçar
         altura com uma marca em duas linhas.
         Tudo o que se ancora no topo lê esta variável (a sidebar, o painel do
         lote, o Comparar, as âncoras de seção do Dashboard), então mudar aqui
         basta. */
      --topbar-h: 64px;
      /* Largura da coluna flutuante de menus. Vira 0 quando ela é escondida
         (body.sb-oculta), e os overlays da esquerda seguem junto sozinhos. */
      --sidebar-w: 300px;

      /* Cores das camadas do mapa */
      --c-setor: #38bdf8;
      --c-distrito: #ffd54f;
      --c-qtr: #81c784;
      --c-eu: #ef9a9a;
    }

    /* ── O VIDRO SOBRE MAPA CLARO ────────────────────────────────────────
       Marcada em _atualizaGatilhoBasemap() (js/40-camadas-controle.js) sempre
       que o basemap não é o Escuro.

       Sobre fundo claro o filtro inverte de papel: em vez de LEVANTAR o escuro
       para a lâmina acender, ele tem de BAIXAR o claro para o texto continuar
       legível. Por isso `brightness` cruza o 1 — de 1,5 para 0,5 — e o véu
       escuro sobe de 62% para 80%. Medido: sobre o cinza do CARTO Claro o
       composto sai de rgb(102,107,116) para rgb(29,34,41), e o contraste do
       texto de 4,3:1 para 13:1.

       Sobrescreve SÓ os dois tokens que dependem do que está atrás. O aro, o
       especular e o desfoque continuam iguais: a leitura de lâmina translúcida
       vem da superfície, não de quanto mapa se enxerga através dela — e é por
       isso que dá para escurecer sem perder o efeito. */
    body.base-clara {
      --glass-blur: blur(24px) saturate(150%) brightness(.5);
      --glass-1: rgba(6,12,22,.80);
    }


    /* ── Padrão dos painéis +4D ─────────────────────────────────────────── */

    /* Faixa lateral de identidade da camada */
    #panel.p4d-layer-setor    { box-shadow: inset 3px 0 0 0 #38bdf8; }
    #panel.p4d-layer-distrito { box-shadow: inset 3px 0 0 0 #ffd54f; }
    #panel.p4d-layer-quadra   { box-shadow: inset 3px 0 0 0 #81c784; }
    #panel.p4d-layer-eu       { box-shadow: inset 3px 0 0 0 #ef9a9a; }
    #panel.p4d-layer-lote-fiscal { box-shadow: inset 3px 0 0 0 #38bdf8; }
    #panel.p4d-layer-bairro   { box-shadow: inset 3px 0 0 0 #a0b4c8; }

    /* Header: badge + ID + meta */
    /* ── ESCALA TIPOGRÁFICA DOS PAINÉIS ──────────────────────────────────
       Os painéis usavam doze tamanhos diferentes — 9, 9.5, 10, 10.5, 11,
       11.5, 12, 12.5, 13, 14, 15 e 17 px — escolhidos um a um, no olho, ao
       longo do tempo. Doze tamanhos não são uma escala: são doze exceções, e
       o efeito é o de página sem regra, onde nada parece ter sido decidido.

       São SETE degraus, e cada um tem um trabalho:

         --fs-micro   ressalva, procedência, rodapé
         --fs-min     rótulo de cartão, nota sob o número
         --fs-peq     rótulo de seção, chip, texto de apoio
         --fs-corpo   texto corrido — o piso do que se lê confortavelmente
         --fs-med     valor secundário, número dentro de cartão
         --fs-num     o número principal do cartão
         --fs-tit     identificação no cabeçalho

       Tudo subiu de um a três pixels em relação ao que havia: o painel é
       consultado por quem não é do ramo, muitas vezes em tela de trabalho, e
       o corpo anterior (12 px para texto corrido, 9 px para rótulo) estava
       abaixo do confortável. */
    :root {
      --fs-rot: 10px;      /* rotulo: legivel e discreto, nunca disputa com o numero */
      /* Peso do rótulo em caixa alta — o mesmo para os três que existem
         (.p4d-kpi-label, .p4d-context-label, .p4d-bloco-rot), que são o mesmo
         papel: a palavra que diz o que o número ao lado significa.
         Estavam todos no peso herdado (400) e sumiam sob os cabeçalhos de
         seção, que já vinham em 700 — a hierarquia ficava ao contrário, com o
         título da caixa mais forte que a etiqueta do dado dentro dela. Em
         caixa alta a 10 px o peso é o único recurso de ênfase que sobra: corpo
         maior brigaria com o número, e cor já está reservada para dizer a que
         entidade o cartão pertence. */
      --fw-rot: 700;
      --fs-micro: 10.5px;
      --fs-min: 12px;
      --fs-peq: 13px;
      --fs-corpo: 14px;
      --fs-med: 16px;
      --fs-num: 21px;
      --fs-tit: 17px;
    }

    .p4d-head {
      display: flex;
      align-items: center;
      gap: 10px;
      min-width: 0;
    }
    /* ── CABEÇALHO COM TÍTULO ────────────────────────────────────────────
       O bloco de marca do topbar, aplicado à identificação do imóvel: uma
       sobrancelha em caixa alta e tracking largo, e sob ela o nome em Space
       Grotesk. Lá em cima é "+4D URBAN INTELLIGENCE" / "URBAN INTELLIGENCE";
       aqui é "LOTE FISCAL · 000413870000" / "R CANCIO GOMES 473".

       O gradiente de dados (ciano → esmeralda) entra só no NÚMERO do endereço,
       e não no nome da rua, por uma razão: ele é o sinal que o sistema usa
       para dizer "isto é dado" — é o mesmo tratamento do wordmark "+DADOS".
       Aplicado no texto inteiro viraria enfeite e perderia o sentido. */
    .p4d-head.com-titulo {
      flex-direction: column;
      align-items: flex-start;
      /* 5px é o respiro entre a sobrancelha e o wordmark em .tb-logo-texts */
      gap: 5px;
      padding: 1px 0;
      width: 100%;
    }
    .p4d-head-tit {
      font-family: var(--display);
      font-size: 19px;
      font-weight: 700;
      line-height: 1.1;
      color: #ffffff;
      /* .tb-logo-title usa 0.08em a 14,5px; a 19px o mesmo valor esgarça um
         nome de rua comprido, então o tracking acompanha o corpo para baixo. */
      letter-spacing: 0.03em;
      text-transform: uppercase;
      display: flex;
      align-items: baseline;
      gap: 9px;
      min-width: 0;
      width: 100%;
    }
    .p4d-head-tit .via {
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .p4d-head-tit .num {
      font-weight: 700;
      background: var(--grad-dados);
      -webkit-background-clip: text;
      background-clip: text;
      -webkit-text-fill-color: transparent;
      white-space: nowrap;
    }
    .p4d-head-linha {
      display: flex;
      align-items: center;
      gap: 9px;
      min-width: 0;
      max-width: 100%;
    }
    /* Sobrancelha: o selo perde a pastilha e passa a ser lido como o eyebrow
       do topbar (.tb-logo-prefix) — Inter 800, 10,5px, tracking 0.3em. A cor
       continua sendo a da camada, que é o que amarra o painel ao mapa; no lote
       fiscal ela já é o ciano do sistema. */
    .p4d-head.com-titulo .p4d-badge {
      background: none;
      padding: 0;
      font-family: var(--body);
      font-weight: 800;
      font-size: 10.5px;
      letter-spacing: 0.3em;
      text-transform: uppercase;
      white-space: nowrap;
      flex-shrink: 0;
    }
    .p4d-badge.proprio {
      color: #00e5ff !important;
      background: rgba(0, 229, 255, 0.14) !important;
      border: 1px solid rgba(0, 229, 255, 0.35) !important;
    }
    .p4d-head.com-titulo .p4d-badge.proprio {
      color: #00e5ff !important;
      background: none !important;
      border: none !important;
    }
    /* Fio divisor no desenho de .tb-nav-divider / .tb-actions-divider */
    .p4d-head-div {
      width: 1px;
      height: 12px;
      background: rgba(255, 255, 255, 0.12);
      flex-shrink: 0;
    }
    /* O CÓDIGO DO IMÓVEL, e não uma legenda do selo ao lado.
       Saía em 11px --t3 — menor E mais apagado que o selo "LOTE", que vem
       colorido dentro de uma pastilha. A etiqueta da CATEGORIA pesava mais que
       o identificador da COISA, e é o identificador que se copia, que se
       procura e que se cita num processo.
       Agora empata com o selo em corpo e ganha dele em contraste. Segue em
       --mono: doze dígitos em fonte proporcional não se leem em grupos, e é
       assim que se confere um NUMBLOCO. */
    .p4d-head.com-titulo .p4d-id {
      font-family: var(--mono);
      font-size: var(--fs-min);
      font-weight: 700;
      letter-spacing: 0.02em;
      color: var(--t1);
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    /* ── RESTRIÇÕES SOBRE O LOTE ─────────────────────────────────────────
       Altura (PBZPA) e proteção cultural são a mesma espécie de informação:
       limites que NÃO vêm do imóvel, e que decidem o que se pode fazer nele.
       Por isso agora vivem num bloco só, e não em dois cartões soltos.

       Cada uma ocupa UMA LINHA fechada — rótulo à esquerda, valor à direita.
       Antes eram dois cartões de cinco linhas cada, e juntos ocupavam mais
       espaço no painel do que a área, a testada e a construção somadas: quem
       abria um lote via primeiro dois blocos de ressalva jurídica.

       O que saiu da vista fechada não sumiu — desceu para dentro do <details>:
       de onde o número vem, o que ele significa e a ressalva completa. Quem só
       olha não é interrompido; quem vai decidir abre e lê tudo. */
    .p4d-restr {
      margin: 8px 0 2px;
      display: flex;
      flex-direction: column;
      gap: 4px;
    }
    /* MANTIDA sem uso próprio: o título do bloco passou a usar `.p4d-grupo`,
       o mesmo de CARACTERÍSTICAS / ATIVIDADE ECONÔMICA / TRIBUTOS. Ter dois
       vocabulários de título no mesmo painel fazia o leitor não saber se "o
       que pesa sobre este lote" era uma seção como as outras. É. */
    .p4d-restr-tit {
      font-family: var(--display);
      font-size: 9px;
      letter-spacing: 0.12em;
      text-transform: uppercase;
      color: var(--muted);
      padding-left: 2px;
      margin-bottom: 1px;
    }
    /* --c: a cor da restrição, injetada por linha. A faixa à esquerda é o que
       liga a linha à camada correspondente no mapa. */
    .rst {
      --c: #fbbf24;
      background: rgba(15, 23, 42, 0.55);
      border: 1px solid rgba(255, 255, 255, 0.1);
      border-left: 4px solid var(--c);
      border-radius: 8px;
      overflow: hidden;
      margin-bottom: 6px;
    }
    .rst > summary {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 10px 12px;
      cursor: pointer;
      list-style: none;
      user-select: none;
    }
    .rst > summary::-webkit-details-marker { display: none; }
    .rst > summary:hover { background: rgba(255, 255, 255, 0.04); }
    .rst-rot {
      font-family: var(--display);
      font-size: 11px;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      color: var(--c);
      flex-shrink: 0;
    }
    .rst-val {
      margin-left: auto;
      font-family: var(--display);
      font-size: 13px;
      font-weight: 700;
      color: #ffffff;
      text-align: right;
      line-height: 1.25;
    }
    .rst-val.sem {
      font-size: 11.5px;
      color: rgba(241, 245, 249, 0.7);
      font-style: italic;
    }
    .rst-chev {
      flex-shrink: 0;
      font-size: 11px;
      color: rgba(255, 255, 255, 0.45);
      transition: transform 0.15s;
    }
    .rst[open] .rst-chev { transform: rotate(180deg); }
    .rst-corpo { padding: 0 10px 10px; }
    .rst-sub {
      font-size: 10.5px;
      color: rgba(221, 232, 248, 0.6);
      line-height: 1.4;
    }
    .rst-aviso {
      font-size: 9.5px;
      color: var(--muted);
      line-height: 1.45;
      margin-top: 6px;
      padding-top: 5px;
      border-top: 1px solid rgba(255, 255, 255, 0.08);
    }
    .rst-aviso a { color: var(--c); }
    /* Selo do TPC — o imóvel já transferiu potencial construtivo. Fica ao lado
       do grau de proteção porque muda o que ainda resta a negociar. Sem escopo
       de bloco: o mesmo selo aparece na linha de restrição do painel do lote e
       no popup do imóvel protegido, que vive fora dele. */
    .pb-tpc {
      display: inline-block;
      font-family: var(--display);
      font-size: 8.5px;
      letter-spacing: 0.1em;
      padding: 2px 6px;
      margin-left: 6px;
      border-radius: 5px;
      vertical-align: 2px;
      color: #f0c9a8;
      background: rgba(235, 146, 77, 0.16);
      border: 1px solid rgba(235, 146, 77, 0.35);
    }
    .p4d-badge {
      font-family: var(--display);
      font-size: var(--fs-min);
      letter-spacing: 0.12em;
      padding: 4px 9px;
      border-radius: 3px;
      font-weight: 500;
      white-space: nowrap;
    }
    .p4d-badge.eu       { background: rgba(239,154,154,0.15); color: #ef9a9a; }
    .p4d-badge.fiscal   { background: rgba(56,189,248,0.15);  color: #38bdf8; }
    .p4d-badge.quadra   { background: rgba(129,199,132,0.15); color: #81c784; }
    .p4d-badge.distrito { background: rgba(255,213,79,0.15);  color: #ffd54f; }
    .p4d-badge.setor    { background: rgba(56,189,248,0.15);  color: #38bdf8; }
    .p4d-badge.bairro   { background: rgba(160,180,200,0.15); color: #a0b4c8; }
    /* Área de Estudo — o mesmo violeta do polígono no mapa, que é o que amarra
       o painel ao recorte desenhado. */
    .p4d-badge.estudo   { background: rgba(167,139,250,0.15); color: #a78bfa; }

    /* O CÓDIGO DO IMÓVEL, e não uma legenda do selo ao lado.
       Ele saía em --muted, sem peso, enquanto o selo ("LOTE") vinha colorido
       dentro de uma pastilha: a etiqueta da CATEGORIA pesava mais que o
       identificador da COISA. Quem trabalha com cadastro copia esse número,
       procura por ele, cita ele num processo — é o dado da linha.
       Branco cheio, 700, e em --mono: doze dígitos em fonte proporcional não
       se leem em grupos, e é assim que se confere um NUMBLOCO. */
    .p4d-id {
      font-family: var(--mono);
      font-size: var(--fs-tit);
      font-weight: 700;
      color: var(--t1);
      letter-spacing: 0.02em;
    }
    .p4d-meta {
      font-family: var(--display);
      font-size: 11px;
      color: rgba(255,255,255,.62);
      margin-left: auto;
      letter-spacing: 0.05em;
    }

    /* Bloco de contexto: label + valor principal (endereço/setor/tipo/região) */
    .p4d-context-label {
      font-family: var(--display);
      font-size: var(--fs-rot);
      font-weight: var(--fw-rot);
      letter-spacing: 0.14em;
      color: var(--muted);
      margin-bottom: 6px;
      text-transform: uppercase;
    }
    .p4d-context-value {
      display: flex;
      align-items: baseline;
      justify-content: space-between;
      gap: 10px;
      margin-bottom: 14px;
      font-size: var(--fs-med);
      color: var(--text);
      font-weight: 500;
    }
    .p4d-context-value .num {
      font-family: var(--display);
      font-size: var(--fs-med);
      font-weight: 500;
      white-space: nowrap;
    }
    /* ── ENDEREÇOS DO LOTE ───────────────────────────────────────────────
       O registro completo do imóvel: cada endereço e o uso do solo declarado
       nele. Vive numa seção RECOLHIDA, junto das outras do painel.

       Antes estava espalhado em dois lugares: um bloco no topo do corpo, que
       reabria a rua e o número já impressos no título, e a lista "ATIVIDADE DO
       LOTE · POR ENDEREÇO" dentro de OCUPAÇÃO DO SOLO, que repetia os mesmos
       endereços com as atividades. Duas listas do mesmo conjunto, em dois
       vocabulários — e um lote de esquina abria com nove linhas de endereço
       antes de qualquer dado.

       A linha segue o item do menu de mapa base do topbar (.tb-base-item):
       rótulo à esquerda, meta encostada à direita. O NÚMERO fica no display,
       em branco pleno — é o dado da linha; a rua é o contexto dele. */
    .p4d-end {
      padding: 8px 2px;
    }
    .p4d-end + .p4d-end {
      border-top: 1px solid rgba(255, 255, 255, 0.05);
    }
    .p4d-end-topo {
      display: flex;
      align-items: baseline;
      gap: 12px;
    }
    .p4d-end-topo .via {
      font-family: var(--body);
      font-size: var(--fs-corpo);
      color: var(--t2);
      letter-spacing: 0.01em;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .p4d-end-topo .num {
      margin-left: auto;
      font-family: var(--display);
      font-size: var(--fs-corpo);
      font-weight: 500;
      color: var(--t1);
      white-space: nowrap;
    }
    .p4d-end-topo .num.sem {
      font-family: var(--body);
      font-size: var(--fs-min);
      font-weight: 400;
      color: var(--t3);
      font-style: italic;
    }
    /* Atividades declaradas no endereço. O chip usa --crgb para tingir fundo e
       contorno com a mesma cor do rótulo — era um `style=` de seis propriedades
       repetido a cada atividade de cada endereço. */
    .p4d-end-ativs {
      display: flex;
      flex-wrap: wrap;
      gap: 5px;
      margin-top: 6px;
    }
    .p4d-end-ativ {
      display: flex;
      flex-direction: column;
      gap: 2px;
      min-width: 0;
    }
    .p4d-end-ativ .chip {
      font-size: var(--fs-min);
      line-height: 1.5;
      padding: 1px 7px;
      border-radius: 5px;
      white-space: nowrap;
      color: var(--c, #90caf9);
      background: rgba(var(--crgb, 144, 202, 249), 0.10);
      border: 1px solid rgba(var(--crgb, 144, 202, 249), 0.25);
    }
    .p4d-end-ativ .nota {
      font-size: var(--fs-micro);
      color: var(--t3);
      letter-spacing: 0.02em;
      padding-left: 2px;
    }
    .p4d-end-vazio {
      font-size: var(--fs-min);
      color: var(--t3);
      font-style: italic;
      margin-top: 4px;
    }

    /* Grade de KPIs (2, 3 ou 4 cards) */
    .p4d-kpi-grid {
      display: grid;
      gap: 8px;
      margin-bottom: 10px;
    }
    /* Um cartão só, largura inteira: o número que manda na seção — o valor
       venal do imóvel, o VGV. Sem ele, um item solto caía em `cols-4` e
       ocupava meia linha, com o outro meio vazio ao lado. */
    .p4d-kpi-grid.cols-1 { grid-template-columns: 1fr; }
    .p4d-kpi-grid.cols-2 { grid-template-columns: 1fr 1fr; }
    .p4d-kpi-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
    /* Quanto mais estreita a coluna, menor o numero: o mesmo corpo que
       parece certo em dois cartoes fica apertado em tres. */
    .p4d-kpi-grid.cols-3 .p4d-kpi-value { font-size: var(--fs-med); }
    .p4d-kpi-grid.cols-4 .p4d-kpi-value { font-size: var(--fs-corpo); }
    .p4d-kpi-grid.cols-4 { grid-template-columns: 1fr 1fr; }

    .p4d-kpi {
      background: var(--glass-sheen), rgba(255,255,255,0.035);
      border: 1px solid rgba(255,255,255,0.09);
      border-radius: 10px;
      padding: 10px 10px;
      min-width: 0;
      /* Mesma aresta de luz das seções que o contêm: o cartão é a lâmina mais
         alta da pilha e é a única que não tinha espessura nenhuma. */
      box-shadow: var(--glass-edge);
    }
    .p4d-kpi-label {
      /* Era "uma linha, sempre", com reticencias — e o motivo estava certo: com
         tres cartoes lado a lado a caixa tem ~150 px, e rotulo quebrado em duas
         linhas desalinharia os numeros entre si.
         So que o preco disso era cortar a palavra: "ANO DE CONSTRUÇÃ…" e
         "AREA DO LOTE FISC…" apareciam truncados no painel do lote. Agora o
         rotulo QUEBRA e a altura de duas linhas fica RESERVADA nas grades
         apertadas (cols-3/cols-4, abaixo) — os numeros seguem alinhados e
         nenhuma palavra some. Mesma solucao do .pd-kpi do Plano Diretor. */
      white-space: normal;
      overflow-wrap: anywhere;
      line-height: 1.3;
      font-family: var(--display);
      font-size: var(--fs-rot);
      font-weight: var(--fw-rot);
      letter-spacing: 0.07em;
      margin-bottom: 5px;
      text-transform: uppercase;
    }
    /* Rótulo em negrito ocupa mais largura, e no cartão estreito (três ou
       quatro por linha) "ANO DE CONSTRUÇÃO" já vinha cortado com reticências
       antes mesmo de o peso subir. O tracking devolve o que o peso tomou —
       é o mesmo ajuste por número de colunas que o corpo do número já faz
       logo acima. */
    .p4d-kpi-grid.cols-3 .p4d-kpi-label,
    .p4d-kpi-grid.cols-4 .p4d-kpi-label { letter-spacing: 0.02em; min-height: 2.6em; }
    .p4d-kpi-value {
      font-family: var(--display);
      font-size: var(--fs-num);
      color: var(--text);
      font-weight: 500;
      white-space: normal;
      overflow-wrap: anywhere;
    }
    .p4d-kpi-value .unit {
      font-size: var(--fs-peq);
      color: var(--muted);
      margin-left: 3px;
      /* A unidade acompanha o número na MESMA linha: ela é parte da leitura
         ("240,45 m"), não um comentário. Por isso não quebra — o que precisar
         de mais de duas palavras vai para .p4d-kpi-nota, abaixo. */
      white-space: nowrap;
    }
    /* Linha de ressalva sob o número: procedência, contagem, "estimada".
       Pequena e apagada de propósito — quem varre o painel lê os números; quem
       vai usar o número lê a ressalva. */
    .p4d-kpi-nota {
      font-size: var(--fs-min);
      line-height: 1.3;
      color: var(--muted);
      margin-top: 3px;
      opacity: 0.85;
      word-break: break-word;
      overflow-wrap: break-word;
    }
    .p4d-kpi-nota[title] {
      cursor: help;
      border-bottom: 1px dotted rgba(255, 255, 255, 0.18);
      display: inline-block;
    }

    /* ── BLOCO DE SEÇÃO ──────────────────────────────────────────────────
       O que não é cartão de número mas também não é texto solto: uma frase
       (a classe CNAE mais recorrente), uma série (impostos por ano), um valor
       com procedência (o m² imobiliário). Antes cada um trazia o seu próprio
       `style=` com fundo e contorno na cor da seção — dentro de um acordeão
       que já tem esse fundo e esse contorno, virava caixa sobre caixa da mesma
       cor. A superfície aqui é a do cartão de indicador; a cor da seção entra
       por `--c`, e só no rótulo. */
    .p4d-bloco {
      background: rgba(255, 255, 255, 0.02);
      border: 1px solid var(--border);
      border-radius: 8px;
      padding: 10px 12px;
      margin-bottom: 8px;
    }
    .p4d-bloco:last-child { margin-bottom: 0; }
    .p4d-bloco-rot {
      font-family: var(--display);
      font-size: var(--fs-rot);
      font-weight: var(--fw-rot);
      letter-spacing: 0.1em;
      text-transform: uppercase;
      color: var(--c, var(--emerald));
      margin-bottom: 6px;
    }
    .p4d-bloco-num {
      font-family: var(--display);
      font-size: var(--fs-med);
      font-weight: 500;
      color: var(--t1);
      line-height: 1.15;
    }
    .p4d-bloco-num .unid {
      font-size: var(--fs-peq);
      color: var(--muted);
      margin-left: 2px;
    }
    /* Ausência de dado não é um número: perde o corpo e o branco pleno. */
    .p4d-bloco-num.sem {
      font-size: var(--fs-peq);
      font-weight: 400;
      color: var(--t3);
    }
    .p4d-bloco-nota {
      font-size: var(--fs-min);
      color: var(--muted);
      margin-top: 3px;
      line-height: 1.4;
    }
    .p4d-bloco-fonte {
      font-size: var(--fs-micro);
      color: var(--t3);
      margin-top: 7px;
      line-height: 1.4;
    }
    /* Disclosure interno do bloco (a lista de ofertas) */
    .p4d-bloco-mais { margin-top: 9px; }
    .p4d-bloco-mais > summary {
      cursor: pointer;
      list-style: none;
      user-select: none;
      display: flex;
      align-items: center;
      gap: 6px;
      font-family: var(--display);
      font-size: var(--fs-min);
      letter-spacing: 0.04em;
      color: var(--c, var(--emerald));
    }
    .p4d-bloco-mais > summary::-webkit-details-marker { display: none; }
    .p4d-bloco-mais > summary::before {
      content: '▸';
      font-size: 10px;
      transition: transform 0.15s;
    }
    .p4d-bloco-mais[open] > summary::before { transform: rotate(90deg); }
    .p4d-bloco-mais-corpo {
      margin-top: 8px;
      display: flex;
      flex-direction: column;
      gap: 7px;
    }
    .p4d-bloco-mais-corpo .oferta {
      border-left: 2px solid rgba(52, 211, 153, 0.45);
      padding-left: 9px;
      line-height: 1.4;
    }
    .p4d-bloco-mais-corpo .oferta .end { font-size: var(--fs-min); color: var(--t2); }
    .p4d-bloco-mais-corpo .oferta .val { font-size: var(--fs-min); color: var(--muted); }
    .p4d-bloco-mais-corpo .oferta .val b { color: var(--c, var(--emerald)); font-weight: 600; }

    /* Selo de ESTADO do imóvel — "lote vazio". Não é número nem seção: é uma
       condição do cadastro, e por isso fica num chip antes dos cartões. */
    .p4d-selo-estado {
      display: inline-flex;
      align-items: center;
      gap: 5px;
      font-family: var(--display);
      font-size: var(--fs-min);
      letter-spacing: 0.1em;
      padding: 3px 9px;
      margin-bottom: 8px;
      border-radius: 6px;
      color: var(--amber);
      background: rgba(251, 191, 36, 0.10);
      border: 1px solid rgba(251, 191, 36, 0.32);
    }

    /* Accordion padronizado (outline + cor semântica) */
    .p4d-acc {
      border-radius: 6px;
      padding: 10px 12px;
      margin-top: 4px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-family: var(--display);
      font-size: 11px;
      letter-spacing: 0.08em;
      cursor: pointer;
      user-select: none;
      text-transform: uppercase;
      transition: background 0.12s;
    }
    .p4d-acc:first-of-type { margin-top: 6px; }
    .p4d-acc .chev { opacity: 0.7; font-size: 12px; }

    html,
    body {
      height: 100%;
      overflow: hidden;
    }

    body {
      font-family: var(--body);
      background: var(--bg);
      color: var(--t1);
      display: flex;
      flex-direction: column;
      /* Brilho ambiente do sistema visual: violeta no alto à direita,
         ciano no alto à esquerda — fixo, não acompanha o scroll. */
      background-image:
        radial-gradient(900px 500px at 78% -8%, rgba(124,58,237,.10), transparent 60%),
        radial-gradient(700px 420px at 4% 4%, rgba(56,189,248,.07), transparent 62%);
      background-attachment: fixed;
    }

    /* Seleção e foco — acento ciano do sistema */
    ::selection { background: rgba(56,189,248,.25); color: #fff; }
    :focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 4px; }
