/* ─── O SITE DA 1001 ────────────────────────────────────────────────────────
 *
 * ⛔ CÓPIA DOS TOKENS, NÃO `@import` de `inad_rails/public/css/cliente.css`.
 * É a mesma decisão que `corretor/tabela.css` já tomou e documentou: um import
 * faria qualquer ajuste na folha do painel do cliente cair de surpresa numa
 * página que ninguém estava olhando. Aqui vale em dobro — são containers
 * diferentes, e o site nem enxerga aquele arquivo.
 *
 * 🎨 A PALETA É FECHADA (`img/marca/LEIA-ME.md`, pág. 8 do manual da marca).
 * Recolorir é a 4ª proibição do designer. Os cinco valores abaixo são os
 * publicados; não invente um "azul parecido".
 * ────────────────────────────────────────────────────────────────────────── */

:root {
  --navy:    #3C3E69;   /* o principal — o campo cheio do hero */
  --aco:     #295787;   /* o secundário */
  --ciano:   #0084A9;   /* gasto em POUCA coisa: é o acento, não uma cor de área */
  /* 🔤 O CIANO PARA TEXTO — o mesmo matiz (193°), 18% mais fechado. NÃO é uma
     sexta cor: é o `--ciano` interpolado com o preto, como os `--fundo-*` são o
     navy interpolado com a tinta. 📏 Medido em 04/09/2026: `#0084A9` como texto
     dá 3,65:1 sobre o papel e 3,89:1 sobre a folha — e a sobrancelha de seção
     (`.bloco__olho`, 12,8px/600) é texto pequeno, que exige 4,5:1. Como
     PREENCHIMENTO ou BORDA (o filete do CRECI, a barra de progresso) 3:1 basta, e
     ali o `--ciano` publicado continua intacto.
     ✅ `#006C8A`: 5,40:1 na folha · 5,07:1 no papel · 4,63:1 no gelo. */
  --ciano-texto: #006C8A;
  --neutro:  #453D4D;
  --gelo:    #E6E2DA;
  --papel:   #EFECE5;
  --folha:   #F6F3EE;
  --risco:   #D6D1C7;

  /* ── O LADO CLARO É QUENTE E FECHADO — nem o marfim, nem o cinza-azulado ──
     📌 *"esse tom combina mais para o branco do que o marfim, fica mais
     elegante"* (responsável, 03/09/2026, mandando a amostra).

     🔑 A história em quatro atos, para ninguém refazer: (1) o claro nasceu
     cinza-AZULADO (`#F2F3F7`/`#F7F8FC`), da família do navy — frio ao lado de
     frio, conjunto clínico. (2) Em 01/09 entrou MARFIM (`#FAF7F1`/`#FFFDFA`) e
     saiu no mesmo dia: *"tá muito claro"*. (3) Voltou um cinza frio mais
     fechado (`#ECEDF1`). (4) Este: a temperatura do marfim com a luminosidade
     do cinza fechado — `#EFECE5`, L≈92, S≈4% (HSB). Lê como papel de gramatura,
     não como tela nem como documento digitalizado.

     🪤 NÃO PODE AMARELAR: acima de ~5% de saturação vira "papel velho". E não
     pode clarear: acima de L≈94 volta a queixa de 01/09. Mexeu num, meça os
     dois e a contagem abaixo.

     📏 Contraste medido (03/09/2026) sobre o papel: `--tinta` 14,6:1 ·
     `--tinta-2` 5,2:1 · `--navy` 8,5:1 · `--aco` 6,3:1. `--tinta-3` dava 3,9:1
     aqui até 04/09/2026 (#6E7490); o valor de hoje (#60667D) dá 4,8:1 — ver a
     nota dele lá embaixo. Ele passa o AA nos RÓTULOS, que é para o que existe;
     em corpo de texto continua sendo `--tinta-2`, por hierarquia, não por falha. */
  --tinta:   #171A2E;

  /* 🔤 A COR DE ÊNFASE, que NÃO é a cor da marca — e a distinção só apareceu
     quando o modo escuro entrou. `--navy` é a marca e não muda com o tema (a
     marca não tem versão escura). Mas números, títulos de pergunta e valores
     usavam `--navy` como cor de ÊNFASE, que é outro papel: ênfase precisa
     contrastar com o fundo, logo precisa mudar com o tema.
     ⛔ Quem fica sobre fundo BRANCO fixo (botão claro, selo do cartão) continua
     em `--navy` — ali a marca está no papel dela. */
  --destaque: #3C3E69;
  --btn-marca-texto: #FFFFFF;   /* ver a nota do `.btn--marca` */

  /* ── OS FUNDOS ESCUROS, e por que eles não são `--navy` ────────────────
     📌 *"no layout as cores escuras deveriam ser mais escuras"* (responsável,
     01/09/2026).

     ⚖️ O manual da identidade proíbe **recolorir a marca** — ele não rege a cor
     de fundo de uma página. Por isso `--navy` continua intacto onde a marca e os
     componentes o exigem, e o campo atrás do conteúdo passa a usar estes três.

     🔑 E ELES NÃO SÃO COR NOVA: são interpolações entre `--navy` e `--tinta`,
     que já é o preto-azulado da própria identidade. Escurece sem sair do sistema.

     🎚️ Três degraus porque campo grande pesa mais no olho: a mesma cor cobrindo
     meia tela parece mais clara e mais chapada que num cartão pequeno.
     📏 Contraste com texto branco, medido (WCAG): hero 15,7:1 · seção 15,1:1 ·
     caixa 13,6:1 — todos acima de 4,5:1, que é o AA para texto normal.
     🔀 Escureceram de novo em 01/09/2026 (📌 "tá claro ainda"): as misturas com
     --tinta subiram de 0,62/0,52/0,34 para 0,80/0,72/0,52.
     ⛔ Se algum dia alguém clarear estes valores, meça de novo antes. */
  --fundo-hero:  #191C32;
  --fundo-secao: #1B1E35;
  --fundo-caixa: #222540;
  /* 🪤 O rodapé parte do `--neutro` (#453D4D), não do navy — é a única área da
     página que usa aquele token, e trocá-la por um azul mudaria a composição em
     vez de só escurecê-la. Interpolado 74% com `--tinta`.
     📏 Contraste medido: 15,4:1 com branco puro. Folgado acima do AA. */
  --fundo-rodape: #1D1E32;
  --tinta-2: #5A6180;
  /* 🔀 Escurecido de #858BA6 para #6E7490 em 02/09/2026, e de #6E7490 para
     #60667D em 04/09/2026. 📏 O primeiro dava **3,07:1** sobre o papel — abaixo
     do AA para texto normal, e o comentário da paleta afirmava que todos passavam.
     🪤 O segundo foi anunciado aqui como "4,62:1", e o número era VERDADEIRO
     SOBRE BRANCO PURO — que não é fundo de lugar nenhum deste site. Sobre o papel
     ele dava 3,90:1 e sobre a folha 4,16:1: reprovado nos dois, e é nos dois que
     ele mora. 📌 E ele é justamente o rótulo de CADA linha das tabelas de
     distância (`.ficha__rot`, 38 vezes), o `.emp__onde` do cartão e a `.fonte` —
     *"a coisa mais importante é a localização"*, escrita na cor de menor
     contraste da página.
     ✅ #60667D, medido pela fórmula do WCAG: 4,82:1 no papel · 5,14:1 na folha.
     Continua mais claro que `--tinta-2` (#5A6180): a hierarquia sobrevive, e o
     resto dela é tipográfico — versalete, 12px, espaçado.
     ⛔ Sobre `--gelo` (#E6E2DA) ele dá 4,40:1 — por isso a `.faixa`, o único
     componente sobre gelo, escreve os rótulos em `--tinta-2`. Meça de novo antes
     de pôr esta tinta sobre o gelo. */
  --tinta-3: #60667D;
  --verde:   #12694A;   /* lote À VENDA no mapa */
  --vermelho:#A6332F;   /* lote indisponível — e o PADRÃO de quem não sabemos */

  --raio: 12px;
  --sombra: 0 1px 2px rgba(23, 26, 46, .06), 0 8px 24px rgba(23, 26, 46, .07);
  --sombra-alta: 0 2px 4px rgba(23, 26, 46, .08), 0 20px 48px rgba(23, 26, 46, .14);
  --topo: 104px;
}

/* ⛔ AQUI HAVIA `html { color-scheme: light dark; }`, e ele sobreviveu à remoção
   do tema escuro por algumas horas em 04/09/2026. Não pintava nada de errado —
   `:root` e `html` são o MESMO elemento, mesma especificidade, e a declaração de
   baixo vencia por vir depois —, e é exatamente por isso que era perigoso:
   regra morta que não quebra nada é a que ninguém apaga, e a próxima pessoa a
   ler o topo da folha concluía que o site ainda sabe os dois temas.
   🔑 Uma declaração só, e ela é a de baixo. */
/* 📌 SÓ TEMA CLARO desde 04/09/2026 — *"pode deixar só o tema claro no site"*
   (responsável). Saíram: o bloco `@media (prefers-color-scheme: dark)`, o
   `:root[data-tema="escuro"]`, o botão `.tema` e as elevações do escuro (~125
   linhas). `color-scheme: light` fixo é o que impede o navegador de pintar de
   escuro os controles nativos (barra de rolagem, campo, seleção) de quem tem o
   SISTEMA no escuro — sem ele, a página clara ganharia scrollbar preta.
   ⛔ Não devolva `prefers-color-scheme` aqui achando que é acessibilidade: a
   decisão é do responsável, e o site tem UM tema. */
:root { color-scheme: light; }

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

body {
  margin: 0;
  background: var(--folha);
  color: var(--tinta);
  font: 400 17px/1.6 'Geist', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.15; letter-spacing: -.02em; margin: 0 0 .5em; font-weight: 600; }
h1 { font-size: clamp(2.1rem, 5.2vw, 3.6rem); }
h2 { font-size: clamp(1.6rem, 3.4vw, 2.4rem); }
h3 { font-size: 1.15rem; }
p  { margin: 0 0 1em; color: var(--tinta-2); }
a  { color: var(--aco); }

/* 🔢 Número é Geist Mono com `tabular-nums`: sem isso a coluna de preço dança
   quando o dígito muda, e preço que dança parece preço inventado. */
.num { font-family: 'Geist Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums; }

/* 🪤 `viewport-fit=cover` (nas 7 páginas) desliga o recuo automático da área
   segura do iOS — no iPhone deitado, o texto encostaria no entalhe. Só o `.zap`
   consumia `env(safe-area-inset-*)`; o container passa a consumir também.
   ⚠️ `max()` porque `env()` vale 0 em aparelho sem entalhe: sem ele, a margem
   sumiria em todo o resto. */
.container {
  width: min(1180px, 100% - 2.5rem);
  margin-inline: auto;
  padding-inline: max(0px, env(safe-area-inset-left), env(safe-area-inset-right));
}

/* ─── Topo ──────────────────────────────────────────────────────────────── */

/* 🔴 z-index 1100, E O NÚMERO NÃO É ARBITRÁRIO. 📌 *"a api do mapa ta
   sobrepondo a camada do toplayer"* (responsável, 01/09/2026) — e estava mesmo:
   o header ficava em **50** e o Leaflet cria panes próprios que vão até **1000**
   (`leaflet.css`, o controle de zoom). O mapa passava por cima da barra, do
   botão de WhatsApp (60) e da barra de progresso (70).
   🪤 O Leaflet NÃO respeita o empilhamento da página: ele monta os panes com
   valores fixos dentro do próprio contêiner. A única saída é o resto do site
   ficar acima do teto dele — 1100/1150/1200, com folga para os 1000 dele.
   📏 E a escada tem um efeito colateral, medido em 04/09/2026: a barra de
   progresso (`.progresso`, `movimento.css`, z 1200, `top: 0`, 3 px) e a barra
   do topo (z 1100, `top: 0`) nascem no MESMO canto, e a de cima desenha por
   cima dos 3 px superiores do header. A resposta NÃO é subir o `.topo` para
   1250: a barra ficaria atrás de um fundo a 88% de alfa, invisível — feature
   morta em silêncio. A barra sai do caminho, logo abaixo, na regra do
   `body > .progresso`. */
/* 🪤 A barra e' `fixed`: sem isto, todo link de ancora (`./#contato`, `#empreendimentos`)
   para com o titulo DEBAIXO dela. Em 768px o `h2` some inteiro. E nao adianta o
   `offset: -90` do Lenis (movimento.js:100): ele vive dentro de
   `(hover:hover) and (pointer:fine)` — em celular e tablet nao existe handler
   nenhum, todo clique de ancora e' salto nativo. `--topo` ja muda por media query. */
section[id] { scroll-margin-top: calc(var(--topo) + 1rem); }

.topo {
  position: fixed; inset: 0 0 auto; z-index: 1100; height: var(--topo);
  display: flex; align-items: center;
  /* 🪤 rgba À MÃO, e não `var(--fundo-hero)`, porque a barra é translúcida: ela
     precisa do canal alfa para o `backdrop-filter` ter o que desfocar. É o mesmo
     `#1E213A` do hero, escrito em decimal — se um dia o token mudar, este valor
     tem de mudar junto, e é por isso que ele está anotado aqui. */
  background: rgba(25, 28, 50, .88);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(255, 255, 255, .10);
}
/* 🪤 SEM `width: 100%`, e a ausência é a correção. 📏 Medido em 01/09/2026 numa
   janela de 1920px: a barra ia de 0 a 1905 enquanto o conteúdo da página ficava
   entre 363 e 1543 — a logo encostada na borda esquerda e o conteúdo começando
   363px adiante, na mesma tela. O elemento é `class="container topo__linha"`:
   a intenção sempre foi usar a grade. Só que `.container` dá
   `width: min(1180px, 100% - 2.5rem)` e este `width: 100%`, vindo DEPOIS na
   folha com a mesma especificidade, vencia o empate e desfazia a grade.
   O `margin-inline: auto` do `.container` já centra; o flex não precisa da
   largura declarada. */
.topo__linha { display: flex; align-items: center; gap: 1.5rem; }

/* 📊 A BARRA DE PROGRESSO SENTA NA BORDA DE BAIXO DO HEADER, não na borda de
   cima da janela. Ela é declarada no `movimento.css` (`inset: 0 0 auto 0`), que
   é linkado DEPOIS desta folha — por isso `body > .progresso` (0,1,1): empata em
   ordem e vence em peso, senão o `inset` de lá reescreveria o `top` daqui.
   🔑 A regra mora AQUI, e não lá, porque é o `.topo` quem sabe a própria altura:
   `--topo` muda por media query (104 → 66 → 60 px) e a barra acompanha sem que
   o `movimento.css` precise conhecer os cortes. O `z-index` 1200 fica como está —
   acima do Leaflet continua sendo necessário; só deixou de ter o header embaixo.
   ⛔ Só `top`: o `transform` da barra é do GSAP (`scaleX`), e duas folhas
   disputando a mesma propriedade animada é o defeito que o cabeçalho do
   `movimento.css` descreve. */
body > .progresso { top: var(--topo); }
/* 🔠 A ALTURA É DITADA PELO SLOGAN, não pelo símbolo.
   📌 "aumenta a logo no canto superior esquerdo, tá ilegível o 'mil
   possibilidades em um só lugar'" (responsável, 01/09/2026).
   📏 O arquivo tem três linhas de texto mais o slogan embaixo; a 34px o slogan
   ficava com ~5px de altura e sumia.
   📏 MEDIDO no arquivo (contagem de pixels com alfa por linha): o slogan ocupa
   73 dos 548px da arte — **13,3% da altura**. Daí a conta que decide o resto:
   logo a 52px dá slogan de 6,9px (ainda ilegível — foi a primeira tentativa,
   e ela falhou); a 64px, 8,5px; **a 78px, 10,4px**, que é onde ele se lê. Por
   isso o `--topo` foi para 104px: é a altura que a arte exige, não uma escolha
   estética.
   🪤 E o ARQUIVO tinha 290x96: exibi-lo maior seria ampliar raster e borrar. Foi
   trocado pelo `1001_PNG11` da pasta da marca (1654x548, a tira BRANCA para topo
   em fundo escuro), reduzido a 942x312 — 3x a altura de exibição, para ficar
   nítido em tela retina sem carregar 1,6k de largura à toa. */
/* 🪤 O ARQUIVO CERTO É O PNG11, NÃO O PNG12 — e a doc da marca diz que os dois são
   "branco". 📏 Medido em 01/09/2026 (média RGB dos pixels com alfa > 128):
   PNG11 = (254,254,254), branco de verdade; PNG12 = (31,29,29), PRETO. Usei o 12
   primeiro e a logo saiu preta sobre o navy do topo — quase invisível. Se um dia
   alguém trocar de novo, MEÇA a cor antes: o nome do arquivo e a tabela do
   LEIA-ME não bastam. */
.topo__logo { display: flex; align-items: center; gap: .6rem; }
.topo__logo img { display: block; height: 78px; width: auto; }

/* 🪪 O CRECI AO LADO DO LOGOTIPO — 📌 *"coloca o CRECI na logo"* (responsável,
   04/09/2026). Quem intermedia imóvel exerce atividade regulada (Lei 6.530/78);
   com ele aqui, o número aparece em TODA página, acima da dobra.

   📏 `.72rem` a 500 sobre o navy da barra: branco a 78% dá 8,9:1 — folga
   confortável sobre os 4,5 que texto pequeno exige. ⛔ Não baixe a opacidade
   para "discretizar": é justamente a informação que a lei manda ser legível.

   🪤 `white-space: nowrap` porque "CRECI-GO 44685-J" quebrado no hífen vira duas
   linhas dentro de uma barra de ALTURA FIXA — e conteúdo que desce dentro de
   caixa de altura fixa é sobreposição, que overflow nenhum denuncia. Foi assim
   que a `.topo` vazou sobre o hero em 320px (site/CLAUDE.md). */
.topo__creci {
  font-size: .72rem; font-weight: 500; letter-spacing: .04em;
  color: rgba(255, 255, 255, .78); white-space: nowrap;
  /* 🪤 Ele mora DENTRO do `<a>` da logo e herdava o sublinhado, virando um
     segundo link aos olhos de quem lê. É informação legal, não navegação. */
  text-decoration: none;
}
/* 📱 No celular a barra não pode comer a tela: o slogan volta a ser ilegível aqui,
   e é uma troca consciente — quem abre no telefone rola a página, não estuda o
   cabeçalho. O hero, logo abaixo, diz a mesma coisa em texto de verdade. */
/* ⛔ O bloco `@media (max-width: 599px)` que ficava aqui era CÓDIGO MORTO desde
   que o bloco de 719px entrou: aquele vem depois na folha, casa em toda largura
   que este casava, e redefine as duas mesmas propriedades. Removido. */
.topo__nav { margin-left: auto; display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.topo__nav a {
  color: rgba(255, 255, 255, .88); text-decoration: none; font-size: .93rem;
  padding: .5rem .8rem; border-radius: 8px; transition: background .18s, color .18s;
}
.topo__nav a:hover { background: rgba(255, 255, 255, .12); color: #fff; }

/* 🚪 O botão que o responsável pediu — *"para os clientes não ficarem perdidos"*.
   Ele importa em dobro desde 01/09/2026: quem digitava o domínio nu caía DIRETO
   no painel, e agora cai aqui. Sem esta porta visível, a mudança vira um cliente
   perdido. Por isso ele é contornado, não um link a mais na fila. */
.topo__nav .porta {
  border: 1px solid rgba(255, 255, 255, .38); color: #fff;
}
.topo__nav .porta:hover { background: #fff; color: var(--navy); border-color: #fff; }

/* ─── Hero ──────────────────────────────────────────────────────────────── */

.hero {
  position: relative; overflow: hidden;
  min-height: min(88vh, 780px);
  display: flex; align-items: center;
  padding: calc(var(--topo) + 3.5rem) 0 4rem;
  background: var(--fundo-hero);
  color: #fff;
}
/* 🖼️ O PATTERN DA MARCA NO LUGAR DA FOTOGRAFIA, e é decisão, não improviso:
   📌 *"pode usar a logo azul, aquele pattern com várias logos também"*
   (responsável). Não há UMA foto do loteamento no repositório, e uma imagem de
   banco mentiria sobre o produto. A identidade não mente. */
.hero::before {
  content: ''; position: absolute; inset: 0;
  background: url('../marca/pattern-1001.png') repeat;
  background-size: 190px;
  opacity: .12;
  /* O pattern é navy sobre branco; invertido ele vira claro sobre o navy. */
  filter: invert(1);
}
/* Uma clareira no canto do texto, para o contraste do título não depender do
   pedaço do padrão que calhar de cair atrás dele. */
.hero::after {
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 18% 45%, rgba(60, 62, 105, .96) 0%, rgba(60, 62, 105, .55) 55%, rgba(60, 62, 105, .22) 100%);
}
.hero > * { position: relative; z-index: 1; }
.hero h1 { color: #fff; max-width: 16ch; }
.hero__olho {
  display: inline-block; margin-bottom: 1.1rem; padding: .3rem .8rem;
  border: 1px solid rgba(255, 255, 255, .34); border-radius: 999px;
  font-size: .82rem; letter-spacing: .08em; text-transform: uppercase;
  color: rgba(255, 255, 255, .92);
}
.hero p { color: rgba(255, 255, 255, .84); max-width: 46ch; font-size: 1.08rem; }
.hero__acoes { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2rem; }

.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .85rem 1.5rem; border-radius: 10px; border: 1px solid transparent;
  font: inherit; font-weight: 600; font-size: 1rem;
  text-decoration: none; cursor: pointer;
  /* 🪤 `color` NA MESMA TRANSIÇÃO QUE `background`, e a falta dela era um flash
     medível. Na troca de tema o `.btn--marca` muda os DOIS tokens de uma vez;
     com só o fundo animado, o texto saltava para o valor novo e o fundo levava
     160 ms para chegar — 📏 aos 40 ms da volta escuro→claro: branco sobre
     #6C96C9, e no primeiro quadro branco sobre #7FA8DC, que é 2,46:1. É o par
     que a nota do `.btn--marca` proíbe, aparecendo por um instante a cada clique
     no botão de tema. Animados juntos, os dois atravessam a troca em lockstep. */
  transition: transform .16s, box-shadow .16s, background .16s, color .16s;
}
.btn:hover { transform: translateY(-1px); }
.btn--claro  { background: #fff; color: var(--navy); box-shadow: var(--sombra); }
.btn--claro:hover { box-shadow: var(--sombra-alta); }
.btn--vazado { border-color: rgba(255, 255, 255, .45); color: #fff; }
.btn--vazado:hover { background: rgba(255, 255, 255, .12); }
/* 🔴 O TEXTO DO BOTÃO NÃO PODE SER `#fff` CRAVADO. 📏 Medido: `--aco` clareia no
   escuro (#295787 → #7FA8DC) e branco sobre ele dá **2,46:1** — abaixo até do
   limiar de texto grande. É o CTA principal de captação, em 4 lugares do site.
   ✅ `--btn-marca-texto` acompanha o tema: branco no claro (7,48:1), tinta
   escura no escuro (#12141F sobre #7FA8DC: 7,45:1).
   📏 Conferido no navegador em 04/09/2026, nos dois caminhos do escuro (o
   `prefers-color-scheme` e o `data-tema`), em REPOUSO: 7,45:1. Se alguém voltar
   a medir 2,46:1 aqui, está medindo DENTRO da transição de tema (ver a nota do
   `.btn`, logo acima) ou uma folha em cache com `?v=` velho. */
.btn--marca  { background: var(--aco); color: var(--btn-marca-texto); box-shadow: var(--sombra); }

/* ─── Faixa de números ──────────────────────────────────────────────────── */

/* ⚠️ Os valores destes cartões são CALCULADOS do JSON pelo `site.js`, nunca
   digitados. O `corretor/index.html` traz "697 / 204x / 16" cravados à mão e o
   CLAUDE.md de lá avisa que eles "envelhecem calados". Não repita o defeito na
   página que o público vê. */
.faixa { background: var(--gelo); border-block: 1px solid var(--risco); padding: 2.2rem 0; }
/* 🪤 Os números da faixa são do Village — é a única obra com tabela e planta.
   Sem este rótulo, logo abaixo de um hero que cita DOIS lugares, eles se leriam
   como a soma dos dois. */
/* 🪤 `--tinta-2` AQUI, e não a terceira tinta dos outros rótulos: a faixa é o
   único componente sobre `--gelo`, o fundo claro mais fechado da paleta, e ali
   `--tinta-3` dá 4,40:1 (a segunda dá 4,70:1). 📏 Medido em 04/09/2026 — a
   faixa não está em página nenhuma hoje, mas quem a trouxer de volta herda a
   regra certa em vez de reabrir o defeito. */
.faixa__de {
  text-align: center; margin: 0 0 1.2rem; font-size: .78rem;
  letter-spacing: .07em; text-transform: uppercase; color: var(--tinta-2);
}
.faixa__grade { display: grid; gap: 1.5rem; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); text-align: center; }
.faixa dt { font-size: .78rem; letter-spacing: .07em; text-transform: uppercase; color: var(--tinta-2); }
.faixa dd { margin: .3rem 0 0; font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 600; color: var(--destaque); }

/* ─── Blocos alternados ─────────────────────────────────────────────────── */

.bloco { padding: clamp(3.5rem, 8vw, 6rem) 0; }
.bloco--gelo { background: var(--papel); }
/* 🌀 A seção que tem desenho passando pelas bordas (hoje só o "quem somos", com
   a linha do fluxo). O `overflow: hidden` é o que faz o traço entrar por cima e
   sair por baixo sem pintar nas seções vizinhas — e é também a rede que impede
   um SVG mal medido de criar rolagem horizontal.
   ⛔ Não a use numa seção com `position: sticky` dentro: `overflow: hidden` num
   ancestral desliga o sticky do descendente, sem erro nenhum. */
/* ⚰️ `.bloco--fluxo { overflow: hidden }` SAIU EM 05/09/2026, com a linha que ela
   existia para cortar. Ela nasceu porque o SVG de 700 px do fluxo passava por
   baixo do rodapé da seção e pintava sobre a faixa de contato; sem SVG, não há o
   que cortar. 📏 Medido antes de tirar: com e sem a regra, a seção dá os mesmos
   604 px de `scrollHeight`/`clientHeight` e a página os mesmos 6846 — ela não
   estava contendo nada. Regra que não muda pixel nenhum é código morto que
   parece decisão, e a próxima pessoa gastaria tempo entendendo por que existe. */
.bloco__par {
  display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: center;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}
.bloco--inverte .bloco__arte { order: 2; }
@media (max-width: 719px) {
  /* 🪤 O CRECI SAI DA BARRA NO CELULAR, e não é descuido: a `.topo` tem altura
     fixa, e em 320px ela já quebrou uma vez com menos conteúdo do que isto. O
     número continua no rodapé de todas as páginas e no bloco legal — a exigência
     é que ele esteja na peça publicitária, não em cada centímetro dela. */
  .topo__creci { display: none; } .bloco--inverte .bloco__arte { order: 0; } }

.bloco__arte {
  aspect-ratio: 4 / 3; border-radius: var(--raio); overflow: hidden;
  background: var(--fundo-caixa) url('../marca/pattern-1001.png') repeat;
  background-size: 130px;
  box-shadow: var(--sombra);
  display: grid; place-items: center;
}
/* 🪧 Enquanto não há fotografia do Village, a arte é a marca. O `data-legenda`
   diz o que a foto vai mostrar quando existir — é um lembrete visível, não um
   quadrado cinza que ninguém percebe que está faltando. */
.bloco__arte::after {
  content: attr(data-legenda);
  color: rgba(255, 255, 255, .55); font-size: .82rem; letter-spacing: .05em;
  text-transform: uppercase; text-align: center; padding: 1rem;
}
/* 🔤 `--ciano-texto`, NÃO `--ciano`: esta é a sobrancelha de TODA seção das 7
   páginas, em 12,8px — texto pequeno, que pede 4,5:1. 📏 O `--ciano` publicado
   dava 3,65:1 sobre o papel e 3,89:1 sobre a folha (04/09/2026). A conta e o
   valor estão na nota do token, no `:root`. */
.bloco__olho { font-size: .8rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ciano-texto); font-weight: 600; }
.bloco ul { padding-left: 1.1rem; color: var(--tinta-2); }
.bloco li { margin-bottom: .4rem; }

/* ─── Passos ───────────────────────────────────────────────────────────── */

.passos { display: grid; gap: 1.2rem; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); margin-top: 2.5rem; }
.passo { background: var(--folha); border: 1px solid var(--risco); border-radius: var(--raio); padding: 1.4rem; }
.passo__n {
  display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%;
  background: var(--navy); color: #fff; font-weight: 600; font-size: .95rem; margin-bottom: .8rem;
}
.passo h3 { margin-bottom: .3rem; }
.passo p { margin: 0; font-size: .95rem; }

/* ─── Contato ──────────────────────────────────────────────────────────── */

.contato { background: var(--fundo-secao); color: #fff; padding: clamp(3.5rem, 8vw, 5.5rem) 0; text-align: center; }
.contato h2 { color: #fff; }
.contato p { color: rgba(255, 255, 255, .84); max-width: 52ch; margin-inline: auto; }
.contato__acoes { display: flex; flex-wrap: wrap; gap: .8rem; justify-content: center; margin-top: 2rem; }

/* ─── Rodapé ───────────────────────────────────────────────────────────── */

/* 🪪 Este bloco é exigência, não crédito de fim de página: razão social, CNPJ,
   CRECI e endereço. O site que serviu de referência não tem nenhum dos quatro. */
/* 🔴 O RODAPÉ É FIXO ESCURO NOS DOIS TEMAS, então o texto dentro dele não pode
   usar os tokens de tinta — eles são calculados para o fundo CLARO. 📏 Medido:
   `p { color: var(--tinta-2) }` herdava aqui e dava **2,69:1** no tema claro,
   justamente no bloco que traz razão social, CNPJ, CRECI e endereço — o que a
   Lei 6.530/78 exige na publicidade.
   ✅ As cores do rodapé são cravadas em branco com alfa, como já eram as dos
   links e dos títulos dele. */
.rodape p, .rodape dd, .rodape li { color: rgba(255, 255, 255, .78); }
.rodape__legal p { color: rgba(255, 255, 255, .72); }
.rodape__legal strong { color: rgba(255, 255, 255, .92); }
.rodape { background: var(--fundo-rodape); color: rgba(255, 255, 255, .72); padding: 3rem 0 2rem; font-size: .9rem; }
.rodape__grade { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.rodape img { height: 56px; width: auto; }
.rodape a { color: rgba(255, 255, 255, .9); }
.rodape h3 { color: #fff; font-size: .82rem; letter-spacing: .07em; text-transform: uppercase; }
.rodape ul { list-style: none; padding: 0; margin: 0; }
.rodape li { margin-bottom: .45rem; }

/* 🪧 O CONTATO COM ÍCONE — a lista vira grade de duas colunas por item.
   📌 *"coloca os icones ali de finalização"* (responsável, 03/09/2026).

   🪤 `flex` e não `list-style-image`: o endereço tem duas linhas, e com
   marcador de lista a segunda volta para debaixo do ícone. Com `align-items:
   flex-start` + `flex: none` no `svg`, o texto quebra alinhado consigo mesmo.
   📏 `1em`, não `16px`: o ícone acompanha o tamanho da fonte — inclusive quando
   o leitor aumenta a fonte do navegador, onde um ícone cravado em px encolhe
   sozinho ao lado do texto.
   ⛔ `fill: currentColor` para o ícone herdar a cor do rodapé (e o tema claro):
   cor cravada aqui reaparece como mancha escura sobre fundo escuro. */
.rodape__contato li { display: flex; align-items: flex-start; gap: .55rem; }
/* 🪤 UM SISTEMA DE ÍCONE SÓ, e este bloco é a metade CSS dele.
   📏 A primeira versão misturava logo de marca sólido (WhatsApp, Instagram) com
   glifo simples (envelope, pin): mesmo tamanho, pesos visuais diferentes — o
   logo cheio pesava o dobro ao lado do contorno, e era isso que se via como
   "o do Insta ficou feio". Agora os quatro são contorno, no mesmo `stroke-width`.
   ⛔ Não volte a colar SVG de marca pronto aqui: ele vem sólido, e um ícone
   sólido no meio de três de contorno estraga a linha inteira.
   📐 `1.05em` com `stroke-width: 1.5`: no contorno o traço come peso visual, e
   no tamanho do sólido o ícone parecia menor que o texto ao lado. */
.rodape__contato svg {
  width: 1.05em; height: 1.05em; flex: none; margin-top: .22em;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
  opacity: .5;
}
.rodape__legal {
  margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid rgba(255, 255, 255, .14);
  font-size: .82rem; color: rgba(255, 255, 255, .55);
}
/* ⚠️ Marcador do que falta antes de publicar. Some quando os dados entrarem. */
.pendente { color: #FFD79B; border-bottom: 1px dashed rgba(255, 215, 155, .5); }
/* 🪤 A versão do CORPO da página (nas páginas internas, num `<style>` próprio)
   usava `--neutro` sobre `--gelo`. `--neutro` é da paleta da MARCA e nunca é
   redeclarado no escuro, enquanto `--gelo` desce para #161930 — o marcador
   sumia (1,67:1), que é exatamente o mal que ele existe para evitar.
   ✅ Passa a usar `--tinta`, que acompanha o tema. A regra vive aqui, e as
   páginas herdam — em vez de cinco cópias divergindo. */
.bloco .pendente {
  color: var(--tinta); background: var(--gelo);
  padding: 0 .3rem; border-radius: 4px; border-bottom: 1px dashed var(--tinta-3);
}

/* ─── O mapa dos lotes ──────────────────────────────────────────────────── */

/* 🚦 DUAS CORES, E SÓ DUAS: `--verde` e `--vermelho`, os dois já declarados lá
   em cima com o comentário dizendo que são do mapa. ⛔ Não acrescente um
   terceiro estado ("reservado", "em negociação"): a regra do responsável é
   binária — *"o resto que a gente não tem info fica vermelho, como se tivesse
   alguém"* — e um matiz a mais é a página afirmando o que ninguém apurou.

   ⚠️ O JavaScript LÊ estes dois valores do `:root` em tempo de execução para
   pintar os polígonos (`cores()` no `planta.js`). Renomear as variáveis não
   quebra nada visível na página, e sim o desenho do mapa — que cai no par de
   reserva em hex e passa a ignorar qualquer ajuste feito aqui. */

.mapa { margin-top: 2.5rem; }

/* A caixa nasce com o padrão da marca, não com um retângulo cinza: enquanto o
   Leaflet não monta — e se ele nunca montar — o que se vê é identidade, não
   uma falha. Mesma arte do `.bloco__arte`. */
.mapa__caixa {
  position: relative;
  height: clamp(340px, 62vh, 620px);
  border-radius: var(--raio); overflow: hidden;
  border: 1px solid var(--risco);
  background: var(--fundo-caixa) url('../marca/pattern-1001.png') repeat;
  background-size: 130px;
  box-shadow: var(--sombra);
}
/* Mapa que não veio encolhe. Uma caixa de 620 px com o padrão da marca e nada
   dentro domina a seção e parece defeito; 200 px de identidade abaixo de uma
   frase honesta parecem o que é — o mapa não carregou, e a frase diz o que
   fazer. Quem põe esta classe é o `falhar()` do `planta.js`. */
.mapa__caixa--vazia { height: clamp(160px, 26vh, 220px); }

/* ⚠️ ESPECIFICIDADE 0,2,0 DE PROPÓSITO, e não é excesso de zelo. O `leaflet.css`
   é injetado em tempo de execução; o `planta.js` o insere ANTES desta folha
   justamente para que a ordem seja a de sempre, mas quem mexer naquela função
   um dia não vai lembrar disto. Com o seletor descendente, a sobrescrita vence
   mesmo que a folha do Leaflet acabe vindo por último. 📏 É o defeito que o
   painel levou até 14/08/2026 (`inad_rails/public/index.html`, o comentário do
   `<link>` do leaflet): as regras empatavam em 0,1,0 e o tooltip ficava ilegível
   — sem nenhum erro no console. */
.mapa__caixa .leaflet-container { font: inherit; background: var(--fundo-caixa); }

/* ⚖️ A ATRIBUIÇÃO É CONDIÇÃO DE LICENÇA (Esri e OpenStreetMap/ODbL). O que este
   bloco faz é deixá-la LEGÍVEL sobre foto de satélite — nunca escondê-la,
   encolhê-la a ponto de não se ler, nem apagar o texto. */
/* 🪤 FUNDO CRAVADO + COR DE TOKEN dá o pior dos dois mundos: a placa é branca
   sempre, mas `--tinta-2` clareia no escuro e o texto sumia (2,17:1). Como a
   placa não muda, a cor do texto dela também não pode mudar — cravada.
   ⚖️ E aqui não é só estética: a atribuição é CONDIÇÃO DE LICENÇA do Esri e do
   OpenStreetMap. Ilegível é quase não ter. */
/* ⚖️ A ATRIBUIÇÃO NÃO PODE FICAR EMBAIXO DO BOTÃO FLUTUANTE. 📏 Medido: o
   `.zap` (fixo, canto inferior direito) cobria os últimos 47 px da linha de
   atribuição do Esri/OpenStreetMap — e ela é condição de licença, não enfeite.
   ✅ Ela sobe 52 px quando o mapa está na tela; o botão continua no lugar. */
.mapa__caixa .leaflet-bottom.leaflet-right { margin-bottom: 52px; }

.mapa__caixa .leaflet-control-attribution {
  background: rgba(255, 255, 255, .86);
  color: #454B63; font-size: 11px;
}
.mapa__caixa .leaflet-control-attribution a { color: #295787; }

/* A dica do lote verde. Fundo navy porque ela aparece por cima de foto aérea,
   onde o branco padrão do Leaflet some sobre telhado claro. */
.mapa__caixa .leaflet-tooltip.mapa__dica {
  background: var(--navy); color: #fff;
  border: 0; border-radius: 8px; box-shadow: var(--sombra-alta);
  padding: .5rem .7rem; font-size: .85rem; line-height: 1.45;
  white-space: nowrap;
}
.mapa__caixa .leaflet-tooltip.mapa__dica::before { border-top-color: var(--navy); }

/* 🖱️ A pílula do gesto — "segure Ctrl", "use dois dedos". Ela existe porque gesto
   que não se anuncia vira mistério: quem rola sem modificador vê a página andar
   e conclui que o mapa não tem zoom. Some sozinha em 1,9 s.

   ⚖️ **CENTRALIZADA, e não numa faixa no rodapé do mapa** — a faixa cobria a
   atribuição da Esri, que fica no canto inferior direito e é condição de
   licença. Encobrir por 1,9 s não é o mesmo que remover, mas o canto de baixo é
   justamente o lugar que este mapa não pode usar para mais nada.
   `pointer-events: none` para a pílula nunca roubar um clique de lote. */
.mapa__gesto {
  position: absolute; z-index: 1000; pointer-events: none;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  max-width: 82%; text-align: center;
  background: rgba(23, 26, 46, .88); color: #fff;
  padding: .65rem 1.1rem; border-radius: 999px; font-size: .88rem;
  box-shadow: var(--sombra-alta);
  animation: mapa-surge .18s ease-out;
}
@keyframes mapa-surge {
  from { opacity: 0; transform: translate(-50%, -46%); }
  to   { opacity: 1; transform: translate(-50%, -50%); }
}

.mapa__legenda {
  display: flex; flex-wrap: wrap; gap: 1.2rem;
  list-style: none; padding: 0; margin: 1rem 0 0;
  font-size: .9rem; color: var(--tinta-2);
}
.mapa__legenda li { display: flex; align-items: center; gap: .45rem; }
.mapa__bola { width: 14px; height: 14px; border-radius: 4px; display: inline-block; }
.mapa__bola--verde    { background: var(--verde); }
.mapa__bola--vermelho { background: var(--vermelho); }

/* A linha de estado. ⛔ Ela nunca fica vazia: com zero lote disponível ela diz
   isso em palavras, porque um mapa todo vermelho e sem legenda seria lido como
   "o site quebrou" em vez de "não há lote confirmado hoje". */
.mapa__estado { margin: .9rem 0 0; font-size: .95rem; max-width: 74ch; }
.mapa__estado a { font-weight: 500; }

/* 🔑 A lista é o mapa dito em texto — é ela que dá teclado e leitor de tela ao
   que o canvas não dá. Vazia (zero disponível) ela não ocupa espaço nenhum, e o
   parágrafo acima é que fala. */
.mapa__lista {
  list-style: none; padding: 0; margin: 1.4rem 0 0;
  display: grid; gap: .7rem;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.mapa__item {
  display: flex; flex-direction: column; gap: .15rem;
  padding: .85rem 1rem; height: 100%;
  border: 1px solid var(--risco); border-left: 4px solid var(--verde);
  border-radius: var(--raio); background: var(--folha);
  color: var(--tinta); text-decoration: none;
  transition: box-shadow .16s, transform .16s;
}
a.mapa__item:hover, a.mapa__item:focus-visible { box-shadow: var(--sombra); transform: translateY(-1px); }
.mapa__id    { font-weight: 600; }
.mapa__area  { color: var(--tinta-2); font-size: .92rem; }
.mapa__preco { color: var(--tinta-2); font-size: .86rem; }
/* O convite só aparece quando a linha é link de verdade — sem número comercial
   preenchido o `planta.js` gera um `<span>`, e prometer "falar" ali seria um
   botão que não leva a lugar nenhum. */
/* O convite só existe quando a linha é link de verdade: sem número comercial
   preenchido o `planta.js` gera um `<span>` SEM este pedaço, em vez de um
   "Falar sobre este lote" que não leva a lugar nenhum. */
.mapa__cta { margin-top: .35rem; font-size: .86rem; font-weight: 600; color: var(--aco); }

/* ══ A VITRINE DOS EMPREENDIMENTOS ═══════════════════════════════════════
   📌 *"no mesmo site, vai ter ambos os loteamentos."* (responsável, 01/09/2026).
   Até então a home inteira falava de UM — o hero dizia "Residencial Village
   Campos Verdes" e o `<h1>` prometia "o seu lote". Com dois, a home deixa de ser
   a página do loteamento e passa a ser a porta que escolhe entre eles.

   🪤 OS DOIS NÃO SÃO O MESMO PRODUTO, e o cartão precisa deixar isso visível
   antes do clique: o Village é RESIDENCIAL, com lote a partir de 250 m² e mapa
   de disponibilidade; o Salutis é COMERCIAL, 245 lotes em Senador Canedo, e
   dele ainda não temos tabela nem planta. Um cartão que igualasse os dois
   mandaria quem procura casa para uma página que não vende casa. */
/* 🐛 O CARTÃO ÓRFÃO — o defeito que mais gritava na fileira (02/09/2026).
   📌 *"tá bugado os cards"*. O `auto-fit` com piso de 300px resolvia em TRÊS
   colunas no container de 1180px — 📏 (1180 − 2×1.4rem) ÷ 3 = 378px por cartão,
   e um quarto de 300px não cabia. Com QUATRO empreendimentos isso dava 3 + 1: o
   cartão de Parceiros descia sozinho para uma segunda fileira, com dois terços da
   largura vazios ao lado dele. Nenhum ajuste de altura conserta isso.
   ✅ Duas colunas fixas fecham 2 × 2 exato. 📏 578px por cartão — a capa 16/9 fica
   com 325px de altura, que é onde as aéreas de 1000×750 finalmente se leem; com
   quatro colunas cada cartão teria 278px e o título de três palavras quebraria em
   três linhas.
   🪤 `minmax(0, 1fr)` e não `1fr`: o mínimo automático de um item de grid é o
   conteúdo, e uma palavra longa (uma URL, um nome composto) esticaria a coluna
   para fora do container em vez de quebrar.
   ⛔ Se um QUINTO empreendimento entrar, o órfão volta — e a resposta é rever esta
   regra, não empurrar o cartão novo para fora da vitrine. */
.vitrine {
  display: grid; gap: 1.4rem; margin-top: 2.5rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
/* Abaixo de 719px — o mesmo corte que o resto do arquivo usa — cabe um só.
   🪤 `minmax(0, 1fr)` e não o `1fr` seco, pelo mesmo motivo da regra de cima: `1fr`
   sozinho deixa o mínimo da coluna em `auto` (= min-content do cartão), e aí um
   conteúdo indivisível estica a coluna para fora do container em vez de quebrar.
   A regra antiga não corria esse risco por acidente — o `minmax(300px, 1fr)` já
   trazia um piso explícito. É prevenção, não conserto.
   📏 MEDIDO a 390px depois da troca, com uma sonda que percorreu todos os
   elementos: `scrollWidth == clientWidth` e ZERO elementos passando da direita —
   a vitrine não estoura, nem antes nem depois.
   ⚠️ E fica o aviso para quem for medir isto: `--window-size=390` no Chrome
   headless do Windows NÃO dá um layout de 390px. A janela é presa numa largura
   mínima maior, a página se monta nela e o `--screenshot` recorta só os 390px da
   esquerda — o que faz cartão inteiro e correto PARECER cortado na direita.
   ⛔ Não "conserte" largura com base nesse print: meça o `scrollWidth`. */
@media (max-width: 719px) { .vitrine { grid-template-columns: minmax(0, 1fr); } }
.emp {
  display: flex; flex-direction: column;
  background: var(--folha); border: 1px solid var(--risco);
  border-radius: var(--raio); overflow: hidden;
  color: inherit; text-decoration: none;
  transition: box-shadow .18s ease, transform .18s ease;
}
/* 🖱️ Só transform e opacity — a regra de animação desta casa. */
a.emp:hover, a.emp:focus-visible { transform: translateY(-2px); box-shadow: var(--sombra-alta); }
.emp__capa {
  aspect-ratio: 16 / 9; background: var(--fundo-caixa);
  background-size: cover; background-position: center;
  position: relative; display: grid; place-items: center;
}
/* Sem foto, a capa mostra o padrão da marca — nunca um retângulo cinza.
   🔀 190px → 130px em 02/09/2026, quando esta classe finalmente passou a ser
   CHAMADA (cartão de Parceiros). 📏 130px é o mesmo tile de `.bloco__arte` e da
   caixa do mapa: com 190px o mesmo padrão aparecia em duas escalas na mesma
   página, e lia como dois padrões diferentes.
   🪤 O PNG é traço navy sobre TRANSPARENTE — quem pinta o fundo é o
   `background: var(--fundo-caixa)` de `.emp__capa`. Trocar esse fundo por um tom
   claro apagaria o traço e, junto com ele, o selo branco que fica por cima. */
.emp__capa--marca {
  background-image: url('/estatico/marca/pattern-1001.png');
  background-size: 130px; background-repeat: repeat;
}
.emp__capa--foto::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(23,26,46,0) 40%, rgba(23,26,46,.55) 100%);
}
.emp__selo {
  position: absolute; top: .8rem; left: .8rem; z-index: 1;
  font-size: .72rem; letter-spacing: .07em; text-transform: uppercase;
  font-weight: 600; padding: .3rem .6rem; border-radius: 999px;
  background: rgba(255, 255, 255, .93); color: var(--navy);
}
.emp__corpo { padding: 1.4rem; display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.emp__corpo h3 { margin: 0; font-size: 1.25rem; }
/* 🪤 ESTA REGRA NUNCA MANDOU NA COR NEM NO TAMANHO, e agora diz a verdade. O
   `.emp__onde` é um `<p>` dentro de `.emp__corpo`, e `.emp__corpo p` (0,1,1),
   duas linhas abaixo, vence esta classe sozinha (0,1,0) em `font-size` e em
   `color`. 📏 Medido no navegador em 04/09/2026: a linha do "onde" sempre saiu
   em `--tinta-2` a .95rem — 5,49:1 sobre a folha — e não no `--tinta-3` a
   .85rem que estava escrito aqui. Quem lia a folha via um rótulo reprovado; quem
   olhava a tela via outro. A cor fica escrita como renderiza: 📌 *"a coisa mais
   importante é a localização"* — a linha que diz onde fica não é a que deve ser
   a mais clara do cartão. Só o `margin` era de fato desta regra. */
.emp__onde { color: var(--tinta-2); margin: 0; }
.emp__corpo p { margin: 0; font-size: .95rem; color: var(--tinta-2); }
/* 🔑 A MOLA QUE ALINHA A FILEIRA — e por que ela é o parágrafo, e não o resto.
   O `.emp__cta { margin-top: auto }` abaixo já colava os CTAs no rodapé de cada
   cartão. O que continuava desalinhado era a FAIXA DE CHIPS: ela vinha logo depois
   do texto, então parava onde o texto parasse — 📏 na renderização de 02/09 os
   chips do Village começavam 105px acima dos do Salutis, e a sobra caía toda num
   buraco no meio do cartão vizinho.
   ✅ Fazendo o PARÁGRAFO crescer, a sobra vai toda para ele e o par chips + CTA
   fica ancorado embaixo nos quatro cartões. O alinhamento passa a valer qualquer
   que seja o tamanho do texto — que é o ponto: ⛔ altura se acerta no CSS, nunca
   aparando descrição nem inventando chip.
   🪤 `flex-grow: 1` sozinho, NÃO o atalho `flex: 1`. `flex: 1` é `1 1 0%`, e uma
   base zero deixa o parágrafo encolher abaixo do próprio texto quando o espaço
   aperta — o texto vazaria da caixa. Com `flex-basis` em `auto` a altura do
   conteúdo continua sendo o piso.
   🪤 E só UMA mola por cartão: com `margin-top: auto` no `.emp__dados` também, o
   flex reparte a sobra entre as duas folgas e nada alinha. */
.emp__texto { flex-grow: 1; }
.emp__dados {
  list-style: none; padding: 0; margin: .4rem 0 0;
  display: flex; flex-wrap: wrap; gap: .4rem;
}
.emp__dados li {
  font-size: .82rem; padding: .25rem .6rem; border-radius: 999px;
  background: var(--gelo); color: var(--tinta-2); border: 1px solid var(--risco);
}
.emp__cta { margin-top: auto; padding-top: .8rem; font-weight: 600; color: var(--aco); font-size: .95rem; }

/* ══ O PANORAMA 360 ══════════════════════════════════════════════════════
   📌 *"ja sobe as fotos 360 do SALUTIS"* (responsável, 01/09/2026).

   🪤 A CAIXA PRECISA DE ALTURA EXPLÍCITA. O Pannellum monta um `<canvas>` dentro
   do contêiner e mede a altura DELE — contêiner sem altura dá canvas de 0 px, e
   a seção fica muda sem um erro no console. É o mesmo defeito que `.mapa__caixa`
   já documenta para o Leaflet.

   ⛔ E o `<noscript>` não é enfeite: sem JS o visualizador não existe, e o que
   sobra tem de ser uma foto de verdade, não uma caixa vazia. */
/* 🖥️ A TELA CHEIA DO IPHONE — 04/09/2026.
   📌 *"no iphone nao da pra colocar em tela cheia o 360"* (responsável).
   🪤 Não é bug do Pannellum: o iOS Safari só expõe tela cheia para `<video>`, e
   `document.fullscreenEnabled` é FALSO para qualquer outro elemento — a lib então
   esconde o próprio botão, corretamente, porque clicar não faria nada. O
   `panorama.js` detecta a ausência da API e monta este modo no lugar.
   🪤 `100dvh` e NÃO `100vh`: no iOS o `vh` conta a viewport COM a barra do Safari
   escondida, então `100vh` deixa a parte de baixo atrás da barra — justamente onde
   fica o botão de fechar. O `dvh` acompanha a barra aparecendo e sumindo.
   🪤 E o `z-index` fica abaixo do skip link (1300) de propósito: quem navega por
   teclado tem de conseguir sair daqui. */
/* 🔴 `.pano.pano--cheio`, COM AS DUAS CLASSES — e isto foi o defeito REAL da
   primeira versão, pior que a detecção de API que o comentário do `panorama.js`
   conta. 📏 Medido em 04/09/2026: `.pano--cheio` sozinha tem especificidade
   (0,1,0), exatamente a mesma de `.pano` — e a regra `.pano { position: relative }`
   vem DEPOIS nesta folha. No empate vence a última, então `relative` sobrescrevia
   o `fixed` e o `clamp(320px, 52vh, 560px)` do palco sobrescrevia o `100dvh`.
   ⇒ A tela cheia não teria funcionado NEM com o botão aparecendo, e o sintoma
   seria "cliquei e não aconteceu nada" — sem erro no console, sem pista.
   🔑 Com as duas classes (0,2,0) e `.pano.pano--cheio .pano__palco` (0,3,0), a
   regra vence por peso e não por posição: mover o bloco na folha deixa de mudar o
   comportamento. ⛔ Não simplifique de volta para uma classe só. */
.pano.pano--cheio {
  position: fixed; inset: 0; z-index: 1250;
  margin: 0; border: 0; border-radius: 0;
  width: 100%; height: 100dvh;
  background: #000;
}
/* (0,3,0) — precisa vencer também o `@media (orientation: landscape)` que fixa
   `height: 70vh` no palco; em tela cheia o palco é a tela toda, em qualquer
   orientação. */
.pano.pano--cheio .pano__palco { height: 100dvh; }
/* 🪤 Trava a rolagem do corpo enquanto a vista está aberta: sem isto o arraste da
   câmera rola a página por baixo, e o visitante sai da vista sem querer. */
body.pano-travado { overflow: hidden; }
.pano__cheio {
  position: absolute; right: .75rem; bottom: .75rem; z-index: 2;
  padding: .7rem 1.1rem; border: 0; border-radius: 999px;
  background: rgba(24, 26, 45, .86); color: #fff;
  font: 600 .9rem/1 Geist, system-ui, sans-serif; cursor: pointer;
  /* 👆 44px é o alvo de toque mínimo. ⛔ Não encolha para "ficar discreto": num
     celular este botão é a única porta para a vista grande, e a vista grande é o
     motivo de a seção existir. */
  min-height: 44px; min-width: 44px;
}
.pano__cheio:focus-visible { outline: 2px solid var(--ciano); outline-offset: 2px; }
.pano.pano--cheio .pano__cheio { bottom: max(.75rem, env(safe-area-inset-bottom)); }

.pano {
  position: relative; border-radius: var(--raio); overflow: hidden;
  border: 1px solid var(--risco); background: var(--fundo-caixa);
  margin-top: 1.8rem;
}
/* 🪤 `.pano .pano__palco`, E O DESCENDENTE NÃO É ENFEITE — é o que ganha do
   Pannellum. 📏 Medido no navegador em 01/09/2026: a lib acrescenta a classe
   `pnlm-container` ao MESMO elemento, e o `pannellum.css` dela traz
   `.pnlm-container{width:100%;height:100%}`. Especificidade igual (uma classe
   cada), e o `pannellum.css` é linkado DEPOIS do `site.css` — então ele vence o
   empate. O pai não tem altura, `height:100%` de pai sem altura resolve para
   zero, e o resultado foi um canvas de **0 px**: a lib carregava a imagem
   inteira, montava tudo, e não aparecia nada.

   🔑 O sintoma foi PIOR que uma tela vazia, e é isso que vale lembrar: com o
   segundo defeito abaixo, a foto plana continuava visível por cima do vazio.
   A seção parecia perfeita — só não girava. Nenhum erro no console, nenhuma
   requisição falhando. `.pano .pano__palco` sobe para (0,2,0) e resolve.

   ⛔ Não troque por `!important`: a próxima versão da lib muda o CSS dela, e
   `!important` esconde o conflito em vez de vencê-lo de forma legível. */
.pano .pano__palco { width: 100%; height: clamp(320px, 52vh, 560px); }

/* 🪤 Celular DEITADO: com viewport de ~320px de altura o `clamp` trava no minimo
   de 320px e o palco toma a tela inteira — nao sobra pista para rolar e sair do
   panorama, que captura o arrasto. Em retrato nao ocorre. */
@media (orientation: landscape) and (max-height: 420px) {
  .pano .pano__palco { height: 70vh; }
}

/* A foto plana que fica no lugar do visualizador quando não há JS ou WebGL.
   🪤 O `:not([hidden])` É OBRIGATÓRIO, e a falta dele foi o segundo defeito
   medido no mesmo dia. O `panorama.js` esconde esta foto com `plana.hidden =
   true` — e `hidden` é um atributo cuja única força é `[hidden]{display:none}`
   na folha do NAVEGADOR, que perde para QUALQUER regra de autor com `display`.
   Com `display: block` cru, a foto continuava ocupando 663 px por cima do
   visualizador: `el.hidden` respondia `true`, `getComputedStyle` respondia
   `block`, e a página mostrava uma foto parada que ninguém conseguia girar. */
.pano__plana:not([hidden]) { display: block; width: 100%; height: auto; }
.pano__dica {
  margin: .7rem 0 0; font-size: .9rem; color: var(--tinta-3);
}
/* O Pannellum traz fundo preto e uma fonte própria; alinhamos os dois à casa
   sem tocar no arquivo vendorizado — atualizar a lib não desfaz o ajuste. */
.pano .pnlm-container { background: var(--fundo-caixa); font-family: inherit; }
.pano .pnlm-load-box { background: rgba(60, 62, 105, .92); }

/* ══ A FICHA TÉCNICA ═════════════════════════════════════════════════════
   Números que vêm de documento (o projeto urbanístico aprovado), não de
   consulta. Por isso ficam em HTML mesmo, e a fonte vai escrita ao lado. */
.ficha {
  list-style: none; padding: 0; margin: 2rem 0 0;
  display: grid; gap: 1px; background: var(--risco);
  border: 1px solid var(--risco); border-radius: var(--raio); overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.ficha li { background: var(--folha); padding: 1.1rem 1.2rem; }

/* 🪤 A GRADE PERDIA PARA A REGRA GENÉRICA DE LISTA, e o defeito aparecia como
   uma faixa do fundo à esquerda e embaixo de cada célula.
   📌 *"tem um espaço na esquerda do lado da caixa do nome do local, feia"*
   (responsável, 03/09/2026, sobre "De carro, daqui até lá").

   📏 Medido: `.bloco ul { padding-left: 1.1rem }` é (0,1,1) — UMA CLASSE E UM
   TIPO — e vence o `padding: 0` da `.ficha`, que é (0,1,0). O mesmo com
   `.bloco li { margin-bottom: .4rem }`. Resultado no ar: 17,6 px de recuo à
   esquerda e 6,4 px sob cada célula, expondo o `--risco` que só devia aparecer
   nos 1 px de `gap`.

   ⛔ Não resolva subindo o `padding: 0` para dentro da `.ficha` de novo: o
   problema não é ordem, é PESO. Estas duas linhas existem para empatar em tipo
   e ganhar em classe. */
.bloco ul.ficha { padding: 0; }
.bloco .ficha li { margin: 0; }

/* ─── A grade de TEMPOS (as três seções "de carro, daqui até lá") ─────────────
   📌 *"tá feio, meio mal dimensionado esse tempo"* (responsável, 03/09/2026).

   📏 O defeito é aritmético, não estético: são NOVE destinos, e o
   `auto-fit minmax(190px)` da `.ficha` genérica cabia SEIS numa tela larga —
   6 + 3, com metade da segunda linha vazia e os rótulos longos ("Setor Leste
   Universitário", "Aeroporto Santa Genoveva") quebrando em duas linhas dentro
   de células estreitas. 9 é múltiplo de 3: com três colunas fecham três linhas
   cheias, e cada célula ganha largura para o rótulo caber numa linha só.

   🪤 A regra é da grade de TEMPOS, não da `.ficha` — a mesma classe serve à
   lista de pendências do Boulevard, onde 6 colunas estão certas. Por isso ela
   mora num seletor de contexto (`#distancias`), e não no componente. */
#distancias .ficha { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { #distancias .ficha { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { #distancias .ficha { grid-template-columns: 1fr; } }

/* 🔢 O tempo alinhado à direita do rótulo, e não embaixo: a coluna de números
   vira uma régua vertical que se lê de cima a baixo — que é como alguém compara
   "quanto tempo até cada lugar". Empilhado, o olho tem de caçar cada número. */
#distancias .ficha li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
}
#distancias .ficha__rot { margin-bottom: 0; }
#distancias .ficha__val { white-space: nowrap; }
.ficha dt, .ficha__rot {
  display: block; font-size: .76rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--tinta-3); margin-bottom: .25rem;
}
.ficha__val { font-size: 1.15rem; font-weight: 600; color: var(--destaque); }
.fonte { margin-top: .9rem; font-size: .85rem; color: var(--tinta-3); }

/* ══ O BOTÃO FLUTUANTE — a vitrine existe para captar lead ═══════════════
   📌 *"esse site é para ser uma vitrine, somente"* · *"só pra captar lead"*
   (responsável, 01/09/2026).

   🔑 O caminho até a conversa passa a estar sempre a um toque. Antes, o único
   botão de WhatsApp ficava no fim da página: quem se convencia no meio do texto
   tinha de rolar até o rodapé para agir — e parte das pessoas não rola.

   🪤 `position: fixed` COM `env(safe-area-inset-bottom)`: sem isso o botão fica
   embaixo da barra de gestos do iPhone, e o toque cai na barra do sistema em vez
   de no link. O `max()` mantém o afastamento mínimo em aparelho sem notch.

   ⛔ Só `transform` e `opacity` na transição — é a regra de animação desta casa,
   e aqui ela importa em dobro: o elemento é fixo e repinta a cada rolagem. */
.zap {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 1150;
  display: inline-flex; align-items: center; gap: .55rem;
  padding: .8rem 1.1rem;
  border-radius: 999px;
  /* 🟢 O teal do WhatsApp, não a paleta da marca — mas 11% mais fechado que o
     #128C7E oficial. 📏 Branco sobre #128C7E dá 4,14:1, e o rótulo "Falar no
     WhatsApp" (15,2px/600) é texto normal, que pede 4,5:1 — nas 7 páginas.
     #107C70 fica no eixo dos dois teais da própria marca deles (#128C7E e
     #075E54), e dá 5,07:1 com o branco. O ícone, que só precisa de 3:1, ganha de
     brinde. (04/09/2026) */
  background: #107C70;
  color: #fff; font-weight: 600; font-size: .95rem;
  text-decoration: none;
  box-shadow: 0 6px 20px rgba(23, 26, 46, .28);
  transition: transform .16s ease, opacity .16s ease;
}
.zap:hover, .zap:focus-visible { transform: translateY(-2px); color: #fff; }
.zap svg { width: 20px; height: 20px; fill: currentColor; flex: none; }

/* 📱 No celular o rótulo sai e fica só o ícone: a barra de 1.1rem de padding
   com texto cobriria a largura útil da tela sobre o conteúdo. */
@media (max-width: 599px) {
  .zap { padding: .85rem; border-radius: 50%; }
  .zap span { position: absolute; width: 1px; height: 1px; overflow: hidden;
              clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}

/* ♿ Quem pediu menos movimento não recebe o salto no hover. */
@media (prefers-reduced-motion: reduce) {
  .zap { transition: none; }
  .zap:hover, .zap:focus-visible { transform: none; }
}

/* ══ "DAQUI, DE CARRO" ═══════════════════════════════════════════════════
   📌 *"aqui tu coloca os pontos mais importantes"* (responsável, 01/09/2026).

   🔑 Duas colunas — lugar à esquerda, minuto à direita — em vez de uma frase
   corrida. Quem lê uma página de imóvel varre esse tipo de informação com o
   olho, procurando o lugar que interessa a ELE; frase corrida obriga a ler tudo
   para achar um. O `justify-content: space-between` mantém os minutos alinhados
   sem tabela.

   🪤 `grid` com `auto-fit`, não `flex`: com flex as duas colunas não fecham na
   mesma largura entre linhas, e os minutos ficam serrilhados. */
.daqui__titulo {
  margin: 1.6rem 0 .7rem; font-size: .78rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--tinta-3); font-weight: 600;
}
/* 🪤 O GAP DE COLUNA ERA `0`, e isso colava as duas colunas uma na outra.
   📏 Medido em 05/09/2026, em 1920px: cada `li` é `space-between`, então o tempo
   do item da esquerda encosta na borda da célula e o nome do item da direita
   começa no pixel seguinte — a linha lia *"Terminal Novo Mundo 4 min Centro
   11 min"*, com o número do primeiro grudado no nome do segundo. Duas colunas
   sem calha não são duas colunas: são uma linha confusa.
   ⛔ O gap de LINHA continua curto (.1rem) de propósito — quem separa as linhas
   é a borda inferior de cada `li`, e afastá-las soltaria a régua. */
.daqui {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: .1rem 2.2rem;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.daqui li {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .6rem; padding: .5rem .1rem;
  border-bottom: 1px solid var(--risco);
}
.daqui__lugar { color: var(--tinta-2); font-size: .95rem; }
.daqui__t { font-weight: 600; color: var(--destaque); white-space: nowrap; }

/* 🥇 OS TRÊS PONTOS DE REFERÊNCIA — 📌 *"todos sao importantes mas esses sao
   mais"* (responsável, 05/09/2026). A lista deixou de ser ordenada por tempo e
   passou a ser por importância, e isso PRECISA aparecer: sem marca nenhuma, uma
   lista de minutos fora de ordem crescente lê como erro de digitação, não como
   escolha. O rótulo diz o critério em palavras; estas regras dizem em forma.

   🪤 `grid-column: 1 / -1` NÃO É ENFEITE, é o que salva a hierarquia. A `.daqui`
   é `auto-fit minmax(230px, 1fr)`, então em tela larga ela vira duas colunas e
   preenche por LINHA — os três primeiros cairiam nas posições 1, 2 e 4 do
   desenho (dois lado a lado e o terceiro embaixo à esquerda), e a leitura "estes
   três são os principais" evaporaria. Ocupando a linha inteira eles viram um
   bloco de três, e o resto segue na grade normal. */
.daqui--forte { grid-column: 1 / -1; border-bottom-color: var(--destaque); }
.daqui--forte .daqui__lugar { color: var(--tinta); font-weight: 600; }
.daqui--forte .daqui__t { font-size: 1.05rem; }

/* O critério, ao lado do rótulo. ⛔ Minúsculo e sem `letter-spacing`, ao
   contrário do `.daqui__titulo`: ele explica o rótulo, não compete com ele.

   🔴 E SEM `opacity`, que é como ele nasceu e durou dez minutos. 📏 Medido em
   05/09/2026: `--tinta-3` sobre `--folha` dá **5,14:1**; com `opacity: .85` a
   cor efetiva composta sobre o fundo cai para **3,79:1**, e o mínimo para texto
   pequeno é 4,5. ⛔ A armadilha é que a opacidade NÃO aparece numa varredura de
   contraste que só lê `color` — ela reprova um par de cores que, no papel,
   passa. Para "apagar" um texto desta casa, use o token mais claro; nunca
   `opacity` por cima de um token que já foi calibrado no limite. */
.daqui__criterio {
  text-transform: none; letter-spacing: 0; font-weight: 400;
  color: var(--tinta-3);
}

/* ══ O CONVITE DE RECUPERAÇÃO DO MAPA ════════════════════════════════════
   🔑 O CTA que mais faltava. O mapa é fail-closed de propósito — verde só o que
   a curadoria confirmou —, então hoje ele mostra uma tela quase toda vermelha.
   Quem não achou o lote que queria tinha de rolar três seções até um botão de
   conversa, e é justamente essa pessoa que está com a intenção mais quente.

   ⛔ O texto não promete estoque: diz que a equipe confere, o que é verdade. */
.mapa__convite {
  margin: 1.4rem 0 0; padding: 1.1rem 1.3rem;
  background: var(--gelo); border: 1px solid var(--risco);
  border-radius: var(--raio);
  display: flex; flex-wrap: wrap; align-items: center; gap: .9rem;
  font-size: .97rem; color: var(--tinta-2);
}
.mapa__convite .btn { margin-left: auto; }
@media (max-width: 599px) { .mapa__convite .btn { margin-left: 0; width: 100%; text-align: center; } }

/* ══ A TEXTURA DA MARCA NAS SEÇÕES CLARAS ════════════════════════════════
   📌 *"nao sei se é falta de elemento, pode pegar o pattern e soltar preto
   traçado […] acho que ia ficar brega mas pode usar ele mais"* (responsável,
   01/09/2026).

   🔑 A suspeita dele tinha fundamento: o traçado em opacidade cheia cobre
   **19,6%** da área — mais que o pattern preenchido (13,7%), porque o contorno
   espalha o mesmo desenho por mais pixels. Sobre isso não se lê texto.

   ✅ Por isso a textura entra a **5,5%**, num pseudo-elemento por baixo do
   conteúdo. De longe a seção ganha superfície; de perto o desenho é da marca; e
   o texto mantém o contraste medido, porque o pseudo-elemento não muda a cor do
   fundo — só acrescenta uma trama.

   🪤 E ELA NÃO VAI EM TODA SEÇÃO. Alternar liso e texturado é o que faz a
   textura ser percebida. Em tudo, ela vira ruído que ninguém vê — e aí seria só
   peso de arquivo.

   🪤 `pointer-events: none` é obrigatório: sem ele a camada cobre a seção
   inteira e engole o clique dos links que estão por baixo. */
.faixa,
.bloco--gelo,
.contato {
  position: relative;
  isolation: isolate;          /* o z-index de dentro não escapa da seção */
}
.faixa::before,
.bloco--gelo::before,
.contato::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  pointer-events: none;
  background: url('../marca/pattern-1001-tracado.png') repeat;
  background-size: 168px;
  opacity: .055;
}
/* 🌑 Sobre fundo escuro o traçado navy some — ali ele vira claro, com a mesma
   discrição. `invert` custa menos que servir um segundo arquivo, e o desenho é
   monocromático, então não há cor para estragar. */
.contato::before { filter: invert(1); opacity: .07; }

/* 📱 No celular a textura sai: a tela é pequena, o desenho fica denso em relação
   ao texto, e o custo de composição por quadro aparece na rolagem. */
@media (max-width: 599px) {
  .faixa::before, .bloco--gelo::before, .contato::before { display: none; }
}

/* 🔤 `.bloco__olho` como `<h2>`: nas páginas longas ele é o rótulo de grupo e
   PRECISA ser um heading — sem isso a árvore ia h1 → h3 e quem navega por
   títulos perdia a estrutura. Estas quatro linhas anulam o estilo padrão de h2
   (tamanho, peso, margem) para que a mudança semântica não mexa no visual. */
h2.bloco__olho {
  font-size: .8rem; font-weight: 600; letter-spacing: .08em;
  line-height: 1.6; margin: 0 0 .3rem;
}

/* ══════════════════════════════════════════════════════════════════════════
   O MODO ESCURO — o site segue o tema do sistema.

   📌 *"coloca a cor do site todo adaptavel de acordo com o sistema do
   celular/pc"* (responsável, 01/09/2026).

   🪤 A ARMADILHA QUE NÃO EXISTE NUM SITE COMUM: esta página JÁ alterna claro e
   escuro entre seções — hero escuro, corpo claro, contato escuro. "Inverter
   tudo" apagaria essa alternância e a página viraria um bloco só.

   ⇒ Aqui a alternância SOBREVIVE: o que era claro vira escuro médio, e o que já
   era escuro desce mais. O ritmo visual continua; só a faixa de luminância baixa.

   🔑 E SÓ OS TOKENS MUDAM. Nenhuma regra de componente é reescrita — é o que
   garante que uma seção nova, escrita amanhã com os tokens da casa, já nasça
   funcionando nos dois temas. Se algum dia for preciso reescrever um componente
   aqui dentro, é sinal de que ele cravou uma cor em vez de usar o token.

   🎨 Os ACENTOS clareiam: `--aco` e `--ciano` no tom original não sobrevivem
   sobre fundo escuro (link azul-escuro em fundo azul-escuro). Os valores abaixo
   são os mesmos matizes, com luminosidade suficiente para o AA. `--ciano-texto`
   vem junto: no claro ele é o ciano fechado para texto; aqui o acento já passa
   como texto, e os dois tokens recebem o mesmo valor.

   ⛔ O `--navy` NÃO muda: ele é a cor da marca, e a marca não tem versão escura.
   Onde ele aparece como fundo de componente pequeno (selo, badge), continua o
   mesmo — sobre ele o texto já é branco nos dois temas.

   📏 Contrastes medidos (WCAG), todos ≥ 4,5:1 — o script que gerou esta paleta
   falha se algum cair abaixo:
   texto/folha 12.2:1 · texto/papel 13.7:1 · secundário/papel 7.5:1 ·
   link/papel 6.7:1 · branco/hero 18.9:1
   ══════════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════════
   O CELULAR — e o que não cabia nele.

   📌 *"esse site tem de estar otimizado para celulares responsivo"*
   (responsável, 01/09/2026).

   🔴 O defeito medido num render de 390 px: a barra do topo tem o logo (236 px)
   MAIS seis links. Não cabe. E como `.topo` tem altura fixa, a nav quebrava em
   duas linhas e vazava pela direita, empurrando a página inteira.
   ══════════════════════════════════════════════════════════════════════════ */

/* 🛡️ O CINTO CONTRA VAZAMENTO HORIZONTAL. Rolagem lateral num site vertical é o
   defeito de celular mais comum e o mais irritante: a página "escorrega" no
   polegar. `overflow-x: hidden` no `html` E no `body` — só num deles não segura
   em Safari iOS. ⚠️ Isto é rede de segurança, não conserto: quem estourar a
   largura continua estourando, só que sem arrastar a página junto. */
html, body { overflow-x: hidden; max-width: 100%; }

/* 🪤 A LARGURA NÃO BASTA: celular DEITADO tem mais de 719 px e voltava ao
   layout de desktop — a barra do topo com seis links num aparelho de 360 px de
   altura. `(max-width: 719px)` OU `(max-height: 500px and orientation: landscape)`
   cobre os dois casos. */
@media (max-width: 719px), (max-height: 500px) and (orientation: landscape) {
  /* ── A barra do topo ────────────────────────────────────────────────────
     🔑 Os quatro links de SEÇÃO somem: a pessoa rola, que é o gesto natural no
     celular, e o conteúdo está todo logo abaixo. As duas PORTAS ficam — elas
     são os únicos destinos que a rolagem não alcança, porque estão noutro
     container (o Rails).
     ⛔ Não é menu hambúrguer de propósito: num site de quatro seções, esconder
     atrás de clique é mais atrito para o mesmo destino. */
  .topo__nav a:not(.porta) { display: none; }
  .topo__nav { gap: .4rem; }
  .topo__nav .porta { font-size: .82rem; padding: .45rem .7rem; }

  /* 🪤 E ATE' AS DUAS PORTAS APERTAM em 390 px, com o logo ao lado. Fica a do
     CLIENTE, que e' quem chega perdido procurando boleto — o corretor sabe onde
     e' o painel dele, e o link continua no rodape de todas as paginas.
     📏 A conta: logo ~133 px + "Area do cliente" ~120 px + "Corretor" ~85 px +
     gaps = 350 px de conteudo em 358 px uteis. Cabe por 8 px, e some no primeiro
     aparelho de 360. */
  .topo__nav .porta[href="/corretor"] { display: none; }

  /* O logo encolhe mais, para as duas portas caberem na mesma linha. */
  .topo__logo img { height: 44px; }
  :root { --topo: 66px; }

  /* ── Respiro geral ──────────────────────────────────────────────────────
     A margem de 2.5rem do `.container` é generosa no desktop e come 1/9 da tela
     no celular. */
  .container { width: min(1180px, 100% - 1.6rem); }

  /* ── O hero ─────────────────────────────────────────────────────────────
     `min(88vh, 780px)` no celular vira uma tela inteira antes de qualquer
     conteúdo. E os botões passam a ocupar a largura toda: alvo de toque grande
     é o que se recomenda, e são os dois CTAs principais da página. */
  .hero { min-height: auto; padding: calc(var(--topo) + 2.2rem) 0 2.6rem; }
  .hero__acoes { flex-direction: column; align-items: stretch; }
  .hero__acoes .btn { text-align: center; }

  /* 🪤 E `.contato__acoes` PRECISA DA MESMA REGRA — ela tinha sido esquecida.
     📏 Achado em 02/09/2026: este bloco estica os CTAs do hero, do `.mapa__convite`
     e da `.faixa-servico`, e deixou de fora justamente o par do FIM da página —
     o CTA de captação. "Falar no WhatsApp" (~200px) + gap + "Já sou cliente"
     (~159px) não cabem em 294px (tela de 320), então quebravam em duas pílulas
     centralizadas de LARGURAS DIFERENTES, empilhadas — enquanto o mesmo par, uma
     tela acima, aparecia esticado e alinhado. */
  .contato__acoes { flex-direction: column; align-items: stretch; }
  .contato__acoes .btn { text-align: center; }

  /* ── A faixa de números ─────────────────────────────────────────────────
     `auto-fit minmax(160px)` cabe 2 por linha em 390 px, e o valor mais longo
     (R$ 10.746,80) transborda. Uma coluna, com a linha separando. */
  .faixa__grade { grid-template-columns: 1fr; gap: 0; }
  .faixa__grade > div { padding: .7rem 0; border-bottom: 1px solid var(--risco); }
  .faixa__grade > div:last-child { border-bottom: 0; }
  .faixa dd { font-size: 1.35rem; }

  /* ── Os blocos com arte ─────────────────────────────────────────────────
     O grid de duas colunas vira uma, e a arte perde a altura fixa de 4/3 para
     não empurrar o texto para fora da primeira tela. */
  .bloco__par { grid-template-columns: 1fr; gap: 1.4rem; }
  .bloco__arte { aspect-ratio: 16 / 10; }
  .bloco--inverte .bloco__arte { order: 0; }   /* no celular a foto vem sempre antes */

  /* ── A grade "daqui, de carro" ──────────────────────────────────────────
     Uma coluna: com duas, o nome do lugar quebra em duas linhas e a leitura
     em varredura (que é o motivo de ela existir) se perde. */
  .daqui { grid-template-columns: 1fr; }

  /* ── O convite do mapa ──────────────────────────────────────────────────
     O botão desce para baixo do texto, ocupando a largura. */
  .mapa__convite { flex-direction: column; align-items: stretch; text-align: left; }
  .mapa__convite .btn { width: 100%; text-align: center; }

  /* ── A ficha técnica ────────────────────────────────────────────────────
     `minmax(190px)` cabe 2 por linha e aperta; uma coluna lê melhor. */
  .ficha { grid-template-columns: 1fr; }

  /* ── O rodapé ───────────────────────────────────────────────────────────
     A logo do rodapé a 56px é grande demais numa coluna estreita. */
  .rodape img { height: 42px; }
  .rodape__grade { gap: 1.6rem; }
}

/* 📱 Telas MUITO estreitas (iPhone SE e similares, 360 px e menos) */
/* ── 📱 A FAIXA DE TABLET EM QUE A BARRA QUEBRAVA (720-839 px) ─────────────
   📌 *"o site é responsivo de vez em quando"* (responsável, 02/09/2026) — este é
   o segundo dos dois defeitos que a varredura achou, e é o menos óbvio.

   📏 MEDIDO largura a largura, em iframe (viewport próprio, media queries de
   verdade):

       700 px   2 itens   desalinho   1 px   ✅ uma linha
       720 px   5 itens   desalinho  45 px   ⛔ DUAS LINHAS
       800 px   5 itens   desalinho  45 px   ⛔
       840 px   5 itens   desalinho   1 px   ✅

   ⇒ O `@media (max-width: 719px)` que esconde os quatro links de seção está no
   lugar errado por ~120 px. Abaixo de 720 eles somem e sobra espaço; acima de
   840 tudo cabe. **Entre os dois, os cinco itens aparecem e não cabem** — e o
   "Área do cliente" cai para uma segunda linha, desalinhado à esquerda, num
   iPad em retrato (768×1024), que é aparelho comum.

   🪤 E ISSO NÃO VAZA DA BARRA: no desktop `--topo` é 104 px, e duas linhas de
   45 px cabem lá dentro. Por isso o defeito é só FEIO, e por isso ele sobreviveu
   — nenhum teste de overflow ou de vazamento o pegaria.

   ⛔ A regra é SEPARADA de propósito, e não uma troca de 719 por 839 no bloco
   grande. Aquele bloco também governa o hero, a faixa de números, o container e
   o rodapé: esticá-lo até 839 daria layout de celular a um tablet inteiro para
   consertar a barra. Aqui muda só a barra.

   ✅ Esconder os links de seção é a decisão que o projeto JÁ tomou no estreito, e
   o motivo continua valendo: *"a pessoa rola, e o conteúdo está todo logo
   abaixo"*. As duas PORTAS ficam — elas levam a outro container. */
/* ── 🃏 O CARTÃO ÓRFÃO, DUAS VEZES — e ele já tinha sido consertado uma vez ──
   📏 Achado pela varredura de 02/09/2026. `repeat(auto-fit, minmax(220px, 1fr))`
   resolve em TRÊS colunas numa faixa larga, e os dois grids que o usam têm
   QUATRO itens. O quarto desce sozinho, com dois terços da fileira vazios ao
   lado — num bloco cujo título promete "Quatro passos".

     .passos          3 colunas de ~741 a ~981 px   (3×220 + 2×19,2 = 698 cabe;
                                                      4×220 + 3×19,2 = 938 não)
     .rodape__grade   3 colunas de ~764 a ~1016 px  (gap maior, 2rem)

   🪤 E no rodapé a que desce é a coluna **Contato** — telefone, e-mail, endereço
   e Instagram. O endereço é exigência de publicidade de imobiliária (Lei
   6.530/78): é a última que convém deslocar.

   🔑 É O MESMO DEFEITO QUE `.vitrine` JÁ REGISTRA COMO CONSERTADO (o comentário
   dela chama de "o defeito que mais gritava na fileira"). O conserto não foi
   aplicado a estes dois — `auto-fit` é cômodo e erra em silêncio sempre que a
   contagem de itens não divide pelo número de colunas que ele escolhe.

   ⛔ `minmax(0, 1fr)` e não `1fr` seco: `1fr` é `minmax(auto, 1fr)`, e o `auto`
   se recusa a encolher abaixo do conteúdo — um nome longo estoura a coluna.
   Abaixo de 720 px os dois já resolvem em 2 ou 1 coluna sozinhos, e por isso a
   faixa tem piso. */
@media (min-width: 741px) and (max-width: 981px) {
  .passos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* 🪤 1039 e não 1016: o limite saiu de MEDIÇÃO, e a primeira conta errou por
   23 px. A grade precisa de 4×220 + 3×32 = **976 px** para caber quatro, e o
   `.container` dá `100% - 2.5rem` — ou seja, viewport ≥ 1016 px. 📏 Mas medido:
   1016 → grade de 961; 1024 → 969 (ainda 3 colunas); **1040 → 985, e aí sim 4**.
   O `.rodape` tem padding próprio que a conta de papel não incluía.
   ⇒ Quando o limite de um breakpoint vier de aritmética, CONFIRA na tela. */
@media (min-width: 741px) and (max-width: 1039px) {
  .rodape__grade { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 720px) and (max-width: 839px) {
  .topo__nav a:not(.porta) { display: none; }
}

@media (max-width: 380px) {
  .topo__nav .porta { font-size: .78rem; padding: .4rem .55rem; }
  .topo__logo img { height: 34px; }
  :root { --topo: 60px; }
  h1 { font-size: 1.85rem; }

  /* ── 🔴 O DEFEITO DOS 320 px, e por que ele não aparecia em teste nenhum ──
     📌 *"o site é responsivo de vez em quando eu aperto f12"* (responsável,
     02/09/2026). Ele não disse o que quebrava; isto é o que quebrava.

     📏 MEDIDO em iframe de 320 px (as media queries respondem ao viewport dele,
     então é simulação de verdade): os dois itens do `.topo__nav` ficavam em
     LINHAS DIFERENTES — `y = -71` e `y = -25`, 46 px de distância. Em 360 px,
     `y = -50` e `-48`: uma linha só. Daí o "de vez em quando".

     ⛔ E A BARRA TEM ALTURA FIXA (`--topo`). Numa caixa de altura fixa, o
     `flex-wrap: wrap` da linha 203 não empurra nada: a segunda linha VAZA para
     fora da barra e fica flutuando SOBRE o hero. Quem olha vê o botão "Área do
     cliente" solto em cima do texto.

     🪤 E ELE NÃO APARECE NO TESTE ÓBVIO. `scrollWidth > innerWidth` — a checagem
     padrão de responsividade — deu ✅ nas 7 páginas, em 320/360/390/768: nada
     transborda para o LADO. O elemento desce e sobrepõe, e sobreposição não é
     overflow. ⇒ **Medir overflow horizontal não prova que a página está inteira.**

     ✅ Três linhas resolvem, e cada uma tem um papel: `nowrap` proíbe a quebra
     numa barra que não pode crescer; o gap menor devolve os pixels que faltavam;
     e a logo a 34 px (era 38) dá a folga final. 📏 Depois: uma linha só em 320. */
  .topo__linha { gap: .7rem; }
  .topo__nav { flex-wrap: nowrap; }
}

/* 🖐️ ALVO DE TOQUE: 44 px é o mínimo recomendado (Apple HIG e WCAG 2.5.8).
   ⚠️ Vale em QUALQUER largura com apontador grosso — um tablet grande também
   tem dedo. Por isso a consulta é `pointer: coarse`, não `max-width`. */
@media (pointer: coarse) {
  /* 🪤 `min-height` NÃO se aplica a elemento `inline` — o link do rodapé é
     inline, e a regra antiga não fazia nada ali. `inline-block` é o mínimo para
     a altura valer. */
  .topo__nav a, .mapa__item, .faq h3, .tema { min-height: 44px; }
  .rodape a { display: inline-block; min-height: 44px; padding: .35rem 0; }
  .topo__nav a { display: inline-flex; align-items: center; }
  .btn { min-height: 46px; display: inline-flex; align-items: center; justify-content: center; }
}

/* 🌓 O ESCURO PEDIDO À MÃO. Os mesmos tokens do bloco automático acima — a
   duplicação é deliberada e é o preço de não ter build: uma lista de tokens
   repetida é mais fácil de conferir que um pré-processador só para isto.
   ⛔ Ao mudar um token do escuro, mude NOS DOIS. */

/* 📱 No celular ele fica: é pequeno, e é a única função da barra que o conteúdo

/* ══════════════════════════════════════════════════════════════════════════
   AS CAMADAS — sombreamento por elevação.

   📌 *"coloca sombreamento nas layers tbm"* (responsável, 01/09/2026).

   🪤 A ARMADILHA: **sombra não funciona no escuro.** Sombra clara-escura simula
   luz vinda de cima sobre papel CLARO; sobre fundo escuro, uma sombra preta é
   invisível — o elemento não sobe, só suja em volta. É por isso que quase todo
   site com modo escuro perde a profundidade quando o tema vira.

   ✅ Por isso o MECANISMO troca, não o valor:
   · no CLARO a camada sobe por **sombra** (luz de cima, objeto acima do papel);
   · no ESCURO a camada sobe por **luz própria** — fundo um pouco mais claro que
     o de trás, mais um filete claro na quina de cima, que imita o reflexo. É
     como material se comporta num ambiente escuro: o que está mais perto da luz
     é mais CLARO, não mais sombreado.

   🎚️ Quatro elevações: 0 papel · 1 apoiado · 2 elevado · 3 flutuante.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* 🔦 A cor da sombra é o `--tinta` em rgba, não preto puro: preto sobre um
     fundo levemente azulado dá um cinza morto. Sombra tingida com a cor do texto
     pertence à mesma paleta. */
  --elev-1: 0 1px 2px rgba(23, 26, 46, .05), 0 2px 8px rgba(23, 26, 46, .05);
  --elev-2: 0 2px 4px rgba(23, 26, 46, .07), 0 12px 28px rgba(23, 26, 46, .09);
  --elev-3: 0 4px 10px rgba(23, 26, 46, .10), 0 24px 56px rgba(23, 26, 46, .16);
  /* O filete de quina só existe no escuro — no claro ele é transparente. */
  --quina: transparent;
}

/* ── ① A barra do topo ganha profundidade AO ROLAR ─────────────────────────
   🔑 Parada no topo ela não precisa de sombra: não há nada por baixo ainda, e a
   sombra sobre o hero só sujaria. A sombra entra quando a página rola e passa
   conteúdo por baixo dela — que é quando ela vira, de fato, uma camada acima.
   🪤 `animation-timeline: scroll()` faz isso sem JS e sem listener de scroll.
   Onde ele não existe (Safari), a barra fica sem a sombra — perda aceitável,
   porque a borda inferior já a separa. */
.topo { box-shadow: none; }
@supports (animation-timeline: scroll()) {
  .topo {
    animation: topo-eleva linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 120px;
  }
}
@keyframes topo-eleva {
  from { box-shadow: none; }
  to   { box-shadow: var(--elev-3); }
}

/* ── ② As camadas ────────────────────────────────────────────────────────── */
.faixa { box-shadow: inset 0 1px 0 var(--quina); }

/* 🪤 `border-top` NÃO pode ser declarado aqui: no claro `--quina` é
   `transparent`, e isto APAGAVA a borda de `--risco` que `.emp`, `.mapa__caixa`
   e `.ficha` já tinham. O filete de quina é só do escuro, então ele vai no
   bloco do escuro — onde nada existia para apagar. */
.emp,
.bloco__arte,
.mapa__caixa,
.pano,
.passo,
.ficha,
.mapa__convite {
  box-shadow: var(--elev-2);
}

.mapa__item,
.emp__dados li,
.daqui li {
  box-shadow: var(--elev-1);
}

/* O hover sobe mais um degrau — o movimento já existia, agora a sombra
   acompanha e o cartão parece realmente se levantar. */
a.emp:hover, a.emp:focus-visible,
a.mapa__item:hover, a.mapa__item:focus-visible {
  box-shadow: var(--elev-3);
}

.zap { box-shadow: var(--elev-3); }

/* ── ③ NO ESCURO, a elevação inverte de mecanismo ──────────────────────────
   As sombras quase somem e quem levanta a camada é o filete de quina mais o
   fundo próprio (`--folha`, que já é mais claro que `--papel`). */

/* ── ④ E as SEÇÕES escuras ganham uma linha de separação ───────────────────
   Entre duas seções escuras vizinhas, a sombra não aparece (escuro sobre
   escuro). O que separa ali é uma linha de 1px — o mesmo recurso que o rodapé
   já usa, aplicado às emendas. */
.hero + .faixa,
.contato,
.bloco--gelo + .bloco--gelo {
  border-top: 1px solid rgba(255, 255, 255, .06);
}

/* ♿ Quem pediu menos movimento não recebe a sombra animada do topo — ela vira
   fixa, no estado final. */
@media (prefers-reduced-motion: reduce) {
  .topo { animation: none !important; box-shadow: var(--elev-3); }
}

/* 🌗 O filete de quina, SÓ no escuro (ver a nota acima). */

/* ═══════════════════════════════════════════════════════════════════════════
   O BRIEFING DA VITRINE — 02/09/2026
   ═══════════════════════════════════════════════════════════════════════════
   📌 "Executa esse projeto abaixo, o que tiver faltando deixa um lorem ipsum"
   (responsável), com o wireframe do one-page.

   ⛔ A PALETA DO BRIEFING NÃO FOI ADOTADA, e isso é decisão dele: ele propunha
   verde escuro #1B3A2F com dourado #B08D4F, e o próprio briefing prevê a
   ressalva — "se já existe manual de marca, ela prevalece". Existe: navy #3C3E69,
   aço #295787, ciano #0084A9. 📌 E ele confirmou em voz alta: "só nao respeita a
   tabela de cores". Recolorir é a 4ª proibição do manual da identidade. */

/* 📖 Bloco de texto centrado — a seção "Quem somos" pede leitura corrida, e
   linha longa demais cansa: 640px é o limite do briefing, e ele está certo. */
.container--estreito { max-width: 640px; }

/* 🪪 O selo do CRECI. Filete em cima, como o briefing pede — só que no ciano da
   marca, não no dourado dele. */
.selo-creci {
  margin-top: 1.6rem; padding-top: 1rem;
  border-top: 2px solid var(--ciano);
  font-family: var(--font-cond, inherit);
  font-size: .82rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--tinta-2);
}

/* 🏠 A FAIXA DE ALUGUÉIS — slim de propósito (§3B do briefing): o serviço ganha
   visibilidade sem virar uma seção do tamanho das outras, porque ele não é o que
   traz a pessoa até aqui. */
.faixa-servico {
  background: var(--navy); color: #fff;
  padding: clamp(1.4rem, 4vw, 2.2rem) 0;
}
.faixa-servico .container {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.2rem; flex-wrap: wrap;
}
.faixa-servico p { margin: 0; max-width: 62ch; color: rgba(255, 255, 255, .92); }
.faixa-servico strong { color: #fff; }

/* 🪤 No celular a faixa empilha e o botão vai para baixo, largura cheia — botão
   estreito ao lado de duas linhas de texto vira alvo de toque ruim. */
@media (max-width: 719px) {
  .faixa-servico .container { flex-direction: column; align-items: flex-start; }
  .faixa-servico .btn { width: 100%; text-align: center; }
}

/* ─── A diretoria (`a-1001`) ──────────────────────────────────────────────────
   🔵 A "bolinha" é CSS, não uma máscara gravada no arquivo: a imagem é um
   QUADRADO e quem faz o círculo é o `border-radius`. Assim a mesma foto serve
   se um dia a seção virar retângulo, e o WebP não carrega um canto transparente
   que ninguém vê. 🪤 `object-fit: cover` fica junto porque sem ele um arquivo
   que não seja exatamente quadrado entraria esticado.
   📏 `clamp` de 220 a 380 px: abaixo de 220 os três rostos somem no celular
   pequeno, e acima de 380 a foto rouba a página do texto que vem depois. */
/* 🖼️ QUEM SOMOS EM DUAS COLUNAS (03/09/2026) — a foto à esquerda, o texto à
   direita. 📌 Nasceu de duas frases do responsável no mesmo pedido: *"quero nossa
   foto aqui"* e *"tem um espaço na esquerda [...] feia"*. Eram a mesma coisa: o
   bloco estreito centralizado deixava um vazio grande dos dois lados.

   ⚰️ AS DUAS COLUNAS DURARAM UM DIA — o bloco abaixo (04/09) as trocou por um
   float com contorno, e com elas saíram o `minmax(0, 1fr)` e a quebra em 900 px
   que este parágrafo justificava. O pedido de 03/09 continua atendido: a foto
   segue à esquerda e o vazio segue preenchido. ⛔ O que NÃO vale mais é a
   conta do breakpoint: ela agora tem três larguras a descontar, não uma. */
/* 🌀 E EM 04/09/2026 A GRADE VIROU FLUXO — 📌 *"aqui podia fazer o texto em
   voltas da bola da foto ia ficar legal, coloca uma linha paralela demonstrando
   que tá descendo um fluxo"* (responsável).

   🔑 O QUE MUDOU DE VERDADE: a foto deixou de ser COLUNA e passou a ser um FLOAT
   dentro do texto. É a única forma de o texto contorná-la — numa grade as duas
   caixas são irmãs e nenhuma linha atravessa a fronteira. O recorte redondo quem
   faz é o `shape-outside` (abaixo), não o `border-radius`: o raio arredonda o
   pixel, o shape arredonda o ESPAÇO que o texto pode ocupar. Os dois têm de
   descrever o mesmo círculo, senão o texto encosta no rosto de um lado e sobra
   um vão do outro.

   📐 1040 px e não os 1180 do `.container`: com a bola de 340 comendo a esquerda,
   a linha ao lado dela fica em ~62ch — a medida de conforto que a seção já tinha
   quando era um bloco estreito. Nos 1180 ela passaria de 80 caracteres.
   🪤 `flow-root` (e não um clearfix): sem BFC no pai, o float VAZA para fora da
   seção quando o texto é mais curto que a foto — e o texto aqui é curto de
   propósito.
   🪤 O `padding-left` é a CALHA da linha do fluxo, e ela precisa dos 60 px: o
   arco chega a 38 px da borda. Estreitou a calha, a linha sai do container e a
   página ganha rolagem horizontal. */
.quem {
  position: relative;
  display: flow-root;
  width: min(1040px, 100% - 2.5rem);
  padding-left: max(60px, env(safe-area-inset-left));
}
/* 🪤 `.quem .quem__foto`, não `.quem__foto`: a figura também carrega
   `.equipe__foto`, que é declarada DEPOIS neste arquivo e tem a mesma
   especificidade — com um seletor só, o `clamp` de lá vencia por ordem e a foto
   saía com 380 px dentro de uma coluna de 340, vazando 40 px para o texto. */
/* 📐 O POLÍGONO É O CÍRCULO DA FOTO, PONTO A PONTO, MAIS A CAIXA DA LEGENDA.
   Dezessete vértices em `x = 170 + 170·sen t, y = 170 − 170·cos t` desenham a
   metade direita do círculo (é só ela que importa: o float é à esquerda, e o
   texto só enxerga a borda voltada para ele). Depois o caminho abre para os
   340 px cheios em y=354 — ali começa a legenda, e nome de gente não se contorna
   pela metade.
   ⛔ POR QUE NÃO `shape-outside: circle(50%)`, que seria uma linha: o `<figure>`
   é MAIS ALTO que largo (foto + legenda), e o `circle(50%)` mede pelo lado menor
   e centraliza na caixa inteira — o texto desceria por cima dos três nomes.
   🪤 Os números são px porque a foto é 340 px fixos. Trocou a largura da foto,
   recalcule os 17 pontos: um polígono defasado não dá erro nenhum, só encosta o
   texto na imagem.
   📏 `shape-margin: 28px` é o respiro entre a curva do texto e a borda da foto —
   abaixo de ~20 px as linhas parecem coladas na bola. */
/* 🔴 A MARGEM DIREITA DE 30 px NÃO É ESPAÇO, É ESPAÇO PARA A CURVA CABER.
   📏 Medido em 04/09/2026, e é o defeito que quase passou: `shape-outside` é
   RECORTADO pela margin box do float. Sem a margem, o círculo inflado pelos
   28 px de `shape-margin` (raio 198 numa caixa de 340) era cortado nos flancos, e
   o texto ficava reto e colado na foto em toda a faixa central — sobrava curva
   só nas pontas. A variação de recuo entre a barriga e o topo da bola era de
   37 px; com a margem, é de ~87 px, que é o efeito que se vê.
   ⚠️ Regra: `margin-right` ≥ `shape-margin`, sempre. */
.quem .quem__foto {
  margin: 0 30px .6rem 0; width: 340px;
  float: left;
  shape-outside: polygon(
    0px 0px, 170px 0px, 203px 3px, 235px 13px, 264px 29px, 290px 50px,
    311px 76px, 327px 105px, 337px 137px, 340px 170px, 337px 203px,
    327px 235px, 311px 264px, 290px 290px, 264px 311px, 235px 327px,
    203px 337px, 170px 340px, 170px 354px, 340px 354px, 340px 100%, 0px 100%
  );
  shape-margin: 28px;
}
/* 🪤 O SELO DO CRECI TEM UMA BORDA, E BORDA NÃO CONTORNA FLOAT. Só as LINHAS de
   texto desviam da foto — a caixa do parágrafo continua começando na borda
   esquerda do container, e a `border-top` ciano dele riscava a página inteira,
   passando por cima da legenda com os nomes da diretoria.
   ✅ `flow-root` cria um contexto de formatação, e caixa de BFC não se sobrepõe a
   float: o navegador a estreita e a encosta ao lado da foto sozinho. Sem número
   escrito à mão, e continua certo se a foto mudar de tamanho. */
.quem__texto .selo-creci { display: flow-root; }
.quem__foto figcaption {
  margin-top: .9rem; font-size: .82rem; line-height: 1.5;
  color: var(--tinta-2); text-align: center; text-wrap: balance;
}
.quem__foto figcaption a { color: var(--destaque); }
.quem__texto > :first-child { margin-top: 0; }
/* 📏 62ch ERA O TETO DA COLUNA, e saiu com a coluna. Quem limita a linha agora é
   o conjunto: 1040 px de container menos a bola e o respiro dela deixam ~62ch na
   barriga do círculo — a mesma medida, obtida pela geometria em vez de por um
   `max-width`. ⛔ Devolver um `max-width` aqui MATA o efeito: a caixa do texto
   encolhe e as linhas param de acompanhar a curva, porque o que sobra à direita
   da bola vira o limite. */
.quem__texto { max-width: none; }
/* 🪤 `text-wrap: pretty` e não `balance` no título: `balance` iguala o
   comprimento das linhas, que é exatamente o oposto do que esta seção quer —
   aqui a linha é curta ou longa porque a bola está ali. */
.quem__texto h2 { text-wrap: pretty; }

/* 📐 A QUEBRA SUBIU DE 900 PARA 1000 PX EM 04/09/2026, e o número é medido.
   O contorno come largura três vezes: 60 px de calha, 340 da foto e 30 de
   margem. 📏 Em 900 px sobravam 415 px de linha — 41 caracteres, o degrau onde a
   leitura começa a doer (era esse mesmo o motivo do 900 antigo, com a conta da
   grade, que tinha uma fronteira a menos). Em 1000 sobram 530 px ≈ 53ch.
   🪤 O `matchMedia` do `movimento.js` (bloco ⑦·b) usa o MESMO 1000. Mexeu aqui,
   mexa lá: senão o JS anima uma linha que o CSS escondeu. */
@media (max-width: 999px) {
  /* Empilha e centraliza: no celular a foto vira abertura, não coluna.
     🔴 `float: none` E `shape-outside: none`: em coluna única o contorno vira
     uma coluna de 3 palavras espremida ao lado da bola. E a linha do fluxo sai
     junto — não há calha onde desenhá-la sem empurrar a foto para fora. */
  .quem {
    display: grid; grid-template-columns: 1fr; justify-items: center;
    text-align: center; padding-left: 0; gap: 2rem;
  }
  .quem .quem__foto {
    float: none; shape-outside: none; margin: 0; width: min(60vw, 260px);
  }
  /* 🔴 O TETO DE LEITURA VOLTA AQUI, e ele não é decoração: sem contorno, quem
     limitava a linha era a bola. 📏 Sem esta regra, um tablet de 768 px lia o
     parágrafo em 71 caracteres, e um de 999 em 96. */
  .quem__texto { text-align: left; max-width: 62ch; }
}

.equipe { text-align: center; }
.equipe__foto { margin: 2rem auto 2.5rem; width: clamp(220px, 62vw, 380px); }
.equipe__foto img {
  width: 100%; height: auto; aspect-ratio: 1; object-fit: cover;
  border-radius: 50%;
  /* 🎯 O anel é a cor do PAPEL, não do navy: ele existe para separar a foto do
     fundo sem desenhar um círculo colorido em volta de rostos. A sombra é a
     mesma dos cartões da vitrine, para a foto pertencer à página. */
  border: 6px solid var(--folha);
  box-shadow: var(--sombra);
}
.equipe__gente {
  list-style: none; padding: 0; margin: 0 auto 2rem; max-width: 760px;
  display: grid; gap: 1.25rem 2rem;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.equipe__gente li { display: flex; flex-direction: column; gap: .15rem; }
/* 🔴 `--destaque`, e não `--navy` — os nomes da diretoria SUMIAM no escuro.
   📏 Medido em 04/09/2026: `--navy` (#3C3E69) é a marca, definido uma vez no
   `:root` e nunca redeclarado nos dois blocos do escuro — de propósito, a marca
   não tem versão escura. Só que das oito vezes em que ele aparece nesta folha,
   esta era a ÚNICA como cor de TEXTO; as outras sete são fundo com branco por
   cima, e por isso não quebram. Sobre o papel escuro (#1B1E33) dava 1,63:1.
   `--destaque` é o token de ÊNFASE que existe exatamente para isto (a nota dele
   está no `:root`): o mesmo #3C3E69 no claro (8,54:1) e #E9EAF2 no escuro
   (13,68:1). */
.equipe__gente strong { color: var(--destaque); font-size: 1.05rem; }
/* `--tinta-2`, e não `--tinta-3`: o cargo é uma linha de leitura em .95rem, não
   um rótulo em versalete — a segunda tinta é a do texto corrido. (Até 04/09 a
   nota aqui dizia que a terceira reprovava no AA; hoje ela passa, e a escolha é
   de hierarquia.) */
.equipe__gente span { color: var(--tinta-2); font-size: .95rem; }
.equipe .prosa { margin-inline: auto; }

/* ─── A planta que abre (`village-campos-verdes`) ─────────────────────────────
   🗺️ A planta é SVG e vive dentro de um `.bloco__arte`, que já tem o tamanho e o
   raio da seção. O que estas regras acrescentam é (a) a troca clara/escura por
   TEMA e (b) o convite para clicar — sem os dois, ela parece uma figura fixa. */
/* 🪤 FUNDO PRÓPRIO, e não o do `.bloco__arte`. As duas versões da planta são
   `loading="lazy"`: a que está escondida NÃO foi baixada, então no instante em
   que alguém troca o tema a caixa fica sem imagem por uma fração de segundo — e
   o que aparecia atrás era o navy com o padrão de casinhas, que num tema claro
   lê como defeito. 📏 Medido em 03/09/2026, e foi o que o responsável viu ("por
   que tá escuro no tema claro?"). Com a cor do papel embaixo, a troca é
   imperceptível: o fundo já é da cor certa antes de a planta chegar. */
.planta-abre {
  position: relative; display: block; overflow: hidden; cursor: zoom-in;
  background-image: none; background-color: var(--folha);
}
/* 🗺️ `contain`, NUNCA `cover` — 04/09/2026, e a diferença é de conteúdo, não de
   gosto. `cover` estava cortando os lados para preencher a caixa 4:3 que a grade
   impõe: com a planta nova (2400×1645), o que ficava de fora era o BLOCO DE
   TÍTULO — a tela mostrava "illage Campos Verdes", sem o V, e a escala e a
   legenda saíam pela borda. 📏 Medido: `render 558×419` (1,33:1) para um desenho
   de 1,46:1.
   🔑 Cortar uma FOTO é enquadrar; cortar um MAPA é remover informação. E aqui não
   custa nada: a caixa já tem `background-color: var(--folha)`, então a sobra
   vertical fica da cor do papel e ninguém vê letterbox.
   🪤 A versão de celular já fazia certo (`contain`, no `@media` abaixo). Era só o
   computador que cortava — o defeito vivia justamente na largura em que dá para
   ler o rodapé da peça. */
.planta-abre img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* 🗺️ A PLANTA EM TELA CHEIA — fundo e variante, agora com UM tema só.
   📌 *"pode deixar só o tema claro no site"* (responsável, 04/09/2026). Este
   bloco tinha quatro regras (`html[data-tema="claro"|"escuro"]` × fundo e
   variante) e virou duas: o site não alterna mais.
   🧹 04/09/2026 — A VARIANTE ESCURA SAIU DE VEZ, e este comentário afirmava o
   contrário: dizia que ela "continua existindo como arquivo", quando o mesmo
   commit que tirou o tema escuro (`7c47e97`) já tinha APAGADO o
   `mapa-village-escuro.svg` do repositório. Sobraram só as referências — o
   `href` do `<a>` (o fallback sem JS, que ia para um 404), o
   `data-planta-escuro` e um `<img>` que este bloco escondia. Os três saíram.
   🪤 E a regra `.planta-abre__escuro { display: none; }` estava escrita DUAS
   VEZES aqui, uma embaixo da outra — sinal de que a remoção do tema passou por
   este bloco sem que ninguém lesse o que já havia. */
.planta-abre { background-color: var(--folha); }
.planta-abre__claro { display: block; }

/* 📱 NO CELULAR, SÓ O MAPA. 📌 *"na versão de cel não, só mostra o mapa"*
   (responsável, 03/09/2026). Sem coluna vizinha para invadir, o efeito de crescer
   não faz sentido lá — o que resolve é a planta usar a largura inteira e ganhar
   altura, saindo do 4:3 que a grade impõe no computador. O `.bloco__par` já
   empilha sozinho abaixo de 720 px; aqui só se ajusta a proporção e o recorte.
   🪤 `contain` e não `cover`: em pé, o `cover` cortaria as duas pontas do
   loteamento — e é justamente o desenho inteiro que a pessoa foi ver. */
@media (max-width: 719px) {
  .planta-abre { aspect-ratio: 3 / 4; }
  .planta-abre img { object-fit: contain; }
}

.planta-abre__lupa {
  position: absolute; right: .9rem; bottom: .9rem;
  padding: .4rem .8rem; border-radius: 999px;
  background: rgba(23, 26, 46, .72); color: #fff; font-size: .85rem; font-weight: 600;
  backdrop-filter: blur(6px);
}
.planta-abre:hover .planta-abre__lupa { background: var(--aco); }
/* 🪤 A PÍLULA VAI PARA O CANTO ESQUERDO — o direito é do botão de WhatsApp.
   📏 Medido em 390×844 (04/09/2026): "Ampliar" ocupava x 274–348 / y 773–807 e
   o `.zap` (fixo, z 1150) x 312–359 / y 781–828 — sobreposição real, com o FAB
   por cima. Os dois eram ancorados à direita: a pílula pelo `right` da regra
   base, o FAB pelo `right: max(1rem, …)`. `right: auto` solta a âncora da base;
   sem ele `left` e `right` valem juntos e a pílula estica de um canto ao outro.

   🪤 E ESTE BLOCO FICA DEPOIS DA REGRA BASE — a ordem é parte do conserto. A
   versão anterior desta regra vivia no `@media (max-width: 719px)` lá em cima,
   ANTES da base, com a mesma especificidade (0,1,0): `right`, `bottom` e
   `font-size` perdiam para a base por ordem, e as três declarações eram letra
   morta — no celular a pílula sempre mediu .9rem/.85rem, não .6rem/.8rem. Foi
   assim que a primeira tentativa desta correção não pegou: `right: auto` perdeu
   para o `right: .9rem` da base, e a pílula esticou de x 22 a 348 (medido em
   iframe de 390 px). ⛔ Não a devolva ao bloco de cima "para ficar junto". */
@media (max-width: 719px) {
  .planta-abre__lupa { left: .6rem; right: auto; bottom: .6rem; font-size: .8rem; }
}

/* 🖼️ O quadro em tela cheia. `dialog` nativo: Esc, foco preso e fundo inerte vêm
   de graça — reimplementar isso à mão é como se erra acessibilidade. */
.planta-quadro {
  width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh;
  margin: 0; padding: 0; border: 0; background: #0E1020;
}
.planta-quadro::backdrop { background: rgba(8, 9, 20, .92); }
.planta-quadro__palco {
  width: 100%; height: 100%; display: grid; place-items: center; overflow: hidden;
  /* 🤏 `none` É A METADE CSS DE UM ACORDO COM O `planta-expandir.js`, e não pode
     mudar sozinho. Até 04/09/2026 o script só tratava roda, duplo clique e
     arraste de UM ponteiro, e este `none` desligava a pinça nativa junto — no
     celular a planta abria em tela cheia e não aproximava de jeito nenhum. O
     conserto ficou no JS, que passou a ler a pinça por Pointer Events (bloco
     "O TOQUE") e grava este mesmo valor INLINE no palco: quem lê o gesto é quem
     diz ao navegador para não o disputar. Aqui ele fica declarado por
     legibilidade e como cinto — o inline vence esta linha de qualquer jeito.
     ⛔ NÃO troque por `pinch-zoom` achando que devolve a pinça ao navegador: o
     zoom nativo é o da PÁGINA (a `meta viewport` permite), o segundo dedo vira
     `pointercancel` para o script, o ✕ sai da tela e, ao fechar o quadro, a
     página atrás continua ampliada. O caso inteiro está no cabeçalho do JS. */
  touch-action: none;
}
/* 🪤 `width/height: 100%` + `object-fit: contain`, e NÃO `max-width/max-height`:
   dentro de um grid o item tem `min-height: auto`, que impede o encolhimento — 📏
   medido, a planta de 2400×1840 renderizava 1920×1472 numa janela de 911 px de
   altura, com o rodapé da legenda cortado. O `contain` faz a planta caber
   INTEIRA, que é o ponto de abrir em tela cheia. */
.planta-quadro__palco img {
  width: 100%; height: 100%; object-fit: contain;
  transform-origin: center center; will-change: transform; user-select: none;
}
.planta-quadro__fechar {
  position: absolute; top: 1rem; right: 1rem; z-index: 2;
  width: 42px; height: 42px; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(255, 255, 255, .14); color: #fff; font-size: 1.1rem;
}
.planta-quadro__fechar:hover { background: rgba(255, 255, 255, .26); }
.planta-quadro__dica {
  position: absolute; left: 0; right: 0; bottom: 1rem; margin: 0;
  text-align: center; color: rgba(255, 255, 255, .66); font-size: .85rem;
}
