/* 99a-responsivo.css — a aplicação em telas estreitas
   ══════════════════════════════════════════════════════════════════════
   POR QUE ESTA FOLHA EXISTE, E POR QUE ELA É A ÚLTIMA

   Até aqui a plataforma era desenhada para uma tela larga, e só. Medido
   num viewport de 390px, antes desta folha:

     · o conteúdo do #topbar transbordava 935px — a navegação começava em
       x=589 e as ações em x=1090, ou seja, INTEIRAMENTE fora da tela;
     · a coluna de menus ocupava 300 dos 390px (77% da largura);
     · o painel do lote, ancorado em `right:70px` com 485px fixos, saía
       pela ESQUERDA: x = −165;
     · a pilha de legendas nascia em x=316, fora do enquadramento.

   Nada disso era "quase certo": era um layout de desktop renderizado num
   telefone. As nove media queries que já existiam cobriam só o miolo do
   Dashboard — a moldura da aplicação não tinha nenhuma.

   ORDEM DE CARGA. Esta folha SOBRESCREVE as anteriores, então precisa ser
   a última da lista do index.html. O nome segue a regra do projeto (o
   número é a posição na cascata) com um sufixo, porque 99 já estava
   ocupado: `99-lote-licenciamentos.css` vem antes de `99a-responsivo.css`
   tanto na ordenação da pasta quanto nas tags — '-' vem antes de 'a'.
   Folha nova depois desta entra como 99b, 99c, e assim por diante.

   OS DOIS CORTES
    ≤ 1340px  COMPACTO — laptop pequeno, tablet e telefone deitado. A moldura encolhe: os
              rótulos da navegação saem e ficam os ícones, a marca perde o
              nome do programa, a busca deixa de ter teto.
     ≤ 560px  TELEFONE — a faixa do topo passa a DUAS linhas, os painéis
              viram folhas que sobem de baixo, e a coluna de menus deixa
              de empurrar os overlays da esquerda.

   Os valores dos cortes foram MEDIDOS, não escolhidos por serem redondos.
   Com rótulos na navegação, a faixa inteira precisa de 1.329px: a 1.366
   ela cabe com duas frestas de 18px, e a 1.024 transbordava 301px. O corte
   fica em 1.340, logo acima do mínimo. O de 560 é onde a faixa em uma
   linha deixa de caber mesmo com tudo já reduzido — abaixo dele o campo de
   busca ficaria com ~90px, que não serve para digitar endereço nenhum.
   ══════════════════════════════════════════════════════════════════════ */


/* ══ ≤ 1340px · COMPACTO ════════════════════════════════════════════ */
/* A assinatura por extenso é informação institucional, não controle da
   aplicação. Em laptops, ela cede espaço à busca e à navegação; o texto
   completo segue presente em telas amplas, onde pode ser lido sem apertar a
   barra. */
@media (max-width: 1719px) {
  .tb-institution { display: none; }
}

@media (max-width: 1340px) {

  /* ── A FAIXA DO TOPO ────────────────────────────────────────────────
     O nome do programa sai; ficam o selo +4D e o +DADOS, que é como o
     produto se chama. Numa faixa estreita, "DISTRITO DA INOVAÇÃO" em
     caixa alta com tracking come 180px para dizer de quem é a coisa —
     informação de rodapé, não de barra de ferramentas. */
  .tb-logo-prefix,
  .tb-logo-sep { display: none; }
  .tb-logo { padding: 0 10px 0 4px; gap: 8px; border-right: none; }

  /* Navegação em ícones. O rótulo vai para o `title`; o SVG já é
     desenho suficiente para três destinos que a pessoa usa todo dia.
     `font-size:0` zera o texto sem precisar envolvê-lo num span — ele é
     nó de texto solto dentro do botão. O SVG tem tamanho próprio e não
     se abala. */
  .tb-nav-btn { font-size: 0; gap: 0; padding: 7px 10px; }
  .tb-nav-btn > svg { width: 15px; height: 15px; }
  /* "Insights" é o único sem destino: numa faixa apertada ele gastaria
     espaço para não levar a lugar nenhum. O selo EM BREVE também sai —
     em `font-size:0` ele viraria um retângulo vazio. */
  .tb-nav-btn.tb-nav-soon { display: none; }
  .tb-nav-divider { display: none; }
  .tb-nav { margin-right: 6px; }

  /* Com a navegação em ícones sobra folga, e parte dela vai para o campo
     — mas não toda: sem teto ele chegava a 811px numa tela de 1280, o que
     é um campo de busca do tamanho de um parágrafo. 520 é o ponto em que
     ele comporta a frase inteira do placeholder com respiro. */
  .tb-search-wrap { max-width: 520px; margin: 0 10px; min-width: 0; }

  /* LIMPAR em ícone, redondo como os utilitários ao lado. Continua fora
     da cápsula — é ação, não utilitário (ver 10-topbar.css). */
  .tb-clear-btn {
    font-size: 0; gap: 0; padding: 0;
    width: 30px; height: 30px; border-radius: 50%;
    justify-content: center;
  }
  .tb-clear-icon { font-size: 15px; }
  .tb-actions { gap: 7px; padding: 0 10px 0 6px; }

  /* A etiqueta de atualização perde o rótulo e fica só no ponto + data.
     "ATUALIZADO EM" custa ~85px de uma faixa que já mandou a navegação
     virar ícone para caber; a data sozinha, ao lado do ponto verde, ainda
     se lê como "no ar, desta data", e o `title`/`aria-label` continuam
     dizendo a frase inteira para quem parar em cima ou ouvir a página. */
  .tb-updated-lbl { display: none; }
  .tb-updated { padding-left: 8px; }

  /* ── PAINÉIS ────────────────────────────────────────────────────────
     485px de painel numa tela de 900 sobra pouco mapa. Vira metade da
     largura, com piso: abaixo de 380px o painel do lote não se lê. */
  /* Só abaixo de 1100 o painel precisa ceder: entre 1100 e 1340 a tela
     ainda comporta os 485px e um mapa útil ao lado. */
  #panel { right: 12px; }
}

@media (max-width: 1100px) {
  #panel { width: min(485px, 54vw); min-width: 360px; }
  #cmp-overlay.open { width: min(780px, 92vw); }
  #cmp-overlay.expanded { width: 100vw; }
}


/* ══ ≤ 560px · TELEFONE ═════════════════════════════════════════════ */
@media (max-width: 560px) {

  :root {
    /* Duas linhas: marca + navegação + ferramentas em cima, busca embaixo.
       Espremer tudo numa linha só dava um campo de busca de ~90px, que não
       serve para digitar endereço nenhum. */
    --topbar-h: 96px;
  }

  /* ── GRADE, NÃO QUEBRA DE LINHA ─────────────────────────────────────
     A primeira versão disto era `flex-wrap:wrap` com `order`. Funciona
     enquanto a conta fecha — e para de funcionar quando não fecha: num
     aparelho de 330px a faixa virava TRÊS linhas, com o bloco de ações
     sozinho no meio, porque ele não coube ao lado da marca e da navegação.
     Quebra automática não é layout: é o que sobra quando não há layout.

     Em grade as duas linhas são declaradas, e o conteúdo se ajusta dentro
     delas em vez de decidir sozinho onde quebrar:

        ┌ ‹ ┬ marca ┬────┬ navegação ┬ ações ┐   ← todos os controles
        ├ busca ─────────────────────────────┤   ← a linha inteira
        └────────────────────────────────────┘

     Primeiro os controles ficaram repartidos entre as duas linhas — a
     navegação em cima, as ações embaixo ao lado da busca. Lia mal por dois
     motivos: os dois grupos de botão são a mesma classe de coisa (chrome da
     aplicação) e estavam separados por um campo de texto no meio; e a busca,
     dividindo a linha com as ações, ficava com 186px num aparelho de 330.
     Juntos em cima, a busca fica com a LARGURA INTEIRA — que é o que ela
     precisa, porque é nela que se digita endereço. */
  #topbar {
    display: grid;
    grid-template-columns: auto auto 1fr auto auto;
    grid-template-rows: auto auto;
    align-items: center;
    row-gap: 6px;
    column-gap: 8px;
    padding: 6px 0 8px;
  }
  /* `height:100%` na marca é correto numa faixa de uma linha — é o que dá a
     área de clique inteira. Em duas linhas vira defeito: ela esticava para
     a altura total, a primeira linha herdava isso e a busca era empurrada
     33px para FORA da faixa, por cima do mapa. Medido. */
  .tb-logo, .tb-back { height: auto; }
  /* A LINHA precisa ser declarada junto com a coluna. Só com `grid-column`
     o posicionamento automático continua mandando: ele preenche a primeira
     célula livre e empurrava a navegação, a busca e as ações cada uma para
     uma linha — três linhas de novo, agora dentro de uma grade. Medido. */
  /* A seta de voltar leva para FORA da aplicação (o site do Distrito). Num
     telefone esse papel é do botão "voltar" do próprio sistema, que está
     sempre à mão — e aqui ela custava 20px da linha em que a marca e os
     controles disputam espaço. */
  .tb-back        { display: none; }
  .tb-logo        { grid-area: 1 / 2; }
  .tb-nav         { grid-area: 1 / 4; margin: 0; justify-self: end; }
  .tb-actions-divider { display: none; }
  .tb-actions     { grid-area: 1 / 5; justify-self: end; padding: 0 10px 0 0; }
  .tb-search-wrap { grid-area: 2 / 1 / 3 / 6; margin: 0 10px; max-width: none; min-width: 0; }
  .tb-logo { min-width: 0; }
  .tb-logo-badge { overflow: hidden; text-overflow: clip; }

  /* O SINO SAI NO TELEFONE.
     Ele é hoje um botão sem ação — não há notificação para mostrar. No
     desktop custa 30px de uma faixa que sobra espaço; aqui, custa 30px da
     linha em que se digita endereço, e a busca ficava colada nas ações.
     Quando as notificações existirem, é aqui que ele volta. */
  .tb-tools > .tb-icon-btn[title="Notificações"] { display: none; }

  /* A ETIQUETA DE ATUALIZAÇÃO SAI NO TELEFONE.
     Duas razões, e a segunda é a que decide. É informação de rodapé, e a
     linha de cima aqui é disputada por marca, navegação e ações. E a faixa
     virou GRADE com as áreas declaradas uma a uma: um filho a mais sem
     `grid-area` cai no posicionamento automático e empurra a busca para
     uma terceira linha — o defeito que o comentário da grade acima
     descreve. Para trazê-la de volta, é preciso dar-lhe uma célula. */
  .tb-updated { display: none; }
  .tb-logo-badge  { font-size: 19px; padding-left: 0; }

  /* ── A COLUNA DE MENUS ──────────────────────────────────────────────
     Ela já é um overlay sobre o mapa (não ocupa largura de layout), então
     o que estraga no telefone não é ela — é o que se ANCORA nela:
     legendas, indicadores e o seletor de granularidade usam
     `calc(var(--sidebar-w) + 14px)` e nasciam fora da tela.
     Aqui --sidebar-w vira 0 para esses três, e a coluna passa a cobrir
     quase toda a largura quando aberta. Quem a abre, abre para usar; quem
     quer o mapa, fecha no « — o mesmo botão de sempre.
     `js/36-indicadores.js` fecha a coluna sozinho ao carregar num
     telefone, para o app não abrir com o menu por cima do mapa. */
  :root { --sidebar-w: 0px; }
  #sidebar { width: min(300px, 88vw); }
  #sb-toggle { left: 12px; }
  /* Com a coluna aberta o botão de fechar ficava logo À DIREITA dela — e a
     coluna ocupa 88% da largura, então "logo à direita" é em cima dos
     controles de zoom do mapa. Trazê-lo para dentro resolveu a colisão com o
     zoom e criou outra: ele pousava em cima do primeiro item da lista, o
     CAMADAS.
     Fica dentro, encostado na borda, e a coluna abre uma faixa livre no topo
     para ele — a lista começa ABAIXO. Nenhum alvo por baixo de outro. */
  /* O botão de fechar voltou para FORA da coluna, à direita dela.
     Dentro não funcionava: o `padding-top` que abria espaço para ele some
     assim que a lista rola, e aí ele pousava em cima do "?" do cabeçalho da
     seção — foi o que apareceu no menu CAMADAS aberto.
     Fora, a colisão que restava era com os controles de zoom do mapa. Eles
     somem enquanto a coluna está aberta: ninguém dá zoom no mapa enquanto
     escolhe camadas, e o mapa está coberto de qualquer forma. */
  body:not(.sb-oculta) #sb-toggle { left: calc(min(300px, 88vw) + 8px); top: 8px; }
  body:not(.sb-oculta) .maplibregl-ctrl-top-right { display: none; }

  #legends-wrap, #eu-quickinfo, #agg-mode-toggle { left: 10px !important; }
  #eu-quickinfo { width: auto; right: 10px; max-height: 42vh; }
  #legends-wrap { bottom: 14px; max-width: calc(100vw - 20px); }
  /* Com um painel aberto a folha ocupa 66% da altura e a pilha de legendas,
     ancorada no rodapé, ficava POR BAIXO dela — visível só pela beirada, sem
     dar para ler nem tocar. Numa tela deste tamanho não há onde as duas
     coisas coexistirem: quem abriu um painel está lendo o painel.
     Volta sozinha ao fechar (a classe sai em closePanel). */
  body.p4d-panel-open #legends-wrap,
  body.p4d-panel-open #eu-quickinfo,
  body.p4d-panel-open #agg-mode-toggle { display: none !important; }

  /* ── PAINÉIS VIRAM FOLHAS QUE SOBEM DE BAIXO ────────────────────────
     `right:70px` + 485px fixos punham o painel do lote em x = −165 num
     telefone: ele saía pela esquerda e ficava cortado dos dois lados.
     Folha de baixo é o padrão da plataforma móvel para conteúdo que
     acompanha o mapa: o mapa continua à vista em cima, e o polegar
     alcança o conteúdo. */
  #panel {
    top: auto; right: 8px; left: 8px; bottom: 8px;
    width: auto; min-width: 0;
    height: 66vh; max-height: calc(100vh - var(--topbar-h) - 16px);
    border-radius: 16px;
  }
  #panel-header { padding: 11px 12px; }
  #panel-body { padding: 12px 12px 16px; }
  .p4d-underline-tabs { margin: -12px -12px 12px; padding: 2px 16px 5px; top: -12px; }

  /* Grades de dois e três em uma coluna: 150px de card em 340px úteis
     dava três colunas de 100px, e "TAXA DE PERMEABILIDADE" não cabe. */
  .p4d-kpi-grid.cols-3, .p4d-kpi-grid.cols-4 { grid-template-columns: 1fr 1fr; }
  .pd-kpis { grid-template-columns: 1fr; }
  .pd-kpis .pd-kpi .k { min-height: 0; }
  .p4d-kpi-grid.cols-3 .p4d-kpi-label,
  .p4d-kpi-grid.cols-4 .p4d-kpi-label { min-height: 0; }

  /* Trilha do Plano Diretor: por direito → teto não cabe lado a lado. */
  .pd-trilha-v { flex-wrap: wrap; }
  .pd-trilha-v .seta { display: none; }
  .pd-trilha-v .d, .pd-trilha-v .t { flex: 0 0 100%; }
  .pd-trilha-v .t { margin-top: 6px; }

  /* ── COMPARAR ───────────────────────────────────────────────────────
     A e B lado a lado em 360px são duas colunas de 165px, com um campo de
     busca em cada. Empilhados, cada lado fica com a largura inteira e o
     botão de inverter vira uma faixa entre os dois. */
  #cmp-overlay.open, #cmp-overlay.expanded { width: 100vw; }
  #cmp-overlay { border-left: none; }
  .cmp-pair { grid-template-columns: 1fr; }
  .cmp-swap-wrap { justify-content: center; }
  .cmp-swap { transform: rotate(90deg); }
  .cmp-swap:hover { transform: rotate(270deg); }
  .cmp-head, .cmp-tabs, .cmp-body { padding-left: 12px; padding-right: 12px; }
  /* O período desce para a própria linha: na faixa das abas ele empurrava
     as seis entidades para fora do alcance da rolagem horizontal. */
  .cmp-tabs { flex-wrap: wrap; row-gap: 4px; }
  .cmp-filters { margin-left: 0; padding-left: 0; flex-basis: 100%; }
  .cmp-kpis { grid-template-columns: 1fr 1fr; }
  .cmp-row-stat { grid-template-columns: 1fr auto auto; }
  .cmp-row-stat-delta { display: none; }

  /* ── MANUAL ─────────────────────────────────────────────────────────
     Ele é uma grade de duas colunas: índice de 240px à esquerda, conteúdo
     à direita. Num telefone de 330px isso deixa 90px para o conteúdo — as
     palavras quebravam letra a letra ("Indicador / — / Econômic…"), e o
     índice, que é navegação, ocupava três quartos da tela para levar a um
     texto ilegível.
     Vira UMA coluna: o índice deita no topo, rolando na horizontal como
     uma fita de abas, e o conteúdo fica com a largura inteira. É a mesma
     transformação que a faixa do topo faz — quem tem duas colunas numa
     tela larga tem duas linhas numa estreita. */
  #manual-overlay { padding: 0; }
  .manual-modal { width: 100%; height: 100%; border-radius: 0; border: none; }
  .manual-head { padding: 10px 12px; gap: 8px; flex-wrap: wrap; }
  .manual-body { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .manual-nav {
    border-right: none;
    border-bottom: 1px solid var(--border);
    padding: 8px 0;
    display: flex;
    gap: 4px;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }
  .manual-nav::-webkit-scrollbar { display: none; }
  .manual-nav-item {
    padding: 7px 12px;
    white-space: nowrap;
    border-left: none;
    border-bottom: 2px solid transparent;
    border-radius: 8px 8px 0 0;
    flex-shrink: 0;
  }
  /* Os rótulos de grupo do índice ("CAMADAS GEOGRÁFICAS", "FONTES DE
     DADOS") são divisores de uma lista VERTICAL. Deitados viram palavras
     soltas no meio dos itens, sem nada para dividir. */
  .manual-nav > .manual-nav-group { display: none; }
  /* O buscador do manual é o primeiro filho da navegação. Deitada, ela é
     uma fita flex, e ele encolhia até sobrar só a lupa. Ganha largura fixa e
     não encolhe — buscar é o atalho de quem sabe o que procura, e some com
     a rolagem horizontal inteira. */
  .manual-nav > .manual-search-wrap {
    flex: 0 0 148px;
    padding: 0 8px 0 10px;
    border-right: 1px solid var(--border);
    border-bottom: none;
    margin: 0;
  }
  .manual-content { padding: 16px 14px 40px; }
  .manual-content table { display: block; overflow-x: auto; }

  /* ── A COLUNA DE MENUS: MENOR, UNIFICADA E VISIVELMENTE SANFONADA ────
     Três problemas, num aparelho em que ela cobre a tela inteira:

     1. DOIS TÍTULOS DE GRUPO para seis seções. "Dados" e "Análise" separam
        bem numa coluna alta de desktop; num telefone eles são duas linhas
        de cabeçalho no meio de seis linhas de conteúdo — mais moldura do
        que lista. Somem, e a lista vira uma só.

     2. ALTURA. 12px de padding, 5px de margem e 12px de raio por cabeçalho
        davam ~46px por seção: seis seções não cabiam sem rolar, num menu
        que existe para se ver de relance.

     3. NÃO PARECIA RECOLHÍVEL. O chevron era um '›' de 13px na ponta, no
        mesmo cinza do resto. Numa tela de toque, o que não parece botão
        não é tocado. Ele cresce, ganha caixa própria e gira 90° ao abrir —
        o giro é o que diz, sem palavra nenhuma, que aquilo abre e fecha. */
  .sb-grupo { display: none; }
  #sidebar { padding-top: 4px; }

  .sb-section-header {
    margin: 3px 8px;
    padding: 9px 11px;
    border-radius: 10px;
    gap: 8px;
  }
  .sb-section-title { font-size: 10.5px; letter-spacing: 0.12em; }
  .ind-sec-ico { width: 26px; height: 26px; }

  /* O chevron vira alvo: caixa de 26px, contraste próprio e giro no aberto.
     `rotate(-90deg)` é o estado fechado que o markup já traz inline; a
     regra do aberto precisa vencer esse inline, daí o !important. */
  .sb-section-chevron {
    font-size: 15px;
    width: 26px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 8px;
    background: rgba(255,255,255,.05);
    border: 1px solid rgba(255,255,255,.09);
    color: rgba(255,255,255,.8);
    margin-left: 2px;
  }
  .sb-section-body:not(.collapsed) { animation: none; }

  .sb-item { margin: 3px 8px; padding: 8px 10px; }

  /* ── DASHBOARD ──────────────────────────────────────────────────────
     Dois problemas, e são de naturezas diferentes.

     (1) TRANSBORDO LATERAL de 435px num viewport de 390. Não é largura
         declarada em lugar nenhum: é o `min-width:auto` que todo item de
         grade e de flex tem por padrão. O item se recusa a ficar menor que
         o próprio conteúdo, e um número com `white-space:nowrap` ou uma
         palavra longa estica a coluna inteira — a grade de `1fr 1fr` vira
         duas colunas de 400px numa tela de 390. `min-width:0` nos filhos é
         o que autoriza a grade a fazer o que ela promete.

     (2) ROLAGEM SEM FIM: 19.735px de altura, 26 telas. Tratada com a
         sanfona por seção — a regra do corpo recolhido está no fim deste
         bloco, e o comportamento em js/48-dashboards.js (d4SelectSec). */

  /* (1) — uma coluna, e itens que aceitam encolher */
  #dash4-overlay .d2-heroes,
  #dash4-overlay .d2-heroes.d3-heroes,
  #dash4-overlay .d2-mini,
  #dash4-overlay .d2-cov,
  #dash4-overlay .d2-pot,
  #dash4-overlay .d2-pipe,
  #dash4-overlay .d2-insights,
  #dash4-overlay .d2-mini.d2-cols-3,
  #dash4-overlay .d2-mini.d2-cols-4,
  #dash4-overlay .d2-mini.d2-cols-5 { grid-template-columns: 1fr 1fr; }
  /* `.d2-occ` NÃO é grade de ladrilho — é anel (auto) + conteúdo (1fr), e o
     anel do card de Aproveitamento chega a 252px. Forçado em "1fr 1fr" como
     os ladrilhos acima, a coluna de conteúdo (tiles + legenda) sobrava ~170px
     num aparelho de 390px — menos que um tile só — e o texto quebrava letra a
     letra ("12 / ,63"). Empilha: o anel (com sua legenda) vem inteiro, o
     conteúdo vem embaixo, cada um com a largura toda do card. */
  #dash4-overlay .d2-occ { grid-template-columns: 1fr; }
  /* Dois por linha, não um: são números curtos com rótulo de duas palavras
     ("132 QUADRAS", "+70 ALVARÁS ATIVOS"). Em coluna única cada um ganharia
     a largura inteira para uma linha de texto, e a fileira que hoje ocupa
     uma tela passaria a ocupar duas. */
  /* `.d2-grid` e a unica da lista acima que NAO guarda ladrilho de numero:
     ela guarda CARDS inteiros — titulo, selo, grafico, lista ordenada. Em
     meia largura de um aparelho de 390px sobram ~170px por card, e a lista
     de CNAE dentro de um deles ficava com 10px para o nome. Cartao inteiro
     ocupa a largura inteira; so os ladrilhos e que cabem dois por linha. */
  #dash4-overlay .d2-grid { grid-template-columns: 1fr; }
  #dash4-overlay .d2-mini-it { min-width: 0; }
  #dash4-overlay .d2-mini-it .v { overflow-wrap: anywhere; }
  #dash4-overlay .d2-heroes > *,
  #dash4-overlay .d2-grid > *,
  #dash4-overlay .d2-mini > *,
  #dash4-overlay .d2-cov > *,
  #dash4-overlay .d2-pot > *,
  #dash4-overlay .d2-pipe > *,
  #dash4-overlay .d2-occ > *,
  #dash4-overlay .d2-insights > *,
  #dash4-overlay .d2-card,
  #dash4-overlay .d2-rank-mid,
  #dash4-overlay .d2-stage { min-width: 0; }

  #dash4-overlay .d2-inner { padding: 0 10px 32px; }
  #dash4-overlay .d2-card { padding: 13px 13px; border-radius: 13px; }
  /* Título e selo do card não cabem lado a lado: o selo desce. */
  #dash4-overlay .d2-card-h { flex-wrap: wrap; gap: 6px; margin-bottom: 11px; }
  #dash4-overlay .d2-card-tag { white-space: normal; }
  #dash4-overlay .d2-rank-row,
  #dash4-overlay .d2-rank-row.d2-rank-96,
  #dash4-overlay .d2-rank-row.d2-rank-108 { grid-template-columns: 16px minmax(0,1fr) auto; gap: 7px; }
  #dash4-overlay .d4-cmp-row { grid-template-columns: 88px minmax(0,1fr) auto; gap: 7px; }
  /* Gráficos e tabelas rolam por dentro em vez de esticar a página. */
  #dash4-overlay .d2-chart-wrap,
  #dash4-overlay .d2-hist,
  #dash4-overlay table { overflow-x: auto; }
  /* `.d2-mini-toggle` nasce com `flex-shrink:0` (ok em telas largas, onde
     sobra espaço ao lado do rótulo "PORTE"). Sem poder encolher, a fileira
     de botões (Todos/MEI/ME sem MEI/EPP/Médio-Grande) nunca chegava a
     quebrar linha — só estourava a largura do card e cortava o último
     botão. `flex-wrap` sozinho não bastava: só quebra depois que a caixa
     encolhe até o espaço disponível. */
  #dash4-overlay .d2-mini-toggle { flex-wrap: wrap; flex-shrink: 1; min-width: 0; }
  /* O número e a unidade quebravam em duas linhas ("1,79 mi" / "m²"), o que
     lê como dois dados. O corpo cede antes da unidade. */
  #dash4-overlay .d2-big { font-size: 26px; }
  #dash4-overlay .d2-mini-it .v { font-size: 21px; }
  #dash4-overlay .d2-hero-val { font-size: 24px; }
  /* A unidade e o selo de tendência dividem uma linha com `space-between`.
     Numa coluna larga o texto cabe; aqui, "nos últimos 12 meses · de 1.578
     deferidos no total" ocupava duas linhas e o selo encavalava a segunda.
     O selo desce para a própria linha quando não couber ao lado. */
  #dash4-overlay .d2-hero-foot { flex-wrap: wrap; row-gap: 6px; }
  #dash4-overlay .d2-hero-unit { min-width: 0; flex: 1 1 100%; }
  #dash4-overlay .d2-hero-foot .d2-trend { margin-left: auto; }
  #dash4-overlay .d2-lead, #dash4-overlay .d4-lead-txt { font-size: 13px; }

  /* (2) — a sanfona. O corpo da seção fechada some; fica o cabeçalho, que
     é o que a torna um índice. `.d2-sec-head` é o primeiro filho e nunca
     é escondido. */
  #dash4-overlay .d3-sec > *:not(.d2-sec-head) { display: none; }
  #dash4-overlay .d3-sec.d4-aberta > * { display: revert; }
  #dash4-overlay .d2-sec-head {
    cursor: pointer;
    padding: 4px 0;
    -webkit-tap-highlight-color: transparent;
  }
  #dash4-overlay .d4-sec-chev {
    font-size: 13px; color: var(--t2); flex-shrink: 0;
    width: 26px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 8px;
    background: rgba(255,255,255,.05);
    border: 1px solid rgba(255,255,255,.10);
    transform: rotate(-90deg);
    transition: transform .2s;
  }
  #dash4-overlay .d3-sec.d4-aberta .d4-sec-chev { transform: rotate(0deg); }
  /* "↑ topo" só faz sentido dentro da seção que está aberta. */
  #dash4-overlay .d3-sec:not(.d4-aberta) .d3-top { display: none; }
  /* ── A BARRA É O ÍNDICE, E PRECISA PARECER UM ─────────────────────────
     Com as seções recolhidas, é por ela que se navega — mas ela tinha a
     aparência de uma fileira de âncoras discretas: fundo de 3%, borda de 8%
     e o título em cinza. Num aparelho de toque, o que não parece botão não
     é tocado, e a pessoa volta a rolar procurando o conteúdo.
     Ela vira uma FITA DE ABAS (regras logo abaixo, junto ao cabeçalho): uma
     linha, rótulos curtos, a corrente pintada com a cor da seção. */
  /* O indice SOBE para antes do bloco de KPIs de abertura. Medido: ele
     nascia em y=648 num aparelho de 760 — encostado na borda de baixo da
     primeira tela, atras de 499px de cartoes. Um indice que so aparece
     depois de rolar nao e indice: e mais uma secao. Subindo, a primeira
     coisa que a pessoa ve ao abrir o painel e a lista do que ha para ver,
     e os KPIs de abertura passam a ser a primeira leitura DEPOIS da escolha.
     O contêiner vira coluna flex so para que `order` exista; `min-width:0`
     porque item flex nasce com `min-width:auto` e volta a estourar a
     largura nas grades de dentro. */
  #dash4-overlay .d2-inner > div:not(.d2-header) {
    display: flex; flex-direction: column; min-width: 0;
  }

  /* ── O CABECALHO: UMA GRADE, SEM REPETIR O NOME TRES VEZES ───────────
     Como estava, empilhado, ele gastava 127px de uma tela de 760 para
     dizer a MESMA COISA tres vezes:

        Porto Alegre > 4º Distrito > Distrito da Inovação   <- trilha
        Distrito da Inovação                                <- titulo
        [ Distrito Inovação ]  [x]                          <- filtro

     A trilha existe para dar contexto — e o contexto e "Porto Alegre, 4º
     Distrito"; a ultima migalha e o proprio titulo, entao ela sai. O
     filtro de recorte tem UMA opcao: um seletor de uma escolha nao e
     seletor, e por isso some (a regra e `:only-child`, entao ele volta
     sozinho no dia em que houver uma segunda regiao).
     Sobram duas linhas, com o fechar alinhado ao titulo:

        Distrito da Inovação                          [x]
        Porto Alegre · 4º Distrito                                  */
  #dash4-overlay .d2-header.d3-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "titulo fechar" "trilha trilha";
    align-items: center;
    gap: 2px 10px;
    padding: 10px 12px 11px;
  }
  /* `display:contents` dissolve o contêiner e entrega trilha e titulo
     direto para a grade do cabecalho — sem isto eles seriam UM item so e
     continuariam empilhados dentro dele. */
  #dash4-overlay .d2-head-left { display: contents; }
  #dash4-overlay .d2-title-row { grid-area: titulo; min-width: 0; }
  #dash4-overlay .d2-head-right { grid-area: fechar; }
  #dash4-overlay .d2-breadcrumb {
    grid-area: trilha;
    font-size: 10.5px;
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* A ultima migalha e o titulo que esta logo acima; o separador que a
     antecedia vai junto, senao a linha termina num "›" solto.
     `:nth-last-child(-n+2)` — os DOIS ultimos filhos — e nao
     `.sep:last-of-type`: `:last-of-type` conta por TAG, e separador e migalha
     corrente sao ambos <span>, entao o "ultimo span" era a propria migalha e
     o separador sobrava. Medido: a trilha terminava em "4º Distrito ›".
     Os dois ultimos funcionam nas duas trilhas que o JS monta — a de tres
     migalhas do Distrito e a de duas do 4º Distrito. */
  #dash4-overlay .d2-breadcrumb > *:nth-last-child(-n + 2) { display: none; }
  #dash4-overlay .d2-title {
    font-size: 19px;
    line-height: 1.15;
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  /* Esconde o CONTÊINER, nao so o botao: escondendo apenas o botao, a capsula
     do filtro continuava desenhada em volta do vazio — um pontinho oco ao lado
     do ✕. E `:has()` em vez de uma classe no JS porque a condicao e "existe
     uma unica opcao": no dia em que voltar uma segunda regiao, o filtro
     reaparece sozinho, sem ninguem precisar lembrar de mexer aqui. */
  #dash4-overlay .d2-head-right .d2-tabs:has(> .d2-tab:only-child) { display: none; }
  #dash4-overlay .d2-close { width: 34px; height: 34px; font-size: 15px; flex-shrink: 0; }

  /* ── O DECK NO TELEFONE: GRADE 2x2 ──────────────────────────────────
     Isto JA FOI uma fita de abas horizontal, e a fita resolvia um problema
     que nao existe mais. Ela nasceu quando os itens eram BOTOES DE TEXTO:
     "Ocupacao Territorial" e "Desenvolvimento Urbano" nao cabem em meia
     largura de um aparelho de 390px, entao a grade 2x2 truncava todo rotulo
     ("Ocupacao Te…") e a fita, com os rotulos curtos, era melhor.
     Hoje os itens sao CARDS COM FOTO, e a conta virou: o valor esta na
     imagem, e imagem espremida em 90px de largura nao e imagem. Numa fita de
     `flex:0 0 auto` os quatro viravam tiras verticais que nao preenchiam a
     largura — sobrava uma faixa morta a direita, que foi o que se viu.
     A grade 2x2 devolve ~165px de largura a cada card: a foto respira, e o
     rotulo CURTO (que a fita ja usava) cabe numa linha sem truncar. O que
     derrubou a grade da primeira vez era o rotulo longo, e ele continua
     escondido. */
  #dash4-overlay .d3-nav {
    order: -1;
    padding: 8px 0 9px;
    margin-bottom: 14px;
    background: rgba(9, 15, 26, 0.97);
    box-shadow: 0 10px 22px -12px rgba(0, 0, 0, .85);
  }
  #dash4-overlay .d3-nav-head { padding: 0 12px 7px; }
  #dash4-overlay .d3-nav-lbl::after {
    content: ' · toque para abrir';
    color: var(--t3);
    font-weight: 500;
    letter-spacing: .04em;
    text-transform: none;
  }
  #dash4-overlay .d3-nav-btns {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 9px;
    padding: 0 12px;
    /* Sem overflow, sem mascara, sem scroll-snap: nao ha o que rolar numa
       grade que cabe inteira. Os tres eram da fita. */
    overflow: visible;
    -webkit-mask-image: none;
            mask-image: none;
  }
  #dash4-overlay .d3-nav-btn {
    width: auto;
    /* Metade da altura do desktop. Quatro cards em 2x2 somam ~2x esta altura
       mais o gap; a 22vh isso da ~44% da tela, a mesma proporcao que o deck
       ocupa no desktop. */
    min-height: clamp(132px, 22vh, 190px);
    padding: 10px 11px 11px;
    border-radius: 13px;
  }
  /* O icone VOLTA. Ele saiu na fita porque custava 19px de largura por aba e
     empurrava a quarta para fora da tela; numa grade 2x2 nao ha essa disputa,
     e ele e o que distingue os cards de relance. */
  #dash4-overlay .d3-nav-ic {
    display: inline-flex;
    width: 30px;
    height: 30px;
    border-radius: 9px;
  }
  #dash4-overlay .d3-nav-ic svg { width: 15px; height: 15px; }
  #dash4-overlay .d3-nav-tit { display: none; }
  #dash4-overlay .d3-nav-curto {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-family: var(--display);
    font-size: 13px;
    font-weight: 700;
    color: #fff;
  }
  #dash4-overlay .d3-nav-badge { font-size: 10px; padding: 3px 7px; }
  #dash4-overlay .d3-nav-btn .d3-nn { font-size: 10.5px; }
  #dash4-overlay .d3-nav-marca { max-width: 120px; }
  #dash4-overlay .d3-nav-btn.on {
    box-shadow: 0 0 0 1px var(--nav-c, #38bdf8);
  }

  /* Controles do mapa: o padrão do MapLibre é dimensionado para mouse. */
  .maplibregl-ctrl-top-right { transform: scale(.86); transform-origin: top right; }
}


/* ══ ≤ 430px · TELEFONE ESTREITO ════════════════════════════════════
   Medido: a 390px a primeira linha pedia ~400px (voltar 12 + marca 100 +
   navegação 123 + ações 165) e estourava por ~10 — o bloco de ações caía
   para uma TERCEIRA linha, que não cabe na altura reservada.
   Não é caso de esconder mais nada: são dez pixels. Some com o excesso
   apertando o que já está lá, sem tirar nenhum destino do alcance. */
@media (max-width: 430px) {
  .tb-logo-badge { font-size: 18px; }
  .tb-logo { padding: 0 6px 0 2px; gap: 6px; }
  .tb-nav-btn { padding: 7px 8px; }
  .tb-nav { padding: 2px; margin-right: 2px; }
  .tb-icon-btn, .tb-clear-btn { width: 28px; height: 28px; }
  .tb-tools { gap: 1px; padding: 2px; }
  .tb-actions { gap: 5px; padding: 0 8px 0 4px; }
}


/* ══ ≤ 380px · SÓ O WORDMARK ════════════════════════════════════════
   Medido: a 330px a linha de controles pede 353px mesmo com a seta de
   voltar fora — a navegação encavalava a marca, e o botão do Mapa
   aparecia por cima dela. Alguma coisa tem de sair.

   Sai o HEXÁGONO, não o "+DADOS".
   Esta é a marca do PRODUTO — é como a plataforma se chama, e é o que a
   pessoa procura na tela. O selo +4D é a marca do PROGRAMA a que ela
   pertence: contexto, não identidade. Numa faixa em que só cabe um, fica
   quem nomeia a coisa que está aberta.
   (A primeira versão disto fazia o contrário, e estava errada.) */
@media (max-width: 380px) {
  .tb-logo > svg { display: none; }
  .tb-logo { padding: 0 4px 0 10px; gap: 0; }
  /* Tirar o hexágono devolveu 33px, e a 320 ainda faltavam ~7: o wordmark
     saía cortado no meio ("+DAD"). O que sobra vem dos BOTÕES, não da
     marca — ícone de 15px numa caixa de 26 continua confortável para o
     dedo, e é o alvo que encolhe, não o nome do produto. */
  .tb-logo-badge { font-size: 17px; }
  .tb-nav-btn { padding: 6px 7px; }
  .tb-nav-btn > svg { width: 14px; height: 14px; }
  .tb-icon-btn, .tb-clear-btn { width: 26px; height: 26px; }
  .tb-icon-btn > svg { width: 15px; height: 15px; }
  .tb-actions { gap: 4px; padding: 0 8px 0 0; }
}


/* ══ TOQUE ══════════════════════════════════════════════════════════
   Não é largura, é APONTADOR: um tablet largo também é dedo. `hover:none`
   pega o dispositivo em que o hover não existe, e nele o alvo tem de ser
   maior — 24px de chevron é confortável no mouse e minúsculo no polegar.
   As referências de acessibilidade pedem 44px; onde a densidade do painel
   não deixa chegar lá, 34 é o piso praticado aqui. */
@media (hover: none) {
  .p4d-sec-summary { padding: 13px 12px; }
  .p4d-chev { padding: 4px; margin: -4px; }
  .tb-icon-btn { width: 34px; height: 34px; }
  .cmp-icon-btn { width: 32px; height: 32px; }
  .timeline-play-btn, .timeline-stop-btn { width: 30px; height: 30px; }
  /* Sem hover, o realce de :hover fica "grudado" depois do toque. */
  .p4d-sec-card:hover { background: var(--glass-sheen), var(--glass-2); }
}

/* Rótulos escritos do gráfico de aberturas (barras + linha): são dois por ano,
   24 no total. Em 1920px cada ano tem ~154px e cabe folgado; abaixo de 560px
   sobram ~45px por ano e os números encavalam. Aí fica um ano sim, um não —
   os pares são irmãos consecutivos (2 por ano), então 4n+3 e 4n+4 derrubam
   exatamente os anos de índice ímpar, preservando a leitura da tendência. */
@media (max-width: 560px) {
  .d2-abrot .d2-crista:nth-child(4n+3),
  .d2-abrot .d2-crista:nth-child(4n+4) { display: none; }
}

/* O card de Aproveitamento do Solo trocou a régua horizontal por anéis
   proporcionais (ver `_d2donut3` em 48-dashboards.js e `.d4-donut-*` em
   92-dash-comparativo.css) — texto sempre ao lado do anel, nunca sobre ele,
   então não sobrou nenhuma regra de mobile pra escrever aqui: não há
   proporção de dado capaz de fazer esse texto colidir com nada. */

/* Rótulos escritos do gráfico Vendas por Mês · ITBI: são até 36 (18 meses,
   barra + acumulado). Em 1920px cada mês tem ~100px e cabe; abaixo de 900px
   sobram ~45px e os números encavalam, então fica um mês sim, um não. A classe
   vem marcada do JS porque nem todo mês tem dois rótulos (a linha do acumulado
   só começa no 12º mês), e contar irmãos no CSS erraria a conta. */
@media (max-width: 900px) { .d2-vmrot .d2-crista-alt { display: none; } }

/* Valores de crista do gráfico Demografia Empresarial (aberturas × baixas):
   16 anos num rótulo só por par (ver `.tlv` na folha principal). Abaixo de
   560px cada coluna tem ~20px e o rótulo, com os dois números, passa dos
   30px — ainda maior que a coluna. Mantém 1 ano sim, 1 não (mesma proporção
   do gráfico de Aberturas por Ano ali em cima), que dá ~40px de sobra entre
   rótulos vizinhos. */
@media (max-width: 560px) {
  .d2-tl .col:nth-child(2n) .tlv { display: none; }
}
